diff options
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r-- | usr/src/lib/libc/amd64/Makefile | 3 | ||||
-rw-r--r-- | usr/src/lib/libc/i386/Makefile.com | 3 | ||||
-rw-r--r-- | usr/src/lib/libc/inc/thr_inlines.h | 12 | ||||
-rw-r--r-- | usr/src/lib/libc/inc/thr_uberdata.h | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/getauxv.c | 15 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/getlogin.c | 1 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/psiginfo.c | 34 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/psignal.c | 9 | ||||
-rw-r--r-- | usr/src/lib/libc/port/mapfile-vers | 13 | ||||
-rw-r--r-- | usr/src/lib/libc/port/sys/epoll.c | 207 | ||||
-rw-r--r-- | usr/src/lib/libc/port/sys/eventfd.c | 65 | ||||
-rw-r--r-- | usr/src/lib/libc/port/sys/inotify.c | 142 | ||||
-rw-r--r-- | usr/src/lib/libc/port/sys/zone.c | 13 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/alloc.c | 3 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/sigaction.c | 12 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/thr.c | 29 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/Makefile.com | 3 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/crt/_rtld.c | 9 | ||||
-rw-r--r-- | usr/src/lib/libc/sparcv9/Makefile.com | 1 |
19 files changed, 544 insertions, 34 deletions
diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index f4b79eedb6..d9f4e5ddc2 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -855,13 +855,16 @@ PORTSYS= \ chmod.o \ chown.o \ corectl.o \ + epoll.o \ exacctsys.o \ execl.o \ execle.o \ execv.o \ + eventfd.o \ fcntl.o \ getpagesizes.o \ getpeerucred.o \ + inotify.o \ inst_sync.o \ issetugid.o \ label.o \ diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index bf9a9f5536..0c7b9b2c1b 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -895,6 +895,8 @@ PORTSYS= \ chmod.o \ chown.o \ corectl.o \ + epoll.o \ + eventfd.o \ exacctsys.o \ execl.o \ execle.o \ @@ -902,6 +904,7 @@ PORTSYS= \ fcntl.o \ getpagesizes.o \ getpeerucred.o \ + inotify.o \ inst_sync.o \ issetugid.o \ label.o \ 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 de0d4a6b05..a58eaf915f 100644 --- a/usr/src/lib/libc/inc/thr_uberdata.h +++ b/usr/src/lib/libc/inc/thr_uberdata.h @@ -932,6 +932,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; @@ -944,6 +945,7 @@ 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 */ struct uberdata **tdb_bootstrap; tdb_t tdb; /* thread debug interfaces (for libc_db) */ } uberdata_t; @@ -1144,6 +1146,7 @@ typedef struct uberdata32 { int ndaemons; int pid; caddr32_t sigacthandler; + caddr32_t setctxt; caddr32_t lwp_stacks; caddr32_t lwp_laststack; int nfreestack; @@ -1243,6 +1246,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/getlogin.c b/usr/src/lib/libc/port/gen/getlogin.c index fadf3e055b..e4b2f62dc3 100644 --- a/usr/src/lib/libc/port/gen/getlogin.c +++ b/usr/src/lib/libc/port/gen/getlogin.c @@ -35,6 +35,7 @@ #include "lint.h" #include <sys/types.h> #include <sys/stat.h> +#include <sys/sysmacros.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> diff --git a/usr/src/lib/libc/port/gen/psiginfo.c b/usr/src/lib/libc/port/gen/psiginfo.c index 1675db36ee..6775fef969 100644 --- a/usr/src/lib/libc/port/gen/psiginfo.c +++ b/usr/src/lib/libc/port/gen/psiginfo.c @@ -27,8 +27,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Print the name of the siginfo indicated by "sig", along with the * supplied message @@ -50,16 +48,23 @@ psiginfo(siginfo_t *sip, 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]); @@ -68,21 +73,20 @@ psiginfo(siginfo_t *sip, 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/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index 8b1fe1363b..68eedf25b0 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -2819,8 +2819,16 @@ $endif _dgettext; _doprnt; _doscan; + epoll_create; + epoll_create1; + epoll_ctl; + epoll_wait; + epoll_pwait; _errfp; _errxfp; + eventfd; + eventfd_read; + eventfd_write; exportfs; _F_cplx_div; _F_cplx_div_ix; @@ -2864,6 +2872,10 @@ $endif __idmap_unreg; __init_daemon_priv; __init_suid_priv; + inotify_init; + inotify_init1; + inotify_add_watch; + inotify_rm_watch; _insert; inst_sync; _iswctype; @@ -3057,6 +3069,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/epoll.c b/usr/src/lib/libc/port/sys/epoll.c new file mode 100644 index 0000000000..93379b583e --- /dev/null +++ b/usr/src/lib/libc/port/sys/epoll.c @@ -0,0 +1,207 @@ +/* + * 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/types.h> +#include <sys/epoll.h> +#include <sys/devpoll.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <poll.h> + +/* + * Events that match their epoll(7) equivalents. + */ +#if EPOLLIN != POLLIN +#error value of EPOLLIN does not match value of POLLIN +#endif + +#if EPOLLPRI != POLLPRI +#error value of EPOLLPRI does not match value of POLLPRI +#endif + +#if EPOLLOUT != POLLOUT +#error value of EPOLLOUT does not match value of POLLOUT +#endif + +#if EPOLLRDNORM != POLLRDNORM +#error value of EPOLLRDNORM does not match value of POLLRDNORM +#endif + +#if EPOLLRDBAND != POLLRDBAND +#error value of EPOLLRDBAND does not match value of POLLRDBAND +#endif + +#if EPOLLERR != POLLERR +#error value of EPOLLERR does not match value of POLLERR +#endif + +#if EPOLLHUP != POLLHUP +#error value of EPOLLHUP does not match value of POLLHUP +#endif + +/* + * Events that we ignore entirely. They can be set in events, but they will + * never be returned. + */ +#define EPOLLIGNORED (EPOLLMSG | EPOLLWAKEUP) + +/* + * Events that we swizzle into other bit positions. + */ +#define EPOLLSWIZZLED \ + (EPOLLRDHUP | EPOLLONESHOT | EPOLLET | EPOLLWRBAND | EPOLLWRNORM) + +int +epoll_create(int size) +{ + int fd; + + /* + * From the epoll_create() man page: "Since Linux 2.6.8, the size + * argument is ignored, but must be greater than zero." You keep using + * that word "ignored"... + */ + if (size <= 0) { + errno = EINVAL; + return (-1); + } + + if ((fd = open("/dev/poll", O_RDWR)) == -1) + return (-1); + + if (ioctl(fd, DP_EPOLLCOMPAT, 0) == -1) { + (void) close(fd); + return (-1); + } + + return (fd); +} + +int +epoll_create1(int flags) +{ + int fd, oflags = O_RDWR; + + if (flags & EPOLL_CLOEXEC) + oflags |= O_CLOEXEC; + + if ((fd = open("/dev/poll", oflags)) == -1) + return (-1); + + if (ioctl(fd, DP_EPOLLCOMPAT, 0) == -1) { + (void) close(fd); + return (-1); + } + + return (fd); +} + +int +epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) +{ + dvpoll_epollfd_t epoll[2]; + uint32_t events, ev = 0; + int i = 0; + + epoll[i].dpep_pollfd.fd = fd; + + switch (op) { + case EPOLL_CTL_DEL: + ev = POLLREMOVE; + break; + + case EPOLL_CTL_MOD: + /* + * In the modify case, we pass down two events: one to + * remove the event and another to add it back. + */ + epoll[i++].dpep_pollfd.events = POLLREMOVE; + epoll[i].dpep_pollfd.fd = fd; + /* FALLTHROUGH */ + + case EPOLL_CTL_ADD: + /* + * Mask off the events that we ignore, and then swizzle the + * events for which our values differ from their epoll(7) + * equivalents. + */ + events = event->events; + ev = events & ~(EPOLLIGNORED | EPOLLSWIZZLED); + + if (events & EPOLLRDHUP) + ev |= POLLRDHUP; + + if (events & EPOLLET) + ev |= POLLET; + + if (events & EPOLLONESHOT) + ev |= POLLONESHOT; + + if (events & EPOLLWRNORM) + ev |= POLLWRNORM; + + if (events & EPOLLWRBAND) + ev |= POLLWRBAND; + + epoll[i].dpep_data = event->data.u64; + break; + + default: + errno = EOPNOTSUPP; + return (-1); + } + + epoll[i].dpep_pollfd.events = ev; + + return (write(epfd, epoll, sizeof (epoll[0]) * (i + 1)) == -1 ? -1 : 0); +} + +int +epoll_wait(int epfd, struct epoll_event *events, + int maxevents, int timeout) +{ + struct dvpoll arg; + + if (maxevents <= 0) { + errno = EINVAL; + return (-1); + } + + arg.dp_nfds = maxevents; + arg.dp_timeout = timeout; + arg.dp_fds = (pollfd_t *)events; + + return (ioctl(epfd, DP_POLL, &arg)); +} + +int +epoll_pwait(int epfd, struct epoll_event *events, + int maxevents, int timeout, const sigset_t *sigmask) +{ + struct dvpoll arg; + + if (maxevents <= 0) { + errno = EINVAL; + return (-1); + } + + arg.dp_nfds = maxevents; + arg.dp_timeout = timeout; + arg.dp_fds = (pollfd_t *)events; + arg.dp_setp = (sigset_t *)sigmask; + + return (ioctl(epfd, DP_PPOLL, &arg)); +} diff --git a/usr/src/lib/libc/port/sys/eventfd.c b/usr/src/lib/libc/port/sys/eventfd.c new file mode 100644 index 0000000000..bd2eba4efa --- /dev/null +++ b/usr/src/lib/libc/port/sys/eventfd.c @@ -0,0 +1,65 @@ +/* + * 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/eventfd.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> + +int +eventfd(unsigned int initval, int flags) +{ + int oflags = O_RDWR; + uint64_t val = initval; + int fd; + + if (flags & ~(EFD_NONBLOCK | EFD_CLOEXEC | EFD_SEMAPHORE)) + return (EINVAL); + + if (flags & EFD_NONBLOCK) + oflags |= O_NONBLOCK; + + if (flags & EFD_CLOEXEC) + oflags |= O_CLOEXEC; + + if ((fd = open("/dev/eventfd", oflags)) < 0) + return (-1); + + if ((flags & EFD_SEMAPHORE) && + ioctl(fd, EVENTFDIOC_SEMAPHORE, 0) != 0) { + (void) close(fd); + return (-1); + } + + if (write(fd, &val, sizeof (val)) < sizeof (val)) { + (void) close(fd); + return (-1); + } + + return (fd); +} + +int +eventfd_read(int fd, eventfd_t *valp) +{ + return (read(fd, valp, sizeof (*valp)) < sizeof (*valp) ? -1 : 0); +} + +int +eventfd_write(int fd, eventfd_t val) +{ + return (write(fd, &val, sizeof (val)) < sizeof (val) ? -1 : 0); +} 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..5d637eaee1 --- /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); + 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/alloc.c b/usr/src/lib/libc/port/threads/alloc.c index 5851212ad4..99f68000d2 100644 --- a/usr/src/lib/libc/port/threads/alloc.c +++ b/usr/src/lib/libc/port/threads/alloc.c @@ -21,13 +21,14 @@ /* * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, Joyent, Inc. All rights reserved. */ #include "lint.h" #include "thr_uberdata.h" #include <sys/syscall.h> -extern int __systemcall6(sysret_t *, int, ...); +extern long __systemcall6(sysret_t *, int, ...); /* * This is a small and simple power of two memory allocator that is diff --git a/usr/src/lib/libc/port/threads/sigaction.c b/usr/src/lib/libc/port/threads/sigaction.c index 8e9df7ab60..dd7e6159fb 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 2014 Joyent, Inc. All rights reserved. */ #include "lint.h" @@ -458,11 +459,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 +473,9 @@ setsigacthandler(void (*nsigacthandler)(int, siginfo_t *, void *), *osigacthandler = udp->sigacthandler; udp->sigacthandler = nsigacthandler; + + if (brsetctxt != NULL) + udp->setctxt = brsetctxt; } /* @@ -522,6 +527,7 @@ int setcontext(const ucontext_t *ucp) { ulwp_t *self = curthread; + uberdata_t *udp = self->ul_uberdata; int ret; ucontext_t uc; @@ -578,7 +584,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 b5d848449d..485d7f8edf 100644 --- a/usr/src/lib/libc/port/threads/thr.c +++ b/usr/src/lib/libc/port/threads/thr.c @@ -23,7 +23,7 @@ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright 2014 Joyent, Inc. All rights reserved. */ #include "lint.h" @@ -124,6 +124,7 @@ uberdata_t __uberdata = { 0, /* ndaemons */ 0, /* pid */ sigacthandler, /* sigacthandler */ + __setcontext, /* setctxt */ NULL, /* lwp_stacks */ NULL, /* lwp_laststack */ 0, /* nfreestack */ @@ -136,6 +137,7 @@ uberdata_t __uberdata = { NULL, /* robustlocks */ NULL, /* robustlist */ NULL, /* progname */ + NULL, /* ub_broot */ NULL, /* __tdb_bootstrap */ { /* tdb */ NULL, /* tdb_sync_addr_hash */ @@ -1219,6 +1221,24 @@ extern void atfork_init(void); extern void __proc64id(void); #endif +static void +init_brandroot(uberdata_t *udp) +{ + Dl_argsinfo_t args; + + udp->ub_broot = NULL; + if (dlinfo(RTLD_SELF, RTLD_DI_ARGSINFO, &args) < 0) + return; + + while (args.dla_auxv->a_type != AT_NULL) { + if (args.dla_auxv->a_type == AT_SUN_BRAND_NROOT) { + udp->ub_broot = args.dla_auxv->a_un.a_ptr; + return; + } + 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. @@ -1255,6 +1275,13 @@ libc_init(void) (void) _atexit(__cleanup); /* + * Every libc, regardless of link map, needs to go through and check its + * aux vectors so as to indicate whether or not this has been given a + * brand root with which we use to qualify various other data. + */ + init_brandroot(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 fdeaaf757f..71867bf07d 100644 --- a/usr/src/lib/libc/sparc/Makefile.com +++ b/usr/src/lib/libc/sparc/Makefile.com @@ -929,6 +929,8 @@ PORTSYS= \ chmod.o \ chown.o \ corectl.o \ + epoll.o \ + eventfd.o \ exacctsys.o \ execl.o \ execle.o \ @@ -936,6 +938,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/crt/_rtld.c b/usr/src/lib/libc/sparc/crt/_rtld.c index a9e9c6d98a..843cfe03a5 100644 --- a/usr/src/lib/libc/sparc/crt/_rtld.c +++ b/usr/src/lib/libc/sparc/crt/_rtld.c @@ -62,6 +62,15 @@ #define SYSCONFIG (*(funcs[SYSCONFIG_F])) /* + * GCC will not emit unused static functions unless specifically told it must + */ +#ifdef __GNUC__ +#define __USED __attribute__((used)) +#else +#define __USED +#endif + +/* * Alias ld.so entry point -- receives a bootstrap structure and a vector * of strings. The vector is "well-known" to us, and consists of pointers * to string constants. This aliasing bootstrap requires no relocation in diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com index 39fa3d2c9f..f6628f8899 100644 --- a/usr/src/lib/libc/sparcv9/Makefile.com +++ b/usr/src/lib/libc/sparcv9/Makefile.com @@ -873,6 +873,7 @@ PORTSYS= \ chmod.o \ chown.o \ corectl.o \ + epoll.o \ exacctsys.o \ execl.o \ execle.o \ |