Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
f69d74e3
Commit
f69d74e3
authored
Aug 13, 2015
by
Serge Hallyn
Browse files
Options
Browse Files
Download
Plain Diff
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
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
463 additions
and
330 deletions
+463
-330
arguments.h
src/lxc/arguments.h
+16
-0
lxc_attach.c
src/lxc/lxc_attach.c
+1
-1
lxc_checkpoint.c
src/lxc/lxc_checkpoint.c
+1
-1
lxc_clone.c
src/lxc/lxc_clone.c
+189
-150
lxc_console.c
src/lxc/lxc_console.c
+1
-1
lxc_create.c
src/lxc/lxc_create.c
+2
-2
lxc_destroy.c
src/lxc/lxc_destroy.c
+56
-18
lxc_device.c
src/lxc/lxc_device.c
+1
-1
lxc_execute.c
src/lxc/lxc_execute.c
+1
-1
lxc_freeze.c
src/lxc/lxc_freeze.c
+1
-1
lxc_info.c
src/lxc/lxc_info.c
+1
-1
lxc_init.c
src/lxc/lxc_init.c
+1
-1
lxc_monitor.c
src/lxc/lxc_monitor.c
+1
-1
lxc_snapshot.c
src/lxc/lxc_snapshot.c
+180
-143
lxc_start.c
src/lxc/lxc_start.c
+1
-1
lxc_stop.c
src/lxc/lxc_stop.c
+1
-1
lxc_unfreeze.c
src/lxc/lxc_unfreeze.c
+1
-1
lxc_wait.c
src/lxc/lxc_wait.c
+1
-1
lxccontainer.c
src/lxc/lxccontainer.c
+7
-4
No files found.
src/lxc/arguments.h
View file @
f69d74e3
...
...
@@ -94,6 +94,22 @@ struct lxc_arguments {
int
list
;
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 */
char
*
const
*
argv
;
int
argc
;
...
...
src/lxc/lxc_attach.c
View file @
f69d74e3
...
...
@@ -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
\
...
...
src/lxc/lxc_checkpoint.c
View file @
f69d74e3
...
...
@@ -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
\
...
...
src/lxc/lxc_clone.c
View file @
f69d74e3
...
...
@@ -27,189 +27,228 @@
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <lxc/lxccontainer.h>
#include "log.h"
#include "config.h"
#include "confile.h"
#include "arguments.h"
#include "lxc.h"
#include "conf.h"
#include "state.h"
lxc_log_define
(
lxc_clone_ui
,
lxc
);
/* we pass fssize in bytes */
static
uint64_t
get_fssize
(
char
*
s
)
{
uint64_t
ret
;
char
*
end
;
ret
=
strtoull
(
s
,
&
end
,
0
);
if
(
end
==
s
)
{
fprintf
(
stderr
,
"Invalid blockdev size '%s', using default size
\n
"
,
s
);
return
0
;
}
while
(
isblank
(
*
end
))
end
++
;
if
(
*
end
==
'\0'
)
ret
*=
1024ULL
*
1024ULL
;
// MB by default
else
if
(
*
end
==
'b'
||
*
end
==
'B'
)
ret
*=
1ULL
;
else
if
(
*
end
==
'k'
||
*
end
==
'K'
)
ret
*=
1024ULL
;
else
if
(
*
end
==
'm'
||
*
end
==
'M'
)
ret
*=
1024ULL
*
1024ULL
;
else
if
(
*
end
==
'g'
||
*
end
==
'G'
)
ret
*=
1024ULL
*
1024ULL
*
1024ULL
;
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
;
}
return
ret
;
}
static
void
usage
(
const
char
*
me
)
{
printf
(
"Usage: %s [-s] [-B backingstore] [-L size[unit]] [-K] [-M] [-H]
\n
"
,
me
);
printf
(
" [-p lxcpath] [-P newlxcpath] orig new
\n
"
);
printf
(
"
\n
"
);
printf
(
" -s: snapshot rather than copy
\n
"
);
printf
(
" -B: use specified new backingstore. Default is the same as
\n
"
);
printf
(
" the original. Options include aufs, btrfs, lvm, overlayfs,
\n
"
);
printf
(
" dir and loop
\n
"
);
printf
(
" -L: for blockdev-backed backingstore, use specified size * specified
\n
"
);
printf
(
" unit. Default size is the size of the source blockdev, default
\n
"
);
printf
(
" unit is MB
\n
"
);
printf
(
" -K: Keep name - do not change the container name
\n
"
);
printf
(
" -M: Keep macaddr - do not choose a random new mac address
\n
"
);
printf
(
" -p: use container orig from custom lxcpath
\n
"
);
printf
(
" -P: create container new in custom lxcpath
\n
"
);
printf
(
" -R: rename existing container
\n
"
);
exit
(
1
);
}
static
int
my_parser
(
struct
lxc_arguments
*
args
,
int
c
,
char
*
arg
);
static
struct
option
options
[]
=
{
static
const
struct
option
my_longopts
[]
=
{
{
"newname"
,
required_argument
,
0
,
'N'
},
{
"newpath"
,
required_argument
,
0
,
'p'
},
{
"rename"
,
no_argument
,
0
,
'R'
},
{
"snapshot"
,
no_argument
,
0
,
's'
},
{
"backingstore"
,
required_argument
,
0
,
'B'
},
{
"size"
,
required_argument
,
0
,
'L'
},
{
"orig"
,
required_argument
,
0
,
'o'
},
{
"new"
,
required_argument
,
0
,
'n'
},
{
"vgname"
,
required_argument
,
0
,
'v'
},
{
"rename"
,
no_argument
,
0
,
'R'
},
{
"fssize"
,
required_argument
,
0
,
'L'
},
{
"keepname"
,
no_argument
,
0
,
'K'
},
{
"keepmac"
,
no_argument
,
0
,
'M'
},
{
"lxcpath"
,
required_argument
,
0
,
'p'
},
{
"newpath"
,
required_argument
,
0
,
'P'
},
{
"fstype"
,
required_argument
,
0
,
't'
},
{
"help"
,
no_argument
,
0
,
'h'
},
{
0
,
0
,
0
,
0
},
LXC_COMMON_OPTIONS
};
static
struct
lxc_arguments
my_args
=
{
.
progname
=
"lxc-clone"
,
.
help
=
"\
--name=NAME [-P lxcpath] -N newname [-p newpath] [-B backingstorage] [-s] [-K] [-M] [-L size [unit]]
\n
\
\n
\
lxc-lcone clone a container
\n
\
\n
\
Options :
\n
\
-n, --name=NAME NAME of the container
\n
\
-N, --newname=NEWNAME NEWNAME for the restored container
\n
\
-p, --newpath=NEWPATH NEWPATH for the container to be stored
\n
\
-R, --rename rename container
\n
\
-s, --snapshot create snapshot instead of clone
\n
\
-B, --backingstorage=TYPE backingstorage type for the container
\n
\
-L, --fssize size of the new block device for block device containers
\n
\
-K, --keepname keep the hostname of the original container
\n
\
-M, --keepmac keep the MAC address of the original container
\n
"
,
.
options
=
my_longopts
,
.
parser
=
my_parser
,
.
checker
=
NULL
,
};
static
int
do_clone
(
struct
lxc_container
*
c
,
char
*
newname
,
char
*
newpath
,
int
flags
,
char
*
bdevtype
,
uint64_t
fssize
,
char
**
args
);
static
int
do_clone_rename
(
struct
lxc_container
*
c
,
char
*
newname
);
static
uint64_t
get_fssize
(
char
*
s
);
int
main
(
int
argc
,
char
*
argv
[])
{
struct
lxc_container
*
c1
=
NULL
,
*
c2
=
NULL
;
int
snapshot
=
0
,
keepname
=
0
,
keepmac
=
0
,
rename
=
0
;
int
flags
=
0
,
option_index
;
uint64_t
newsize
=
0
;
char
*
bdevtype
=
NULL
,
*
lxcpath
=
NULL
,
*
newpath
=
NULL
,
*
fstype
=
NULL
;
char
*
orig
=
NULL
,
*
new
=
NULL
,
*
vgname
=
NULL
;
char
**
args
=
NULL
;
int
c
;
bool
ret
;
struct
lxc_container
*
c
;
int
flags
=
0
;
int
ret
;
if
(
argc
<
3
)
usage
(
argv
[
0
]);
while
(
1
)
{
c
=
getopt_long
(
argc
,
argv
,
"sB:L:o:n:v:KMHp:P:Rt:h"
,
options
,
&
option_index
);
if
(
c
==
-
1
)
break
;
switch
(
c
)
{
case
's'
:
snapshot
=
1
;
break
;
case
'B'
:
bdevtype
=
optarg
;
break
;
case
'L'
:
newsize
=
get_fssize
(
optarg
);
break
;
case
'o'
:
orig
=
optarg
;
break
;
case
'n'
:
new
=
optarg
;
break
;
case
'v'
:
vgname
=
optarg
;
break
;
case
'K'
:
keepname
=
1
;
break
;
case
'M'
:
keepmac
=
1
;
break
;
case
'p'
:
lxcpath
=
optarg
;
break
;
case
'P'
:
newpath
=
optarg
;
break
;
case
'R'
:
rename
=
1
;
break
;
case
't'
:
fstype
=
optarg
;
break
;
case
'h'
:
usage
(
argv
[
0
]);
default:
break
;
}
}
if
(
optind
<
argc
&&
!
orig
)
orig
=
argv
[
optind
++
];
if
(
optind
<
argc
&&
!
new
)
new
=
argv
[
optind
++
];
if
(
optind
<
argc
)
/* arguments for the clone hook */
args
=
&
argv
[
optind
];
if
(
!
new
||
!
orig
)
{
printf
(
"Error: you must provide orig and new names
\n
"
);
usage
(
argv
[
0
]);
}
if
(
lxc_arguments_parse
(
&
my_args
,
argc
,
argv
))
exit
(
EXIT_FAILURE
);
if
(
!
my_args
.
log_file
)
my_args
.
log_file
=
"none"
;
if
(
snapshot
)
flags
|=
LXC_CLONE_SNAPSHOT
;
if
(
keepname
)
flags
|=
LXC_CLONE_KEEPNAME
;
if
(
keepmac
)
flags
|=
LXC_CLONE_KEEPMACADDR
;
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
();
// vgname and fstype could be supported by sending them through the
// bdevdata. However, they currently are not yet. I'm not convinced
// they are worthwhile.
if
(
vgname
)
{
printf
(
"Error: vgname not supported
\n
"
);
usage
(
argv
[
0
]);
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
(
fstype
)
{
printf
(
"Error: fstype not supported
\n
"
);
usage
(
argv
[
0
]);
if
(
!
my_args
.
newname
)
{
printf
(
"Error: You must provide a NEWNAME for the clone.
\n
"
);
exit
(
EXIT_FAILURE
);
}
c1
=
lxc_container_new
(
orig
,
lxcpath
);
if
(
!
c1
)
if
(
my_args
.
task
==
SNAP
)
flags
|=
LXC_CLONE_SNAPSHOT
;
if
(
my_args
.
keepname
)
flags
|=
LXC_CLONE_KEEPNAME
;
if
(
my_args
.
keepmac
)
flags
|=
LXC_CLONE_KEEPMACADDR
;
c
=
lxc_container_new
(
my_args
.
name
,
my_args
.
lxcpath
[
0
]);
if
(
!
c
)
exit
(
EXIT_FAILURE
);
if
(
!
c1
->
may_control
(
c1
))
{
fprintf
(
stderr
,
"Insufficent privileges to control %s
\n
"
,
orig
);
lxc_container_put
(
c1
);
if
(
!
c
->
may_control
(
c
))
{
fprintf
(
stderr
,
"Insufficent privileges to control %s
\n
"
,
c
->
name
);
lxc_container_put
(
c
);
exit
(
EXIT_FAILURE
);
}
if
(
!
c1
->
is_defined
(
c1
))
{
fprintf
(
stderr
,
"Error: container %s is not defined
\n
"
,
orig
);
lxc_container_put
(
c1
);
if
(
!
c
->
is_defined
(
c
))
{
fprintf
(
stderr
,
"Error: container %s is not defined
\n
"
,
c
->
name
);
lxc_container_put
(
c
);
exit
(
EXIT_FAILURE
);
}
if
(
rename
)
{
ret
=
c1
->
rename
(
c1
,
new
);
if
(
!
ret
)
{
fprintf
(
stderr
,
"Error: Renaming container %s to %s failed
\n
"
,
c1
->
name
,
new
);
lxc_container_put
(
c1
);
exit
(
EXIT_FAILURE
);
}
if
(
my_args
.
task
==
RENAME
)
{
ret
=
do_clone_rename
(
c
,
my_args
.
newname
);
}
else
{
c2
=
c1
->
clone
(
c1
,
new
,
newpath
,
flags
,
bdevtype
,
NULL
,
newsize
,
args
);
if
(
c2
==
NULL
)
{
lxc_container_put
(
c1
);
fprintf
(
stderr
,
"clone failed
\n
"
);
exit
(
EXIT_FAILURE
);
}
printf
(
"Created container %s as %s of %s
\n
"
,
new
,
snapshot
?
"snapshot"
:
"copy"
,
orig
);
lxc_container_put
(
c2
);
ret
=
do_clone
(
c
,
my_args
.
newname
,
my_args
.
newpath
,
flags
,
my_args
.
bdevtype
,
my_args
.
fssize
,
&
argv
[
optind
]);
}
lxc_container_put
(
c1
);
exit
(
EXIT_SUCCESS
);
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
'N'
:
args
->
newname
=
arg
;
break
;
case
'p'
:
args
->
newpath
=
arg
;
break
;
case
'R'
:
args
->
task
=
RENAME
;
break
;
case
's'
:
args
->
task
=
SNAP
;
break
;
case
'B'
:
args
->
bdevtype
=
arg
;
break
;
case
'L'
:
args
->
fssize
=
get_fssize
(
optarg
);
break
;
case
'K'
:
args
->
keepname
=
1
;
break
;
case
'M'
:
args
->
keepmac
=
1
;
break
;
}
return
0
;
}
static
int
do_clone_rename
(
struct
lxc_container
*
c
,
char
*
newname
)
{
bool
ret
;
ret
=
c
->
rename
(
c
,
newname
);
if
(
!
ret
)
{
ERROR
(
"Error: Renaming container %s to %s failed
\n
"
,
c
->
name
,
my_args
.
newname
);
return
-
1
;
}
INFO
(
"Renamed container %s to %s
\n
"
,
c
->
name
,
newname
);
return
0
;
}
static
int
do_clone
(
struct
lxc_container
*
c
,
char
*
newname
,
char
*
newpath
,
int
flags
,
char
*
bdevtype
,
uint64_t
fssize
,
char
**
args
)
{
struct
lxc_container
*
clone
;
clone
=
c
->
clone
(
c
,
newname
,
newpath
,
flags
,
bdevtype
,
NULL
,
fssize
,
args
);
if
(
clone
==
NULL
)
{
fprintf
(
stderr
,
"clone failed
\n
"
);
return
-
1
;
}
INFO
(
"Created container %s as %s of %s
\n
"
,
newname
,
my_args
.
task
?
"snapshot"
:
"copy"
,
c
->
name
);
lxc_container_put
(
clone
);
return
0
;
}
/* we pass fssize in bytes */
static
uint64_t
get_fssize
(
char
*
s
)
{
uint64_t
ret
;
char
*
end
;
ret
=
strtoull
(
s
,
&
end
,
0
);
if
(
end
==
s
)
{
fprintf
(
stderr
,
"Invalid blockdev size '%s', using default size
\n
"
,
s
);
return
0
;
}
while
(
isblank
(
*
end
))
end
++
;
if
(
*
end
==
'\0'
)
{
ret
*=
1024ULL
*
1024ULL
;
// MB by default
}
else
if
(
*
end
==
'b'
||
*
end
==
'B'
)
{
ret
*=
1ULL
;
}
else
if
(
*
end
==
'k'
||
*
end
==
'K'
)
{
ret
*=
1024ULL
;
}
else
if
(
*
end
==
'm'
||
*
end
==
'M'
)
{
ret
*=
1024ULL
*
1024ULL
;
}
else
if
(
*
end
==
'g'
||
*
end
==
'G'
)
{
ret
*=
1024ULL
*
1024ULL
*
1024ULL
;
}
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
;
}
return
ret
;
}
src/lxc/lxc_console.c
View file @
f69d74e3
...
...
@@ -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
,
...
...
src/lxc/lxc_create.c
View file @
f69d74e3
...
...
@@ -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=NAME NAME
for name
of the container
\n
\
-n, --name=NAME NAME of the container
\n
\
-f, --config=file Initial configuration file
\n
\
-t, --template=t Template to use to setup container
\n
\
-B, --bdev=BDEV Backing store type to use
\n
\
...
...
src/lxc/lxc_destroy.c
View file @
f69d74e3
...
...
@@ -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
;
}
src/lxc/lxc_device.c
View file @
f69d74e3
...
...
@@ -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
,
...
...
src/lxc/lxc_execute.c
View file @
f69d74e3
...
...
@@ -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=FILE Load configuration file FILE
\n
\
-s, --define KEY=VAL Assign VAL to configuration variable KEY
\n
"
,
.
options
=
my_longopts
,
...
...
src/lxc/lxc_freeze.c
View file @
f69d74e3
...
...
@@ -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
of the container"
,
-n, --name=NAME NAME of the container"
,
.
options
=
my_longopts
,
.
parser
=
NULL
,
.
checker
=
NULL
,
...
...
src/lxc/lxc_info.c
View file @
f69d74e3
...
...
@@ -87,7 +87,7 @@ static struct lxc_arguments my_args = {
lxc-info display some information about 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
\
-c, --config=KEY show configuration variable KEY from running container
\n
\
-i, --ips shows the IP addresses
\n
\
-p, --pid shows the process id of the init container
\n
\
...
...
src/lxc/lxc_init.c
View file @
f69d74e3
...
...
@@ -61,7 +61,7 @@ static void interrupt_handler(int sig)
static
void
usage
(
void
)
{
fprintf
(
stderr
,
"Usage: lxc-init [OPTION]...
\n\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
"
" -q, --quiet Don't produce any output
\n
"
" -P, --lxcpath=PATH Use specified container path
\n
"
...
...
src/lxc/lxc_monitor.c
View file @
f69d74e3
...
...
@@ -61,7 +61,7 @@ static struct lxc_arguments my_args = {
lxc-monitor monitors the state of the NAME container
\n
\
\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
\
-Q, --quit tell lxc-monitord to quit
\n
"
,
.
name
=
".*"
,
...
...
src/lxc/lxc_snapshot.c
View file @
f69d74e3
...
...
@@ -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,149 @@
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'
},
{
"newname"
,
required_argument
,
0
,
'N'
},
{
"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 [-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
;
...
...
@@ -57,26 +188,11 @@ static int do_snapshot(struct lxc_container *c)
}
INFO
(
"Created snapshot snap%d"
,
ret
);
return
0
;
}
static
void
print_file
(
char
*
path
)
{
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
);
return
0
;
}
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
;
int
i
,
n
;
...
...
@@ -90,148 +206,69 @@ static int do_list_snapshots(struct lxc_container *c)
printf
(
"No snapshots
\n
"
);
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
);
if
(
print_comments
)
print_file
(
s
[
i
].
comment_pathname
);
s
[
i
].
free
(
&
s
[
i
]);
}
free
(
s
);
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
;
ERROR
(
"Error restoring snapshot %s"
,
snapshot
);
ERROR
(
"Error restoring snapshot %s"
,
snapname
);
return
-
1
;
}
static
int
do_destroy_snapshots
(
struct
lxc_container
*
c
)
static
int
do_destroy_snapshots
(
struct
lxc_container
*
c
,
char
*
snapname
)
{
bool
bret
;
if
(
strcmp
(
snapshot
,
"ALL"
)
==
0
)
bret
=
c
->
snapshot_destroy_all
(
c
);
bool
ret
;
if
(
strcmp
(
snapname
,
"ALL"
)
==
0
)
ret
=
c
->
snapshot_destroy_all
(
c
);
else
bret
=
c
->
snapshot_destroy
(
c
,
snapshot
);
ret
=
c
->
snapshot_destroy
(
c
,
snapname
);
if
(
b
ret
)
if
(
ret
)
return
0
;
ERROR
(
"Error destroying snapshot %s"
,
snapshot
);
return
-
1
;
}
ERROR
(
"Error destroying snapshot %s"
,
snapname
);
static
int
my_parser
(
struct
lxc_arguments
*
args
,
int
c
,
char
*
arg
)
{
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
;
return
-
1
;
}
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 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
[])
static
void
print_file
(
char
*
path
)
{
struct
lxc_container
*
c
;
int
ret
=
0
;
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
);
}
}
if
(
!
path
)
return
;
c
=
lxc_container_new
(
my_args
.
name
,
my_args
.
lxcpath
[
0
]);
if
(
!
c
)
{
fprintf
(
stderr
,
"System error loading container
\n
"
);
exit
(
1
);
}
FILE
*
f
=
fopen
(
path
,
"r"
);
char
*
line
=
NULL
;
size_t
sz
=
0
;
if
(
!
c
->
may_control
(
c
))
{
fprintf
(
stderr
,
"Insufficent privileges to control %s
\n
"
,
my_args
.
name
);
lxc_container_put
(
c
);
exit
(
1
);
}
if
(
!
f
)
return
;
switch
(
action
)
{
case
DO_SNAP
:
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
;
while
(
getline
(
&
line
,
&
sz
,
f
)
!=
-
1
)
{
printf
(
"%s"
,
line
);
}
lxc_container_put
(
c
);
if
(
ret
==
0
)
exit
(
EXIT_SUCCESS
);
exit
(
EXIT_FAILURE
);
free
(
line
);
fclose
(
f
);
}
src/lxc/lxc_start.c
View file @
f69d74e3
...
...
@@ -181,7 +181,7 @@ static struct lxc_arguments my_args = {
lxc-start start COMMAND in specified container NAME
\n
\
\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
\
-F, --foreground Start with the current tty attached to /dev/console
\n
\
-p, --pidfile=FILE Create a file with the process id
\n
\
...
...
src/lxc/lxc_stop.c
View file @
f69d74e3
...
...
@@ -69,7 +69,7 @@ static struct lxc_arguments my_args = {
lxc-stop stops 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
\
-r, --reboot reboot the container
\n
\
-W, --nowait don't wait for shutdown or reboot to complete
\n
\
-t, --timeout=T wait T seconds before hard-stopping
\n
\
...
...
src/lxc/lxc_unfreeze.c
View file @
f69d74e3
...
...
@@ -45,7 +45,7 @@ static struct lxc_arguments my_args = {
lxc-unfreeze unfreezes 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
"
,
.
options
=
my_longopts
,
.
parser
=
NULL
,
.
checker
=
NULL
,
...
...
src/lxc/lxc_wait.c
View file @
f69d74e3
...
...
@@ -68,7 +68,7 @@ static struct lxc_arguments my_args = {
lxc-wait waits for NAME container state to reach STATE
\n
\
\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
\
STOPPED, STARTING, RUNNING, STOPPING,
\n
\
ABORTING, FREEZING, FROZEN, THAWED
\n
\
...
...
src/lxc/lxccontainer.c
View file @
f69d74e3
...
...
@@ -2906,12 +2906,15 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
if
(
ret
<
0
)
goto
out
;
clear_unexp_config_line
(
c2
->
lxc_conf
,
"lxc.utsname"
,
false
);
// update utsname
if
(
!
set_config_item_locked
(
c2
,
"lxc.utsname"
,
newname
))
{
ERROR
(
"Error setting new hostname"
);
goto
out
;
if
(
!
(
flags
&
LXC_CLONE_KEEPNAME
))
{
clear_unexp_config_line
(
c2
->
lxc_conf
,
"lxc.utsname"
,
false
);
if
(
!
set_config_item_locked
(
c2
,
"lxc.utsname"
,
newname
))
{
ERROR
(
"Error setting new hostname"
);
goto
out
;
}
}
// copy hooks
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment