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
a73846d8
Commit
a73846d8
authored
Jul 20, 2018
by
2xsec
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lxccontainer: coding rules
Signed-off-by:
2xsec
<
dh48.jeong@samsung.com
>
parent
29c98ddd
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
242 additions
and
74 deletions
+242
-74
lxccontainer.c
src/lxc/lxccontainer.c
+242
-74
No files found.
src/lxc/lxccontainer.c
View file @
a73846d8
...
...
@@ -167,11 +167,12 @@ static int ongoing_create(struct lxc_container *c)
ret
=
fcntl
(
fd
,
F_OFD_GETLK
,
&
lk
);
if
(
ret
<
0
&&
errno
==
EINVAL
)
ret
=
flock
(
fd
,
LOCK_EX
|
LOCK_NB
);
close
(
fd
);
if
(
ret
==
0
&&
lk
.
l_pid
!=
-
1
)
{
if
(
ret
==
0
&&
lk
.
l_pid
!=
-
1
)
/* create is still ongoing */
return
1
;
}
/* Create completed but partial is still there. */
return
2
;
...
...
@@ -221,6 +222,7 @@ static void remove_partial(struct lxc_container *c, int fd)
char
*
path
;
close
(
fd
);
/* $lxcpath + '/' + $name + '/partial' + \0 */
len
=
strlen
(
c
->
config_path
)
+
strlen
(
c
->
name
)
+
10
;
path
=
alloca
(
len
);
...
...
@@ -254,7 +256,6 @@ static void remove_partial(struct lxc_container *c, int fd)
* decrement numthreads under privlock, then if it hits 0 you can delete.
* Do not ever use a lxccontainer whose numthreads you did not bump.
*/
static
void
lxc_container_free
(
struct
lxc_container
*
c
)
{
if
(
!
c
)
...
...
@@ -358,7 +359,6 @@ int lxc_container_put(struct lxc_container *c)
}
container_mem_unlock
(
c
);
return
0
;
}
...
...
@@ -385,7 +385,6 @@ static bool do_lxcapi_is_defined(struct lxc_container *c)
on_error:
container_mem_unlock
(
c
);
return
ret
;
}
...
...
@@ -596,7 +595,6 @@ static bool load_config_locked(struct lxc_container *c, const char *fname)
return
false
;
c
->
lxc_conf
->
name
=
c
->
name
;
return
true
;
}
...
...
@@ -610,8 +608,10 @@ static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file)
return
false
;
fname
=
c
->
configfile
;
if
(
alt_file
)
fname
=
alt_file
;
if
(
!
fname
)
return
false
;
...
...
@@ -746,9 +746,8 @@ static char **split_init_cmd(const char *incmd)
len
=
strlen
(
incmd
)
+
1
;
copy
=
alloca
(
len
);
retlen
=
strlcpy
(
copy
,
incmd
,
len
);
if
(
retlen
>=
len
)
{
if
(
retlen
>=
len
)
return
NULL
;
}
do
{
argv
=
malloc
(
sizeof
(
char
*
));
...
...
@@ -781,62 +780,62 @@ static void free_init_cmd(char **argv)
static
int
lxc_rcv_status
(
int
state_socket
)
{
int
ret
;
int
state
=
-
1
;
int
ret
;
int
state
=
-
1
;
again
:
/* Receive container state. */
ret
=
lxc_abstract_unix_rcv_credential
(
state_socket
,
&
state
,
sizeof
(
int
));
if
(
ret
<=
0
)
{
/* Receive container state. */
ret
=
lxc_abstract_unix_rcv_credential
(
state_socket
,
&
state
,
sizeof
(
int
));
if
(
ret
<=
0
)
{
if
(
errno
!=
EINTR
)
return
-
1
;
TRACE
(
"Caught EINTR; retrying"
);
goto
again
;
}
return
state
;
return
state
;
}
static
bool
wait_on_daemonized_start
(
struct
lxc_handler
*
handler
,
int
pid
)
{
int
ret
,
state
;
int
ret
,
state
;
/* Close write end of the socket pair. */
close
(
handler
->
state_socket_pair
[
1
]);
handler
->
state_socket_pair
[
1
]
=
-
1
;
/* Close write end of the socket pair. */
close
(
handler
->
state_socket_pair
[
1
]);
handler
->
state_socket_pair
[
1
]
=
-
1
;
state
=
lxc_rcv_status
(
handler
->
state_socket_pair
[
0
]);
state
=
lxc_rcv_status
(
handler
->
state_socket_pair
[
0
]);
/* Close read end of the socket pair. */
close
(
handler
->
state_socket_pair
[
0
]);
handler
->
state_socket_pair
[
0
]
=
-
1
;
/* Close read end of the socket pair. */
close
(
handler
->
state_socket_pair
[
0
]);
handler
->
state_socket_pair
[
0
]
=
-
1
;
/* The first child is going to fork() again and then exits. So we reap
* the first child here.
*/
/* The first child is going to fork() again and then exits. So we reap
* the first child here.
*/
ret
=
wait_for_pid
(
pid
);
if
(
ret
<
0
)
DEBUG
(
"Failed waiting on first child %d"
,
pid
);
DEBUG
(
"Failed waiting on first child %d"
,
pid
);
else
DEBUG
(
"First child %d exited"
,
pid
);
DEBUG
(
"First child %d exited"
,
pid
);
if
(
state
<
0
)
{
SYSERROR
(
"Failed to receive the container state"
);
return
false
;
}
if
(
state
<
0
)
{
SYSERROR
(
"Failed to receive the container state"
);
return
false
;
}
/* If we receive anything else then running we know that the container
* failed to start.
*/
if
(
state
!=
RUNNING
)
{
ERROR
(
"Received container state
\"
%s
\"
instead of
\"
RUNNING
\"
"
,
lxc_state2str
(
state
));
return
false
;
}
/* If we receive anything else then running we know that the container
* failed to start.
*/
if
(
state
!=
RUNNING
)
{
ERROR
(
"Received container state
\"
%s
\"
instead of
\"
RUNNING
\"
"
,
lxc_state2str
(
state
));
return
false
;
}
TRACE
(
"Container is in
\"
RUNNING
\"
state"
);
return
true
;
TRACE
(
"Container is in
\"
RUNNING
\"
state"
);
return
true
;
}
static
bool
do_lxcapi_start
(
struct
lxc_container
*
c
,
int
useinit
,
char
*
const
argv
[])
...
...
@@ -1147,6 +1146,7 @@ static bool lxcapi_startl(struct lxc_container *c, int useinit, ...)
on_error
:
if
(
inargs
)
{
char
**
arg
;
for
(
arg
=
inargs
;
*
arg
;
arg
++
)
free
(
*
arg
);
free
(
inargs
);
...
...
@@ -1405,9 +1405,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
* args.
*/
if
(
argv
)
for
(
nargs
=
0
;
argv
[
nargs
];
nargs
++
)
{
for
(
nargs
=
0
;
argv
[
nargs
];
nargs
++
)
;
}
/* template, path, rootfs and name args */
nargs
+=
4
;
...
...
@@ -1421,6 +1421,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
patharg
=
malloc
(
len
);
if
(
!
patharg
)
_exit
(
EXIT_FAILURE
);
ret
=
snprintf
(
patharg
,
len
,
"--path=%s/%s"
,
c
->
config_path
,
c
->
name
);
if
(
ret
<
0
||
ret
>=
len
)
_exit
(
EXIT_FAILURE
);
...
...
@@ -1431,6 +1432,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
namearg
=
malloc
(
len
);
if
(
!
namearg
)
_exit
(
EXIT_FAILURE
);
ret
=
snprintf
(
namearg
,
len
,
"--name=%s"
,
c
->
name
);
if
(
ret
<
0
||
ret
>=
len
)
_exit
(
EXIT_FAILURE
);
...
...
@@ -1441,6 +1443,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
rootfsarg
=
malloc
(
len
);
if
(
!
rootfsarg
)
_exit
(
EXIT_FAILURE
);
ret
=
snprintf
(
rootfsarg
,
len
,
"--rootfs=%s"
,
bdev
->
dest
);
if
(
ret
<
0
||
ret
>=
len
)
_exit
(
EXIT_FAILURE
);
...
...
@@ -1478,6 +1481,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
newargv
[
0
]
=
tpath
;
tpath
=
"lxc-usernsexec"
;
n2
[
0
]
=
"lxc-usernsexec"
;
lxc_list_for_each
(
it
,
&
conf
->
id_map
)
{
map
=
it
->
elem
;
n2args
+=
2
;
...
...
@@ -1499,6 +1503,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
hostuid_mapped
=
mapped_hostid
(
geteuid
(),
conf
,
ID_TYPE_UID
);
extraargs
=
hostuid_mapped
>=
0
?
1
:
3
;
n2
=
realloc
(
n2
,
(
nargs
+
n2args
+
extraargs
)
*
sizeof
(
char
*
));
if
(
!
n2
)
_exit
(
EXIT_FAILURE
);
...
...
@@ -1516,6 +1521,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
SYSERROR
(
"out of memory"
);
_exit
(
EXIT_FAILURE
);
}
ret
=
snprintf
(
n2
[
n2args
-
1
],
200
,
"u:%d:%d:1"
,
hostuid_mapped
,
geteuid
());
if
(
ret
<
0
||
ret
>=
200
)
...
...
@@ -1524,6 +1530,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
hostgid_mapped
=
mapped_hostid
(
getegid
(),
conf
,
ID_TYPE_GID
);
extraargs
=
hostgid_mapped
>=
0
?
1
:
3
;
n2
=
realloc
(
n2
,
(
nargs
+
n2args
+
extraargs
)
*
sizeof
(
char
*
));
if
(
!
n2
)
_exit
(
EXIT_FAILURE
);
...
...
@@ -1547,7 +1554,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
if
(
ret
<
0
||
ret
>=
200
)
_exit
(
EXIT_FAILURE
);
}
n2
[
n2args
++
]
=
"--"
;
for
(
i
=
0
;
i
<
nargs
;
i
++
)
n2
[
i
+
n2args
]
=
newargv
[
i
];
n2args
+=
nargs
;
...
...
@@ -1644,6 +1653,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
goto
out_free_contents
;
contents
[
flen
]
=
'\0'
;
ret
=
fclose
(
f
);
f
=
NULL
;
if
(
ret
<
0
)
...
...
@@ -1681,6 +1691,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
}
fprintf
(
f
,
"
\n
"
);
}
#if HAVE_LIBGNUTLS
fprintf
(
f
,
"# Template script checksum (SHA-1): "
);
for
(
i
=
0
;
i
<
SHA_DIGEST_LENGTH
;
i
++
)
...
...
@@ -1770,7 +1781,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
* existing container. Return an error, but do NOT delete the container.
*/
if
(
do_lxcapi_is_defined
(
c
)
&&
c
->
lxc_conf
&&
c
->
lxc_conf
->
rootfs
.
path
&&
access
(
c
->
lxc_conf
->
rootfs
.
path
,
F_OK
)
==
0
&&
tpath
)
{
access
(
c
->
lxc_conf
->
rootfs
.
path
,
F_OK
)
==
0
&&
tpath
)
{
ERROR
(
"Container
\"
%s
\"
already exists in
\"
%s
\"
"
,
c
->
name
,
c
->
config_path
);
goto
free_tpath
;
...
...
@@ -1811,6 +1822,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
*/
if
(
!
c
->
save_config
(
c
,
NULL
))
ERROR
(
"Failed to save initial config for
\"
%s
\"
"
,
c
->
name
);
ret
=
true
;
goto
out
;
}
...
...
@@ -1856,14 +1868,17 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
bdev
->
ops
->
destroy
(
bdev
);
_exit
(
EXIT_FAILURE
);
}
_exit
(
EXIT_SUCCESS
);
}
if
(
wait_for_pid
(
pid
)
!=
0
)
goto
out_unlock
;
/* Reload config to get the rootfs. */
lxc_conf_free
(
c
->
lxc_conf
);
c
->
lxc_conf
=
NULL
;
if
(
!
load_config_locked
(
c
,
c
->
configfile
))
goto
out_unlock
;
...
...
@@ -1881,15 +1896,18 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
goto
out_unlock
;
}
}
ret
=
load_config_locked
(
c
,
c
->
configfile
);
out_unlock
:
umask
(
mask
);
if
(
partial_fd
>=
0
)
remove_partial
(
c
,
partial_fd
);
out
:
if
(
!
ret
)
container_destroy
(
c
,
NULL
);
free_tpath
:
free
(
tpath
);
return
ret
;
...
...
@@ -1900,7 +1918,9 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
int
flags
,
char
*
const
argv
[])
{
bool
ret
;
current_config
=
c
?
c
->
lxc_conf
:
NULL
;
ret
=
do_lxcapi_create
(
c
,
t
,
bdevtype
,
specs
,
flags
,
argv
);
current_config
=
NULL
;
return
ret
;
...
...
@@ -1981,6 +2001,7 @@ static bool do_lxcapi_reboot2(struct lxc_container *c, int timeout)
if
(
killret
<
0
)
{
if
(
state_client_fd
>=
0
)
close
(
state_client_fd
);
WARN
(
"Failed to send signal %d to pid %d"
,
rebootsignal
,
pid
);
return
false
;
}
...
...
@@ -2051,6 +2072,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
if
(
killret
<
0
)
{
if
(
state_client_fd
>=
0
)
close
(
state_client_fd
);
WARN
(
"Failed to send signal %d to pid %d"
,
haltsignal
,
pid
);
return
false
;
}
...
...
@@ -2151,6 +2173,7 @@ static bool do_lxcapi_clear_config_item(struct lxc_container *c,
*/
if
(
config
&&
config
->
clr
)
ret
=
config
->
clr
(
key
,
c
->
lxc_conf
,
NULL
);
if
(
!
ret
)
do_clear_unexp_config_line
(
c
->
lxc_conf
,
key
);
...
...
@@ -2164,10 +2187,11 @@ static inline bool enter_net_ns(struct lxc_container *c)
{
pid_t
pid
=
do_lxcapi_init_pid
(
c
);
if
((
geteuid
()
!=
0
||
(
c
->
lxc_conf
&&
!
lxc_list_empty
(
&
c
->
lxc_conf
->
id_map
)))
&&
access
(
"/proc/self/ns/user"
,
F_OK
)
==
0
)
{
if
((
geteuid
()
!=
0
||
(
c
->
lxc_conf
&&
!
lxc_list_empty
(
&
c
->
lxc_conf
->
id_map
)))
&&
(
access
(
"/proc/self/ns/user"
,
F_OK
)
==
0
))
if
(
!
switch_to_ns
(
pid
,
"user"
))
return
false
;
}
return
switch_to_ns
(
pid
,
"net"
);
}
...
...
@@ -2229,10 +2253,11 @@ static char** get_from_array(char ***names, char *cname, int size)
return
(
char
**
)
bsearch
(
&
cname
,
*
names
,
size
,
sizeof
(
char
*
),
(
int
(
*
)(
const
void
*
,
const
void
*
))
string_cmp
);
}
static
bool
array_contains
(
char
***
names
,
char
*
cname
,
int
size
)
{
static
bool
array_contains
(
char
***
names
,
char
*
cname
,
int
size
)
{
if
(
get_from_array
(
names
,
cname
,
size
)
!=
NULL
)
return
true
;
return
false
;
}
...
...
@@ -2243,6 +2268,7 @@ static bool remove_from_array(char ***names, char *cname, int size)
free
(
result
);
return
true
;
}
return
false
;
}
...
...
@@ -2293,6 +2319,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
}
count
++
;
}
ret
=
0
;
out
:
...
...
@@ -2322,6 +2349,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
if
(
wait_for_pid
(
pid
)
!=
0
)
{
for
(
i
=
0
;
i
<
count
;
i
++
)
free
(
interfaces
[
i
]);
free
(
interfaces
);
interfaces
=
NULL
;
}
...
...
@@ -2422,8 +2450,10 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface,
address
);
goto
out
;
}
count
++
;
}
ret
=
0
;
out
:
...
...
@@ -2497,8 +2527,10 @@ static char* do_lxcapi_get_running_config_item(struct lxc_container *c, const ch
if
(
!
c
||
!
c
->
lxc_conf
)
return
NULL
;
if
(
container_mem_lock
(
c
))
return
NULL
;
ret
=
lxc_cmd_get_config_item
(
c
->
name
,
key
,
do_lxcapi_get_config_path
(
c
));
container_mem_unlock
(
c
);
return
ret
;
...
...
@@ -2542,6 +2574,7 @@ static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file)
if
(
!
alt_file
)
alt_file
=
c
->
configfile
;
if
(
!
alt_file
)
return
false
;
...
...
@@ -2615,6 +2648,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
ret
=
snprintf
(
path
,
MAXPATHLEN
,
"%s/%s/lxc_snapshots"
,
c0
->
config_path
,
c0
->
name
);
if
(
ret
<
0
||
ret
>
MAXPATHLEN
)
goto
out
;
ret
=
snprintf
(
newpath
,
MAXPATHLEN
,
"%s
\n
%s
\n
"
,
c
->
config_path
,
c
->
name
);
if
(
ret
<
0
||
ret
>
MAXPATHLEN
)
goto
out
;
...
...
@@ -2702,6 +2736,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
goto
out
;
}
}
close
(
fd
);
}
...
...
@@ -2737,9 +2772,11 @@ void mod_all_rdeps(struct lxc_container *c, bool inc)
ERROR
(
"Path name too long"
);
return
;
}
f
=
fopen
(
path
,
"r"
);
if
(
f
==
NULL
)
return
;
while
(
getline
(
&
lxcpath
,
&
pathlen
,
f
)
!=
-
1
)
{
if
(
getline
(
&
lxcname
,
&
namelen
,
f
)
==
-
1
)
{
ERROR
(
"badly formatted file %s"
,
path
);
...
...
@@ -2754,11 +2791,14 @@ void mod_all_rdeps(struct lxc_container *c, bool inc)
lxcpath
,
lxcname
);
continue
;
}
if
(
!
mod_rdep
(
p
,
c
,
inc
))
ERROR
(
"Failed to update snapshots file for %s:%s"
,
lxcpath
,
lxcname
);
lxc_container_put
(
p
);
}
out
:
free
(
lxcpath
);
free
(
lxcname
);
...
...
@@ -2777,20 +2817,24 @@ static bool has_fs_snapshots(struct lxc_container *c)
c
->
name
);
if
(
ret
<
0
||
ret
>
MAXPATHLEN
)
goto
out
;
/* If the file doesn't exist there are no snapshots. */
if
(
stat
(
path
,
&
fbuf
)
<
0
)
goto
out
;
v
=
fbuf
.
st_size
;
if
(
v
!=
0
)
{
f
=
fopen
(
path
,
"r"
);
if
(
!
f
)
goto
out
;
ret
=
fscanf
(
f
,
"%d"
,
&
v
);
fclose
(
f
);
/* TODO: Figure out what to do with the return value of fscanf. */
if
(
ret
!=
1
)
INFO
(
"Container uses new lxc-snapshots format %s"
,
path
);
}
bret
=
v
!=
0
;
out
:
...
...
@@ -2806,9 +2850,11 @@ static bool has_snapshots(struct lxc_container *c)
if
(
!
get_snappath_dir
(
c
,
path
))
return
false
;
dir
=
opendir
(
path
);
if
(
!
dir
)
return
false
;
while
((
direntp
=
readdir
(
dir
)))
{
if
(
!
strcmp
(
direntp
->
d_name
,
"."
))
continue
;
...
...
@@ -2818,6 +2864,7 @@ static bool has_snapshots(struct lxc_container *c)
count
++
;
break
;
}
closedir
(
dir
);
return
count
>
0
;
}
...
...
@@ -2901,6 +2948,7 @@ static bool container_destroy(struct lxc_container *c,
if
(
current_config
&&
conf
==
current_config
)
{
current_config
=
NULL
;
if
(
conf
->
logfd
!=
-
1
)
{
close
(
conf
->
logfd
);
conf
->
logfd
=
-
1
;
...
...
@@ -2966,6 +3014,7 @@ static bool container_destroy(struct lxc_container *c,
ret
=
snprintf
(
path
,
len
,
"%s/%s"
,
p1
,
c
->
name
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
len
)
goto
out
;
if
(
am_guest_unpriv
())
ret
=
userns_exec_full
(
conf
,
lxc_rmdir_onedev_wrapper
,
path
,
"lxc_rmdir_onedev_wrapper"
);
...
...
@@ -2983,6 +3032,7 @@ static bool container_destroy(struct lxc_container *c,
out
:
if
(
path
)
free
(
path
);
container_disk_unlock
(
c
);
return
bret
;
}
...
...
@@ -3011,10 +3061,12 @@ static bool do_lxcapi_destroy_with_snapshots(struct lxc_container *c)
{
if
(
!
c
||
!
lxcapi_is_defined
(
c
))
return
false
;
if
(
!
lxcapi_snapshot_destroy_all
(
c
))
{
ERROR
(
"Error deleting all snapshots"
);
return
false
;
}
return
lxcapi_destroy
(
c
);
}
...
...
@@ -3085,6 +3137,7 @@ static char *lxcapi_config_file_name(struct lxc_container *c)
{
if
(
!
c
||
!
c
->
configfile
)
return
NULL
;
return
strdup
(
c
->
configfile
);
}
...
...
@@ -3092,6 +3145,7 @@ static const char *lxcapi_get_config_path(struct lxc_container *c)
{
if
(
!
c
||
!
c
->
config_path
)
return
NULL
;
return
(
const
char
*
)(
c
->
config_path
);
}
...
...
@@ -3160,6 +3214,7 @@ static bool do_lxcapi_set_config_path(struct lxc_container *c, const char *path)
c
->
config_path
=
oldpath
;
oldpath
=
NULL
;
}
err
:
free
(
oldpath
);
container_mem_unlock
(
c
);
...
...
@@ -3248,6 +3303,7 @@ static int copy_file(const char *old, const char *new)
ERROR
(
"copy destination %s exists"
,
new
);
return
-
1
;
}
ret
=
stat
(
old
,
&
sbuf
);
if
(
ret
<
0
)
{
INFO
(
"Error stat'ing %s"
,
old
);
...
...
@@ -3259,6 +3315,7 @@ static int copy_file(const char *old, const char *new)
SYSERROR
(
"Error opening original file %s"
,
old
);
return
-
1
;
}
out
=
open
(
new
,
O_CREAT
|
O_EXCL
|
O_WRONLY
,
0644
);
if
(
out
<
0
)
{
SYSERROR
(
"Error opening new file %s"
,
new
);
...
...
@@ -3272,14 +3329,17 @@ static int copy_file(const char *old, const char *new)
SYSERROR
(
"Error reading old file %s"
,
old
);
goto
err
;
}
if
(
len
==
0
)
break
;
ret
=
write
(
out
,
buf
,
len
);
if
(
ret
<
len
)
{
/* should we retry? */
SYSERROR
(
"Error: write to new file %s was interrupted"
,
new
);
goto
err
;
}
}
close
(
in
);
close
(
out
);
...
...
@@ -3317,19 +3377,24 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
char
tmppath
[
MAXPATHLEN
];
if
(
!
fname
)
/* relative path - we don't support, but maybe we should */
return
0
;
if
(
strncmp
(
hookname
,
cpath
,
len
-
1
)
!=
0
)
{
/* this hook is public - ignore */
continue
;
}
/* copy the script, and change the entry in confile */
ret
=
snprintf
(
tmppath
,
MAXPATHLEN
,
"%s/%s/%s"
,
c
->
config_path
,
c
->
name
,
fname
+
1
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
-
1
;
ret
=
copy_file
(
it
->
elem
,
tmppath
);
if
(
ret
<
0
)
return
-
1
;
free
(
it
->
elem
);
it
->
elem
=
strdup
(
tmppath
);
if
(
!
it
->
elem
)
{
ERROR
(
"out of memory copying hook path"
);
...
...
@@ -3343,6 +3408,7 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
ERROR
(
"Error saving new hooks in clone"
);
return
-
1
;
}
do_lxcapi_save_config
(
c
,
NULL
);
return
0
;
}
...
...
@@ -3362,12 +3428,14 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
char
*
p
=
strrchr
(
oldpath
,
'/'
);
if
(
!
p
)
return
-
1
;
ret
=
snprintf
(
newpath
,
MAXPATHLEN
,
"%s/%s%s"
,
c
->
config_path
,
c
->
name
,
p
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
{
ERROR
(
"error printing new path for %s"
,
oldpath
);
return
-
1
;
}
if
(
file_exists
(
newpath
))
{
ERROR
(
"error: fstab file %s exists"
,
newpath
);
return
-
1
;
...
...
@@ -3377,12 +3445,15 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
ERROR
(
"error: copying %s to %s"
,
oldpath
,
newpath
);
return
-
1
;
}
free
(
c
->
lxc_conf
->
fstab
);
c
->
lxc_conf
->
fstab
=
strdup
(
newpath
);
if
(
!
c
->
lxc_conf
->
fstab
)
{
ERROR
(
"error: allocating pathname"
);
return
-
1
;
}
if
(
!
do_append_unexp_config_line
(
c
->
lxc_conf
,
"lxc.mount.fstab"
,
newpath
))
{
ERROR
(
"error saving new lxctab"
);
return
-
1
;
...
...
@@ -3402,12 +3473,14 @@ static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0)
WARN
(
"Error copying reverse dependencies"
);
return
;
}
ret
=
snprintf
(
path1
,
MAXPATHLEN
,
"%s/%s/lxc_rdepends"
,
c
->
config_path
,
c
->
name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
{
WARN
(
"Error copying reverse dependencies"
);
return
;
}
if
(
copy_file
(
path0
,
path1
)
<
0
)
{
INFO
(
"Error copying reverse dependencies"
);
return
;
...
...
@@ -3425,15 +3498,20 @@ static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0)
c
->
name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
false
;
f
=
fopen
(
path
,
"a"
);
if
(
!
f
)
return
false
;
bret
=
true
;
/* If anything goes wrong, just return an error. */
if
(
fprintf
(
f
,
"%s
\n
%s
\n
"
,
c0
->
config_path
,
c0
->
name
)
<
0
)
bret
=
false
;
if
(
fclose
(
f
)
!=
0
)
bret
=
false
;
return
bret
;
}
...
...
@@ -3506,6 +3584,7 @@ static int copy_storage(struct lxc_container *c0, struct lxc_container *c,
if
(
flags
&
LXC_CLONE_SNAPSHOT
)
copy_rdepends
(
c
,
c0
);
if
(
need_rdep
)
{
if
(
!
add_rdepends
(
c
,
c0
))
WARN
(
"Error adding reverse dependency from %s to %s"
,
...
...
@@ -3543,30 +3622,36 @@ static int clone_update_rootfs(struct clone_update_data *data)
ERROR
(
"Failed to setgid to 0"
);
return
-
1
;
}
if
(
setuid
(
0
)
<
0
)
{
ERROR
(
"Failed to setuid to 0"
);
return
-
1
;
}
if
(
setgroups
(
0
,
NULL
)
<
0
)
WARN
(
"Failed to clear groups"
);
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
return
-
1
;
bdev
=
storage_init
(
c
->
lxc_conf
);
if
(
!
bdev
)
return
-
1
;
if
(
strcmp
(
bdev
->
type
,
"dir"
)
!=
0
)
{
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
{
ERROR
(
"error unsharing mounts"
);
storage_put
(
bdev
);
return
-
1
;
}
if
(
detect_shared_rootfs
())
{
if
(
mount
(
NULL
,
"/"
,
NULL
,
MS_SLAVE
|
MS_REC
,
NULL
))
{
SYSERROR
(
"Failed to make / rslave"
);
ERROR
(
"Continuing..."
);
}
}
if
(
bdev
->
ops
->
mount
(
bdev
)
<
0
)
{
storage_put
(
bdev
);
return
-
1
;
...
...
@@ -3578,21 +3663,20 @@ static int clone_update_rootfs(struct clone_update_data *data)
if
(
!
lxc_list_empty
(
&
conf
->
hooks
[
LXCHOOK_CLONE
]))
{
/* Start of environment variable setup for hooks */
if
(
c0
->
name
&&
setenv
(
"LXC_SRC_NAME"
,
c0
->
name
,
1
))
{
if
(
c0
->
name
&&
setenv
(
"LXC_SRC_NAME"
,
c0
->
name
,
1
))
SYSERROR
(
"failed to set environment variable for source container name"
);
}
if
(
setenv
(
"LXC_NAME"
,
c
->
name
,
1
))
{
if
(
setenv
(
"LXC_NAME"
,
c
->
name
,
1
))
SYSERROR
(
"failed to set environment variable for container name"
);
}
if
(
conf
->
rcfile
&&
setenv
(
"LXC_CONFIG_FILE"
,
conf
->
rcfile
,
1
))
{
if
(
conf
->
rcfile
&&
setenv
(
"LXC_CONFIG_FILE"
,
conf
->
rcfile
,
1
))
SYSERROR
(
"failed to set environment variable for config path"
);
}
if
(
bdev
->
dest
&&
setenv
(
"LXC_ROOTFS_MOUNT"
,
bdev
->
dest
,
1
))
{
if
(
bdev
->
dest
&&
setenv
(
"LXC_ROOTFS_MOUNT"
,
bdev
->
dest
,
1
))
SYSERROR
(
"failed to set environment variable for rootfs mount"
);
}
if
(
conf
->
rootfs
.
path
&&
setenv
(
"LXC_ROOTFS_PATH"
,
conf
->
rootfs
.
path
,
1
))
{
if
(
conf
->
rootfs
.
path
&&
setenv
(
"LXC_ROOTFS_PATH"
,
conf
->
rootfs
.
path
,
1
))
SYSERROR
(
"failed to set environment variable for rootfs mount"
);
}
if
(
run_lxc_hooks
(
c
->
name
,
"clone"
,
conf
,
hookargs
))
{
ERROR
(
"Error executing clone hook for %s"
,
c
->
name
);
...
...
@@ -3607,16 +3691,20 @@ static int clone_update_rootfs(struct clone_update_data *data)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
-
1
;
if
(
!
file_exists
(
path
))
return
0
;
if
(
!
(
fout
=
fopen
(
path
,
"w"
)))
{
SYSERROR
(
"unable to open %s: ignoring"
,
path
);
return
0
;
}
if
(
fprintf
(
fout
,
"%s"
,
c
->
name
)
<
0
)
{
fclose
(
fout
);
return
-
1
;
}
if
(
fclose
(
fout
)
<
0
)
return
-
1
;
}
else
{
...
...
@@ -3650,9 +3738,11 @@ static int create_file_dirname(char *path, struct lxc_conf *conf)
if
(
!
p
)
return
-
1
;
*
p
=
'\0'
;
ret
=
do_create_container_dir
(
path
,
conf
);
*
p
=
'/'
;
return
ret
;
}
...
...
@@ -3684,8 +3774,10 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
/* Make sure the container doesn't yet exist. */
if
(
!
newname
)
newname
=
c
->
name
;
if
(
!
lxcpath
)
lxcpath
=
do_lxcapi_get_config_path
(
c
);
ret
=
snprintf
(
newpath
,
MAXPATHLEN
,
"%s/%s/config"
,
lxcpath
,
newname
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
{
SYSERROR
(
"clone: failed making config pathname"
);
...
...
@@ -3727,7 +3819,9 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
clear_unexp_config_line
(
c
->
lxc_conf
,
"lxc.rootfs.path"
,
false
);
write_config
(
fd
,
c
->
lxc_conf
);
close
(
fd
);
c
->
lxc_conf
->
rootfs
.
path
=
origroot
;
free
(
c
->
lxc_conf
->
unexpanded_config
);
c
->
lxc_conf
->
unexpanded_config
=
saved_unexp_conf
;
saved_unexp_conf
=
NULL
;
...
...
@@ -3771,7 +3865,6 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
if
(
ret
<
0
)
goto
out
;
/* update utsname */
if
(
!
(
flags
&
LXC_CLONE_KEEPNAME
))
{
clear_unexp_config_line
(
c2
->
lxc_conf
,
"lxc.utsname"
,
false
);
...
...
@@ -3819,17 +3912,21 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
SYSERROR
(
"fork"
);
goto
out
;
}
if
(
pid
>
0
)
{
ret
=
wait_for_pid
(
pid
);
if
(
ret
)
goto
out
;
container_mem_unlock
(
c
);
return
c2
;
}
data
.
c0
=
c
;
data
.
c1
=
c2
;
data
.
flags
=
flags
;
data
.
hookargs
=
hookargs
;
if
(
am_guest_unpriv
())
ret
=
userns_exec_full
(
c
->
lxc_conf
,
clone_update_rootfs_wrapper
,
&
data
,
"clone_update_rootfs_wrapper"
);
...
...
@@ -3846,6 +3943,7 @@ out:
if
(
c2
)
{
if
(
!
storage_copied
)
c2
->
lxc_conf
->
rootfs
.
path
=
NULL
;
c2
->
destroy
(
c2
);
lxc_container_put
(
c2
);
}
...
...
@@ -3859,9 +3957,11 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
char
**
hookargs
)
{
struct
lxc_container
*
ret
;
current_config
=
c
?
c
->
lxc_conf
:
NULL
;
ret
=
do_lxcapi_clone
(
c
,
newname
,
lxcpath
,
flags
,
bdevtype
,
bdevdata
,
newsize
,
hookargs
);
current_config
=
NULL
;
return
ret
;
}
...
...
@@ -3877,6 +3977,7 @@ static bool do_lxcapi_rename(struct lxc_container *c, const char *newname)
ERROR
(
"Renaming a container with snapshots is not supported"
);
return
false
;
}
bdev
=
storage_init
(
c
->
lxc_conf
);
if
(
!
bdev
)
{
ERROR
(
"Failed to find original backing store type"
);
...
...
@@ -3897,6 +3998,7 @@ static bool do_lxcapi_rename(struct lxc_container *c, const char *newname)
ERROR
(
"Could not destroy existing container %s"
,
c
->
name
);
return
false
;
}
return
true
;
}
...
...
@@ -3927,20 +4029,24 @@ static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options
command
.
program
=
(
char
*
)
program
;
command
.
argv
=
(
char
**
)
argv
;
r
=
lxc_attach
(
c
->
name
,
c
->
config_path
,
lxc_attach_run_command
,
&
command
,
options
,
&
pid
);
if
(
r
<
0
)
{
ERROR
(
"ups"
);
return
r
;
}
return
lxc_wait_for_pid_status
(
pid
);
}
static
int
lxcapi_attach_run_wait
(
struct
lxc_container
*
c
,
lxc_attach_options_t
*
options
,
const
char
*
program
,
const
char
*
const
argv
[])
{
int
ret
;
current_config
=
c
?
c
->
lxc_conf
:
NULL
;
ret
=
do_lxcapi_attach_run_wait
(
c
,
options
,
program
,
argv
);
current_config
=
NULL
;
return
ret
;
}
...
...
@@ -3951,11 +4057,14 @@ static int get_next_index(const char *lxcpath, char *cname)
int
i
=
0
,
ret
;
fname
=
alloca
(
strlen
(
lxcpath
)
+
20
);
while
(
1
)
{
sprintf
(
fname
,
"%s/snap%d"
,
lxcpath
,
i
);
ret
=
stat
(
fname
,
&
sb
);
if
(
ret
!=
0
)
return
i
;
i
++
;
}
}
...
...
@@ -3963,6 +4072,7 @@ static int get_next_index(const char *lxcpath, char *cname)
static
bool
get_snappath_dir
(
struct
lxc_container
*
c
,
char
*
snappath
)
{
int
ret
;
/*
* If the old style snapshot path exists, use it
* /var/lib/lxc -> /var/lib/lxcsnaps
...
...
@@ -3970,10 +4080,12 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath)
ret
=
snprintf
(
snappath
,
MAXPATHLEN
,
"%ssnaps"
,
c
->
config_path
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
false
;
if
(
dir_exists
(
snappath
))
{
ret
=
snprintf
(
snappath
,
MAXPATHLEN
,
"%ssnaps/%s"
,
c
->
config_path
,
c
->
name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
false
;
return
true
;
}
...
...
@@ -3984,6 +4096,7 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath)
ret
=
snprintf
(
snappath
,
MAXPATHLEN
,
"%s/%s/snaps"
,
c
->
config_path
,
c
->
name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
false
;
return
true
;
}
...
...
@@ -4029,6 +4142,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
ERROR
(
"and keep the original container pristine."
);
flags
&=
~
LXC_CLONE_SNAPSHOT
|
LXC_CLONE_MAYBE_SNAPSHOT
;
}
c2
=
do_lxcapi_clone
(
c
,
newname
,
snappath
,
flags
,
NULL
,
NULL
,
0
,
NULL
);
if
(
!
c2
)
{
ERROR
(
"clone of %s:%s failed"
,
c
->
config_path
,
c
->
name
);
...
...
@@ -4055,11 +4169,13 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
ERROR
(
"Failed to open %s"
,
dfnam
);
return
-
1
;
}
if
(
fprintf
(
f
,
"%s"
,
buffer
)
<
0
)
{
SYSERROR
(
"Writing timestamp"
);
fclose
(
f
);
return
-
1
;
}
ret
=
fclose
(
f
);
if
(
ret
!=
0
)
{
SYSERROR
(
"Writing timestamp"
);
...
...
@@ -4070,6 +4186,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
/* $p / $name / comment \0 */
int
len
=
strlen
(
snappath
)
+
strlen
(
newname
)
+
10
;
char
*
path
=
alloca
(
len
);
sprintf
(
path
,
"%s/%s/comment"
,
snappath
,
newname
);
return
copy_file
(
commentfile
,
path
)
<
0
?
-
1
:
i
;
}
...
...
@@ -4100,6 +4217,7 @@ static char *get_snapcomment_path(char* snappath, char *name)
s
=
NULL
;
}
}
return
s
;
}
...
...
@@ -4112,9 +4230,11 @@ static char *get_timestamp(char* snappath, char *name)
ret
=
snprintf
(
path
,
MAXPATHLEN
,
"%s/%s/ts"
,
snappath
,
name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
return
NULL
;
fin
=
fopen
(
path
,
"r"
);
if
(
!
fin
)
return
NULL
;
(
void
)
fseek
(
fin
,
0
,
SEEK_END
);
len
=
ftell
(
fin
);
(
void
)
fseek
(
fin
,
0
,
SEEK_SET
);
...
...
@@ -4129,6 +4249,7 @@ static char *get_timestamp(char* snappath, char *name)
}
}
}
fclose
(
fin
);
return
s
;
}
...
...
@@ -4148,9 +4269,10 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
ERROR
(
"path name too long"
);
return
-
1
;
}
dir
=
opendir
(
snappath
);
if
(
!
dir
)
{
INFO
(
"
f
ailed to open %s - assuming no snapshots"
,
snappath
);
INFO
(
"
F
ailed to open %s - assuming no snapshots"
,
snappath
);
return
0
;
}
...
...
@@ -4166,30 +4288,35 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
ERROR
(
"pathname too long"
);
goto
out_free
;
}
if
(
!
file_exists
(
path2
))
continue
;
nsnaps
=
realloc
(
snaps
,
(
count
+
1
)
*
sizeof
(
*
snaps
));
if
(
!
nsnaps
)
{
SYSERROR
(
"Out of memory"
);
goto
out_free
;
}
snaps
=
nsnaps
;
snaps
[
count
].
free
=
lxcsnap_free
;
snaps
[
count
].
name
=
strdup
(
direntp
->
d_name
);
if
(
!
snaps
[
count
].
name
)
goto
out_free
;
snaps
[
count
].
lxcpath
=
strdup
(
snappath
);
if
(
!
snaps
[
count
].
lxcpath
)
{
free
(
snaps
[
count
].
name
);
goto
out_free
;
}
snaps
[
count
].
comment_pathname
=
get_snapcomment_path
(
snappath
,
direntp
->
d_name
);
snaps
[
count
].
timestamp
=
get_timestamp
(
snappath
,
direntp
->
d_name
);
count
++
;
}
if
(
closedir
(
dir
))
WARN
(
"
f
ailed to close directory"
);
WARN
(
"
F
ailed to close directory"
);
*
ret_snaps
=
snaps
;
return
count
;
...
...
@@ -4197,12 +4324,16 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
out_free
:
if
(
snaps
)
{
int
i
;
for
(
i
=
0
;
i
<
count
;
i
++
)
lxcsnap_free
(
&
snaps
[
i
]);
free
(
snaps
);
}
if
(
closedir
(
dir
))
WARN
(
"failed to close directory"
);
WARN
(
"Failed to close directory"
);
return
-
1
;
}
...
...
@@ -4250,8 +4381,10 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap
snap
=
lxc_container_new
(
snapname
,
clonelxcpath
);
if
(
!
snap
||
!
lxcapi_is_defined
(
snap
))
{
ERROR
(
"Could not open snapshot %s"
,
snapname
);
if
(
snap
)
lxc_container_put
(
snap
);
storage_put
(
bdev
);
return
false
;
}
...
...
@@ -4270,11 +4403,13 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap
if
(
!
strcmp
(
bdev
->
type
,
"overlay"
)
||
!
strcmp
(
bdev
->
type
,
"overlayfs"
))
flags
|=
LXC_STORAGE_INTERNAL_OVERLAY_RESTORE
;
rest
=
lxcapi_clone
(
snap
,
newname
,
c
->
config_path
,
flags
,
bdev
->
type
,
NULL
,
0
,
NULL
);
storage_put
(
bdev
);
if
(
rest
&&
lxcapi_is_defined
(
rest
))
b
=
true
;
if
(
rest
)
lxc_container_put
(
rest
);
...
...
@@ -4299,11 +4434,13 @@ static bool do_snapshot_destroy(const char *snapname, const char *clonelxcpath)
ERROR
(
"Could not destroy snapshot %s"
,
snapname
);
goto
err
;
}
bret
=
true
;
err
:
if
(
snap
)
lxc_container_put
(
snap
);
return
bret
;
}
...
...
@@ -4318,11 +4455,14 @@ static bool remove_all_snapshots(const char *path)
SYSERROR
(
"opendir on snapshot path %s"
,
path
);
return
false
;
}
while
((
direntp
=
readdir
(
dir
)))
{
if
(
!
strcmp
(
direntp
->
d_name
,
"."
))
continue
;
if
(
!
strcmp
(
direntp
->
d_name
,
".."
))
continue
;
if
(
!
do_snapshot_destroy
(
direntp
->
d_name
,
path
))
{
bret
=
false
;
continue
;
...
...
@@ -4507,6 +4647,7 @@ static bool do_lxcapi_add_device_node(struct lxc_container *c, const char *src_p
ERROR
(
LXC_UNPRIV_EOPNOTSUPP
,
__FUNCTION__
);
return
false
;
}
return
add_remove_device_node
(
c
,
src_path
,
dest_path
,
true
);
}
...
...
@@ -4518,6 +4659,7 @@ static bool do_lxcapi_remove_device_node(struct lxc_container *c, const char *sr
ERROR
(
LXC_UNPRIV_EOPNOTSUPP
,
__FUNCTION__
);
return
false
;
}
return
add_remove_device_node
(
c
,
src_path
,
dest_path
,
false
);
}
...
...
@@ -4621,6 +4763,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
ERROR
(
"Network device
\"
%s
\"
not found"
,
ifname
);
else
ERROR
(
"Failed to remove network device
\"
%s
\"
"
,
ifname
);
_exit
(
EXIT_FAILURE
);
}
...
...
@@ -4654,11 +4797,10 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
addr
=
(
void
*
)
opts
+
sizeof
(
*
opts
);
end
=
(
void
*
)
opts
+
size
;
for
(;
addr
<
end
;
addr
++
)
{
if
(
*
addr
)
{
for
(;
addr
<
end
;
addr
++
)
if
(
*
addr
)
return
-
E2BIG
;
}
}
}
/* If the caller has a smaller struct, let's zero out the end for them
...
...
@@ -4680,6 +4822,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR
(
"container is not running"
);
goto
on_error
;
}
ret
=
!
__criu_pre_dump
(
c
,
valid_opts
);
break
;
case
MIGRATE_DUMP
:
...
...
@@ -4687,6 +4830,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR
(
"container is not running"
);
goto
on_error
;
}
ret
=
!
__criu_dump
(
c
,
valid_opts
);
break
;
case
MIGRATE_RESTORE
:
...
...
@@ -4694,6 +4838,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR
(
"container is already running"
);
goto
on_error
;
}
ret
=
!
__criu_restore
(
c
,
valid_opts
);
break
;
case
MIGRATE_FEATURE_CHECK
:
...
...
@@ -4772,6 +4917,7 @@ static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t
ret
=
do_lxcapi_attach_run_wait
(
c
,
options
,
program
,
(
const
char
*
const
*
)
argv
);
free
((
void
*
)
argv
);
out
:
current_config
=
NULL
;
return
ret
;
...
...
@@ -4796,7 +4942,6 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
c
->
config_path
=
strdup
(
configpath
);
else
c
->
config_path
=
strdup
(
lxc_global_config_value
(
"lxc.lxcpath"
));
if
(
!
c
->
config_path
)
{
fprintf
(
stderr
,
"Failed to allocate memory for %s
\n
"
,
name
);
goto
err
;
...
...
@@ -4840,6 +4985,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
container_destroy
(
c
,
NULL
);
lxcapi_clear_config
(
c
);
}
c
->
daemonize
=
true
;
c
->
pidfile
=
NULL
;
...
...
@@ -4914,6 +5060,7 @@ int lxc_get_wait_states(const char **states)
if
(
states
)
for
(
i
=
0
;
i
<
MAX_STATE
;
i
++
)
states
[
i
]
=
lxc_state2str
(
i
);
return
MAX_STATE
;
}
...
...
@@ -4939,6 +5086,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if
(
cret
)
*
cret
=
NULL
;
if
(
names
)
*
names
=
NULL
;
...
...
@@ -4950,10 +5098,10 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if
(
!
config_file_exists
(
lxcpath
,
direntp
->
d_name
))
continue
;
if
(
names
)
{
if
(
names
)
if
(
!
add_to_array
(
names
,
direntp
->
d_name
,
cfound
))
goto
free_bad
;
}
cfound
++
;
if
(
!
cret
)
{
...
...
@@ -4965,17 +5113,22 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if
(
!
c
)
{
INFO
(
"Container %s:%s has a config but could not be loaded"
,
lxcpath
,
direntp
->
d_name
);
if
(
names
)
if
(
!
remove_from_array
(
names
,
direntp
->
d_name
,
cfound
--
))
goto
free_bad
;
continue
;
}
if
(
!
do_lxcapi_is_defined
(
c
))
{
INFO
(
"Container %s:%s has a config but is not defined"
,
lxcpath
,
direntp
->
d_name
);
if
(
names
)
if
(
!
remove_from_array
(
names
,
direntp
->
d_name
,
cfound
--
))
goto
free_bad
;
lxc_container_put
(
c
);
continue
;
}
...
...
@@ -4984,6 +5137,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
lxc_container_put
(
c
);
goto
free_bad
;
}
nfound
++
;
}
...
...
@@ -4996,11 +5150,13 @@ free_bad:
free
((
*
names
)[
i
]);
free
(
*
names
);
}
if
(
cret
&&
*
cret
)
{
for
(
i
=
0
;
i
<
nfound
;
i
++
)
lxc_container_put
((
*
cret
)[
i
]);
free
(
*
cret
);
}
closedir
(
dir
);
return
-
1
;
}
...
...
@@ -5022,6 +5178,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
if
(
cret
)
*
cret
=
NULL
;
if
(
nret
)
*
nret
=
NULL
;
...
...
@@ -5030,16 +5187,17 @@ int list_active_containers(const char *lxcpath, char ***nret,
return
-
1
;
while
(
getline
(
&
line
,
&
len
,
f
)
!=
-
1
)
{
char
*
p
=
strrchr
(
line
,
' '
),
*
p2
;
if
(
!
p
)
continue
;
p
++
;
if
(
*
p
!=
0x40
)
continue
;
p
++
;
is_hashed
=
false
;
if
(
strncmp
(
p
,
lxcpath
,
lxcpath_len
)
==
0
)
{
p
+=
lxcpath_len
;
}
else
if
(
strncmp
(
p
,
"lxc/"
,
4
)
==
0
)
{
...
...
@@ -5062,11 +5220,13 @@ int list_active_containers(const char *lxcpath, char ***nret,
char
*
recvpath
=
lxc_cmd_get_lxcpath
(
p
);
if
(
!
recvpath
)
continue
;
if
(
strncmp
(
lxcpath
,
recvpath
,
lxcpath_len
)
!=
0
)
{
free
(
recvpath
);
continue
;
}
free
(
recvpath
);
p
=
lxc_cmd_get_name
(
p
);
if
(
!
p
)
continue
;
...
...
@@ -5096,9 +5256,11 @@ int list_active_containers(const char *lxcpath, char ***nret,
if
(
!
c
)
{
INFO
(
"Container %s:%s is running but could not be loaded"
,
lxcpath
,
p
);
remove_from_array
(
&
ct_name
,
p
,
ct_name_cnt
--
);
if
(
is_hashed
)
free
(
p
);
continue
;
}
...
...
@@ -5115,6 +5277,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
lxc_container_put
(
c
);
goto
free_cret_list
;
}
cret_cnt
++
;
}
...
...
@@ -5129,6 +5292,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
*
nret
=
ct_name
;
else
goto
free_ct_name
;
goto
out
;
free_cret_list
:
...
...
@@ -5147,7 +5311,6 @@ free_ct_name:
out
:
free
(
line
);
fclose
(
f
);
return
ret
;
}
...
...
@@ -5176,11 +5339,14 @@ int list_all_containers(const char *lxcpath, char ***nret,
ret
=
-
1
;
goto
free_active_name
;
}
ct_cnt
++
;
}
free
(
active_name
[
i
]);
active_name
[
i
]
=
NULL
;
}
free
(
active_name
);
active_name
=
NULL
;
active_cnt
=
0
;
...
...
@@ -5200,18 +5366,20 @@ int list_all_containers(const char *lxcpath, char ***nret,
ret
=
-
1
;
goto
free_ct_list
;
}
ct_list_cnt
++
;
}
if
(
cret
)
*
cret
=
ct_list
;
if
(
nret
)
if
(
nret
)
{
*
nret
=
ct_name
;
else
{
}
else
{
ret
=
ct_cnt
;
goto
free_ct_name
;
}
return
ct_cnt
;
free_ct_list
:
...
...
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