Commit f69d74e3 by Serge Hallyn

Merge pull request #621 from brauner/arguments

Refactor lxc-snapshot, lxc-clone, make LXC_CLONE_KEEPNAME work and add option to destroy container with all snapshots to lxc-destroy
parents 3cd05817 7909bb03
...@@ -94,6 +94,22 @@ struct lxc_arguments { ...@@ -94,6 +94,22 @@ struct lxc_arguments {
int list; int list;
char *groups; char *groups;
/* lxc-snapshot and lxc-clone */
enum task {
DESTROY,
LIST,
RESTORE,
SNAP,
RENAME,
} task;
int print_comments;
char *commentfile;
char *newname;
char *newpath;
char *snapname;
int keepname;
int keepmac;
/* remaining arguments */ /* remaining arguments */
char *const *argv; char *const *argv;
int argc; int argc;
......
...@@ -146,7 +146,7 @@ static struct lxc_arguments my_args = { ...@@ -146,7 +146,7 @@ static struct lxc_arguments my_args = {
Execute the specified COMMAND - enter the container NAME\n\ Execute the specified COMMAND - enter the container NAME\n\
\n\ \n\
Options :\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\ -e, --elevated-privileges=PRIVILEGES\n\
Use elevated privileges instead of those of the\n\ Use elevated privileges instead of those of the\n\
container. If you don't specify privileges to be\n\ container. If you don't specify privileges to be\n\
......
...@@ -105,7 +105,7 @@ lxc-checkpoint checkpoints and restores a container\n\ ...@@ -105,7 +105,7 @@ lxc-checkpoint checkpoints and restores a container\n\
its running state at a later time.\n\ its running state at a later time.\n\
\n\ \n\
Options :\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\ -r, --restore Restore container\n\
-D, --checkpoint-dir=DIR directory to save the checkpoint in\n\ -D, --checkpoint-dir=DIR directory to save the checkpoint in\n\
-v, --verbose Enable verbose criu logs\n\ -v, --verbose Enable verbose criu logs\n\
......
...@@ -78,7 +78,7 @@ static struct lxc_arguments my_args = { ...@@ -78,7 +78,7 @@ static struct lxc_arguments my_args = {
lxc-console logs on the container with the identifier NAME\n\ lxc-console logs on the container with the identifier NAME\n\
\n\ \n\
Options :\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\ -t, --tty=NUMBER console tty number\n\
-e, --escape=PREFIX prefix for escape command\n", -e, --escape=PREFIX prefix for escape command\n",
.options = my_longopts, .options = my_longopts,
......
...@@ -61,7 +61,7 @@ static uint64_t get_fssize(char *s) ...@@ -61,7 +61,7 @@ static uint64_t get_fssize(char *s)
else if (*end == 't' || *end == 'T') else if (*end == 't' || *end == 'T')
ret *= 1024ULL * 1024ULL * 1024ULL * 1024ULL; ret *= 1024ULL * 1024ULL * 1024ULL * 1024ULL;
else else
{ {
fprintf(stderr, "Invalid blockdev unit size '%c' in '%s', using default size\n", *end, s); fprintf(stderr, "Invalid blockdev unit size '%c' in '%s', using default size\n", *end, s);
return 0; return 0;
} }
...@@ -131,7 +131,7 @@ static struct lxc_arguments my_args = { ...@@ -131,7 +131,7 @@ static struct lxc_arguments my_args = {
lxc-create creates a container\n\ lxc-create creates a container\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container\n\ -n, --name=NAME NAME of the container\n\
-f, --config=file Initial configuration file\n\ -f, --config=file Initial configuration file\n\
-t, --template=t Template to use to setup container\n\ -t, --template=t Template to use to setup container\n\
-B, --bdev=BDEV Backing store type to use\n\ -B, --bdev=BDEV Backing store type to use\n\
......
...@@ -31,16 +31,11 @@ ...@@ -31,16 +31,11 @@
lxc_log_define(lxc_destroy_ui, lxc); lxc_log_define(lxc_destroy_ui, lxc);
static int my_parser(struct lxc_arguments* args, int c, char* arg) static int my_parser(struct lxc_arguments* args, int c, char* arg);
{
switch (c) {
case 'f': args->force = 1; break;
}
return 0;
}
static const struct option my_longopts[] = { static const struct option my_longopts[] = {
{"force", no_argument, 0, 'f'}, {"force", no_argument, 0, 'f'},
{"snapshots", no_argument, 0, 's'},
LXC_COMMON_OPTIONS LXC_COMMON_OPTIONS
}; };
...@@ -52,61 +47,104 @@ static struct lxc_arguments my_args = { ...@@ -52,61 +47,104 @@ static struct lxc_arguments my_args = {
lxc-destroy destroys a container with the identifier NAME\n\ lxc-destroy destroys a container with the identifier NAME\n\
\n\ \n\
Options :\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", -f, --force wait for the container to shut down\n",
.options = my_longopts, .options = my_longopts,
.parser = my_parser, .parser = my_parser,
.checker = NULL, .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[]) int main(int argc, char *argv[])
{ {
struct lxc_container *c; struct lxc_container *c;
int ret;
if (lxc_arguments_parse(&my_args, argc, argv)) if (lxc_arguments_parse(&my_args, argc, argv))
exit(1); exit(EXIT_FAILURE);
if (!my_args.log_file) if (!my_args.log_file)
my_args.log_file = "none"; my_args.log_file = "none";
if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, 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])) my_args.progname, my_args.quiet, my_args.lxcpath[0]))
exit(1); exit(EXIT_FAILURE);
lxc_log_options_no_override(); lxc_log_options_no_override();
c = lxc_container_new(my_args.name, my_args.lxcpath[0]); c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
if (!c) { if (!c) {
fprintf(stderr, "System error loading container\n"); fprintf(stderr, "System error loading container\n");
exit(1); exit(EXIT_FAILURE);
} }
if (!c->may_control(c)) { if (!c->may_control(c)) {
fprintf(stderr, "Insufficent privileges to control %s\n", my_args.name); fprintf(stderr, "Insufficent privileges to control %s\n", my_args.name);
lxc_container_put(c); lxc_container_put(c);
exit(1); exit(EXIT_FAILURE);
} }
if (!c->is_defined(c)) { if (!c->is_defined(c)) {
fprintf(stderr, "Container is not defined\n"); fprintf(stderr, "Container is not defined\n");
lxc_container_put(c); lxc_container_put(c);
exit(1); exit(EXIT_FAILURE);
} }
if (c->is_running(c)) { if (c->is_running(c)) {
if (!my_args.force) { if (!my_args.force) {
fprintf(stderr, "%s is running\n", my_args.name); fprintf(stderr, "%s is running\n", my_args.name);
lxc_container_put(c); lxc_container_put(c);
exit(1); exit(EXIT_FAILURE);
} }
c->stop(c); 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)) { if (!c->destroy(c)) {
fprintf(stderr, "Destroying %s failed\n", my_args.name); fprintf(stderr, "Destroying %s failed\n", my_args.name);
lxc_container_put(c); return -1;
exit(1);
} }
lxc_container_put(c); printf("Destroyed container %s\n", my_args.name);
exit(0);
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;
}
...@@ -53,7 +53,7 @@ static struct lxc_arguments my_args = { ...@@ -53,7 +53,7 @@ static struct lxc_arguments my_args = {
lxc-device attach or detach DEV to or from container.\n\ lxc-device attach or detach DEV to or from container.\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container", -n, --name=NAME NAME of the container",
.options = my_longopts, .options = my_longopts,
.parser = NULL, .parser = NULL,
.checker = NULL, .checker = NULL,
......
...@@ -79,7 +79,7 @@ lxc-execute creates a container with the identifier NAME\n\ ...@@ -79,7 +79,7 @@ lxc-execute creates a container with the identifier NAME\n\
and execs COMMAND into this container.\n\ and execs COMMAND into this container.\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container\n\ -n, --name=NAME NAME of the container\n\
-f, --rcfile=FILE Load configuration file FILE\n\ -f, --rcfile=FILE Load configuration file FILE\n\
-s, --define KEY=VAL Assign VAL to configuration variable KEY\n", -s, --define KEY=VAL Assign VAL to configuration variable KEY\n",
.options = my_longopts, .options = my_longopts,
......
...@@ -47,7 +47,7 @@ static struct lxc_arguments my_args = { ...@@ -47,7 +47,7 @@ static struct lxc_arguments my_args = {
lxc-freeze freezes a container with the identifier NAME\n\ lxc-freeze freezes a container with the identifier NAME\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container", -n, --name=NAME NAME of the container",
.options = my_longopts, .options = my_longopts,
.parser = NULL, .parser = NULL,
.checker = NULL, .checker = NULL,
......
...@@ -87,7 +87,7 @@ static struct lxc_arguments my_args = { ...@@ -87,7 +87,7 @@ static struct lxc_arguments my_args = {
lxc-info display some information about a container with the identifier NAME\n\ lxc-info display some information about a container with the identifier NAME\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container\n\ -n, --name=NAME NAME of the container\n\
-c, --config=KEY show configuration variable KEY from running container\n\ -c, --config=KEY show configuration variable KEY from running container\n\
-i, --ips shows the IP addresses\n\ -i, --ips shows the IP addresses\n\
-p, --pid shows the process id of the init container\n\ -p, --pid shows the process id of the init container\n\
......
...@@ -61,7 +61,7 @@ static void interrupt_handler(int sig) ...@@ -61,7 +61,7 @@ static void interrupt_handler(int sig)
static void usage(void) { static void usage(void) {
fprintf(stderr, "Usage: lxc-init [OPTION]...\n\n" fprintf(stderr, "Usage: lxc-init [OPTION]...\n\n"
"Common options :\n" "Common options :\n"
" -n, --name=NAME NAME for name of the container\n" " -n, --name=NAME NAME of the container\n"
" -l, --logpriority=LEVEL Set log priority to LEVEL\n" " -l, --logpriority=LEVEL Set log priority to LEVEL\n"
" -q, --quiet Don't produce any output\n" " -q, --quiet Don't produce any output\n"
" -P, --lxcpath=PATH Use specified container path\n" " -P, --lxcpath=PATH Use specified container path\n"
......
...@@ -61,7 +61,7 @@ static struct lxc_arguments my_args = { ...@@ -61,7 +61,7 @@ static struct lxc_arguments my_args = {
lxc-monitor monitors the state of the NAME container\n\ lxc-monitor monitors the state of the NAME container\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container\n\ -n, --name=NAME NAME of the container\n\
NAME may be a regular expression\n\ NAME may be a regular expression\n\
-Q, --quit tell lxc-monitord to quit\n", -Q, --quit tell lxc-monitord to quit\n",
.name = ".*", .name = ".*",
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "config.h"
#include "confile.h"
#include <stdio.h> #include <stdio.h>
#include <libgen.h> #include <libgen.h>
#include <unistd.h> #include <unistd.h>
...@@ -35,18 +35,149 @@ ...@@ -35,18 +35,149 @@
lxc_log_define(lxc_snapshot_ui, lxc); lxc_log_define(lxc_snapshot_ui, lxc);
static char *newname; static int my_parser(struct lxc_arguments *args, int c, char *arg);
static char *snapshot;
#define DO_SNAP 0 static const struct option my_longopts[] = {
#define DO_LIST 1 {"list", no_argument, 0, 'L'},
#define DO_RESTORE 2 {"restore", required_argument, 0, 'r'},
#define DO_DESTROY 3 {"newname", required_argument, 0, 'N'},
static int action; {"destroy", required_argument, 0, 'd'},
static int print_comments; {"comment", required_argument, 0, 'c'},
static char *commentfile; {"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 [-N newname]]\n\
\n\
lxc-snapshot snapshots a container\n\
\n\
Options :\n\
-n, --name=NAME NAME of the container\n\
-L, --list list all snapshots\n\
-r, --restore=NAME restore snapshot NAME, e.g. 'snap0'\n\
-N, --newname=NEWNAME NEWNAME for the restored container\n\
-d, --destroy=NAME destroy snapshot NAME, e.g. 'snap0'\n\
use ALL to destroy all snapshots\n\
-c, --comment=FILE add FILE as a comment\n\
-C, --showcomments show snapshot comments\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);
}
}
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)) {
fprintf(stderr, "Insufficent privileges to control %s\n",
my_args.name);
lxc_container_put(c);
exit(EXIT_FAILURE);
}
static int do_snapshot(struct lxc_container *c) ret = do_snapshot_task(c, my_args.task);
lxc_container_put(c);
if (ret == 0)
exit(EXIT_SUCCESS);
exit(EXIT_FAILURE);
}
static int do_snapshot_task(struct lxc_container *c, enum task task)
{
int ret = 0;
switch (task) {
case DESTROY:
ret = do_destroy_snapshots(c, my_args.snapname);
break;
case LIST:
ret = do_list_snapshots(c, my_args.print_comments);
break;
case RESTORE:
ret =
do_restore_snapshots(c, my_args.snapname, my_args.newname);
break;
case SNAP:
ret = do_snapshot(c, my_args.commentfile);
break;
default:
ret = 0;
break;
}
return ret;
}
static int my_parser(struct lxc_arguments *args, int c, char *arg)
{
switch (c) {
case 'L':
args->task = LIST;
break;
case 'r':
args->task = RESTORE;
args->snapname = arg;
break;
case 'N':
args->newname = arg;
break;
case 'd':
args->task = DESTROY;
args->snapname = arg;
break;
case 'c':
args->commentfile = arg;
break;
case 'C':
args->print_comments = 1;
break;
}
return 0;
}
static int do_snapshot(struct lxc_container *c, char *commentfile)
{ {
int ret; int ret;
...@@ -57,26 +188,11 @@ static int do_snapshot(struct lxc_container *c) ...@@ -57,26 +188,11 @@ static int do_snapshot(struct lxc_container *c)
} }
INFO("Created snapshot snap%d", ret); INFO("Created snapshot snap%d", ret);
return 0;
}
static void print_file(char *path) return 0;
{
if (!path)
return;
FILE *f = fopen(path, "r");
char *line = NULL;
size_t sz = 0;
if (!f)
return;
while (getline(&line, &sz, f) != -1) {
printf("%s", line);
}
free(line);
fclose(f);
} }
static int do_list_snapshots(struct lxc_container *c) static int do_list_snapshots(struct lxc_container *c, int print_comments)
{ {
struct lxc_snapshot *s; struct lxc_snapshot *s;
int i, n; int i, n;
...@@ -90,148 +206,69 @@ static int do_list_snapshots(struct lxc_container *c) ...@@ -90,148 +206,69 @@ static int do_list_snapshots(struct lxc_container *c)
printf("No snapshots\n"); printf("No snapshots\n");
return 0; return 0;
} }
for (i=0; i<n; i++) {
for (i = 0; i < n; i++) {
printf("%s (%s) %s\n", s[i].name, s[i].lxcpath, s[i].timestamp); printf("%s (%s) %s\n", s[i].name, s[i].lxcpath, s[i].timestamp);
if (print_comments) if (print_comments)
print_file(s[i].comment_pathname); print_file(s[i].comment_pathname);
s[i].free(&s[i]); s[i].free(&s[i]);
} }
free(s); free(s);
return 0; return 0;
} }
static int do_restore_snapshots(struct lxc_container *c) static int do_restore_snapshots(struct lxc_container *c, char *snapname,
char *newname)
{ {
if (c->snapshot_restore(c, snapshot, newname)) if (!newname) {
printf("Error: You must provide a NEWNAME for the container\n");
return -1;
}
if (c->snapshot_restore(c, snapname, newname))
return 0; return 0;
ERROR("Error restoring snapshot %s", snapshot); ERROR("Error restoring snapshot %s", snapname);
return -1; return -1;
} }
static int do_destroy_snapshots(struct lxc_container *c) static int do_destroy_snapshots(struct lxc_container *c, char *snapname)
{ {
bool bret; bool ret;
if (strcmp(snapshot, "ALL") == 0)
bret = c->snapshot_destroy_all(c); if (strcmp(snapname, "ALL") == 0)
ret = c->snapshot_destroy_all(c);
else else
bret = c->snapshot_destroy(c, snapshot); ret = c->snapshot_destroy(c, snapname);
if (bret) if (ret)
return 0; return 0;
ERROR("Error destroying snapshot %s", snapshot); ERROR("Error destroying snapshot %s", snapname);
return -1;
}
static int my_parser(struct lxc_arguments* args, int c, char* arg) return -1;
{
switch (c) {
case 'L': action = DO_LIST; break;
case 'r': snapshot = arg; action = DO_RESTORE; break;
case 'd': snapshot = arg; action = DO_DESTROY; break;
case 'c': commentfile = arg; break;
case 'C': print_comments = true; break;
}
return 0;
} }
static const struct option my_longopts[] = { static void print_file(char *path)
{"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 snapshots\n\
-C, --showcomments show snapshot comments in list\n\
-c, --comment=file add file as a comment\n\
-r, --restore=name restore snapshot name, i.e. 'snap0'\n\
-d, --destroy=name destroy snapshot name, i.e. 'snap0'\n\
use ALL to destroy all snapshots\n",
.options = my_longopts,
.parser = my_parser,
.checker = NULL,
};
/*
* lxc-snapshot -P lxcpath -n container
* lxc-snapshot -P lxcpath -n container -l
* lxc-snapshot -P lxcpath -n container -r snap3 recovered_1
*/
int main(int argc, char *argv[])
{ {
struct lxc_container *c; if (!path)
int ret = 0; return;
if (lxc_arguments_parse(&my_args, argc, argv))
exit(1);
if (!my_args.log_file)
my_args.log_file = "none";
if (my_args.argc > 1) {
ERROR("Too many arguments");
exit(1);
}
if (my_args.argc == 1)
newname = my_args.argv[0];
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);
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(1);
}
}
c = lxc_container_new(my_args.name, my_args.lxcpath[0]); FILE *f = fopen(path, "r");
if (!c) { char *line = NULL;
fprintf(stderr, "System error loading container\n"); size_t sz = 0;
exit(1);
}
if (!c->may_control(c)) { if (!f)
fprintf(stderr, "Insufficent privileges to control %s\n", my_args.name); return;
lxc_container_put(c);
exit(1);
}
switch(action) { while (getline(&line, &sz, f) != -1) {
case DO_SNAP: printf("%s", line);
ret = do_snapshot(c);
break;
case DO_LIST:
ret = do_list_snapshots(c);
break;
case DO_RESTORE:
ret = do_restore_snapshots(c);
break;
case DO_DESTROY:
ret = do_destroy_snapshots(c);
break;
} }
lxc_container_put(c); free(line);
fclose(f);
if (ret == 0)
exit(EXIT_SUCCESS);
exit(EXIT_FAILURE);
} }
...@@ -181,7 +181,7 @@ static struct lxc_arguments my_args = { ...@@ -181,7 +181,7 @@ static struct lxc_arguments my_args = {
lxc-start start COMMAND in specified container NAME\n\ lxc-start start COMMAND in specified container NAME\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container\n\ -n, --name=NAME NAME of the container\n\
-d, --daemon Daemonize the container (default)\n\ -d, --daemon Daemonize the container (default)\n\
-F, --foreground Start with the current tty attached to /dev/console\n\ -F, --foreground Start with the current tty attached to /dev/console\n\
-p, --pidfile=FILE Create a file with the process id\n\ -p, --pidfile=FILE Create a file with the process id\n\
......
...@@ -69,7 +69,7 @@ static struct lxc_arguments my_args = { ...@@ -69,7 +69,7 @@ static struct lxc_arguments my_args = {
lxc-stop stops a container with the identifier NAME\n\ lxc-stop stops a container with the identifier NAME\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container\n\ -n, --name=NAME NAME of the container\n\
-r, --reboot reboot the container\n\ -r, --reboot reboot the container\n\
-W, --nowait don't wait for shutdown or reboot to complete\n\ -W, --nowait don't wait for shutdown or reboot to complete\n\
-t, --timeout=T wait T seconds before hard-stopping\n\ -t, --timeout=T wait T seconds before hard-stopping\n\
......
...@@ -45,7 +45,7 @@ static struct lxc_arguments my_args = { ...@@ -45,7 +45,7 @@ static struct lxc_arguments my_args = {
lxc-unfreeze unfreezes a container with the identifier NAME\n\ lxc-unfreeze unfreezes a container with the identifier NAME\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container\n", -n, --name=NAME NAME of the container\n",
.options = my_longopts, .options = my_longopts,
.parser = NULL, .parser = NULL,
.checker = NULL, .checker = NULL,
......
...@@ -68,7 +68,7 @@ static struct lxc_arguments my_args = { ...@@ -68,7 +68,7 @@ static struct lxc_arguments my_args = {
lxc-wait waits for NAME container state to reach STATE\n\ lxc-wait waits for NAME container state to reach STATE\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container\n\ -n, --name=NAME NAME of the container\n\
-s, --state=STATE ORed states to wait for\n\ -s, --state=STATE ORed states to wait for\n\
STOPPED, STARTING, RUNNING, STOPPING,\n\ STOPPED, STARTING, RUNNING, STOPPING,\n\
ABORTING, FREEZING, FROZEN, THAWED\n\ ABORTING, FREEZING, FROZEN, THAWED\n\
......
...@@ -2906,12 +2906,15 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char ...@@ -2906,12 +2906,15 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
if (ret < 0) if (ret < 0)
goto out; goto out;
clear_unexp_config_line(c2->lxc_conf, "lxc.utsname", false);
// update utsname // update utsname
if (!set_config_item_locked(c2, "lxc.utsname", newname)) { if (!(flags & LXC_CLONE_KEEPNAME)) {
ERROR("Error setting new hostname"); clear_unexp_config_line(c2->lxc_conf, "lxc.utsname", false);
goto out;
if (!set_config_item_locked(c2, "lxc.utsname", newname)) {
ERROR("Error setting new hostname");
goto out;
}
} }
// copy hooks // copy hooks
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment