From 2baf1ae1015da35bdfe583808e8ed78b2ab4ac96 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Wed, 6 May 2015 11:40:19 +0200 Subject: [PATCH] xbps-uunshare: replace -D/-H/-S with -b src/dest and switch to getopt(3). --- NEWS | 3 + bin/xbps-uunshare/main.c | 112 ++++++++++++++++++------------ bin/xbps-uunshare/xbps-uunshare.8 | 28 ++++---- 3 files changed, 85 insertions(+), 58 deletions(-) diff --git a/NEWS b/NEWS index 459b717d..11450e69 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,8 @@ xbps-0.45 (???): + * xbps-uunshare(8): replaced -D, -H and -S with -b src:dest. This bind mounts + src into dir/dest and allows unlimited mounts. + * xbps-uchroot(8): replaced -D, -H and -S with -b src:dest. This bind mounts src into dir/dest and allows unlimited mounts. diff --git a/bin/xbps-uunshare/main.c b/bin/xbps-uunshare/main.c index dd42adfb..7abe5639 100644 --- a/bin/xbps-uunshare/main.c +++ b/bin/xbps-uunshare/main.c @@ -39,12 +39,24 @@ #include #include #include +#include + +#include +#include "queue.h" #ifdef __clang__ #pragma clang diagnostic ignored "-Wformat-nonliteral" #endif +struct bindmnt { + SIMPLEQ_ENTRY(bindmnt) entries; + char *src; + const char *dest; +}; + static int errval = 0; +static SIMPLEQ_HEAD(bindmnt_head, bindmnt) bindmnt_queue = + SIMPLEQ_HEAD_INITIALIZER(bindmnt_queue); static void __attribute__((noreturn)) die(const char *fmt, ...) @@ -63,13 +75,38 @@ die(const char *fmt, ...) static void __attribute__((noreturn)) usage(const char *p) { - printf("Usage: %s [-D dir] [-H dir] [-S dir] \n\n" - "-D Directory to be bind mounted at /void-packages\n" - "-H Directory to be bind mounted at /host\n" - "-S Directory to be bind mounted at /\n", p); + printf("Usage: %s [-b src:dest] []\n\n" + "-b src:dest Bind mounts into / (may be specified multiple times)\n\n", p); exit(EXIT_FAILURE); } +static void +add_bindmount(char *bm) +{ + struct bindmnt *bmnt; + char *b, *src, *dest; + size_t len; + + src = strdup(bm); + assert(src); + dest = strchr(bm, ':'); + if (dest == NULL || *dest == '\0') { + errno = EINVAL; + die("invalid argument for bindmount: %s", bm); + } + dest++; + b = strchr(bm, ':'); + len = strlen(bm) - strlen(b); + src[len] = '\0'; + + bmnt = malloc(sizeof(struct bindmnt)); + assert(bmnt); + + bmnt->src = src; + bmnt->dest = dest; + SIMPLEQ_INSERT_TAIL(&bindmnt_queue, bmnt, entries); +} + static void bindmount(const char *chrootdir, const char *dir, const char *dest) { @@ -85,43 +122,40 @@ bindmount(const char *chrootdir, const char *dir, const char *dest) int main(int argc, char **argv) { + struct bindmnt *bmnt; uid_t uid = getuid(); gid_t gid = getgid(); - const char *chrootdir, *distdir, *hostdir, *shmdir, *cmd, *argv0; + const char *chrootdir, *cmd, *argv0; char **cmdargs, buf[32]; - int fd, aidx = 0; + int c, fd; - chrootdir = distdir = hostdir = shmdir = cmd = NULL; + chrootdir = cmd = NULL; argv0 = argv[0]; - argc--; - argv++; + + while ((c = getopt(argc, argv, "b:V")) != -1) { + switch (c) { + case 'b': + if (optarg == NULL || *optarg == '\0') + break; + add_bindmount(optarg); + break; + case 'V': + printf("%s\n", XBPS_RELVER); + exit(EXIT_SUCCESS); + case '?': + default: + usage(argv0); + } + } + argc -= optind; + argv += optind; if (argc < 2) usage(argv0); - while (aidx < argc) { - if (strcmp(argv[aidx], "-D") == 0) { - /* distdir */ - distdir = argv[aidx+1]; - aidx += 2; - } else if (strcmp(argv[aidx], "-H") == 0) { - /* hostdir */ - hostdir = argv[aidx+1]; - aidx += 2; - } else if (strcmp(argv[aidx], "-S") == 0) { - /* shmdir */ - shmdir = argv[aidx+1]; - aidx += 2; - } else { - break; - } - } - if ((argc - aidx) < 2) - usage(argv0); - - chrootdir = argv[aidx]; - cmd = argv[aidx+1]; - cmdargs = argv + aidx + 1; + chrootdir = argv[0]; + cmd = argv[1]; + cmdargs = argv + 1; /* Never allow chrootdir == / */ if (strcmp(chrootdir, "/") == 0) @@ -166,17 +200,9 @@ main(int argc, char **argv) /* bind mount /dev */ bindmount(chrootdir, "/dev", NULL); - /* bind mount hostdir if set */ - if (hostdir) - bindmount(chrootdir, hostdir, "/host"); - - /* bind mount distdir (if set) */ - if (distdir) - bindmount(chrootdir, distdir, "/void-packages"); - - /* bind mount shmdir (if set) */ - if (shmdir) - bindmount(chrootdir, shmdir, NULL); + /* bind mount all user specified mnts */ + SIMPLEQ_FOREACH(bmnt, &bindmnt_queue, entries) + bindmount(chrootdir, bmnt->src, bmnt->dest); /* move chrootdir to / and chroot to it */ if (chdir(chrootdir) == -1) diff --git a/bin/xbps-uunshare/xbps-uunshare.8 b/bin/xbps-uunshare/xbps-uunshare.8 index 70e7fa99..414a1df5 100644 --- a/bin/xbps-uunshare/xbps-uunshare.8 +++ b/bin/xbps-uunshare/xbps-uunshare.8 @@ -1,4 +1,4 @@ -.Dd April 13, 2015 +.Dd May 6, 2015 .Dt XBPS-UUNSHARE 8 .Sh NAME .Nm xbps-uunshare @@ -17,6 +17,7 @@ utility allows users to chroot and bind mount required pseudo-filesystems .Ar CHROOTDIR to execute .Ar COMMAND . +.Pp The .Nm utility uses by default Linux namespaces to isolate IPC, PIDs and mounts to @@ -25,20 +26,17 @@ the calling process. Thanks to the user does not need any privilege to create an isolated lightweight container. .Sh OPTIONS .Bl -tag -width -x -.It Fl D Ar dir -Specifies a full path to a directory that will be bind mounted at -.Ar CHROOTDIR/void-packages . -.It Fl H Ar dir -Specifies a full path to a directory that will be bind mounted at -.Ar CHROOTDIR/host . -.It Fl S Ar dir -Specifies a full path to a directory to allow shm functionality to be used -in the target -.Ar CHROOTDIR/dir . -If your system uses -.Sy /dev/shm -use it, otherwise use -.Sy /run/shm . +.It Fl b Ar src:dest +Bind mounts +.Ar src +into +.Ar CHROOTDIR/dest . +This option may be specified multiple times. +Please note that both +.Ar src +and +.Ar dest +must be absolute paths and must exist. .El .Sh NOTES The