diff options
Diffstat (limited to 'usr/src/lib/libc')
27 files changed, 413 insertions, 63 deletions
diff --git a/usr/src/lib/libc/Makefile.targ b/usr/src/lib/libc/Makefile.targ index 9f9f6d2dfb..bb9ccf467d 100644 --- a/usr/src/lib/libc/Makefile.targ +++ b/usr/src/lib/libc/Makefile.targ @@ -21,6 +21,7 @@ # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2016 Joyent, Inc. # # @@ -93,6 +94,10 @@ pics/%.o: $(LIBCBASE)/../$(MACH)/sys/%.s $(BUILD.s) $(POST_PROCESS_O) +pics/%.o: $(LIBCBASE)/../$(MACH)/sys/%.c + $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) + pics/%.o: $(LIBCBASE)/../$(TARGET_ARCH)/sys/%.c $(COMPILE.c) -o $@ $< $(POST_PROCESS_O) diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index 4580972482..a2803faedf 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -36,6 +36,10 @@ VERS= .1 CPP= /usr/lib/cpp TARGET_ARCH= amd64 +# include comm page definitions +include $(SRC)/lib/commpage/Makefile.shared.targ +include $(SRC)/lib/commpage/Makefile.shared.com + # objects are grouped by source directory # local objects @@ -106,6 +110,7 @@ COMOBJS= \ strtoull.o GENOBJS= \ + $(COMMPAGE_OBJS) \ _getsp.o \ abs.o \ alloca.o \ @@ -281,6 +286,7 @@ COMSYSOBJS= \ SYSOBJS= \ __clock_gettime.o \ + __clock_gettime_sys.o \ __getcontext.o \ __uadmin.o \ _lwp_mutex_unlock.o \ @@ -876,6 +882,7 @@ PORTSYS= \ fcntl.o \ getpagesizes.o \ getpeerucred.o \ + inotify.o \ inst_sync.o \ issetugid.o \ label.o \ @@ -1183,6 +1190,8 @@ $(PORTI18N_COND:%=pics/%) := \ pics/arc4random.o := CPPFLAGS += -I$(SRC)/common/crypto/chacha +pics/__clock_gettime.o := CPPFLAGS += $(COMMPAGE_CPPFLAGS) + .KEEP_STATE: all: $(LIBS) $(LIB_PIC) diff --git a/usr/src/lib/libc/amd64/gen/siginfolst.c b/usr/src/lib/libc/amd64/gen/siginfolst.c index 8451dfbb4f..8b8a1b4669 100644 --- a/usr/src/lib/libc/amd64/gen/siginfolst.c +++ b/usr/src/lib/libc/amd64/gen/siginfolst.c @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2015, Joyent, Inc. */ /* Copyright (c) 1988 AT&T */ @@ -188,6 +189,7 @@ static const struct siginfolist _sys_siginfolist_data[NSIG-1] = { 0, 0, 0, 0, 0, 0, /* SIGRTMIN+15 */ + 0, 0, /* SIGRTMIN+16 */ 0, 0, /* SIGRTMAX-15 */ 0, 0, 0, 0, diff --git a/usr/src/lib/libc/amd64/sys/__clock_gettime.s b/usr/src/lib/libc/amd64/sys/__clock_gettime_sys.s index 0a98de28a9..bef188c18e 100644 --- a/usr/src/lib/libc/amd64/sys/__clock_gettime.s +++ b/usr/src/lib/libc/amd64/sys/__clock_gettime_sys.s @@ -21,25 +21,28 @@ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2016 Joyent, Inc. */ - .file "__clock_gettime.s" + .file "__clock_gettime_sys.s" +#include <sys/asm_linkage.h> #include <sys/time_impl.h> #include "SYS.h" + /* * int - * __clock_gettime(clockid_t clock_id, timespec_t *tp) + * __clock_gettime_sys(clockid_t clock_id, timespec_t *tp) */ - ENTRY(__clock_gettime) + ENTRY(__clock_gettime_sys) cmpl $__CLOCK_REALTIME0, %edi /* if (clock_id) */ - je 2f /* equal to __CLOCK_REALTIME0 */ + je 2f /* equals __CLOCK_REALTIME0 */ cmpl $CLOCK_REALTIME, %edi /* or if (clock_id) */ - jne 1f /* equal to CLOCK_REALTIME */ + jne 1f /* equals CLOCK_REALTIME */ 2: - pushq %rsi /* preserve the timespec_t pointer */ + pushq %rsi /* preserve timespec_t ptr */ SYSFASTTRAP(GETHRESTIME) popq %rsi movq %rax, (%rsi) @@ -49,4 +52,4 @@ SYSTRAP_RVAL1(clock_gettime) SYSCERROR RETC - SET_SIZE(__clock_gettime) + SET_SIZE(__clock_gettime_sys) diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index c73b03879f..7c768d1019 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -34,6 +34,10 @@ VERS= .1 CPP= /usr/lib/cpp TARGET_ARCH= i386 +# include comm page definitions +include $(SRC)/lib/commpage/Makefile.shared.targ +include $(SRC)/lib/commpage/Makefile.shared.com + VALUES= values-Xa.o # objects are grouped by source directory @@ -110,6 +114,7 @@ DTRACEOBJS= \ dtrace_data.o GENOBJS= \ + $(COMMPAGE_OBJS) \ _div64.o \ _divdi3.o \ _getsp.o \ @@ -305,6 +310,7 @@ COMSYSOBJS= \ SYSOBJS= \ __clock_gettime.o \ + __clock_gettime_sys.o \ __getcontext.o \ __uadmin.o \ _lwp_mutex_unlock.o \ @@ -916,6 +922,7 @@ PORTSYS= \ fcntl.o \ getpagesizes.o \ getpeerucred.o \ + inotify.o \ inst_sync.o \ issetugid.o \ label.o \ @@ -1251,6 +1258,8 @@ $(PORTI18N_COND:%=pics/%) := \ pics/arc4random.o := CPPFLAGS += -I$(SRC)/common/crypto/chacha +pics/__clock_gettime.o := CPPFLAGS += $(COMMPAGE_CPPFLAGS) + .KEEP_STATE: all: $(LIBS) $(LIB_PIC) diff --git a/usr/src/lib/libc/i386/gen/siginfolst.c b/usr/src/lib/libc/i386/gen/siginfolst.c index 8451dfbb4f..8b8a1b4669 100644 --- a/usr/src/lib/libc/i386/gen/siginfolst.c +++ b/usr/src/lib/libc/i386/gen/siginfolst.c @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2015, Joyent, Inc. */ /* Copyright (c) 1988 AT&T */ @@ -188,6 +189,7 @@ static const struct siginfolist _sys_siginfolist_data[NSIG-1] = { 0, 0, 0, 0, 0, 0, /* SIGRTMIN+15 */ + 0, 0, /* SIGRTMIN+16 */ 0, 0, /* SIGRTMAX-15 */ 0, 0, 0, 0, diff --git a/usr/src/lib/libc/i386/sys/__clock_gettime.c b/usr/src/lib/libc/i386/sys/__clock_gettime.c new file mode 100644 index 0000000000..cdc40f7747 --- /dev/null +++ b/usr/src/lib/libc/i386/sys/__clock_gettime.c @@ -0,0 +1,45 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Joyent, Inc. + */ + + + +#include "thr_uberdata.h" +#include <cp_defs.h> + +extern int __clock_gettime_sys(clockid_t, timespec_t *); + +int +__clock_gettime(clockid_t clock_id, timespec_t *tp) +{ + comm_page_t *cp = (comm_page_t *)__uberdata.ub_comm_page; + + if (cp != NULL && __cp_can_gettime(cp) == 0) { + switch (clock_id) { + case __CLOCK_REALTIME0: + case CLOCK_REALTIME: + __cp_clock_gettime_realtime(cp, tp); + return (0); + + case CLOCK_MONOTONIC: + hrt2ts(__cp_gethrtime(cp), tp); + return (0); + + default: + /* Fallback */ + break; + } + } + return (__clock_gettime_sys(clock_id, tp)); +} diff --git a/usr/src/lib/libc/i386/sys/__clock_gettime.s b/usr/src/lib/libc/i386/sys/__clock_gettime_sys.s index cf9ee306ff..57c831843a 100644 --- a/usr/src/lib/libc/i386/sys/__clock_gettime.s +++ b/usr/src/lib/libc/i386/sys/__clock_gettime_sys.s @@ -21,24 +21,26 @@ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2016 Joyent, Inc. */ - .file "__clock_gettime.s" + .file "__clock_gettime_sys.s" +#include <sys/asm_linkage.h> #include <sys/time_impl.h> #include "SYS.h" /* * int - * __clock_gettime(clockid_t clock_id, timespec_t *tp) + * __sys_clock_gettime(clockid_t clock_id, timespec_t *tp) */ - ENTRY(__clock_gettime) + ENTRY(__clock_gettime_sys) movl 4(%esp), %eax - cmpl $__CLOCK_REALTIME0, %eax / if (clock_id) - je 2f / equal to __CLOCK_REALTIME0 - cmpl $CLOCK_REALTIME, %eax / or if (clock_id) - jne 1f / equal to CLOCK_REALTIME + cmpl $__CLOCK_REALTIME0, %eax /* if (clock_id) */ + je 2f /* equal to __CLOCK_REALTIME0 */ + cmpl $CLOCK_REALTIME, %eax /* or if (clock_id) */ + jne 1f /* equal to CLOCK_REALTIME */ 2: SYSFASTTRAP(GETHRESTIME) movl 8(%esp), %ecx @@ -49,4 +51,4 @@ SYSTRAP_RVAL1(clock_gettime) SYSCERROR RETC - SET_SIZE(__clock_gettime) + SET_SIZE(__clock_gettime_sys) diff --git a/usr/src/lib/libc/inc/thr_inlines.h b/usr/src/lib/libc/inc/thr_inlines.h index f7cdc6a6bd..66d811f25b 100644 --- a/usr/src/lib/libc/inc/thr_inlines.h +++ b/usr/src/lib/libc/inc/thr_inlines.h @@ -47,17 +47,19 @@ extern __GNU_INLINE ulwp_t * _curthread(void) { -#if defined(__amd64) ulwp_t *__value; - __asm__ __volatile__("movq %%fs:0, %0" : "=r" (__value)); + __asm__ __volatile__( +#if defined(__amd64) + "movq %%fs:0, %0\n\t" #elif defined(__i386) - ulwp_t *__value; - __asm__ __volatile__("movl %%gs:0, %0" : "=r" (__value)); + "movl %%gs:0, %0\n\t" #elif defined(__sparc) - register ulwp_t *__value __asm__("g7"); + ".register %%g7, #scratch\n\t" + "mov %%g7, %0\n\t" #else #error "port me" #endif + : "=r" (__value)); return (__value); } diff --git a/usr/src/lib/libc/inc/thr_uberdata.h b/usr/src/lib/libc/inc/thr_uberdata.h index 384a23582d..ff18c8e9f4 100644 --- a/usr/src/lib/libc/inc/thr_uberdata.h +++ b/usr/src/lib/libc/inc/thr_uberdata.h @@ -956,6 +956,7 @@ typedef struct uberdata { int ndaemons; /* total number of THR_DAEMON threads/lwps */ pid_t pid; /* the current process's pid */ void (*sigacthandler)(int, siginfo_t *, void *); + int (*setctxt)(const ucontext_t *); ulwp_t *lwp_stacks; ulwp_t *lwp_laststack; int nfreestack; @@ -968,6 +969,8 @@ typedef struct uberdata { robust_t **robustlocks; /* table of registered robust locks */ robust_t *robustlist; /* list of registered robust locks */ char *progname; /* the basename of the program, from argv[0] */ + char *ub_broot; /* the root of the native code in the brand */ + void *ub_comm_page; /* arch-specific comm page of kernel data */ struct uberdata **tdb_bootstrap; tdb_t tdb; /* thread debug interfaces (for libc_db) */ } uberdata_t; @@ -1169,6 +1172,7 @@ typedef struct uberdata32 { int ndaemons; int pid; caddr32_t sigacthandler; + caddr32_t setctxt; caddr32_t lwp_stacks; caddr32_t lwp_laststack; int nfreestack; @@ -1181,6 +1185,7 @@ typedef struct uberdata32 { caddr32_t robustlocks; caddr32_t robustlist; caddr32_t progname; + caddr32_t ub_comm_page; caddr32_t tdb_bootstrap; tdb32_t tdb; } uberdata32_t; @@ -1270,6 +1275,7 @@ extern void rwl_free(ulwp_t *); extern void heldlock_exit(void); extern void heldlock_free(ulwp_t *); extern void sigacthandler(int, siginfo_t *, void *); +extern int setctxt(const ucontext_t *); extern void signal_init(void); extern int sigequalset(const sigset_t *, const sigset_t *); extern void mutex_setup(void); diff --git a/usr/src/lib/libc/port/gen/getauxv.c b/usr/src/lib/libc/port/gen/getauxv.c index 500675719c..4356a01392 100644 --- a/usr/src/lib/libc/port/gen/getauxv.c +++ b/usr/src/lib/libc/port/gen/getauxv.c @@ -24,9 +24,8 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "lint.h" +#include "thr_uberdata.h" #include <libc.h> #include <fcntl.h> #include <stdlib.h> @@ -38,6 +37,7 @@ #include <thread.h> #include <synch.h> #include <atomic.h> +#include <limits.h> static mutex_t auxlock = DEFAULTMUTEX; @@ -59,11 +59,20 @@ _getaux(int type) if (auxb == NULL) { lmutex_lock(&auxlock); if (auxb == NULL) { + uberdata_t *udp = curthread->ul_uberdata; struct stat statb; auxv_t *buf = NULL; + char *path = "/proc/self/auxv"; + char pbuf[PATH_MAX]; int fd; - if ((fd = open("/proc/self/auxv", O_RDONLY)) != -1 && + if (udp->ub_broot != NULL) { + (void) snprintf(pbuf, sizeof (pbuf), + "%s/proc/self/auxv", udp->ub_broot); + path = pbuf; + } + + if ((fd = open(path, O_RDONLY)) != -1 && fstat(fd, &statb) != -1) buf = libc_malloc( statb.st_size + sizeof (auxv_t)); diff --git a/usr/src/lib/libc/port/gen/getenv.c b/usr/src/lib/libc/port/gen/getenv.c index c345226d0c..bd13a749ed 100644 --- a/usr/src/lib/libc/port/gen/getenv.c +++ b/usr/src/lib/libc/port/gen/getenv.c @@ -21,6 +21,7 @@ /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2016 Joyent, Inc. */ /* Copyright (c) 1988 AT&T */ @@ -336,6 +337,16 @@ addtoenv(char *string, int overwrite) int putenv(char *string) { + /* + * Historically a call to putenv() with no '=' in the string would work + * great until someone called getenv() on that particular environment + * variable again. As we've always treated this as valid, rather than + * teaching the rest of the environment code how to handle something + * without an '=' sign, it instead just calls unsetenv(). + */ + if (strchr(string, '=') == NULL) + return (unsetenv(string)); + return (addtoenv(string, 1)); } diff --git a/usr/src/lib/libc/port/gen/psiginfo.c b/usr/src/lib/libc/port/gen/psiginfo.c index a648c81094..e7cf46abef 100644 --- a/usr/src/lib/libc/port/gen/psiginfo.c +++ b/usr/src/lib/libc/port/gen/psiginfo.c @@ -51,16 +51,23 @@ psiginfo(const siginfo_t *sip, const char *s) { char buf[256]; char *c; + size_t l = 0; const struct siginfolist *listp; - if (sip == 0) + if (sip == NULL) return; + if (s != NULL && *s != '\0') { + l = snprintf(buf, sizeof (buf), _libc_gettext("%s : "), s); + if (l > sizeof (buf)) + l = sizeof (buf); + } + if (sip->si_code <= 0) { - (void) snprintf(buf, sizeof (buf), - _libc_gettext("%s : %s ( from process %d )\n"), - s, strsignal(sip->si_signo), sip->si_pid); + (void) snprintf(buf + l, sizeof (buf) - l, + _libc_gettext("%s ( from process %d )\n"), + strsignal(sip->si_signo), sip->si_pid); } else if (((listp = &_sys_siginfolist[sip->si_signo-1]) != NULL) && sip->si_code <= listp->nsiginfo) { c = _libc_gettext(listp->vsiginfo[sip->si_code-1]); @@ -69,21 +76,20 @@ psiginfo(const siginfo_t *sip, const char *s) case SIGBUS: case SIGILL: case SIGFPE: - (void) snprintf(buf, sizeof (buf), - _libc_gettext("%s : %s ( [%p] %s)\n"), - s, strsignal(sip->si_signo), + (void) snprintf(buf + l, sizeof (buf) - l, + _libc_gettext("%s ( [%p] %s)\n"), + strsignal(sip->si_signo), sip->si_addr, c); break; default: - (void) snprintf(buf, sizeof (buf), - _libc_gettext("%s : %s (%s)\n"), - s, strsignal(sip->si_signo), c); + (void) snprintf(buf + l, sizeof (buf) - l, + _libc_gettext("%s (%s)\n"), + strsignal(sip->si_signo), c); break; } } else { - (void) snprintf(buf, sizeof (buf), - _libc_gettext("%s : %s\n"), - s, strsignal(sip->si_signo)); + (void) snprintf(buf + l, sizeof (buf) - l, + _libc_gettext("%s\n"), strsignal(sip->si_signo)); } (void) write(2, buf, strlen(buf)); } diff --git a/usr/src/lib/libc/port/gen/psignal.c b/usr/src/lib/libc/port/gen/psignal.c index 201beaacd7..2a61cd9610 100644 --- a/usr/src/lib/libc/port/gen/psignal.c +++ b/usr/src/lib/libc/port/gen/psignal.c @@ -37,8 +37,6 @@ * contributors. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Print the name of the signal indicated by "sig", along with the * supplied message @@ -61,14 +59,15 @@ void psignal(int sig, const char *s) { char *c; - size_t n; + size_t n = 0; char buf[256]; if (sig < 0 || sig >= NSIG) sig = 0; c = strsignal(sig); - n = strlen(s); - if (n) { + if (s != NULL) + n = strlen(s); + if (n != 0) { (void) snprintf(buf, sizeof (buf), "%s: %s\n", s, c); } else { (void) snprintf(buf, sizeof (buf), "%s\n", c); diff --git a/usr/src/lib/libc/port/gen/sh_locks.c b/usr/src/lib/libc/port/gen/sh_locks.c index 6583efbc9c..cf879195c6 100644 --- a/usr/src/lib/libc/port/gen/sh_locks.c +++ b/usr/src/lib/libc/port/gen/sh_locks.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "lint.h" #include <mtlib.h> #include <sys/types.h> diff --git a/usr/src/lib/libc/port/gen/siglist.c b/usr/src/lib/libc/port/gen/siglist.c index 441cc4c2c5..bc6dc1b731 100644 --- a/usr/src/lib/libc/port/gen/siglist.c +++ b/usr/src/lib/libc/port/gen/siglist.c @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2015, Joyent, Inc. */ /* Copyright (c) 1988 AT&T */ @@ -128,6 +129,7 @@ static const char *_sys_siglist_data[NSIG] = { "Fourteenth Realtime Signal", /* SIGRTMIN+13 */ "Fifteenth Realtime Signal", /* SIGRTMIN+14 */ "Sixteenth Realtime Signal", /* SIGRTMIN+15 */ + "Seventeenth Realtime Signal", /* SIGRTMIN+16 */ "Sixteenth Last Realtime Signal", /* SIGRTMAX-15 */ "Fifteenth Last Realtime Signal", /* SIGRTMAX-14 */ "Fourteenth Last Realtime Signal", /* SIGRTMAX-13 */ diff --git a/usr/src/lib/libc/port/gen/str2sig.c b/usr/src/lib/libc/port/gen/str2sig.c index e0c4e89d68..02c6f3cb65 100644 --- a/usr/src/lib/libc/port/gen/str2sig.c +++ b/usr/src/lib/libc/port/gen/str2sig.c @@ -22,7 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright (c) 2014, Joyent, Inc. All rights reserved. + * Copyright 2015, Joyent, Inc. */ /* Copyright (c) 1988 AT&T */ @@ -102,6 +102,7 @@ static signame_t signames[] = { { "RTMIN+13", _SIGRTMIN+13 }, { "RTMIN+14", _SIGRTMIN+14 }, { "RTMIN+15", _SIGRTMIN+15 }, + { "RTMIN+16", _SIGRTMIN+16 }, { "RTMAX-15", _SIGRTMAX-15 }, { "RTMAX-14", _SIGRTMAX-14 }, { "RTMAX-13", _SIGRTMAX-13 }, diff --git a/usr/src/lib/libc/port/llib-lc b/usr/src/lib/libc/port/llib-lc index b86f23280c..d887a44f37 100644 --- a/usr/src/lib/libc/port/llib-lc +++ b/usr/src/lib/libc/port/llib-lc @@ -25,6 +25,7 @@ * Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2013 Gary Mills * Copyright 2014 Garrett D'Amore <garrett@damore.org> + * Copyright 2015 Joyent, Inc. * Copyright 2015 Circonus, Inc. All rights reserved. * Copyright 2015 Joyent, Inc. */ diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index afb07a4bb9..c278c6a8ee 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -2986,6 +2986,10 @@ $endif __idmap_unreg; __init_daemon_priv; __init_suid_priv; + inotify_init; + inotify_init1; + inotify_add_watch; + inotify_rm_watch; _insert; inst_sync; _iswctype; @@ -3066,7 +3070,9 @@ $endif scrwidth; semctl64; _semctl64; + set_escaped_context_cleanup; set_setcontext_enforcement; + setcontext_sigmask; _setbufend; __set_errno; setprojrctl; @@ -3183,6 +3189,7 @@ $endif zone_list; zone_list_datalink; zonept; + zone_get_nroot; zone_remove_datalink; zone_setattr; zone_shutdown; diff --git a/usr/src/lib/libc/port/sys/inotify.c b/usr/src/lib/libc/port/sys/inotify.c new file mode 100644 index 0000000000..90d04b5dd3 --- /dev/null +++ b/usr/src/lib/libc/port/sys/inotify.c @@ -0,0 +1,142 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014, Joyent, Inc. All rights reserved. + */ + +#include <sys/inotify.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <strings.h> +#include <dirent.h> + +int +inotify_init() +{ + return (open("/dev/inotify", O_RDWR)); +} + +int +inotify_init1(int flags) +{ + int oflags = O_RDWR; + + if (flags & IN_NONBLOCK) + oflags |= O_NONBLOCK; + + if (flags & IN_CLOEXEC) + oflags |= O_CLOEXEC; + + return (open("/dev/inotify", oflags)); +} + +int +inotify_add_watch(int fd, const char *pathname, uint32_t mask) +{ + inotify_addwatch_t ioc; + inotify_addchild_t cioc; + struct stat buf; + int dirfd, wd; + DIR *dir; + struct dirent *dp; + int oflags = O_RDONLY; + + if (mask & IN_DONT_FOLLOW) + oflags |= O_NOFOLLOW; + + if ((dirfd = open(pathname, oflags)) < 0) + return (-1); + + if (fstat(dirfd, &buf) != 0) { + (void) close(dirfd); + return (-1); + } + + if ((mask & IN_ONLYDIR) && !(buf.st_mode & S_IFDIR)) { + (void) close(dirfd); + errno = ENOTDIR; + return (-1); + } + + bzero(&ioc, sizeof (ioc)); + ioc.inaw_fd = dirfd; + ioc.inaw_mask = mask; + + if ((wd = ioctl(fd, INOTIFYIOC_ADD_WATCH, &ioc)) < 0) { + (void) close(dirfd); + return (-1); + } + + if (!(buf.st_mode & S_IFDIR) || !(mask & IN_CHILD_EVENTS)) { + (void) close(dirfd); + (void) ioctl(fd, INOTIFYIOC_ACTIVATE, wd); + return (wd); + } + + /* + * If we have a directory and we have a mask that denotes child events, + * we need to manually add a child watch to every directory entry. + * (Because our watch is in place, it will automatically be added to + * files that are newly created after this point.) + */ + if ((dir = fdopendir(dirfd)) == NULL) { + (void) inotify_rm_watch(fd, wd); + (void) close(dirfd); + return (-1); + } + + bzero(&cioc, sizeof (cioc)); + cioc.inac_fd = dirfd; + + while ((dp = readdir(dir)) != NULL) { + if (strcmp(dp->d_name, ".") == 0) + continue; + + if (strcmp(dp->d_name, "..") == 0) + continue; + + cioc.inac_name = dp->d_name; + + if (ioctl(fd, INOTIFYIOC_ADD_CHILD, &cioc) != 0) { + /* + * If we get an error that indicates clear internal + * malfunctioning, we propagate the error. Otherwise + * we eat it: this could be a file that no longer + * exists or a symlink or something else that we + * can't lookup. + */ + switch (errno) { + case ENXIO: + case EFAULT: + case EBADF: + (void) closedir(dir); + (void) inotify_rm_watch(fd, wd); + return (-1); + default: + break; + } + } + } + + (void) closedir(dir); + (void) ioctl(fd, INOTIFYIOC_ACTIVATE, wd); + + return (wd); +} + +int +inotify_rm_watch(int fd, int wd) +{ + return (ioctl(fd, INOTIFYIOC_RM_WATCH, wd)); +} diff --git a/usr/src/lib/libc/port/sys/zone.c b/usr/src/lib/libc/port/sys/zone.c index 4a4c70043d..8cf28c3ccf 100644 --- a/usr/src/lib/libc/port/sys/zone.c +++ b/usr/src/lib/libc/port/sys/zone.c @@ -22,9 +22,11 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2011 Joyent Inc. All rights reserved. */ #include "lint.h" +#include "thr_uberdata.h" #include <sys/types.h> #include <sys/syscall.h> #include <sys/zone.h> @@ -39,7 +41,8 @@ zoneid_t zone_create(const char *name, const char *root, const struct priv_set *privs, const char *rctls, size_t rctlsz, const char *zfs, size_t zfssz, - int *extended_error, int match, int doi, const bslabel_t *label, int flags) + int *extended_error, int match, int doi, const bslabel_t *label, int flags, + zoneid_t req_zoneid) { zone_def zd; priv_data_t *d; @@ -59,6 +62,7 @@ zone_create(const char *name, const char *root, const struct priv_set *privs, zd.doi = doi; zd.label = label; zd.flags = flags; + zd.zoneid = req_zoneid; return ((zoneid_t)syscall(SYS_zone, ZONE_CREATE, &zd)); } @@ -241,3 +245,10 @@ zone_list_datalink(zoneid_t zoneid, int *dlnump, datalink_id_t *linkids) { return (syscall(SYS_zone, ZONE_LIST_DATALINK, zoneid, dlnump, linkids)); } + +const char * +zone_get_nroot() +{ + uberdata_t *udp = curthread->ul_uberdata; + return (udp->ub_broot); +} diff --git a/usr/src/lib/libc/port/threads/sigaction.c b/usr/src/lib/libc/port/threads/sigaction.c index 571e211f97..6a283be33b 100644 --- a/usr/src/lib/libc/port/threads/sigaction.c +++ b/usr/src/lib/libc/port/threads/sigaction.c @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2015 Joyent, Inc. */ #include "lint.h" @@ -284,6 +285,24 @@ take_deferred_signal(int sig) thr_panic("take_deferred_signal(): __sigresend() failed"); } +/* + * sigacthandler() attempts to clean up dangling uc_link pointers in + * signal handling contexts when libc believes us to have escaped + * a signal handler incorrectly in the past. + * + * Branded processes have a legitimate use for a chain including contexts + * other than those used for signal handling when tracking emulation + * requests from the kernel. We allow them to disable this cleanup + * behaviour. + */ +static int escaped_context_cleanup = 1; + +void +set_escaped_context_cleanup(int on) +{ + escaped_context_cleanup = on; +} + void sigacthandler(int sig, siginfo_t *sip, void *uvp) { @@ -306,7 +325,7 @@ sigacthandler(int sig, siginfo_t *sip, void *uvp) * we are actually executing at main level (self->ul_siglink == NULL). * See the code for setjmp()/longjmp() for more details. */ - if (self->ul_siglink == NULL) + if (escaped_context_cleanup && self->ul_siglink == NULL) ucp->uc_link = NULL; /* @@ -458,11 +477,12 @@ sigaction(int sig, const struct sigaction *nact, struct sigaction *oact) } /* - * This is a private interface for the linux brand interface. + * This is a private interface for the lx brand. */ void setsigacthandler(void (*nsigacthandler)(int, siginfo_t *, void *), - void (**osigacthandler)(int, siginfo_t *, void *)) + void (**osigacthandler)(int, siginfo_t *, void *), + int (*brsetctxt)(const ucontext_t *)) { ulwp_t *self = curthread; uberdata_t *udp = self->ul_uberdata; @@ -471,6 +491,9 @@ setsigacthandler(void (*nsigacthandler)(int, siginfo_t *, void *), *osigacthandler = udp->sigacthandler; udp->sigacthandler = nsigacthandler; + + if (brsetctxt != NULL) + udp->setctxt = brsetctxt; } /* @@ -517,11 +540,39 @@ set_setcontext_enforcement(int on) setcontext_enforcement = on; } +/* + * The LX brand emulation library implements an operation that is analogous to + * setcontext(), but takes a different path in to the kernel. So that it can + * correctly restore a signal mask, we expose just the signal mask handling + * part of the regular setcontext() routine as a private interface. + */ +void +setcontext_sigmask(ucontext_t *ucp) +{ + ulwp_t *self = curthread; + + if (ucp->uc_flags & UC_SIGMASK) { + block_all_signals(self); + delete_reserved_signals(&ucp->uc_sigmask); + self->ul_sigmask = ucp->uc_sigmask; + if (self->ul_cursig) { + /* + * We have a deferred signal present. + * The signal mask will be set when the + * signal is taken in take_deferred_signal(). + */ + ASSERT(self->ul_critical + self->ul_sigdefer != 0); + ucp->uc_flags &= ~UC_SIGMASK; + } + } +} + #pragma weak _setcontext = setcontext int setcontext(const ucontext_t *ucp) { ulwp_t *self = curthread; + uberdata_t *udp = self->ul_uberdata; int ret; ucontext_t uc; @@ -536,20 +587,7 @@ setcontext(const ucontext_t *ucp) /* * Restore previous signal mask and context link. */ - if (uc.uc_flags & UC_SIGMASK) { - block_all_signals(self); - delete_reserved_signals(&uc.uc_sigmask); - self->ul_sigmask = uc.uc_sigmask; - if (self->ul_cursig) { - /* - * We have a deferred signal present. - * The signal mask will be set when the - * signal is taken in take_deferred_signal(). - */ - ASSERT(self->ul_critical + self->ul_sigdefer != 0); - uc.uc_flags &= ~UC_SIGMASK; - } - } + setcontext_sigmask(&uc); self->ul_siglink = uc.uc_link; /* @@ -578,7 +616,7 @@ setcontext(const ucontext_t *ucp) */ set_parking_flag(self, 0); self->ul_sp = 0; - ret = __setcontext(&uc); + ret = udp->setctxt(&uc); /* * It is OK for setcontext() to return if the user has not specified diff --git a/usr/src/lib/libc/port/threads/thr.c b/usr/src/lib/libc/port/threads/thr.c index 88ce377f21..fcfdf6b93a 100644 --- a/usr/src/lib/libc/port/threads/thr.c +++ b/usr/src/lib/libc/port/threads/thr.c @@ -125,6 +125,7 @@ uberdata_t __uberdata = { 0, /* ndaemons */ 0, /* pid */ sigacthandler, /* sigacthandler */ + __setcontext, /* setctxt */ NULL, /* lwp_stacks */ NULL, /* lwp_laststack */ 0, /* nfreestack */ @@ -137,6 +138,8 @@ uberdata_t __uberdata = { NULL, /* robustlocks */ NULL, /* robustlist */ NULL, /* progname */ + NULL, /* ub_broot */ + NULL, /* ub_comm_page */ NULL, /* __tdb_bootstrap */ { /* tdb */ NULL, /* tdb_sync_addr_hash */ @@ -1220,6 +1223,29 @@ extern void atfork_init(void); extern void __proc64id(void); #endif +static void +init_auxv_data(uberdata_t *udp) +{ + Dl_argsinfo_t args; + + udp->ub_broot = NULL; + udp->ub_comm_page = NULL; + if (dlinfo(RTLD_SELF, RTLD_DI_ARGSINFO, &args) < 0) + return; + + while (args.dla_auxv->a_type != AT_NULL) { + switch (args.dla_auxv->a_type) { + case AT_SUN_BRAND_NROOT: + udp->ub_broot = args.dla_auxv->a_un.a_ptr; + break; + case AT_SUN_COMMPAGE: + udp->ub_comm_page = args.dla_auxv->a_un.a_ptr; + break; + } + args.dla_auxv++; + } +} + /* * libc_init() is called by ld.so.1 for library initialization. * We perform minimal initialization; enough to work with the main thread. @@ -1256,6 +1282,14 @@ libc_init(void) (void) _atexit(__cleanup); /* + * Every libc, regardless of link map, needs to go through and check + * its aux vectors. Doing so will indicate whether or not this has + * been given a brand root (used to qualify various other data) or a + * comm page (to optimize certain system actions). + */ + init_auxv_data(udp); + + /* * We keep our uberdata on one of (a) the first alternate link map * or (b) the primary link map. We switch to the primary link map * and stay there once we see it. All intermediate link maps are diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com index 062949b3f9..c525f28b3d 100644 --- a/usr/src/lib/libc/sparc/Makefile.com +++ b/usr/src/lib/libc/sparc/Makefile.com @@ -950,6 +950,7 @@ PORTSYS= \ fcntl.o \ getpagesizes.o \ getpeerucred.o \ + inotify.o \ inst_sync.o \ issetugid.o \ label.o \ diff --git a/usr/src/lib/libc/sparc/gen/siginfolst.c b/usr/src/lib/libc/sparc/gen/siginfolst.c index 8451dfbb4f..8b8a1b4669 100644 --- a/usr/src/lib/libc/sparc/gen/siginfolst.c +++ b/usr/src/lib/libc/sparc/gen/siginfolst.c @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2015, Joyent, Inc. */ /* Copyright (c) 1988 AT&T */ @@ -188,6 +189,7 @@ static const struct siginfolist _sys_siginfolist_data[NSIG-1] = { 0, 0, 0, 0, 0, 0, /* SIGRTMIN+15 */ + 0, 0, /* SIGRTMIN+16 */ 0, 0, /* SIGRTMAX-15 */ 0, 0, 0, 0, diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com index 596d349dfb..ff896639e2 100644 --- a/usr/src/lib/libc/sparcv9/Makefile.com +++ b/usr/src/lib/libc/sparcv9/Makefile.com @@ -886,6 +886,7 @@ PORTSYS= \ chmod.o \ chown.o \ corectl.o \ + epoll.o \ eventfd.o \ epoll.o \ exacctsys.o \ diff --git a/usr/src/lib/libc/sparcv9/gen/siginfolst.c b/usr/src/lib/libc/sparcv9/gen/siginfolst.c index 8451dfbb4f..8b8a1b4669 100644 --- a/usr/src/lib/libc/sparcv9/gen/siginfolst.c +++ b/usr/src/lib/libc/sparcv9/gen/siginfolst.c @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2015, Joyent, Inc. */ /* Copyright (c) 1988 AT&T */ @@ -188,6 +189,7 @@ static const struct siginfolist _sys_siginfolist_data[NSIG-1] = { 0, 0, 0, 0, 0, 0, /* SIGRTMIN+15 */ + 0, 0, /* SIGRTMIN+16 */ 0, 0, /* SIGRTMAX-15 */ 0, 0, 0, 0, |