Re: [lxc-devel] lxc-clone rewrite
On Thu, Aug 27, 2015 at 03:41:03PM -0400, Stéphane Graber wrote: On Sun, Aug 16, 2015 at 04:46:31PM +, Serge Hallyn wrote: Quoting Christian Brauner (christianvanbrau...@gmail.com): Integrating lxc-clone with the standard lxc parser is not possible unless it is allowed to change command line options. lxc-clone uses -n, -P and -o in a way that is inconsistent with the standard lxc common options defined in LXC_COMMON_OPTIONS in arguments.h and the parser in arguments.c. Since we do not want to break expectations of existing users that rely on lxc-clone I thought it might be a good idea to reimplement lxc-clone as lxc-copy. This way we can retain lxc-clone as a working executable but have it print out a will soon be deprecated. Please switch to lxc-copy-type message similar to what e.g. Docker does. The main arguments for reimplementing lxc-clone for is the tighter integration with the rest of the lxc-executables, using the standard parser and most of all the standard lxc-logging feature which we get by integrating it with the standard parser. I provided a branch on github which implements this idea (manpages and all included). git clone https://github.com/brauner/lxc.git git checkout copy I'd be happy to hear whether you think this is a good idea or if you would like to just keep the old lxc-clone. Hey, I'll leave this to Stéphane, as he's pretty keen on leaving the # commands low. As you say we might eventually be able to deprecate lxc-clone, and lxc-copy might eventually be a nice hook for migration. That'd be fine with me I think, bonus point if we can somehow merge lxc-start-ephemeral in there and kill two birds with one stone (lxc-clone lxc-start-ephemeral). The timeline for this would be having lxc-copy in 1.2 with both lxc-clone and lxc-start-ephemeral doing arg swapping + re-exec tricks with a warning that they'll go away for good in 2.0. How does that sound? Sounds good! I'm on it! Christian -- Stéphane Graber Ubuntu developer http://www.ubuntu.com signature.asc Description: PGP signature ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
Re: [lxc-devel] [PATCH 4/4] Fix grammar in some of the executables NAME for name of the container becomes NAME of the container
Updated PR on Github. Retains old behaviour of lxc executables. ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [PATCH 2/4] lxc-destroy: Remove container with all snapshots
- This enables the user to destroy a container with all its snapshots without having to use lxc-snapshot first to destroy all snapshots. (The enum values DESTROY and SNAP from the previous commit are reused here again.) - Some unification regarding the usage of exit() and return has been done. Signed-off-by: Christian Brauner christianvanbrau...@gmail.com --- src/lxc/lxc_destroy.c | 74 ++- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/src/lxc/lxc_destroy.c b/src/lxc/lxc_destroy.c index 955fc23..32bd2b4 100644 --- a/src/lxc/lxc_destroy.c +++ b/src/lxc/lxc_destroy.c @@ -31,16 +31,11 @@ lxc_log_define(lxc_destroy_ui, lxc); -static int my_parser(struct lxc_arguments* args, int c, char* arg) -{ - switch (c) { - case 'f': args-force = 1; break; - } - return 0; -} +static int my_parser(struct lxc_arguments* args, int c, char* arg); static const struct option my_longopts[] = { {force, no_argument, 0, 'f'}, + {snapshots, no_argument, 0, 's'}, LXC_COMMON_OPTIONS }; @@ -52,61 +47,104 @@ static struct lxc_arguments my_args = { lxc-destroy destroys a container with the identifier NAME\n\ \n\ Options :\n\ - -n, --name=NAME NAME for name of the container\n\ + -n, --name=NAME NAME of the container\n\ + -s, --snapshots destroy including all snapshots\n\ -f, --force wait for the container to shut down\n, .options = my_longopts, .parser = my_parser, .checker = NULL, + .task = DESTROY, }; +static int do_destroy(struct lxc_container *c); +static int do_destroy_with_snapshots(struct lxc_container *c); + int main(int argc, char *argv[]) { struct lxc_container *c; + int ret; if (lxc_arguments_parse(my_args, argc, argv)) - exit(1); + exit(EXIT_FAILURE); if (!my_args.log_file) my_args.log_file = none; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, my_args.progname, my_args.quiet, my_args.lxcpath[0])) - exit(1); + exit(EXIT_FAILURE); lxc_log_options_no_override(); c = lxc_container_new(my_args.name, my_args.lxcpath[0]); if (!c) { fprintf(stderr, System error loading container\n); - exit(1); + exit(EXIT_FAILURE); } if (!c-may_control(c)) { fprintf(stderr, Insufficent privileges to control %s\n, my_args.name); lxc_container_put(c); - exit(1); + exit(EXIT_FAILURE); } if (!c-is_defined(c)) { fprintf(stderr, Container is not defined\n); lxc_container_put(c); - exit(1); + exit(EXIT_FAILURE); } if (c-is_running(c)) { if (!my_args.force) { fprintf(stderr, %s is running\n, my_args.name); lxc_container_put(c); - exit(1); + exit(EXIT_FAILURE); } c-stop(c); } + if (my_args.task == SNAP) { + ret = do_destroy_with_snapshots(c); + } else { + ret = do_destroy(c); + } + + lxc_container_put(c); + + if (ret == 0) + exit(EXIT_SUCCESS); + exit(EXIT_FAILURE); +} + +static int my_parser(struct lxc_arguments *args, int c, char *arg) +{ + switch (c) { + case 'f': args-force = 1; break; + case 's': args-task = SNAP; break; + } + return 0; +} + +static int do_destroy(struct lxc_container *c) +{ if (!c-destroy(c)) { fprintf(stderr, Destroying %s failed\n, my_args.name); - lxc_container_put(c); - exit(1); + return -1; } - lxc_container_put(c); - exit(0); + printf(Destroyed container %s\n, my_args.name); + + return 0; } + +static int do_destroy_with_snapshots(struct lxc_container *c) +{ + if (!c-destroy_with_snapshots(c)) { + fprintf(stderr, Destroying %s failed\n, my_args.name); + return -1; + } + + printf(Destroyed container including snapshots %s\n, my_args.name); + + return 0; +} + -- 2.5.0 ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [PATCH 4/4] Fix grammar in some of the executables NAME for name of the container becomes NAME of the container
Signed-off-by: Christian Brauner christianvanbrau...@gmail.com --- src/lxc/lxc_attach.c | 2 +- src/lxc/lxc_cgroup.c | 2 +- src/lxc/lxc_checkpoint.c | 2 +- src/lxc/lxc_console.c| 2 +- src/lxc/lxc_create.c | 4 ++-- src/lxc/lxc_device.c | 2 +- src/lxc/lxc_execute.c| 2 +- src/lxc/lxc_freeze.c | 2 +- src/lxc/lxc_info.c | 2 +- src/lxc/lxc_init.c | 2 +- src/lxc/lxc_monitor.c| 2 +- src/lxc/lxc_start.c | 2 +- src/lxc/lxc_stop.c | 2 +- src/lxc/lxc_unfreeze.c | 2 +- src/lxc/lxc_wait.c | 2 +- 15 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c index d28b22c..94f0f7a 100644 --- a/src/lxc/lxc_attach.c +++ b/src/lxc/lxc_attach.c @@ -146,7 +146,7 @@ static struct lxc_arguments my_args = { Execute the specified COMMAND - enter the container NAME\n\ \n\ Options :\n\ - -n, --name=NAME NAME for name of the container\n\ + -n, --name=NAME NAME of the container\n\ -e, --elevated-privileges=PRIVILEGES\n\ Use elevated privileges instead of those of the\n\ container. If you don't specify privileges to be\n\ diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index f150c43..dd60fd1 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -56,7 +56,7 @@ Get or set the value of a state object (for example, 'cpuset.cpus')\n\ in the container's cgroup for the corresponding subsystem.\n\ \n\ Options :\n\ - -n, --name=NAME container name, + -n, --name=NAME NAME of the container, .options = my_longopts, .parser = NULL, .checker = my_checker, diff --git a/src/lxc/lxc_checkpoint.c b/src/lxc/lxc_checkpoint.c index 2e76c2e..3e5de4a 100644 --- a/src/lxc/lxc_checkpoint.c +++ b/src/lxc/lxc_checkpoint.c @@ -105,7 +105,7 @@ lxc-checkpoint checkpoints and restores a container\n\ its running state at a later time.\n\ \n\ Options :\n\ - -n, --name=NAME NAME for name of the container\n\ + -n, --name=NAME NAME of the container\n\ -r, --restore Restore container\n\ -D, --checkpoint-dir=DIR directory to save the checkpoint in\n\ -v, --verbose Enable verbose criu logs\n\ diff --git a/src/lxc/lxc_console.c b/src/lxc/lxc_console.c index b22322b..adbd7e0 100644 --- a/src/lxc/lxc_console.c +++ b/src/lxc/lxc_console.c @@ -78,7 +78,7 @@ static struct lxc_arguments my_args = { lxc-console logs on the container with the identifier NAME\n\ \n\ Options :\n\ - -n, --name=NAME NAME for name of the container\n\ + -n, --name=NAME NAME of the container\n\ -t, --tty=NUMBER console tty number\n\ -e, --escape=PREFIX prefix for escape command\n, .options = my_longopts, diff --git a/src/lxc/lxc_create.c b/src/lxc/lxc_create.c index 8f46db9..f1094fb 100644 --- a/src/lxc/lxc_create.c +++ b/src/lxc/lxc_create.c @@ -61,7 +61,7 @@ static uint64_t get_fssize(char *s) else if (*end == 't' || *end == 'T') ret *= 1024ULL * 1024ULL * 1024ULL * 1024ULL; else - { + { fprintf(stderr, Invalid blockdev unit size '%c' in '%s', using default size\n, *end, s); return 0; } @@ -131,7 +131,7 @@ static struct lxc_arguments my_args = { lxc-create creates a container\n\ \n\ Options :\n\ - -n, --name=NAMENAME for name of the container\n\ + -n, --name=NAMENAME of the container\n\ -f, --config=file Initial configuration file\n\ -t, --template=t Template to use to setup container\n\ -B, --bdev=BDEVBacking store type to use\n\ diff --git a/src/lxc/lxc_device.c b/src/lxc/lxc_device.c index 6d715d3..0c9e066 100644 --- a/src/lxc/lxc_device.c +++ b/src/lxc/lxc_device.c @@ -53,7 +53,7 @@ static struct lxc_arguments my_args = { lxc-device attach or detach DEV to or from container.\n\ \n\ Options :\n\ - -n, --name=NAME NAME for name of the container, + -n, --name=NAME NAME of the container, .options = my_longopts, .parser = NULL, .checker = NULL, diff --git a/src/lxc/lxc_execute.c b/src/lxc/lxc_execute.c index 4f1e1f6..d2c1248 100644 --- a/src/lxc/lxc_execute.c +++ b/src/lxc/lxc_execute.c @@ -79,7 +79,7 @@ lxc-execute creates a container with the identifier NAME\n\ and execs COMMAND into this container.\n\ \n\ Options :\n\ - -n, --name=NAME NAME for name of the container\n\ + -n, --name=NAME NAME of the container\n\ -f, --rcfile=FILELoad configuration file FILE\n\ -s, --define KEY=VAL Assign VAL to configuration variable KEY\n, .options = my_longopts, diff --git a/src/lxc/lxc_freeze.c b/src/lxc/lxc_freeze.c index 0744c82..ea8bd3e 100644 --- a/src/lxc/lxc_freeze.c +++ b/src/lxc/lxc_freeze.c @@ -47,7 +47,7 @@ static struct lxc_arguments my_args = { lxc-freeze freezes a container with the identifier NAME\n\ \n\ Options :\n\ - -n, --name=NAME NAME for name
[lxc-devel] lxc-clone rewrite
Integrating lxc-clone with the standard lxc parser is not possible unless it is allowed to change command line options. lxc-clone uses -n, -P and -o in a way that is inconsistent with the standard lxc common options defined in LXC_COMMON_OPTIONS in arguments.h and the parser in arguments.c. Since we do not want to break expectations of existing users that rely on lxc-clone I thought it might be a good idea to reimplement lxc-clone as lxc-copy. This way we can retain lxc-clone as a working executable but have it print out a will soon be deprecated. Please switch to lxc-copy-type message similar to what e.g. Docker does. The main arguments for reimplementing lxc-clone for is the tighter integration with the rest of the lxc-executables, using the standard parser and most of all the standard lxc-logging feature which we get by integrating it with the standard parser. I provided a branch on github which implements this idea (manpages and all included). git clone https://github.com/brauner/lxc.git git checkout copy I'd be happy to hear whether you think this is a good idea or if you would like to just keep the old lxc-clone. Christian signature.asc Description: PGP signature ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [PATCH] mod_rdep(): Write path and name of clone to file
This is rather a first-pass suggestion than a full commit to discuss: The idea: - - If a container has clone-snapshots created by lxc-clone -n NAME -N NEWNAME -s then even the new version lxc-destroy (see patch on github) cannot remove the container because the original container only stores the number of clone-snapshotted containers in the file lxc_snapshots. Hence, it has no way of looking up the copy-snapshots containers that belong to the container to delete them and then delete the original container. I suggest modifying mod_rdep() so it will store not the plain number in the file but rather the paths and names to the containers that are a clone-snapshots (similar to the lxc_rdepends file for the clones). An example how the file lxc_snapshots of the original container could look like would be: /var/lib/lxc:bb /var/lib/lxc:cc /opt:dd This would be an example of a container that provides the base for three clone-snapshots bb, cc, and dd. Where bb and cc both are placed in the usual path for privileged containers and dd is placed in a custom path. I could then go on to modify lxc-destroy to actually not just remove the original container including all snapshots but also with all its clone-snapshots. Following is a first idea for rewriting mod_rdep(). If you think its generally not something you want just leave a short reply. If you would like to have this feature but rather implement it in a different way it would be nice if you could leave some more feedback and suggestions and then I'll rewrite the patch. Thanks! Summary: - Add additional argument to function that takes in the clone-snapshotted lxc_container. - Have mod_rdep() write the path and name of the clone-snapshotted container the file lxc_snapshots of the original container. - If a clone-snapshot gets deleted the corresponding line in the file lxc_snapshot of the original container will be deleted and the file updated. - Change has_fs_snapshots() to check if the file is empty. If it is it is safe to delete the original container if the file is not empty then it is not safe. Signed-off-by: Christian Brauner christianvanbrau...@gmail.com --- src/lxc/lxccontainer.c | 98 +++--- 1 file changed, 61 insertions(+), 37 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 1c103e8..e10ccc7 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1970,47 +1970,76 @@ out: WRAP_API_1(bool, lxcapi_save_config, const char *) -static bool mod_rdep(struct lxc_container *c, bool inc) +static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc) { - char path[MAXPATHLEN]; - int ret, v = 0; - FILE *f; + char *buf; + size_t len = 0; + FILE *f1, *f2; + char path1[MAXPATHLEN]; + char path2[MAXPATHLEN]; + int ret; bool bret = false; - if (container_disk_lock(c)) + if (container_disk_lock(c0)) return false; - ret = snprintf(path, MAXPATHLEN, %s/%s/lxc_snapshots, c-config_path, - c-name); + + ret = snprintf(path1, MAXPATHLEN, %s/%s/lxc_snapshots, c0-config_path, + c0-name); if (ret 0 || ret MAXPATHLEN) goto out; - f = fopen(path, r); - if (f) { - ret = fscanf(f, %d, v); - fclose(f); - if (ret != 1) { - ERROR(Corrupted file %s, path); + + if (inc) { + f1 = fopen(path1, a); + if (!f1) + goto out; + + if (fprintf(f1, %s:%s\n, c-config_path, c-name) 0) { + ERROR(Error writing new snapshots value); + fclose(f1); goto out; } - } - v += inc ? 1 : -1; - f = fopen(path, w); - if (!f) - goto out; - if (fprintf(f, %d\n, v) 0) { - ERROR(Error writing new snapshots value); - fclose(f); - goto out; - } - ret = fclose(f); - if (ret != 0) { - SYSERROR(Error writing to or closing snapshots file); - goto out; + + ret = fclose(f1); + if (ret != 0) { + SYSERROR(Error writing to or closing snapshots file); + goto out; + } + } else if (!inc) { + ret = snprintf(path1, MAXPATHLEN, %s/%s/lxc_snapshots, + c0-config_path, c0-name); + if (ret 0 || ret MAXPATHLEN) + goto out; + ret = snprintf(path2, MAXPATHLEN, %s/%s/lxc_snapshots_tmp, + c0-config_path, c0-name); + if (ret 0 || ret MAXPATHLEN) + goto
Re: [lxc-devel] [PATCH] Refactor lxc-snapshot
Updated version as PR on github. On Thu, Aug 06, 2015 at 03:47:04PM +0200, Christian Brauner wrote: - lxc_snapshot.c lacked necessary members in the associated lxc_arguments struct in arguments.h. This commit extends the lxc_arguments struct to include several parameters used by lxc-snapshot which allows a rewrite that is more consistent with the rest of the lxc-* executables. - All tests have been moved beyond the call to lxc_log_init() to allow for the messages to be printed or saved. - Some small changes to the my_args struct. (The enum task is set to SNAP (for snapshot) per default and variables illustrating the usage of the command line flags are written in all caps.) Signed-off-by: Christian Brauner christianvanbrau...@gmail.com --- src/lxc/arguments.h| 8 ++ src/lxc/lxc_snapshot.c | 317 +++-- 2 files changed, 182 insertions(+), 143 deletions(-) diff --git a/src/lxc/arguments.h b/src/lxc/arguments.h index cc85f86..86fd02e 100644 --- a/src/lxc/arguments.h +++ b/src/lxc/arguments.h @@ -94,12 +94,20 @@ struct lxc_arguments { int list; char *groups; + /* lxc-snapshot and lxc-clone */ + enum task {DESTROY, LIST, RESTORE, SNAP, } task; + int print_comments; + char *commentfile; + char *newname; + char *snapname; + /* remaining arguments */ char *const *argv; int argc; /* private arguments */ void *data; + }; #define LXC_COMMON_OPTIONS \ diff --git a/src/lxc/lxc_snapshot.c b/src/lxc/lxc_snapshot.c index a03c0c0..99cbe48 100644 --- a/src/lxc/lxc_snapshot.c +++ b/src/lxc/lxc_snapshot.c @@ -16,8 +16,8 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include config.h +#include confile.h #include stdio.h #include libgen.h #include unistd.h @@ -35,18 +35,148 @@ lxc_log_define(lxc_snapshot_ui, lxc); -static char *newname; -static char *snapshot; +static int my_parser(struct lxc_arguments *args, int c, char *arg); -#define DO_SNAP 0 -#define DO_LIST 1 -#define DO_RESTORE 2 -#define DO_DESTROY 3 -static int action; -static int print_comments; -static char *commentfile; +static const struct option my_longopts[] = { + {list, no_argument, 0, 'L'}, + {restore, required_argument, 0, 'r'}, + {destroy, required_argument, 0, 'd'}, + {comment, required_argument, 0, 'c'}, + {showcomments, no_argument, 0, 'C'}, + LXC_COMMON_OPTIONS}; + +static struct lxc_arguments my_args = { + .progname = lxc-snapshot, + .help = \ +--name=NAME [-P lxcpath] [-L [-C]] [-c commentfile] [-r snapname [newname]]\n\ +\n\ +lxc-snapshot snapshots a container\n\ +\n\ +Options :\n\ + -n, --name=NAME NAME for name of the container\n\ + -L, --list list all snapshots\n\ + -C, --showcomments show snapshot comments\n\ + -c, --comment=FILE add FILE as a comment\n\ + -r, --restore=NAME restore snapshot NAME, e.g. 'snap0'\n\ + -d, --destroy=NAME destroy snapshot NAME, e.g. 'snap0'\n\ + use ALL to destroy all snapshots\n, + .options = my_longopts, + .parser = my_parser, + .checker = NULL, + .task = SNAP, +}; + +static int do_destroy_snapshots(struct lxc_container *c, char *snapname); +static int do_list_snapshots(struct lxc_container *c, int print_comments); +static int do_restore_snapshots(struct lxc_container *c, char *snapname, + char *newname); +static int do_snapshot(struct lxc_container *c, char *commentfile); +static int do_snapshot_task(struct lxc_container *c, enum task task); +static void print_file(char *path); + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + int ret; + + if (lxc_arguments_parse(my_args, argc, argv)) + exit(EXIT_FAILURE); + + if (!my_args.log_file) + my_args.log_file = none; + + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) + exit(EXIT_FAILURE); + lxc_log_options_no_override(); + + if (geteuid()) { + if (access(my_args.lxcpath[0], O_RDWR) 0) { + fprintf(stderr, You lack access to %s\n, + my_args.lxcpath[0]); + exit(EXIT_FAILURE); + } + } + + if (my_args.argc 1) { + ERROR(Too many arguments); + exit(EXIT_FAILURE); + } + + if (my_args.argc == 1) + my_args.newname = my_args.argv[0]; + + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); + if (!c) { + fprintf(stderr, System error loading container\n); + exit(EXIT_FAILURE); + } + + if (!c-may_control(c
[lxc-devel] Extending lxc_arguments struct
Hi Serge, hi Stéphane, currently the struct lxc_arguments lacks quite a few options which are required by e.g. lxc-snapshot and lxc-clone which leads to a non-uniform implementation of some of the executables. Would you be open to adding new members to the lxc_arguments struct in order to rewrite some of the executables? Best, Christian signature.asc Description: PGP signature ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] Archlinux in download
Hello, since systemd 219 was released and included in Archlinux unprivileged Archlinux containers work out of the box. Simply bootstrapping a barebone rootfs via pacstrap and uidmapshifting it will suffice. However, it would be convenient to be able to download unprivileged Archlinux containers via the download template provided by lxc. Are there any plans of making this happen in the near future? Best, Christian pgp7jFtz29K0F.pgp Description: PGP signature ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] uidmapshift et al.
Hello, I think it would be a really good idea to provide the nsexec tools with lxc per default. A lot of users (including myself) probably bootstrap a new filesystem for various distributions. Hence, they do not necessarily rely on templates or download templates provided with lxc. In order to convert such containers to unprivileged containers uidmapshift is a great tool. I think shipping it with lxc would be a lot easier. Christian pgprlD14xjj8B.pgp Description: PGP signature ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] Systemd creates btrfs subvolume under /var/lib/machines and makes lxc-destroy fail
Quoting Christian Brauner (christianvanbrauner at gmail.com): On Sun, Feb 15, 2015 at 05:21:19PM +0100, Christian Brauner wrote: Hello, I test the newest systemd from git on a regular basis by compiling it and installing it into a container and booting it. I did that with the several current systemd versions from git for the last couple of weeks. It seems that in the next version when booting a container with lxc-start, systemd creates a btrfs subvolume under rootfs/var/lib/machines in every container. This will cause lxc-destroy for unprivileged containers to fail. (Because subvolumes can currently be created but not destroyed by unprivileged users.) There either needs to be a way to destroy btrfs subvolumes for unprivileged user with lxc-destroy or the creation of btrfs subvolumes during container boot needs to be prevented. Is the second option already available? Best, Christian Add user_subvol_rm_allowed to your fstab and unprivileged users will be able to remove subvolumes. I have user_subvol_rm_allowed set. But it will fail nonetheless. lxc-destroy seems to expect that the rootfs is a btrfs subvolume. However, if it sees that rootfs itself is simply a folder and not a subvolume it will try to recursively delete it and then fail when it encounters a subvolume within the rootfs. (Systemd seems to create a btrfs subvolume only when the rootfs is a simple folder.) I think there should be some way of making lxc-destroy destroy all btrfs subvolumes within rootfs no matter if it is itself a subvolume or a simple folder. Sorry, this wasn't clear in my first mail. Ugh. I guess patch for that would be welcome, though the safety of that in case of a misconfigured privileged container worries me. But we can only protect that user from himself so much... The problem is pretty annoying actually and it will probably soon affect Fedora 22, Archlinux (and Ubuntu Vivid?). I'm running an Archlinux host with systemd 219 which was officially released yesterday. This is taken from the systemd 219 announce: (http://lists.freedesktop.org/archives/systemd-devel/2015-February/028447.html) * tmpfiles gained support for a new v line type for creating btrfs subvolumes. If the underlying file system is a legacy file system, this automatically degrades to creating a normal directory. Among others /var/lib/machines is now created like this at boot, should it be missing. This means that systemd 219 will create a subvolume when the container's rootfs is a btrfs subvolume. Here exemplified on two containers (arch, image) running Archlinux with systemd 219 inside: [chb@conventiont ~]$ sudo btrfs subvolume list / ID 257 gen 92117 top level 5 path @ D 1465 gen 91684 top level 257 path home/chb/.local/share/lxc/image/rootfs ID 1466 gen 91244 top level 1465 path home/chb/.local/share/lxc/image/rootfs/var/lib/machines ID 1459 gen 92126 top level 257 path home/chb/.local/share/lxc/arch/rootfs ID 1467 gen 92126 top level 1459 path home/chb/.local/share/lxc/arch/rootfs/var/lib/machines This now means that lxc-destroy will fail when the rootfs is a btrfs subvolume which contains a btrfs subvolume itself. (Or can lxc-destroy currently destroy rootfs which are btrfs subvolumes which contain subolumes themselves? If not it seems it should soon. But I'm definitely not acquainted enough with the lxc codebase to implement this.) Christian pgpIASheaJygX.pgp Description: PGP signature ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [PATCH] /proc/stat in lxcfs
+else if (sscanf(cpu_char, %d, cpu) != 1) { This is an unorthodox (for lxc) coding style. Could you explain exactly what you're doing here? I would expect just: if (sscanf(cpu_char, %d, cpu) != 1)) continue; if (!cpu_in_cpuset(cpu, cpuset)) continue; Your way is the better way to do it. I adjusted and squased the PR and post the patch again here as well: commit 21c3c7ace34eaf5f19074e33d050896b5cc3 Author: Christian Brauner christianvanbrau...@gmail.com Date: Sun Feb 15 11:31:31 2015 +0100 Show cpu-average in /proc/stat and start cup numbering at 0 diff --git a/lxcfs.c b/lxcfs.c index d6fb101..d358829 100644 --- a/lxcfs.c +++ b/lxcfs.c @@ -1642,7 +1642,7 @@ static int proc_stat_read(char *buf, size_t size, off_t offset, nih_local char *cpuset = NULL; char *line = NULL; size_t linelen = 0, total_len = 0; - int curcpu = 0; + int curcpu = -1; /* cpu numbering starts at 0 */ FILE *f; if (offset) @@ -1662,16 +1662,21 @@ static int proc_stat_read(char *buf, size_t size, off_t offset, while (getline(line, linelen, f) != -1) { size_t l; int cpu; +char cpu_char[10]; /* That's a lot of cores */ char *c; - if (sscanf(line, cpu%d, cpu) != 1) { - /* not a ^cpu line, just print it */ + if (sscanf(line, cpu%9[^ ], cpu_char) != 1) { + /* not a ^cpuN line containing a number N, just print it */ l = snprintf(buf, size, %s, line); buf += l; size -= l; total_len += l; continue; } + +if (sscanf(cpu_char, %d, cpu) != 1) +continue; + if (!cpu_in_cpuset(cpu, cpuset)) continue; curcpu ++; Christian pgp5TpkB7blqb.pgp Description: PGP signature ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] Systemd creates btrfs subvolume under /var/lib/machines and makes lxc-destroy fail
Hello, I test the newest systemd from git on a regular basis by compiling it and installing it into a container and booting it. I did that with the several current systemd versions from git for the last couple of weeks. It seems that in the next version when booting a container with lxc-start, systemd creates a btrfs subvolume under rootfs/var/lib/machines in every container. This will cause lxc-destroy for unprivileged containers to fail. (Because subvolumes can currently be created but not destroyed by unprivileged users.) There either needs to be a way to destroy btrfs subvolumes for unprivileged user with lxc-destroy or the creation of btrfs subvolumes during container boot needs to be prevented. Is the second option already available? Best, Christian From the man page of machinectl: (http://man7.org/linux/man-pages/man1/machinectl.1.html) FILES AND DIRECTORIES top Machine images are preferably stored in /var/lib/machines/, but are also searched for in /usr/local/lib/machines/ and /usr/lib/machines/. For compatibility reasons the directory /var/lib/container/ is searched, too. Note that images stored below /usr are always considered read-only. It is possible to symlink machines images from other directories into /var/lib/machines/ to make them available for control with machinectl. pgp0EfUpn3ZYZ.pgp Description: PGP signature ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [PATCH] /proc/stat in lxcfs
Hello, /proc/stat mounted at /var/lib/lxcfs/ is currently missing (a) the cpu average-line from the hosts /proc/stat and (b) the numbering of the cores starts with 1 and not with the 0. (This will e.g. cause confusion for top/htop in the container.) I wrote a minimally invasive patch for that: Signed-off-by: Christian Brauner christianvanbrau...@gmail.com Date: Sun Feb 15 10:34:41 2015 +0100 Bring the cpu-average line to /proc/stat mounted by lxcfs and let the core numbering start at 0. diff --git a/lxcfs.c b/lxcfs.c index d6fb101..ab296e7 100644 --- a/lxcfs.c +++ b/lxcfs.c @@ -1642,7 +1642,7 @@ static int proc_stat_read(char *buf, size_t size, off_t offset, nih_local char *cpuset = NULL; char *line = NULL; size_t linelen = 0, total_len = 0; - int curcpu = 0; + int curcpu = -1; /* cpu numbering starts at 0 */ FILE *f; if (offset) @@ -1662,16 +1662,22 @@ static int proc_stat_read(char *buf, size_t size, off_t offset, while (getline(line, linelen, f) != -1) { size_t l; int cpu; +char cpu_char[10]; /* That's a lot of cores */ char *c; - if (sscanf(line, cpu%d, cpu) != 1) { - /* not a ^cpu line, just print it */ + if (sscanf(line, cpu%9[^ ], cpu_char) != 1) { + /* not a ^cpuN line containing a number N, just print it */ l = snprintf(buf, size, %s, line); buf += l; size -= l; total_len += l; continue; } +else if (sscanf(cpu_char, %d, cpu) != 1) { +} +else { +} + if (!cpu_in_cpuset(cpu, cpuset)) continue; curcpu ++; Best, Christian - Forwarded message from Serge Hallyn serge.hal...@ubuntu.com - Date: Fri, 13 Feb 2015 04:14:11 + From: Serge Hallyn serge.hal...@ubuntu.com To: Christian Brauner christianvanbrau...@gmail.com Subject: Re: cpusets in non-unified hierarchy broken? User-Agent: Mutt/1.5.21 (2010-09-15) Quoting Christian Brauner (christianvanbrau...@gmail.com): On Thu, Feb 12, 2015 at 11:44:32PM +, Serge Hallyn wrote: Quoting Christian Brauner (christianvanbrau...@gmail.com): Hi Serge, There is random misreporting at times from top/htop inside of the container. Whereas e.g. cat /proc/self/status show Cpus_allowed 0-3, top/htop will show only 1 core. It may be getting it from /proc/stat, which you *may* be getting through lxcfs. It would then be filtering it through the container's cgroup info. When you start the container, does uptime say 1 minute, or does it match the host's uptime? It says uptime 0 minutes aka it does not match the host's uptime. /proc/stat is looking different in the container than on the host (probably because of the cgroup filtering you mentioned). I mentioned random misreporting mainly because the number of cores as displayed by top/htop in the container does not match the number of cores on the host. It is always less than on the host. I think this is caused by the implementation of /proc/stat by lxcfs. E.g. on the host [chb@conventiont ~]$ cat /proc/stat | grep cpu will show cpu 2061 0 1623 259471 4879 0 38 0 0 0 cpu0 568 0 458 63949 1905 0 12 0 0 0 cpu1 584 0 371 65044 1018 0 8 0 0 0 cpu2 410 0 390 65450 786 0 12 0 0 0 cpu3 498 0 403 65026 1169 0 5 0 0 0 whereas in the container root@vivid:~# cat /proc/stat | grep cpu will show cpu1 580 0 473 68799 1906 0 12 0 0 0 cpu2 600 0 384 69836 1080 0 8 0 0 0 cpu3 434 0 413 70268 786 0 12 0 0 0 cpu4 545 0 428 69839 1169 0 5 0 0 0 So (a) the cpu average-line from the hosts /proc/stat is missing. and (b) the numbering of the cores seems to be different in the container I guess this causes top/htop in the container to e.g. only show three cores on a four core system. Maybe, it doesn't show cpu0 at all because it thinks cpu0 is actually cpu (average)? Lxcfs bug maybe? Seems very likely. If you have time to write a patch for that that'd be awesome :) (Else I'll keep it on my list) thanks, -serge - End forwarded message - pgp0mVEW5q19s.pgp Description: PGP signature ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] Followup to: capset fails with userns
Here is the original problem which I'm still experiencing with lxc 1.1: w/ userns: [root at fedora2 ~]# setcap 'cap_net_admin,cap_net_raw+ep' /usr/bin/ping Failed to set capabilities on file `/usr/bin/ping' (Operation not permitted) [root at fedora2 ~]# id uid=0(root) gid=0(root) groups=0(root) w/o userns: [root at fedora2 ~]# setcap 'cap_net_admin,cap_net_raw+ep' /usr/bin/ping [root at fedora2 ~]# getcap /usr/bin/ping /usr/bin/ping = cap_net_admin,cap_net_raw+ep [root at fedora2 ~]# id uid=0(root) gid=0(root) groups=0(root) every yum install pkg where the pkg has file capabilities fails with Error unpacking rpm package PKG error: unpacking of archive failed on file FILE: cpio: cap_set_file is there a way to get this working? (posted by Stephan Sachse) The relevant threads are: https://lists.linuxcontainers.org/pipermail/lxc-devel/2014-February/008220.html and: https://www.redhat.com/archives/libvir-list/2014-February/msg01545.html Has there been a solution to this problem / an acceptable patch? Running Fedora Rawhide unprivileged trying to install iputils still shows this behaviour. Best, Christian pgpjhnYG8DCUH.pgp Description: PGP signature ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel