diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c index 51fd536a2..4dd38839a 100644 --- a/src/lxc/tools/lxc_attach.c +++ b/src/lxc/tools/lxc_attach.c @@ -107,6 +107,8 @@ static int add_to_simple_array(char ***array, ssize_t *capacity, char *value) static int my_parser(struct lxc_arguments* args, int c, char* arg) { + char **it; + char *del; int ret; switch (c) { @@ -125,6 +127,30 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg) break; case 's': namespace_flags = 0; + + /* The identifiers for namespaces used with lxc-attach as given + * on the manpage do not align with the standard identifiers. + * This affects network, mount, and uts namespaces. The standard + * identifiers are: "mnt", "uts", and "net" whereas lxc-attach + * uses "MOUNT", "UTSNAME", and "NETWORK". So let's use some + * cheap memmove()s to replace them by their standard + * identifiers. Let's illustrate this with an example: + * Assume the string: + * + * "IPC|MOUNT|PID" + * + * then we memmove() + * + * dest: del + 1 == ONT|PID + * src: del + 3 == NT|PID + */ + while ((del = strstr(arg, "MOUNT"))) + memmove(del + 1, del + 3, strlen(del) - 2); + + for (it = (char *[]){"NETWORK", "UTSNAME", NULL}; it && *it; it++) + while ((del = strstr(arg, *it))) + memmove(del + 3, del + 7, strlen(del) - 6); + ret = lxc_fill_namespace_flags(arg, &namespace_flags); if (ret) return -1; diff --git a/src/lxc/tools/lxc_unshare.c b/src/lxc/tools/lxc_unshare.c index 6c9423fae..72ea00ce0 100644 --- a/src/lxc/tools/lxc_unshare.c +++ b/src/lxc/tools/lxc_unshare.c @@ -76,7 +76,7 @@ static void usage(char *cmd) fprintf(stderr, "\t -i : Interface name to be moved into container (presumably with NETWORK unsharing set)\n"); fprintf(stderr, "\t -H : Set the hostname in the container\n"); fprintf(stderr, "\t -d : Daemonize (do not wait for container to exit)\n"); - fprintf(stderr, "\t -M : reMount default fs inside container (/proc /dev/shm /dev/mqueue)\n"); + fprintf(stderr, "\t -M : Remount default fs inside container (/proc /dev/shm /dev/mqueue)\n"); _exit(EXIT_SUCCESS); } @@ -151,12 +151,12 @@ static int do_start(void *arg) int main(int argc, char *argv[]) { + char *del; + char **it, **args; int opt, status; int ret; char *namespaces = NULL; - char **args; - int flags = 0; - int daemonize = 0; + int flags = 0, daemonize = 0; uid_t uid = 0; /* valid only if (flags & CLONE_NEWUSER) */ pid_t pid; struct my_iflist *tmpif, *my_iflist = NULL; @@ -213,6 +213,28 @@ int main(int argc, char *argv[]) if (ret) exit(EXIT_FAILURE); + /* The identifiers for namespaces used with lxc-unshare as given on the + * manpage do not align with the standard identifiers. This affects + * network, mount, and uts namespaces. The standard identifiers are: + * "mnt", "uts", and "net" whereas lxc-unshare uses "MOUNT", "UTSNAME", + * and "NETWORK". So let's use some cheap memmove()s to replace them by + * their standard identifiers. Let's illustrate this with an example: + * Assume the string: + * + * "IPC|MOUNT|PID" + * + * then we memmove() + * + * dest: del + 1 == ONT|PID + * src: del + 3 == NT|PID + */ + while ((del = strstr(namespaces, "MOUNT"))) + memmove(del + 1, del + 3, strlen(del) - 2); + + for (it = (char *[]){"NETWORK", "UTSNAME", NULL}; it && *it; it++) + while ((del = strstr(namespaces, *it))) + memmove(del + 3, del + 7, strlen(del) - 6); + ret = lxc_fill_namespace_flags(namespaces, &flags); if (ret) usage(argv[0]);