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
be459e99
Unverified
Commit
be459e99
authored
Dec 08, 2017
by
Serge Hallyn
Committed by
GitHub
Dec 08, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1950 from brauner/2017-11-27/criu_fixes
bugfixes
parents
f6812e7f
1c7222c0
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
322 additions
and
235 deletions
+322
-235
conf.c
src/lxc/conf.c
+4
-4
conf.h
src/lxc/conf.h
+1
-1
confile.c
src/lxc/confile.c
+35
-1
criu.c
src/lxc/criu.c
+2
-0
lxccontainer.c
src/lxc/lxccontainer.c
+76
-65
btrfs.c
src/lxc/storage/btrfs.c
+6
-5
dir.c
src/lxc/storage/dir.c
+4
-3
loop.c
src/lxc/storage/loop.c
+8
-2
lvm.c
src/lxc/storage/lvm.c
+9
-7
nbd.c
src/lxc/storage/nbd.c
+1
-1
overlay.c
src/lxc/storage/overlay.c
+41
-42
overlay.h
src/lxc/storage/overlay.h
+1
-1
rbd.c
src/lxc/storage/rbd.c
+2
-2
rsync.c
src/lxc/storage/rsync.c
+1
-1
storage.c
src/lxc/storage/storage.c
+78
-52
storage.h
src/lxc/storage/storage.h
+16
-17
storage_utils.c
src/lxc/storage/storage_utils.c
+9
-7
storage_utils.h
src/lxc/storage/storage_utils.h
+1
-1
zfs.c
src/lxc/storage/zfs.c
+22
-18
utils.c
src/lxc/utils.c
+4
-4
utils.h
src/lxc/utils.h
+1
-1
No files found.
src/lxc/conf.c
View file @
be459e99
...
...
@@ -1191,7 +1191,7 @@ static int lxc_setup_rootfs(struct lxc_conf *conf)
return
-
1
;
}
bdev
=
storage_init
(
conf
,
rootfs
->
path
,
rootfs
->
mount
,
rootfs
->
options
);
bdev
=
storage_init
(
conf
);
if
(
!
bdev
)
{
ERROR
(
"Failed to mount rootfs
\"
%s
\"
onto
\"
%s
\"
with options
\"
%s
\"
."
,
rootfs
->
path
,
rootfs
->
mount
,
...
...
@@ -2725,7 +2725,7 @@ int chown_mapped_root_exec_wrapper(void *args)
* root is privileged with respect to hostuid/hostgid X, allowing
* him to do the chown.
*/
int
chown_mapped_root
(
char
*
path
,
struct
lxc_conf
*
conf
)
int
chown_mapped_root
(
c
onst
c
har
*
path
,
struct
lxc_conf
*
conf
)
{
uid_t
rootuid
,
rootgid
;
unsigned
long
val
;
...
...
@@ -2733,14 +2733,14 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
struct
stat
sb
;
char
map1
[
100
],
map2
[
100
],
map3
[
100
],
map4
[
100
],
map5
[
100
];
char
ugid
[
100
];
char
*
args1
[]
=
{
"lxc-usernsexec"
,
c
onst
c
har
*
args1
[]
=
{
"lxc-usernsexec"
,
"-m"
,
map1
,
"-m"
,
map2
,
"-m"
,
map3
,
"-m"
,
map5
,
"--"
,
"chown"
,
ugid
,
path
,
NULL
};
char
*
args2
[]
=
{
"lxc-usernsexec"
,
c
onst
c
har
*
args2
[]
=
{
"lxc-usernsexec"
,
"-m"
,
map1
,
"-m"
,
map2
,
"-m"
,
map3
,
...
...
src/lxc/conf.h
View file @
be459e99
...
...
@@ -410,7 +410,7 @@ extern int setup_resource_limits(struct lxc_list *limits, pid_t pid);
extern
int
find_unmapped_nsid
(
struct
lxc_conf
*
conf
,
enum
idtype
idtype
);
extern
int
mapped_hostid
(
unsigned
id
,
struct
lxc_conf
*
conf
,
enum
idtype
idtype
);
extern
int
chown_mapped_root
(
char
*
path
,
struct
lxc_conf
*
conf
);
extern
int
chown_mapped_root
(
c
onst
c
har
*
path
,
struct
lxc_conf
*
conf
);
extern
int
lxc_ttys_shift_ids
(
struct
lxc_conf
*
c
);
extern
int
userns_exec_1
(
struct
lxc_conf
*
conf
,
int
(
*
fn
)(
void
*
),
void
*
data
,
const
char
*
fn_name
);
...
...
src/lxc/confile.c
View file @
be459e99
...
...
@@ -1910,7 +1910,41 @@ static int set_config_includefiles(const char *key, const char *value,
static
int
set_config_rootfs_path
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
return
set_config_path_item
(
&
lxc_conf
->
rootfs
.
path
,
value
);
int
ret
;
char
*
dup
,
*
tmp
;
const
char
*
container_path
;
if
(
lxc_config_value_empty
(
value
))
{
free
(
lxc_conf
->
rootfs
.
path
);
lxc_conf
->
rootfs
.
path
=
NULL
;
return
0
;
}
dup
=
strdup
(
value
);
if
(
!
dup
)
return
-
1
;
/* Split <storage type>:<container path> into <storage type> and
* <container path>. Set "rootfs.bdev_type" to <storage type> and
* "rootfs.path" to <container path>.
*/
tmp
=
strchr
(
dup
,
':'
);
if
(
tmp
)
{
*
tmp
=
'\0'
;
ret
=
set_config_path_item
(
&
lxc_conf
->
rootfs
.
bdev_type
,
dup
);
if
(
ret
<
0
)
{
free
(
dup
);
return
-
1
;
}
tmp
++
;
container_path
=
tmp
;
}
else
{
container_path
=
value
;
}
ret
=
set_config_path_item
(
&
lxc_conf
->
rootfs
.
path
,
container_path
);
free
(
dup
);
return
ret
;
}
static
int
set_config_rootfs_mount
(
const
char
*
key
,
const
char
*
value
,
...
...
src/lxc/criu.c
View file @
be459e99
...
...
@@ -564,6 +564,8 @@ static void exec_criu(struct criu_opts *opts)
switch
(
n
->
type
)
{
case
LXC_NET_VETH
:
veth
=
n
->
priv
.
veth_attr
.
pair
;
if
(
veth
[
0
]
==
'\0'
)
veth
=
n
->
priv
.
veth_attr
.
veth1
;
if
(
n
->
link
[
0
]
!=
'\0'
)
{
if
(
external_not_veth
)
...
...
src/lxc/lxccontainer.c
View file @
be459e99
...
...
@@ -61,6 +61,7 @@
#include "start.h"
#include "state.h"
#include "storage.h"
#include "storage_utils.h"
#include "storage/btrfs.h"
#include "storage/overlay.h"
#include "sync.h"
...
...
@@ -1172,13 +1173,14 @@ static struct lxc_storage *do_storage_create(struct lxc_container *c,
const
char
*
type
,
struct
bdev_specs
*
specs
)
{
char
*
des
t
;
int
re
t
;
size_t
len
;
char
*
dest
;
struct
lxc_storage
*
bdev
;
int
ret
;
/* rootfs.path or lxcpath/lxcname/rootfs */
if
(
c
->
lxc_conf
->
rootfs
.
path
&&
!
access
(
c
->
lxc_conf
->
rootfs
.
path
,
F_OK
))
{
if
(
c
->
lxc_conf
->
rootfs
.
path
&&
(
access
(
c
->
lxc_conf
->
rootfs
.
path
,
F_OK
)
==
0
))
{
const
char
*
rpath
=
c
->
lxc_conf
->
rootfs
.
path
;
len
=
strlen
(
rpath
)
+
1
;
dest
=
alloca
(
len
);
...
...
@@ -1189,27 +1191,28 @@ static struct lxc_storage *do_storage_create(struct lxc_container *c,
dest
=
alloca
(
len
);
ret
=
snprintf
(
dest
,
len
,
"%s/%s/rootfs"
,
lxcpath
,
c
->
name
);
}
if
(
ret
<
0
||
ret
>=
len
)
if
(
ret
<
0
||
(
size_t
)
ret
>=
len
)
return
NULL
;
bdev
=
storage_create
(
dest
,
type
,
c
->
name
,
specs
);
if
(
!
bdev
)
{
ERROR
(
"Failed to create
backing store type %s
"
,
type
);
ERROR
(
"Failed to create
\"
%s
\"
storage
"
,
type
);
return
NULL
;
}
if
(
!
c
->
set_config_item
(
c
,
"lxc.rootfs.path"
,
bdev
->
src
))
{
ERROR
(
"Failed to set config item
\"
lxc.rootfs.path
\"
to
\"
%s
\"
"
,
bdev
->
src
);
ERROR
(
"Failed to set
\"
lxc.rootfs.path = %s
\"
"
,
bdev
->
src
);
return
NULL
;
}
/* If we are not root, chown the rootfs dir to root in the
*
target uidmap
.
/* If we are not root, chown the rootfs dir to root in the
target user
*
namespace
.
*/
if
(
geteuid
()
!=
0
||
(
c
->
lxc_conf
&&
!
lxc_list_empty
(
&
c
->
lxc_conf
->
id_map
)))
{
if
(
chown_mapped_root
(
bdev
->
dest
,
c
->
lxc_conf
)
<
0
)
{
ERROR
(
"Error chowning %s to container root"
,
bdev
->
dest
);
ret
=
geteuid
();
if
(
ret
!=
0
||
(
c
->
lxc_conf
&&
!
lxc_list_empty
(
&
c
->
lxc_conf
->
id_map
)))
{
ret
=
chown_mapped_root
(
bdev
->
dest
,
c
->
lxc_conf
);
if
(
ret
<
0
)
{
ERROR
(
"Error chowning
\"
%s
\"
to container root"
,
bdev
->
dest
);
suggest_default_idmap
();
storage_put
(
bdev
);
return
NULL
;
...
...
@@ -1253,7 +1256,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
exit
(
1
);
}
bdev
=
storage_init
(
c
->
lxc_conf
,
c
->
lxc_conf
->
rootfs
.
path
,
c
->
lxc_conf
->
rootfs
.
mount
,
NULL
);
bdev
=
storage_init
(
c
->
lxc_conf
);
if
(
!
bdev
)
{
ERROR
(
"Error opening rootfs"
);
exit
(
1
);
...
...
@@ -1315,7 +1318,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
}
}
}
else
{
/* TODO come up with a better way here! */
char
*
src
;
c
onst
c
har
*
src
;
free
(
bdev
->
dest
);
src
=
lxc_storage_get_path
(
bdev
->
src
,
bdev
->
type
);
bdev
->
dest
=
strdup
(
src
);
...
...
@@ -1623,10 +1626,10 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
const
char
*
bdevtype
,
struct
bdev_specs
*
specs
,
int
flags
,
char
*
const
argv
[])
{
bool
ret
=
false
;
int
partial_fd
;
pid_t
pid
;
bool
ret
=
false
;
char
*
tpath
=
NULL
;
int
partial_fd
;
if
(
!
c
)
return
false
;
...
...
@@ -1634,26 +1637,26 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
if
(
t
)
{
tpath
=
get_template_path
(
t
);
if
(
!
tpath
)
{
ERROR
(
"
bad template: %s
"
,
t
);
ERROR
(
"
Unknown template
\"
%s
\"
"
,
t
);
goto
out
;
}
}
/*
* If a template is passed in, and the rootfs already is defined in
* the container config and exists, then * caller is trying to create
* an existing container. Return an error, but do NOT delete the
* container.
/* If a template is passed in, and the rootfs already is defined in the
* container config and exists, then the caller is trying to create an
* 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
)
{
ERROR
(
"Container %s:%s already exists"
,
c
->
config_path
,
c
->
name
);
ERROR
(
"Container
\"
%s
\"
already exists in
\"
%s
\"
"
,
c
->
name
,
c
->
config_path
);
goto
free_tpath
;
}
if
(
!
c
->
lxc_conf
)
{
if
(
!
do_lxcapi_load_config
(
c
,
lxc_global_config_value
(
"lxc.default_config"
)))
{
ERROR
(
"Error loading default configuration file %s"
,
lxc_global_config_value
(
"lxc.default_config"
));
ERROR
(
"Error loading default configuration file %s"
,
lxc_global_config_value
(
"lxc.default_config"
));
goto
free_tpath
;
}
}
...
...
@@ -1661,39 +1664,42 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
if
(
!
create_container_dir
(
c
))
goto
free_tpath
;
/*
*
if both template and rootfs.path are set, template is setup as rootfs.path.
*
container is already created if we have a config and
rootfs.path is accessible
/*
If both template and rootfs.path are set, template is setup as
*
rootfs.path. The container is already created if we have a config and
* rootfs.path is accessible
*/
if
(
!
c
->
lxc_conf
->
rootfs
.
path
&&
!
tpath
)
{
/*
no template passed in and rootfs does not exist
*/
/*
No template passed in and rootfs does not exist.
*/
if
(
!
c
->
save_config
(
c
,
NULL
))
{
ERROR
(
"
failed to save starting configuration for %s
\n
"
,
c
->
name
);
ERROR
(
"
Failed to save initial config for
\"
%s
\"
"
,
c
->
name
);
goto
out
;
}
ret
=
true
;
goto
out
;
}
/* Rootfs passed into configuration, but does not exist. */
if
(
c
->
lxc_conf
->
rootfs
.
path
&&
access
(
c
->
lxc_conf
->
rootfs
.
path
,
F_OK
)
!=
0
)
/* rootfs passed into configuration, but does not exist: error */
goto
out
;
if
(
do_lxcapi_is_defined
(
c
)
&&
c
->
lxc_conf
->
rootfs
.
path
&&
!
tpath
)
{
/* Rootfs already existed, user just wanted to save the
* loaded configuration */
/* Rootfs already existed, user just wanted to save the loaded
* configuration.
*/
if
(
!
c
->
save_config
(
c
,
NULL
))
ERROR
(
"
failed to save starting configuration for %s
\n
"
,
c
->
name
);
ERROR
(
"
Failed to save initial config for
\"
%s
\"
"
,
c
->
name
);
ret
=
true
;
goto
out
;
}
/* Mark that this container is being created */
if
((
partial_fd
=
create_partial
(
c
))
<
0
)
partial_fd
=
create_partial
(
c
);
if
(
partial_fd
<
0
)
goto
out
;
/*
no need to get disk lock bc we have the partial locked
*/
/*
No need to get disk lock bc we have the partial lock.
*/
/*
* Create the backing store
/* Create the storage.
* Note we can't do this in the same task as we use to execute the
* template because of the way zfs works.
* After you 'zfs create', zfs mounts the fs only in the initial
...
...
@@ -1701,7 +1707,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
*/
pid
=
fork
();
if
(
pid
<
0
)
{
SYSERROR
(
"
f
ailed to fork task for container creation template"
);
SYSERROR
(
"
F
ailed to fork task for container creation template"
);
goto
out_unlock
;
}
...
...
@@ -1710,15 +1716,17 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
bdev
=
do_storage_create
(
c
,
bdevtype
,
specs
);
if
(
!
bdev
)
{
ERROR
(
"
Error creating backing store type %s
for %s"
,
bdevtype
?
bdevtype
:
"(none)"
,
c
->
name
);
ERROR
(
"
Failed to create %s storage
for %s"
,
bdevtype
?
bdevtype
:
"(none)"
,
c
->
name
);
exit
(
EXIT_FAILURE
);
}
/*
save config file again to store the new rootfs location
*/
/*
Save config file again to store the new rootfs location.
*/
if
(
!
do_lxcapi_save_config
(
c
,
NULL
))
{
ERROR
(
"failed to save starting configuration for %s"
,
c
->
name
);
/* Parent task won't see bdev in config so we delete it. */
ERROR
(
"Failed to save initial config for %s"
,
c
->
name
);
/* Parent task won't see the storage driver in the
* config so we delete it.
*/
bdev
->
ops
->
umount
(
bdev
);
bdev
->
ops
->
destroy
(
bdev
);
exit
(
EXIT_FAILURE
);
...
...
@@ -1728,7 +1736,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
if
(
wait_for_pid
(
pid
)
!=
0
)
goto
out_unlock
;
/*
reload config to get the rootfs
*/
/*
Reload config to get the rootfs.
*/
lxc_conf_free
(
c
->
lxc_conf
);
c
->
lxc_conf
=
NULL
;
if
(
!
load_config_locked
(
c
,
c
->
configfile
))
...
...
@@ -1744,7 +1752,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
if
(
t
)
{
if
(
!
prepend_lxc_header
(
c
->
configfile
,
tpath
,
argv
))
{
ERROR
(
"
Error prepending header to configuration
file"
);
ERROR
(
"
Failed to prepend header to config
file"
);
goto
out_unlock
;
}
}
...
...
@@ -1762,8 +1770,8 @@ free_tpath:
}
static
bool
lxcapi_create
(
struct
lxc_container
*
c
,
const
char
*
t
,
const
char
*
bdevtype
,
struct
bdev_specs
*
specs
,
int
flag
s
,
char
*
const
argv
[])
const
char
*
bdevtype
,
struct
bdev_specs
*
spec
s
,
int
flags
,
char
*
const
argv
[])
{
bool
ret
;
current_config
=
c
?
c
->
lxc_conf
:
NULL
;
...
...
@@ -1954,7 +1962,7 @@ static bool lxcapi_createl(struct lxc_container *c, const char *t,
args
=
lxc_va_arg_list_to_argv
(
ap
,
0
,
0
);
va_end
(
ap
);
if
(
!
args
)
{
ERROR
(
"
Memory allocation error.
"
);
ERROR
(
"
Failed to allocate memory
"
);
goto
out
;
}
...
...
@@ -3408,7 +3416,7 @@ static int clone_update_rootfs(struct clone_update_data *data)
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
return
-
1
;
bdev
=
storage_init
(
c
->
lxc_conf
,
c
->
lxc_conf
->
rootfs
.
path
,
c
->
lxc_conf
->
rootfs
.
mount
,
NULL
);
bdev
=
storage_init
(
c
->
lxc_conf
);
if
(
!
bdev
)
return
-
1
;
if
(
strcmp
(
bdev
->
type
,
"dir"
)
!=
0
)
{
...
...
@@ -3739,7 +3747,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
,
c
->
lxc_conf
->
rootfs
.
path
,
c
->
lxc_conf
->
rootfs
.
mount
,
NULL
);
bdev
=
storage_init
(
c
->
lxc_conf
);
if
(
!
bdev
)
{
ERROR
(
"Failed to find original backing store type"
);
return
false
;
...
...
@@ -3884,7 +3892,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
*/
flags
=
LXC_CLONE_SNAPSHOT
|
LXC_CLONE_KEEPMACADDR
|
LXC_CLONE_KEEPNAME
|
LXC_CLONE_KEEPBDEVTYPE
|
LXC_CLONE_MAYBE_SNAPSHOT
;
if
(
storage_is_dir
(
c
->
lxc_conf
,
c
->
lxc_conf
->
rootfs
.
path
))
{
if
(
storage_is_dir
(
c
->
lxc_conf
))
{
ERROR
(
"Snapshot of directory-backed container requested."
);
ERROR
(
"Making a copy-clone. If you do want snapshots, then"
);
ERROR
(
"please create an aufs or overlay clone first, snapshot that"
);
...
...
@@ -4089,8 +4097,7 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap
return
false
;
}
bdev
=
storage_init
(
c
->
lxc_conf
,
c
->
lxc_conf
->
rootfs
.
path
,
c
->
lxc_conf
->
rootfs
.
mount
,
NULL
);
bdev
=
storage_init
(
c
->
lxc_conf
);
if
(
!
bdev
)
{
ERROR
(
"Failed to find original backing store type"
);
return
false
;
...
...
@@ -4136,8 +4143,8 @@ 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
);
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
;
...
...
@@ -4601,7 +4608,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
c
=
malloc
(
sizeof
(
*
c
));
if
(
!
c
)
{
fprintf
(
stderr
,
"
failed to malloc lxc_container
\n
"
);
fprintf
(
stderr
,
"
Failed to allocate memory for %s
\n
"
,
name
);
return
NULL
;
}
memset
(
c
,
0
,
sizeof
(
*
c
));
...
...
@@ -4612,39 +4619,43 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
c
->
config_path
=
strdup
(
lxc_global_config_value
(
"lxc.lxcpath"
));
if
(
!
c
->
config_path
)
{
fprintf
(
stderr
,
"
Out of memory
\n
"
);
fprintf
(
stderr
,
"
Failed to allocate memory for %s
\n
"
,
name
);
goto
err
;
}
remove_trailing_slashes
(
c
->
config_path
);
c
->
name
=
malloc
(
strlen
(
name
)
+
1
);
if
(
!
c
->
name
)
{
fprintf
(
stderr
,
"
Error allocating lxc_container name
\n
"
);
fprintf
(
stderr
,
"
Failed to allocate memory for %s
\n
"
,
name
);
goto
err
;
}
strcpy
(
c
->
name
,
name
);
c
->
numthreads
=
1
;
if
(
!
(
c
->
slock
=
lxc_newlock
(
c
->
config_path
,
name
)))
{
fprintf
(
stderr
,
"failed to create lock
\n
"
);
c
->
slock
=
lxc_newlock
(
c
->
config_path
,
name
);
if
(
!
c
->
slock
)
{
fprintf
(
stderr
,
"Failed to create lock for %s
\n
"
,
name
);
goto
err
;
}
if
(
!
(
c
->
privlock
=
lxc_newlock
(
NULL
,
NULL
)))
{
fprintf
(
stderr
,
"failed to alloc privlock
\n
"
);
c
->
privlock
=
lxc_newlock
(
NULL
,
NULL
);
if
(
!
c
->
privlock
)
{
fprintf
(
stderr
,
"Failed to create private lock for %s
\n
"
,
name
);
goto
err
;
}
if
(
!
set_config_filename
(
c
))
{
fprintf
(
stderr
,
"
Error allocating config file pathname
\n
"
);
fprintf
(
stderr
,
"
Failed to create config file name for %s
\n
"
,
name
);
goto
err
;
}
if
(
file_exists
(
c
->
configfile
)
&&
!
lxcapi_load_config
(
c
,
NULL
))
if
(
file_exists
(
c
->
configfile
)
&&
!
lxcapi_load_config
(
c
,
NULL
))
{
fprintf
(
stderr
,
"Failed to load config for %s
\n
"
,
name
);
goto
err
;
}
if
(
ongoing_create
(
c
)
==
2
)
{
ERROR
(
"
Error: %s creation was not completed
"
,
c
->
name
);
ERROR
(
"
Failed to complete container creation for %s
"
,
c
->
name
);
container_destroy
(
c
,
NULL
);
lxcapi_clear_config
(
c
);
}
...
...
src/lxc/storage/btrfs.c
View file @
be459e99
...
...
@@ -187,7 +187,8 @@ bool btrfs_detect(const char *path)
int
btrfs_mount
(
struct
lxc_storage
*
bdev
)
{
unsigned
long
mntflags
;
char
*
mntdata
,
*
src
;
char
*
mntdata
;
const
char
*
src
;
int
ret
;
if
(
strcmp
(
bdev
->
type
,
"btrfs"
))
...
...
@@ -348,7 +349,7 @@ out:
int
btrfs_snapshot_wrapper
(
void
*
data
)
{
char
*
src
;
c
onst
c
har
*
src
;
struct
rsync_data_char
*
arg
=
data
;
if
(
setgid
(
0
)
<
0
)
{
...
...
@@ -372,7 +373,7 @@ int btrfs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
const
char
*
oldpath
,
const
char
*
lxcpath
,
int
snap
,
uint64_t
newsize
,
struct
lxc_conf
*
conf
)
{
char
*
src
;
c
onst
c
har
*
src
;
if
(
!
orig
->
dest
||
!
orig
->
src
)
return
-
1
;
...
...
@@ -483,7 +484,7 @@ bool btrfs_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
return
true
;
}
ret
=
btrfs_snapshot
(
orig
->
dest
,
new
->
dest
);
ret
=
btrfs_snapshot
(
orig
->
src
,
new
->
dest
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to create btrfs snapshot
\"
%s
\"
from
\"
%s
\"
"
,
new
->
dest
,
orig
->
dest
);
...
...
@@ -821,7 +822,7 @@ bool btrfs_try_remove_subvol(const char *path)
int
btrfs_destroy
(
struct
lxc_storage
*
orig
)
{
char
*
src
;
c
onst
c
har
*
src
;
src
=
lxc_storage_get_path
(
orig
->
src
,
"btrfs"
);
...
...
src/lxc/storage/dir.c
View file @
be459e99
...
...
@@ -39,7 +39,7 @@ int dir_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
const
char
*
lxcpath
,
int
snap
,
uint64_t
newsize
,
struct
lxc_conf
*
conf
)
{
char
*
src_no_prefix
;
c
onst
c
har
*
src_no_prefix
;
int
ret
;
size_t
len
;
...
...
@@ -121,7 +121,7 @@ int dir_create(struct lxc_storage *bdev, const char *dest, const char *n,
int
dir_destroy
(
struct
lxc_storage
*
orig
)
{
int
ret
;
char
*
src
;
c
onst
c
har
*
src
;
src
=
lxc_storage_get_path
(
orig
->
src
,
orig
->
src
);
...
...
@@ -149,7 +149,8 @@ int dir_mount(struct lxc_storage *bdev)
{
int
ret
;
unsigned
long
mflags
,
mntflags
;
char
*
src
,
*
mntdata
;
char
*
mntdata
;
const
char
*
src
;
if
(
strcmp
(
bdev
->
type
,
"dir"
))
return
-
22
;
...
...
src/lxc/storage/loop.c
View file @
be459e99
...
...
@@ -204,7 +204,13 @@ int loop_create(struct lxc_storage *bdev, const char *dest, const char *n,
}
int
loop_destroy
(
struct
lxc_storage
*
orig
)
{
return
unlink
(
orig
->
src
+
5
);
char
*
dir
;
dir
=
orig
->
src
;
if
(
strncmp
(
orig
->
src
,
"loop:"
,
5
)
==
0
)
dir
+=
5
;
return
unlink
(
dir
);
}
bool
loop_detect
(
const
char
*
path
)
...
...
@@ -229,7 +235,7 @@ int loop_mount(struct lxc_storage *bdev)
{
int
ret
,
loopfd
;
char
loname
[
MAXPATHLEN
];
char
*
src
;
c
onst
c
har
*
src
;
if
(
strcmp
(
bdev
->
type
,
"loop"
))
return
-
22
;
...
...
src/lxc/storage/lvm.c
View file @
be459e99
...
...
@@ -235,7 +235,7 @@ bool lvm_detect(const char *path)
int
lvm_mount
(
struct
lxc_storage
*
bdev
)
{
char
*
src
;
c
onst
c
har
*
src
;
if
(
strcmp
(
bdev
->
type
,
"lvm"
))
return
-
22
;
...
...
@@ -330,11 +330,12 @@ static int lvm_snapshot_create_new_uuid_wrapper(void *data)
static
int
lvm_snapshot
(
struct
lxc_storage
*
orig
,
const
char
*
path
,
uint64_t
size
)
{
int
ret
;
char
*
origsrc
,
*
pathdup
,
*
lv
;
char
*
lv
,
*
pathdup
;
char
sz
[
24
];
char
fstype
[
100
];
char
cmd_output
[
MAXPATHLEN
];
char
repairchar
;
const
char
*
origsrc
;
struct
lvcreate_args
cmd_args
=
{
0
};
ret
=
snprintf
(
sz
,
24
,
"%"
PRIu64
"b"
,
size
);
...
...
@@ -433,7 +434,8 @@ int lvm_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
(
const
char
*
[]){
"lvm:"
,
"dev"
,
vg
,
cname
,
NULL
},
false
);
}
else
{
char
*
dup
,
*
slider
,
*
src
;
const
char
*
src
;
char
*
dup
,
*
slider
;
src
=
lxc_storage_get_path
(
orig
->
src
,
orig
->
type
);
...
...
@@ -497,11 +499,11 @@ int lvm_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
bool
lvm_create_clone
(
struct
lxc_conf
*
conf
,
struct
lxc_storage
*
orig
,
struct
lxc_storage
*
new
,
uint64_t
newsize
)
{
char
*
src
;
const
char
*
thinpool
;
int
ret
;
const
char
*
src
;
const
char
*
thinpool
;
struct
rsync_data
data
;
char
*
cmd_args
[
2
];
c
onst
c
har
*
cmd_args
[
2
];
char
cmd_output
[
MAXPATHLEN
]
=
{
0
};
char
fstype
[
100
]
=
"ext4"
;
uint64_t
size
=
newsize
;
...
...
@@ -560,7 +562,7 @@ bool lvm_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
struct
lxc_storage
*
new
,
uint64_t
newsize
)
{
int
ret
;
char
*
newsrc
;
c
onst
c
har
*
newsrc
;
uint64_t
size
=
newsize
;
if
(
is_blktype
(
orig
))
{
...
...
src/lxc/storage/nbd.c
View file @
be459e99
...
...
@@ -118,7 +118,7 @@ bool nbd_detect(const char *path)
int
nbd_mount
(
struct
lxc_storage
*
bdev
)
{
int
ret
=
-
1
,
partition
;
char
*
src
;
c
onst
c
har
*
src
;
char
path
[
50
];
if
(
strcmp
(
bdev
->
type
,
"nbd"
))
...
...
src/lxc/storage/overlay.c
View file @
be459e99
...
...
@@ -54,7 +54,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
int
snap
,
uint64_t
newsize
,
struct
lxc_conf
*
conf
)
{
int
ret
;
char
*
src
;
c
onst
c
har
*
src
;
if
(
!
snap
)
{
ERROR
(
"The overlay storage driver can only be used for "
...
...
@@ -199,12 +199,11 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
return
-
22
;
}
nsrc
=
strchr
(
osrc
,
':'
)
+
1
;
if
((
nsrc
!=
osrc
+
8
)
&&
(
nsrc
!=
osrc
+
10
))
{
ERROR
(
"Detected
\"
:
\"
in
\"
%s
\"
at wrong position"
,
osrc
);
free
(
osrc
);
return
-
22
;
}
nsrc
=
osrc
;
if
(
strncmp
(
osrc
,
"overlay:"
,
8
)
==
0
)
nsrc
+=
8
;
else
if
(
strncmp
(
osrc
,
"overlayfs:"
,
10
)
==
0
)
nsrc
+=
10
;
odelta
=
strchr
(
nsrc
,
':'
);
if
(
!
odelta
)
{
...
...
@@ -457,22 +456,17 @@ int ovl_create(struct lxc_storage *bdev, const char *dest, const char *n,
int
ovl_destroy
(
struct
lxc_storage
*
orig
)
{
bool
ovl
;
char
*
upper
=
orig
->
src
;
ovl
=
!
strncmp
(
upper
,
"overlay:"
,
8
);
if
(
!
ovl
&&
strncmp
(
upper
,
"overlayfs:"
,
10
))
return
-
22
;
/* For an overlay container the rootfs is considered immutable
* and cannot be removed when restoring from a snapshot.
*/
if
(
orig
->
flags
&
LXC_STORAGE_INTERNAL_OVERLAY_RESTORE
)
return
0
;
if
(
ovl
)
if
(
strncmp
(
upper
,
"overlay:"
,
8
)
==
0
)
upper
+=
8
;
else
else
if
(
strncmp
(
upper
,
"overlayfs:"
,
10
)
==
0
)
upper
+=
10
;
upper
=
strchr
(
upper
,
':'
);
...
...
@@ -485,10 +479,10 @@ int ovl_destroy(struct lxc_storage *orig)
bool
ovl_detect
(
const
char
*
path
)
{
if
(
!
strncmp
(
path
,
"overlay
fs:"
,
10
))
if
(
!
strncmp
(
path
,
"overlay
:"
,
8
))
return
true
;
if
(
!
strncmp
(
path
,
"overlay
:"
,
8
))
if
(
!
strncmp
(
path
,
"overlay
fs:"
,
10
))
return
true
;
return
false
;
...
...
@@ -521,18 +515,19 @@ int ovl_mount(struct lxc_storage *bdev)
ERROR
(
"Failed to allocate memory"
);
return
-
1
;
}
upper
=
dup
;
lower
=
dup
;
/* support multiple lower layers */
lower
=
strstr
(
dup
,
":/"
);
if
(
!
lower
)
{
ERROR
(
"Failed to detect
\"
:/
\"
in string
\"
%s
\"
"
,
dup
);
free
(
dup
);
return
-
22
;
}
if
(
strncmp
(
dup
,
"overlay:"
,
8
)
==
0
)
lower
+=
8
;
else
if
(
strncmp
(
dup
,
"overlayfs:"
,
10
)
==
0
)
lower
+=
10
;
if
(
upper
!=
lower
)
upper
=
lower
;
lower
++
;
upper
=
lower
;
while
((
tmp
=
strstr
(
++
upper
,
":/"
)))
{
/* support multiple lower layers */
while
((
tmp
=
strstr
(
upper
,
":/"
)))
{
tmp
++
;
upper
=
tmp
;
}
...
...
@@ -688,14 +683,14 @@ int ovl_umount(struct lxc_storage *bdev)
return
ret
;
}
char
*
ovl_get_lower
(
const
char
*
rootfs_path
)
c
onst
c
har
*
ovl_get_lower
(
const
char
*
rootfs_path
)
{
c
har
*
s1
;
c
onst
char
*
s1
=
rootfs_path
;
s1
=
strstr
(
rootfs_path
,
":/"
);
if
(
!
s1
)
return
NULL
;
s1
++
;
if
(
strncmp
(
rootfs_path
,
"overlay:"
,
8
)
==
0
)
s1
+=
8
;
else
if
(
strncmp
(
rootfs_path
,
"overlayfs:"
,
10
)
==
0
)
s1
+=
10
;
s1
=
strstr
(
s1
,
":/"
);
if
(
!
s1
)
...
...
@@ -719,16 +714,20 @@ char *ovl_get_rootfs(const char *rootfs_path, size_t *rootfslen)
if
(
!
s1
)
return
NULL
;
s2
=
strstr
(
s1
,
":/"
);
if
(
s2
)
{
s2
=
s2
+
1
;
if
((
s3
=
strstr
(
s2
,
":/"
)))
*
s3
=
'\0'
;
rootfsdir
=
strdup
(
s2
);
if
(
!
rootfsdir
)
{
free
(
s1
);
return
NULL
;
}
s2
=
s1
;
if
(
strncmp
(
rootfs_path
,
"overlay:"
,
8
)
==
0
)
s2
+=
8
;
else
if
(
strncmp
(
rootfs_path
,
"overlayfs:"
,
10
)
==
0
)
s2
+=
10
;
s3
=
strstr
(
s2
,
":/"
);
if
(
s3
)
*
s3
=
'\0'
;
rootfsdir
=
strdup
(
s2
);
if
(
!
rootfsdir
)
{
free
(
s1
);
return
NULL
;
}
if
(
!
rootfsdir
)
...
...
src/lxc/storage/overlay.h
View file @
be459e99
...
...
@@ -66,7 +66,7 @@ extern int ovl_update_abs_paths(struct lxc_conf *lxc_conf, const char *lxc_path,
/* To be called from functions in lxccontainer.c: Get lower directory for
* overlay rootfs.
*/
extern
char
*
ovl_get_lower
(
const
char
*
rootfs_path
);
extern
c
onst
c
har
*
ovl_get_lower
(
const
char
*
rootfs_path
);
/* Get rootfs path for overlay backed containers. Allocated memory must be freed
* by caller.
...
...
src/lxc/storage/rbd.c
View file @
be459e99
...
...
@@ -189,7 +189,7 @@ int rbd_create(struct lxc_storage *bdev, const char *dest, const char *n,
int
rbd_destroy
(
struct
lxc_storage
*
orig
)
{
int
ret
;
char
*
src
;
c
onst
c
har
*
src
;
char
*
rbdfullname
;
char
cmd_output
[
MAXPATHLEN
];
struct
rbd_args
args
=
{
0
};
...
...
@@ -233,7 +233,7 @@ bool rbd_detect(const char *path)
int
rbd_mount
(
struct
lxc_storage
*
bdev
)
{
char
*
src
;
c
onst
c
har
*
src
;
if
(
strcmp
(
bdev
->
type
,
"rbd"
))
return
-
22
;
...
...
src/lxc/storage/rsync.c
View file @
be459e99
...
...
@@ -87,7 +87,7 @@ int lxc_rsync_exec(const char *src, const char *dest)
int
lxc_rsync
(
struct
rsync_data
*
data
)
{
int
ret
;
char
*
dest
,
*
src
;
c
onst
c
har
*
dest
,
*
src
;
struct
lxc_storage
*
orig
=
data
->
orig
,
*
new
=
data
->
new
;
ret
=
unshare
(
CLONE_NEWNS
);
...
...
src/lxc/storage/storage.c
View file @
be459e99
...
...
@@ -213,17 +213,27 @@ static const struct lxc_storage_type bdevs[] = {
static
const
size_t
numbdevs
=
sizeof
(
bdevs
)
/
sizeof
(
struct
lxc_storage_type
);
static
const
struct
lxc_storage_type
*
get_storage_by_name
(
const
char
*
name
)
static
const
struct
lxc_storage_type
*
get_storage_by_name
(
const
char
*
path
,
const
char
*
type
)
{
int
ret
;
size_t
i
,
cmplen
;
cmplen
=
strcspn
(
name
,
":"
);
if
(
type
)
cmplen
=
strlen
(
type
);
else
cmplen
=
strcspn
(
path
,
":"
);
if
(
cmplen
==
0
)
return
NULL
;
for
(
i
=
0
;
i
<
numbdevs
;
i
++
)
if
(
strncmp
(
bdevs
[
i
].
name
,
name
,
cmplen
)
==
0
)
for
(
i
=
0
;
i
<
numbdevs
;
i
++
)
{
if
(
type
)
ret
=
strncmp
(
bdevs
[
i
].
name
,
type
,
cmplen
);
else
ret
=
strncmp
(
bdevs
[
i
].
name
,
path
,
cmplen
);
if
(
ret
==
0
)
break
;
}
if
(
i
==
numbdevs
)
return
NULL
;
...
...
@@ -232,18 +242,19 @@ static const struct lxc_storage_type *get_storage_by_name(const char *name)
return
&
bdevs
[
i
];
}
const
struct
lxc_storage_type
*
storage_query
(
struct
lxc_conf
*
conf
,
const
char
*
src
)
static
const
struct
lxc_storage_type
*
storage_query
(
struct
lxc_conf
*
conf
)
{
size_t
i
;
const
struct
lxc_storage_type
*
bdev
;
const
char
*
path
=
conf
->
rootfs
.
path
;
const
char
*
type
=
conf
->
rootfs
.
bdev_type
;
bdev
=
get_storage_by_name
(
src
);
bdev
=
get_storage_by_name
(
path
,
type
);
if
(
bdev
)
return
bdev
;
for
(
i
=
0
;
i
<
numbdevs
;
i
++
)
if
(
bdevs
[
i
].
ops
->
detect
(
src
))
if
(
bdevs
[
i
].
ops
->
detect
(
path
))
break
;
if
(
i
==
numbdevs
)
...
...
@@ -258,10 +269,9 @@ struct lxc_storage *storage_get(const char *type)
size_t
i
;
struct
lxc_storage
*
bdev
;
for
(
i
=
0
;
i
<
numbdevs
;
i
++
)
{
for
(
i
=
0
;
i
<
numbdevs
;
i
++
)
if
(
strcmp
(
bdevs
[
i
].
name
,
type
)
==
0
)
break
;
}
if
(
i
==
numbdevs
)
return
NULL
;
...
...
@@ -274,7 +284,7 @@ struct lxc_storage *storage_get(const char *type)
bdev
->
ops
=
bdevs
[
i
].
ops
;
bdev
->
type
=
bdevs
[
i
].
name
;
if
(
!
strcmp
(
bdev
->
type
,
"aufs"
)
)
if
(
strcmp
(
bdev
->
type
,
"aufs"
)
==
0
)
WARN
(
"The
\"
aufs
\"
driver will is deprecated and will soon be "
"removed. For similar functionality see the
\"
overlay
\"
"
"storage driver"
);
...
...
@@ -286,7 +296,7 @@ static struct lxc_storage *do_storage_create(const char *dest, const char *type,
const
char
*
cname
,
struct
bdev_specs
*
specs
)
{
int
ret
;
struct
lxc_storage
*
bdev
;
if
(
!
type
)
...
...
@@ -296,7 +306,8 @@ static struct lxc_storage *do_storage_create(const char *dest, const char *type,
if
(
!
bdev
)
return
NULL
;
if
(
bdev
->
ops
->
create
(
bdev
,
dest
,
cname
,
specs
)
<
0
)
{
ret
=
bdev
->
ops
->
create
(
bdev
,
dest
,
cname
,
specs
);
if
(
ret
<
0
)
{
storage_put
(
bdev
);
return
NULL
;
}
...
...
@@ -306,9 +317,10 @@ static struct lxc_storage *do_storage_create(const char *dest, const char *type,
bool
storage_can_backup
(
struct
lxc_conf
*
conf
)
{
struct
lxc_storage
*
bdev
=
storage_init
(
conf
,
NULL
,
NULL
,
NULL
);
bool
ret
;
struct
lxc_storage
*
bdev
;
bdev
=
storage_init
(
conf
);
if
(
!
bdev
)
return
false
;
...
...
@@ -326,16 +338,16 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
uint64_t
newsize
,
bool
*
needs_rdep
)
{
int
ret
;
struct
lxc_storage
*
orig
,
*
new
;
char
*
src_no_prefix
;
bool
snap
=
flags
&
LXC_CLONE_SNAPSHOT
;
bool
maybe_snap
=
flags
&
LXC_CLONE_MAYBE_SNAPSHOT
;
bool
keepbdevtype
=
flags
&
LXC_CLONE_KEEPBDEVTYPE
;
const
char
*
src_no_prefix
;
struct
lxc_storage
*
new
,
*
orig
;
bool
snap
=
(
flags
&
LXC_CLONE_SNAPSHOT
)
;
bool
maybe_snap
=
(
flags
&
LXC_CLONE_MAYBE_SNAPSHOT
)
;
bool
keepbdevtype
=
(
flags
&
LXC_CLONE_KEEPBDEVTYPE
)
;
const
char
*
src
=
c
->
lxc_conf
->
rootfs
.
path
;
const
char
*
oldname
=
c
->
name
;
const
char
*
oldpath
=
c
->
config_path
;
struct
rsync_data
data
=
{
0
};
char
cmd_output
[
MAXPATHLEN
]
=
{
0
};
struct
rsync_data
data
=
{
0
};
if
(
!
src
)
{
ERROR
(
"No rootfs specified"
);
...
...
@@ -351,9 +363,9 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
return
NULL
;
}
orig
=
storage_init
(
c
->
lxc_conf
,
src
,
NULL
,
NULL
);
orig
=
storage_init
(
c
->
lxc_conf
);
if
(
!
orig
)
{
ERROR
(
"Failed to detect storage driver for
\"
%s
\"
"
,
src
);
ERROR
(
"Failed to detect storage driver for
\"
%s
\"
"
,
oldname
);
return
NULL
;
}
...
...
@@ -422,11 +434,11 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
/* get new bdev type */
new
=
storage_get
(
bdevtype
);
if
(
!
new
)
{
ERROR
(
"Failed to initialize
\"
%s
\"
storage driver"
,
ERROR
(
"Failed to initialize
%s
storage driver"
,
bdevtype
?
bdevtype
:
orig
->
type
);
goto
on_error_put_orig
;
}
TRACE
(
"Initialized
\"
%s
\"
storage driver"
,
new
->
type
);
TRACE
(
"Initialized
%s
storage driver"
,
new
->
type
);
/* create new paths */
ret
=
new
->
ops
->
clone_paths
(
orig
,
new
,
oldname
,
cname
,
oldpath
,
lxcpath
,
...
...
@@ -440,14 +452,15 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
* snapshot directory under "<lxcpath>/<name>/snaps/" we don't need to
* record a dependency. If we would restore would also fail.
*/
if
((
!
strcmp
(
new
->
type
,
"overlay"
)
||
!
strcmp
(
new
->
type
,
"overlayfs"
)
)
&&
if
((
strcmp
(
new
->
type
,
"overlay"
)
==
0
||
strcmp
(
new
->
type
,
"overlayfs"
)
==
0
)
&&
ret
==
LXC_CLONE_SNAPSHOT
)
*
needs_rdep
=
false
;
/* btrfs */
if
(
!
strcmp
(
orig
->
type
,
"btrfs"
)
&&
!
strcmp
(
new
->
type
,
"btrfs"
))
{
bool
bret
=
false
;
bool
bret
;
if
(
snap
||
btrfs_same_fs
(
orig
->
dest
,
new
->
dest
)
==
0
)
bret
=
new
->
ops
->
snapshot
(
c
->
lxc_conf
,
orig
,
new
,
0
);
else
...
...
@@ -460,10 +473,10 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
/* lvm */
if
(
!
strcmp
(
orig
->
type
,
"lvm"
)
&&
!
strcmp
(
new
->
type
,
"lvm"
))
{
bool
bret
=
false
;
bool
bret
;
if
(
snap
)
bret
=
new
->
ops
->
snapshot
(
c
->
lxc_conf
,
orig
,
new
,
newsize
);
bret
=
new
->
ops
->
snapshot
(
c
->
lxc_conf
,
orig
,
new
,
newsize
);
else
bret
=
new
->
ops
->
copy
(
c
->
lxc_conf
,
orig
,
new
,
newsize
);
if
(
!
bret
)
...
...
@@ -474,11 +487,10 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
/* zfs */
if
(
!
strcmp
(
orig
->
type
,
"zfs"
)
&&
!
strcmp
(
new
->
type
,
"zfs"
))
{
bool
bret
=
false
;
bool
bret
;
if
(
snap
)
bret
=
new
->
ops
->
snapshot
(
c
->
lxc_conf
,
orig
,
new
,
newsize
);
bret
=
new
->
ops
->
snapshot
(
c
->
lxc_conf
,
orig
,
new
,
newsize
);
else
bret
=
new
->
ops
->
copy
(
c
->
lxc_conf
,
orig
,
new
,
newsize
);
if
(
!
bret
)
...
...
@@ -547,20 +559,21 @@ on_error_put_orig:
struct
lxc_storage
*
storage_create
(
const
char
*
dest
,
const
char
*
type
,
const
char
*
cname
,
struct
bdev_specs
*
specs
)
{
int
ret
;
struct
lxc_storage
*
bdev
;
char
*
best_options
[]
=
{
"btrfs"
,
"zfs"
,
"lvm"
,
"dir"
,
"rbd"
,
NULL
};
if
(
!
type
)
return
do_storage_create
(
dest
,
"dir"
,
cname
,
specs
);
if
(
strcmp
(
type
,
"best"
)
==
0
)
{
ret
=
strcmp
(
type
,
"best"
);
if
(
ret
==
0
)
{
int
i
;
/* Try for the best backing store type, according to our
* opinionated preferences.
*/
for
(
i
=
0
;
best_options
[
i
];
i
++
)
{
bdev
=
do_storage_create
(
dest
,
best_options
[
i
],
cname
,
specs
);
bdev
=
do_storage_create
(
dest
,
best_options
[
i
],
cname
,
specs
);
if
(
bdev
)
return
bdev
;
}
...
...
@@ -569,12 +582,16 @@ struct lxc_storage *storage_create(const char *dest, const char *type,
}
/* -B lvm,dir */
if
(
strchr
(
type
,
','
)
!=
NULL
)
{
char
*
dup
=
alloca
(
strlen
(
type
)
+
1
),
*
saveptr
=
NULL
,
*
token
;
if
(
strchr
(
type
,
','
))
{
char
*
dup
,
*
token
;
char
*
saveptr
=
NULL
;
dup
=
alloca
(
strlen
(
type
)
+
1
);
strcpy
(
dup
,
type
);
for
(
token
=
strtok_r
(
dup
,
","
,
&
saveptr
);
token
;
token
=
strtok_r
(
NULL
,
","
,
&
saveptr
))
{
if
((
bdev
=
do_storage_create
(
dest
,
token
,
cname
,
specs
)))
bdev
=
do_storage_create
(
dest
,
token
,
cname
,
specs
);
if
(
bdev
)
return
bdev
;
}
}
...
...
@@ -587,32 +604,32 @@ bool storage_destroy(struct lxc_conf *conf)
struct
lxc_storage
*
r
;
bool
ret
=
false
;
r
=
storage_init
(
conf
,
conf
->
rootfs
.
path
,
conf
->
rootfs
.
mount
,
NULL
);
r
=
storage_init
(
conf
);
if
(
!
r
)
return
ret
;
if
(
r
->
ops
->
destroy
(
r
)
==
0
)
ret
=
r
->
ops
->
destroy
(
r
);
if
(
ret
==
0
)
ret
=
true
;
storage_put
(
r
);
return
ret
;
}
struct
lxc_storage
*
storage_init
(
struct
lxc_conf
*
conf
,
const
char
*
src
,
const
char
*
dst
,
const
char
*
mntopts
)
struct
lxc_storage
*
storage_init
(
struct
lxc_conf
*
conf
)
{
struct
lxc_storage
*
bdev
;
const
struct
lxc_storage_type
*
q
;
const
char
*
src
=
conf
->
rootfs
.
path
;
const
char
*
dst
=
conf
->
rootfs
.
mount
;
const
char
*
mntopts
=
conf
->
rootfs
.
options
;
BUILD_BUG_ON
(
LXC_STORAGE_INTERNAL_OVERLAY_RESTORE
<=
LXC_CLONE_MAXFLAGS
);
if
(
!
src
)
src
=
conf
->
rootfs
.
path
;
if
(
!
src
)
return
NULL
;
q
=
storage_query
(
conf
,
src
);
q
=
storage_query
(
conf
);
if
(
!
q
)
return
NULL
;
...
...
@@ -621,18 +638,23 @@ struct lxc_storage *storage_init(struct lxc_conf *conf, const char *src,
return
NULL
;
memset
(
bdev
,
0
,
sizeof
(
struct
lxc_storage
));
bdev
->
ops
=
q
->
ops
;
bdev
->
type
=
q
->
name
;
if
(
mntopts
)
bdev
->
mntopts
=
strdup
(
mntopts
);
if
(
src
)
bdev
->
src
=
strdup
(
src
);
if
(
dst
)
bdev
->
dest
=
strdup
(
dst
);
if
(
strcmp
(
bdev
->
type
,
"nbd"
)
==
0
)
bdev
->
nbd_idx
=
conf
->
nbd_idx
;
if
(
!
strcmp
(
bdev
->
type
,
"aufs"
)
)
if
(
strcmp
(
bdev
->
type
,
"aufs"
)
==
0
)
WARN
(
"The
\"
aufs
\"
driver will is deprecated and will soon be "
"removed. For similar functionality see the
\"
overlay
\"
"
"storage driver"
);
...
...
@@ -640,12 +662,16 @@ struct lxc_storage *storage_init(struct lxc_conf *conf, const char *src,
return
bdev
;
}
bool
storage_is_dir
(
struct
lxc_conf
*
conf
,
const
char
*
path
)
bool
storage_is_dir
(
struct
lxc_conf
*
conf
)
{
struct
lxc_storage
*
orig
;
char
*
type
=
conf
->
rootfs
.
bdev_type
;
bool
bret
=
false
;
orig
=
storage_init
(
conf
,
path
,
NULL
,
NULL
);
if
(
type
)
return
(
strcmp
(
type
,
"dir"
)
==
0
);
orig
=
storage_init
(
conf
);
if
(
!
orig
)
return
bret
;
...
...
@@ -678,7 +704,7 @@ bool rootfs_is_blockdev(struct lxc_conf *conf)
if
(
ret
==
0
&&
S_ISBLK
(
st
.
st_mode
))
return
true
;
q
=
storage_query
(
conf
,
conf
->
rootfs
.
path
);
q
=
storage_query
(
conf
);
if
(
!
q
)
return
false
;
...
...
@@ -692,7 +718,7 @@ bool rootfs_is_blockdev(struct lxc_conf *conf)
return
false
;
}
char
*
lxc_storage_get_path
(
char
*
src
,
const
char
*
prefix
)
c
onst
c
har
*
lxc_storage_get_path
(
char
*
src
,
const
char
*
prefix
)
{
size_t
prefix_len
;
...
...
src/lxc/storage/storage.h
View file @
be459e99
...
...
@@ -109,23 +109,24 @@ struct lxc_storage {
int
flags
;
};
extern
bool
storage_is_dir
(
struct
lxc_conf
*
conf
,
const
char
*
path
);
/**
* storage_is_dir : Check whether the roots is a directory. This function will
* trust the config file. If the config file key
* lxc.rootfs.path is set to <storage type>:<container path>
* the confile parser will have split this into <storage type>
* and <container path> and set the <bdev_type> member in the
* lxc_rootfs struct to <storage type> and the <path> member
* will be set to a clean <container path> without the <storage
* type> prefix. This is the new, clean way of handling storage
* type specifications. If the <storage type> prefix is not
* detected liblxc will try to detect the storage type.
*/
extern
bool
storage_is_dir
(
struct
lxc_conf
*
conf
);
extern
bool
storage_can_backup
(
struct
lxc_conf
*
conf
);
/* Instantiate a lxc_storage object. The src is used to determine which blockdev
* type this should be. The dst and data are optional, and will be used in case
* of mount/umount.
*
* The source will be "dir:/var/lib/lxc/c1" or "lvm:/dev/lxc/c1". For other
* backing stores, this will allow additional options. In particular,
* "overlayfs:/var/lib/lxc/canonical/rootfs:/var/lib/lxc/c1/delta" will mean use
* /var/lib/lxc/canonical/rootfs as lower dir, and /var/lib/lxc/c1/delta as the
* upper, writeable layer.
*/
extern
struct
lxc_storage
*
storage_init
(
struct
lxc_conf
*
conf
,
const
char
*
src
,
const
char
*
dst
,
const
char
*
data
);
extern
struct
lxc_storage
*
storage_init
(
struct
lxc_conf
*
conf
);
extern
struct
lxc_storage
*
storage_copy
(
struct
lxc_container
*
c
0
,
extern
struct
lxc_storage
*
storage_copy
(
struct
lxc_container
*
c
,
const
char
*
cname
,
const
char
*
lxcpath
,
const
char
*
bdevtype
,
int
flags
,
const
char
*
bdevdata
,
uint64_t
newsize
,
...
...
@@ -135,9 +136,7 @@ extern struct lxc_storage *storage_create(const char *dest, const char *type,
struct
bdev_specs
*
specs
);
extern
void
storage_put
(
struct
lxc_storage
*
bdev
);
extern
bool
storage_destroy
(
struct
lxc_conf
*
conf
);
extern
int
storage_destroy_wrapper
(
void
*
data
);
extern
bool
rootfs_is_blockdev
(
struct
lxc_conf
*
conf
);
extern
char
*
lxc_storage_get_path
(
char
*
src
,
const
char
*
prefix
);
extern
c
onst
c
har
*
lxc_storage_get_path
(
char
*
src
,
const
char
*
prefix
);
#endif
/* #define __LXC_STORAGE_H */
src/lxc/storage/storage_utils.c
View file @
be459e99
...
...
@@ -133,7 +133,7 @@ bool attach_block_device(struct lxc_conf *conf)
int
blk_getsize
(
struct
lxc_storage
*
bdev
,
uint64_t
*
size
)
{
int
fd
,
ret
;
char
*
src
;
c
onst
c
har
*
src
;
src
=
lxc_storage_get_path
(
bdev
->
src
,
bdev
->
type
);
fd
=
open
(
src
,
O_RDONLY
);
...
...
@@ -162,11 +162,15 @@ void detach_block_device(struct lxc_conf *conf)
*/
int
detect_fs
(
struct
lxc_storage
*
bdev
,
char
*
type
,
int
len
)
{
int
p
[
2
],
ret
;
int
ret
;
int
p
[
2
];
size_t
linelen
;
pid_t
pid
;
FILE
*
f
;
char
*
sp1
,
*
sp2
,
*
sp3
,
*
srcdev
,
*
line
=
NULL
;
char
*
sp1
,
*
sp2
,
*
sp3
;
const
char
*
l
,
*
srcdev
;
char
devpath
[
MAXPATHLEN
];
char
*
line
=
NULL
;
if
(
!
bdev
||
!
bdev
->
src
||
!
bdev
->
dest
)
return
-
1
;
...
...
@@ -218,9 +222,7 @@ int detect_fs(struct lxc_storage *bdev, char *type, int len)
exit
(
1
);
}
/* if symlink, get the real dev name */
char
devpath
[
MAXPATHLEN
];
char
*
l
=
linkderef
(
srcdev
,
devpath
);
l
=
linkderef
(
srcdev
,
devpath
);
if
(
!
l
)
exit
(
1
);
f
=
fopen
(
"/proc/self/mounts"
,
"r"
);
...
...
@@ -383,7 +385,7 @@ int find_fstype_cb(char *buffer, void *data)
return
1
;
}
c
har
*
linkderef
(
char
*
path
,
char
*
dest
)
c
onst
char
*
linkderef
(
const
char
*
path
,
char
*
dest
)
{
struct
stat
sbuf
;
ssize_t
ret
;
...
...
src/lxc/storage/storage_utils.h
View file @
be459e99
...
...
@@ -45,7 +45,7 @@ extern int is_blktype(struct lxc_storage *b);
extern
int
mount_unknown_fs
(
const
char
*
rootfs
,
const
char
*
target
,
const
char
*
options
);
extern
int
find_fstype_cb
(
char
*
buffer
,
void
*
data
);
extern
c
har
*
linkderef
(
char
*
path
,
char
*
dest
);
extern
c
onst
char
*
linkderef
(
const
char
*
path
,
char
*
dest
);
extern
bool
unpriv_snap_allowed
(
struct
lxc_storage
*
b
,
const
char
*
t
,
bool
snap
,
bool
maybesnap
);
extern
bool
is_valid_storage_type
(
const
char
*
type
);
...
...
src/lxc/storage/zfs.c
View file @
be459e99
...
...
@@ -180,7 +180,8 @@ int zfs_mount(struct lxc_storage *bdev)
{
int
ret
;
size_t
oldlen
,
newlen
,
totallen
;
char
*
mntdata
,
*
src
,
*
tmp
;
char
*
mntdata
,
*
tmp
;
const
char
*
src
;
unsigned
long
mntflags
;
char
cmd_output
[
MAXPATHLEN
]
=
{
0
};
...
...
@@ -287,13 +288,13 @@ bool zfs_copy(struct lxc_conf *conf, struct lxc_storage *orig,
char
cmd_output
[
MAXPATHLEN
],
option
[
MAXPATHLEN
];
struct
rsync_data
data
=
{
0
,
0
};
struct
zfs_args
cmd_args
=
{
0
};
c
har
*
argv
[]
=
{
"zfs"
,
/* 0 */
"create"
,
/* 1 */
"-o"
,
""
,
/* 2, 3 */
"-o"
,
"canmount=noauto"
,
/* 4, 5 */
"-p"
,
/* 6 */
""
,
/* 7 */
NULL
};
c
onst
char
*
argv
[]
=
{
"zfs"
,
/* 0 */
"create"
,
/* 1 */
"-o"
,
""
,
/* 2, 3 */
"-o"
,
"canmount=noauto"
,
/* 4, 5 */
"-p"
,
/* 6 */
""
,
/* 7 */
NULL
};
/* mountpoint */
ret
=
snprintf
(
option
,
MAXPATHLEN
,
"mountpoint=%s"
,
new
->
dest
);
...
...
@@ -342,7 +343,8 @@ bool zfs_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
{
int
ret
;
size_t
snapshot_len
,
len
;
char
*
orig_src
,
*
tmp
,
*
snap_name
,
*
snapshot
;
char
*
tmp
,
*
snap_name
,
*
snapshot
;
const
char
*
orig_src
;
struct
zfs_args
cmd_args
=
{
0
};
char
cmd_output
[
MAXPATHLEN
]
=
{
0
},
option
[
MAXPATHLEN
];
...
...
@@ -447,8 +449,9 @@ int zfs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
const
char
*
lxcpath
,
int
snap
,
uint64_t
newsize
,
struct
lxc_conf
*
conf
)
{
char
*
dataset
,
*
orig_src
,
*
tmp
;
int
ret
;
char
*
dataset
,
*
tmp
;
const
char
*
orig_src
;
size_t
dataset_len
,
len
;
char
cmd_output
[
MAXPATHLEN
]
=
{
0
};
...
...
@@ -576,7 +579,8 @@ int zfs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
int
zfs_destroy
(
struct
lxc_storage
*
orig
)
{
int
ret
;
char
*
dataset
,
*
src
,
*
tmp
;
char
*
dataset
,
*
tmp
;
const
char
*
src
;
bool
found
;
char
*
parent_snapshot
=
NULL
;
struct
zfs_args
cmd_args
=
{
0
};
...
...
@@ -709,13 +713,13 @@ int zfs_create(struct lxc_storage *bdev, const char *dest, const char *n,
size_t
len
;
struct
zfs_args
cmd_args
=
{
0
};
char
cmd_output
[
MAXPATHLEN
],
option
[
MAXPATHLEN
];
c
har
*
argv
[]
=
{
"zfs"
,
/* 0 */
"create"
,
/* 1 */
"-o"
,
""
,
/* 2, 3 */
"-o"
,
"canmount=noauto"
,
/* 4, 5 */
"-p"
,
/* 6 */
""
,
/* 7 */
NULL
};
c
onst
char
*
argv
[]
=
{
"zfs"
,
/* 0 */
"create"
,
/* 1 */
"-o"
,
""
,
/* 2, 3 */
"-o"
,
"canmount=noauto"
,
/* 4, 5 */
"-p"
,
/* 6 */
""
,
/* 7 */
NULL
};
if
(
!
specs
||
!
specs
->
zfs
.
zfsroot
)
zfsroot
=
lxc_global_config_value
(
"lxc.bdev.zfs.root"
);
...
...
src/lxc/utils.c
View file @
be459e99
...
...
@@ -65,7 +65,7 @@ lxc_log_define(lxc_utils, lxc);
*/
extern
bool
btrfs_try_remove_subvol
(
const
char
*
path
);
static
int
_recursive_rmdir
(
char
*
dirname
,
dev_t
pdev
,
static
int
_recursive_rmdir
(
c
onst
c
har
*
dirname
,
dev_t
pdev
,
const
char
*
exclude
,
int
level
,
bool
onedev
)
{
struct
dirent
*
direntp
;
...
...
@@ -180,18 +180,18 @@ static bool is_native_overlayfs(const char *path)
}
/* returns 0 on success, -1 if there were any failures */
extern
int
lxc_rmdir_onedev
(
char
*
path
,
const
char
*
exclude
)
extern
int
lxc_rmdir_onedev
(
c
onst
c
har
*
path
,
const
char
*
exclude
)
{
struct
stat
mystat
;
bool
onedev
=
true
;
if
(
is_native_overlayfs
(
path
))
{
if
(
is_native_overlayfs
(
path
))
onedev
=
false
;
}
if
(
lstat
(
path
,
&
mystat
)
<
0
)
{
if
(
errno
==
ENOENT
)
return
0
;
ERROR
(
"Failed to stat %s"
,
path
);
return
-
1
;
}
...
...
src/lxc/utils.h
View file @
be459e99
...
...
@@ -93,7 +93,7 @@
#define LXC_IDMAPLEN 4096
/* returns 1 on success, 0 if there were any failures */
extern
int
lxc_rmdir_onedev
(
char
*
path
,
const
char
*
exclude
);
extern
int
lxc_rmdir_onedev
(
c
onst
c
har
*
path
,
const
char
*
exclude
);
extern
int
get_u16
(
unsigned
short
*
val
,
const
char
*
arg
,
int
base
);
extern
int
mkdir_p
(
const
char
*
dir
,
mode_t
mode
);
extern
char
*
get_rundir
(
void
);
...
...
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