xbps-uunshare: replace -D/-H/-S with -b src/dest and switch to getopt(3).

This commit is contained in:
Juan RP 2015-05-06 11:40:19 +02:00
parent 4a97810c0b
commit 2baf1ae101
3 changed files with 85 additions and 58 deletions

3
NEWS
View File

@ -1,5 +1,8 @@
xbps-0.45 (???): 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 * xbps-uchroot(8): replaced -D, -H and -S with -b src:dest. This bind mounts
src into dir/dest and allows unlimited mounts. src into dir/dest and allows unlimited mounts.

View File

@ -39,12 +39,24 @@
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <syscall.h> #include <syscall.h>
#include <assert.h>
#include <xbps.h>
#include "queue.h"
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic ignored "-Wformat-nonliteral" #pragma clang diagnostic ignored "-Wformat-nonliteral"
#endif #endif
struct bindmnt {
SIMPLEQ_ENTRY(bindmnt) entries;
char *src;
const char *dest;
};
static int errval = 0; static int errval = 0;
static SIMPLEQ_HEAD(bindmnt_head, bindmnt) bindmnt_queue =
SIMPLEQ_HEAD_INITIALIZER(bindmnt_queue);
static void __attribute__((noreturn)) static void __attribute__((noreturn))
die(const char *fmt, ...) die(const char *fmt, ...)
@ -63,13 +75,38 @@ die(const char *fmt, ...)
static void __attribute__((noreturn)) static void __attribute__((noreturn))
usage(const char *p) usage(const char *p)
{ {
printf("Usage: %s [-D dir] [-H dir] [-S dir] <chrootdir> <command>\n\n" printf("Usage: %s [-b src:dest] <dir> <cmd> [<cmdargs>]\n\n"
"-D <distdir> Directory to be bind mounted at <chrootdir>/void-packages\n" "-b src:dest Bind mounts <src> into <dir>/<dest> (may be specified multiple times)\n\n", p);
"-H <hostdir> Directory to be bind mounted at <chrootdir>/host\n"
"-S <shmdir> Directory to be bind mounted at <chrootdir>/<shmdir>\n", p);
exit(EXIT_FAILURE); 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 static void
bindmount(const char *chrootdir, const char *dir, const char *dest) 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 int
main(int argc, char **argv) main(int argc, char **argv)
{ {
struct bindmnt *bmnt;
uid_t uid = getuid(); uid_t uid = getuid();
gid_t gid = getgid(); gid_t gid = getgid();
const char *chrootdir, *distdir, *hostdir, *shmdir, *cmd, *argv0; const char *chrootdir, *cmd, *argv0;
char **cmdargs, buf[32]; char **cmdargs, buf[32];
int fd, aidx = 0; int c, fd;
chrootdir = distdir = hostdir = shmdir = cmd = NULL; chrootdir = cmd = NULL;
argv0 = argv[0]; 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) if (argc < 2)
usage(argv0); usage(argv0);
while (aidx < argc) { chrootdir = argv[0];
if (strcmp(argv[aidx], "-D") == 0) { cmd = argv[1];
/* distdir */ cmdargs = argv + 1;
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;
/* Never allow chrootdir == / */ /* Never allow chrootdir == / */
if (strcmp(chrootdir, "/") == 0) if (strcmp(chrootdir, "/") == 0)
@ -166,17 +200,9 @@ main(int argc, char **argv)
/* bind mount /dev */ /* bind mount /dev */
bindmount(chrootdir, "/dev", NULL); bindmount(chrootdir, "/dev", NULL);
/* bind mount hostdir if set */ /* bind mount all user specified mnts */
if (hostdir) SIMPLEQ_FOREACH(bmnt, &bindmnt_queue, entries)
bindmount(chrootdir, hostdir, "/host"); bindmount(chrootdir, bmnt->src, bmnt->dest);
/* bind mount distdir (if set) */
if (distdir)
bindmount(chrootdir, distdir, "/void-packages");
/* bind mount shmdir (if set) */
if (shmdir)
bindmount(chrootdir, shmdir, NULL);
/* move chrootdir to / and chroot to it */ /* move chrootdir to / and chroot to it */
if (chdir(chrootdir) == -1) if (chdir(chrootdir) == -1)

View File

@ -1,4 +1,4 @@
.Dd April 13, 2015 .Dd May 6, 2015
.Dt XBPS-UUNSHARE 8 .Dt XBPS-UUNSHARE 8
.Sh NAME .Sh NAME
.Nm xbps-uunshare .Nm xbps-uunshare
@ -17,6 +17,7 @@ utility allows users to chroot and bind mount required pseudo-filesystems
.Ar CHROOTDIR .Ar CHROOTDIR
to execute to execute
.Ar COMMAND . .Ar COMMAND .
.Pp
The The
.Nm .Nm
utility uses by default Linux namespaces to isolate IPC, PIDs and mounts to 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. the user does not need any privilege to create an isolated lightweight container.
.Sh OPTIONS .Sh OPTIONS
.Bl -tag -width -x .Bl -tag -width -x
.It Fl D Ar dir .It Fl b Ar src:dest
Specifies a full path to a directory that will be bind mounted at Bind mounts
.Ar CHROOTDIR/void-packages . .Ar src
.It Fl H Ar dir into
Specifies a full path to a directory that will be bind mounted at .Ar CHROOTDIR/dest .
.Ar CHROOTDIR/host . This option may be specified multiple times.
.It Fl S Ar dir Please note that both
Specifies a full path to a directory to allow shm functionality to be used .Ar src
in the target and
.Ar CHROOTDIR/dir . .Ar dest
If your system uses must be absolute paths and must exist.
.Sy /dev/shm
use it, otherwise use
.Sy /run/shm .
.El .El
.Sh NOTES .Sh NOTES
The The