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
493de765
Unverified
Commit
493de765
authored
Jun 04, 2017
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bdev: non-functional changes
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
b9986e43
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
105 additions
and
63 deletions
+105
-63
bdev.c
src/lxc/bdev/bdev.c
+83
-39
bdev.h
src/lxc/bdev/bdev.h
+22
-24
No files found.
src/lxc/bdev/bdev.c
View file @
493de765
...
@@ -187,21 +187,22 @@ struct bdev_type {
...
@@ -187,21 +187,22 @@ struct bdev_type {
};
};
static
const
struct
bdev_type
bdevs
[]
=
{
static
const
struct
bdev_type
bdevs
[]
=
{
{
.
name
=
"zfs"
,
.
ops
=
&
zfs_ops
,
},
{
.
name
=
"zfs"
,
.
ops
=
&
zfs_ops
,
},
{
.
name
=
"lvm"
,
.
ops
=
&
lvm_ops
,
},
{
.
name
=
"lvm"
,
.
ops
=
&
lvm_ops
,
},
{
.
name
=
"rbd"
,
.
ops
=
&
rbd_ops
,
},
{
.
name
=
"rbd"
,
.
ops
=
&
rbd_ops
,
},
{
.
name
=
"btrfs"
,
.
ops
=
&
btrfs_ops
,
},
{
.
name
=
"btrfs"
,
.
ops
=
&
btrfs_ops
,
},
{
.
name
=
"dir"
,
.
ops
=
&
dir_ops
,
},
{
.
name
=
"dir"
,
.
ops
=
&
dir_ops
,
},
{
.
name
=
"aufs"
,
.
ops
=
&
aufs_ops
,
},
{
.
name
=
"aufs"
,
.
ops
=
&
aufs_ops
,
},
{
.
name
=
"overlayfs"
,
.
ops
=
&
ovl_ops
,
},
{
.
name
=
"overlayfs"
,
.
ops
=
&
ovl_ops
,
},
{
.
name
=
"loop"
,
.
ops
=
&
loop_ops
,
},
{
.
name
=
"loop"
,
.
ops
=
&
loop_ops
,
},
{
.
name
=
"nbd"
,
.
ops
=
&
nbd_ops
,
},
{
.
name
=
"nbd"
,
.
ops
=
&
nbd_ops
,
},
};
};
static
const
size_t
numbdevs
=
sizeof
(
bdevs
)
/
sizeof
(
struct
bdev_type
);
static
const
size_t
numbdevs
=
sizeof
(
bdevs
)
/
sizeof
(
struct
bdev_type
);
/* helpers */
/* helpers */
static
const
struct
bdev_type
*
bdev_query
(
struct
lxc_conf
*
conf
,
const
char
*
src
);
static
const
struct
bdev_type
*
bdev_query
(
struct
lxc_conf
*
conf
,
const
char
*
src
);
static
struct
bdev
*
bdev_get
(
const
char
*
type
);
static
struct
bdev
*
bdev_get
(
const
char
*
type
);
static
struct
bdev
*
do_bdev_create
(
const
char
*
dest
,
const
char
*
type
,
static
struct
bdev
*
do_bdev_create
(
const
char
*
dest
,
const
char
*
type
,
const
char
*
cname
,
struct
bdev_specs
*
specs
);
const
char
*
cname
,
struct
bdev_specs
*
specs
);
...
@@ -245,7 +246,8 @@ char *dir_new_path(char *src, const char *oldname, const char *name,
...
@@ -245,7 +246,8 @@ char *dir_new_path(char *src, const char *oldname, const char *name,
while
((
p2
=
strstr
(
src
,
oldname
))
!=
NULL
)
{
while
((
p2
=
strstr
(
src
,
oldname
))
!=
NULL
)
{
strncpy
(
p
,
src
,
p2
-
src
);
// copy text up to oldname
strncpy
(
p
,
src
,
p2
-
src
);
// copy text up to oldname
p
+=
p2
-
src
;
// move target pointer (p)
p
+=
p2
-
src
;
// move target pointer (p)
p
+=
sprintf
(
p
,
"%s"
,
name
);
// print new name in place of oldname
p
+=
sprintf
(
p
,
"%s"
,
name
);
// print new name in place of oldname
src
=
p2
+
l2
;
// move src to end of oldname
src
=
p2
+
l2
;
// move src to end of oldname
}
}
sprintf
(
p
,
"%s"
,
src
);
// copy the rest of src
sprintf
(
p
,
"%s"
,
src
);
// copy the rest of src
...
@@ -264,15 +266,19 @@ bool attach_block_device(struct lxc_conf *conf)
...
@@ -264,15 +266,19 @@ bool attach_block_device(struct lxc_conf *conf)
if
(
!
conf
->
rootfs
.
path
)
if
(
!
conf
->
rootfs
.
path
)
return
true
;
return
true
;
path
=
conf
->
rootfs
.
path
;
path
=
conf
->
rootfs
.
path
;
if
(
!
requires_nbd
(
path
))
if
(
!
requires_nbd
(
path
))
return
true
;
return
true
;
path
=
strchr
(
path
,
':'
);
path
=
strchr
(
path
,
':'
);
if
(
!
path
)
if
(
!
path
)
return
false
;
return
false
;
path
++
;
path
++
;
if
(
!
attach_nbd
(
path
,
conf
))
if
(
!
attach_nbd
(
path
,
conf
))
return
false
;
return
false
;
return
true
;
return
true
;
}
}
...
@@ -283,6 +289,7 @@ bool bdev_can_backup(struct lxc_conf *conf)
...
@@ -283,6 +289,7 @@ bool bdev_can_backup(struct lxc_conf *conf)
if
(
!
bdev
)
if
(
!
bdev
)
return
false
;
return
false
;
ret
=
bdev
->
ops
->
can_backup
;
ret
=
bdev
->
ops
->
can_backup
;
bdev_put
(
bdev
);
bdev_put
(
bdev
);
return
ret
;
return
ret
;
...
@@ -311,7 +318,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
...
@@ -311,7 +318,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
* we don't know how to come up with a new name
* we don't know how to come up with a new name
*/
*/
if
(
strstr
(
src
,
oldname
)
==
NULL
)
{
if
(
strstr
(
src
,
oldname
)
==
NULL
)
{
ERROR
(
"original rootfs path %s doesn't include container name %s"
,
ERROR
(
"original rootfs path %s doesn't include container name %s"
,
src
,
oldname
);
src
,
oldname
);
return
NULL
;
return
NULL
;
}
}
...
@@ -334,6 +342,7 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
...
@@ -334,6 +342,7 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
bdev_put
(
orig
);
bdev_put
(
orig
);
return
NULL
;
return
NULL
;
}
}
ret
=
snprintf
(
orig
->
dest
,
len
,
"%s/%s/rootfs"
,
oldpath
,
oldname
);
ret
=
snprintf
(
orig
->
dest
,
len
,
"%s/%s/rootfs"
,
oldpath
,
oldname
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
len
)
{
if
(
ret
<
0
||
(
size_t
)
ret
>=
len
)
{
ERROR
(
"rootfs path too long"
);
ERROR
(
"rootfs path too long"
);
...
@@ -341,9 +350,11 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
...
@@ -341,9 +350,11 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
return
NULL
;
return
NULL
;
}
}
ret
=
stat
(
orig
->
dest
,
&
sb
);
ret
=
stat
(
orig
->
dest
,
&
sb
);
if
(
ret
<
0
&&
errno
==
ENOENT
)
if
(
ret
<
0
&&
errno
==
ENOENT
)
if
(
mkdir_p
(
orig
->
dest
,
0755
)
<
0
)
if
(
mkdir_p
(
orig
->
dest
,
0755
)
<
0
)
WARN
(
"Error creating '%s', continuing."
,
orig
->
dest
);
WARN
(
"Error creating '%s', continuing."
,
orig
->
dest
);
}
}
/*
/*
...
@@ -357,7 +368,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
...
@@ -357,7 +368,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
/*
/*
* If newtype is NULL and snapshot is set, then use overlayfs
* If newtype is NULL and snapshot is set, then use overlayfs
*/
*/
if
(
!
bdevtype
&&
!
keepbdevtype
&&
snap
&&
strcmp
(
orig
->
type
,
"dir"
)
==
0
)
if
(
!
bdevtype
&&
!
keepbdevtype
&&
snap
&&
strcmp
(
orig
->
type
,
"dir"
)
==
0
)
bdevtype
=
"overlayfs"
;
bdevtype
=
"overlayfs"
;
if
(
am_unpriv
()
&&
!
unpriv_snap_allowed
(
orig
,
bdevtype
,
snap
,
maybe_snap
))
{
if
(
am_unpriv
()
&&
!
unpriv_snap_allowed
(
orig
,
bdevtype
,
snap
,
maybe_snap
))
{
...
@@ -378,7 +390,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
...
@@ -378,7 +390,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
new
=
bdev_get
(
bdevtype
?
bdevtype
:
orig
->
type
);
new
=
bdev_get
(
bdevtype
?
bdevtype
:
orig
->
type
);
if
(
!
new
)
{
if
(
!
new
)
{
ERROR
(
"no such block device type: %s"
,
bdevtype
?
bdevtype
:
orig
->
type
);
ERROR
(
"no such block device type: %s"
,
bdevtype
?
bdevtype
:
orig
->
type
);
bdev_put
(
orig
);
bdev_put
(
orig
);
return
NULL
;
return
NULL
;
}
}
...
@@ -397,10 +410,11 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
...
@@ -397,10 +410,11 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
/*
/*
* https://github.com/lxc/lxc/issues/131
* https://github.com/lxc/lxc/issues/131
* Use btrfs snapshot feature instead of rsync to restore if both orig and new are btrfs
* Use btrfs snapshot feature instead of rsync to restore if both orig
* and new are btrfs
*/
*/
if
(
bdevtype
&&
if
(
bdevtype
&&
strcmp
(
orig
->
type
,
"btrfs"
)
==
0
&&
strcmp
(
orig
->
type
,
"btrfs"
)
==
0
&&
strcmp
(
new
->
type
,
"btrfs"
)
==
0
&&
strcmp
(
new
->
type
,
"btrfs"
)
==
0
&&
btrfs_same_fs
(
orig
->
dest
,
new
->
dest
)
==
0
)
{
btrfs_same_fs
(
orig
->
dest
,
new
->
dest
)
==
0
)
{
if
(
btrfs_destroy
(
new
)
<
0
)
{
if
(
btrfs_destroy
(
new
)
<
0
)
{
ERROR
(
"Error destroying %s subvolume"
,
new
->
dest
);
ERROR
(
"Error destroying %s subvolume"
,
new
->
dest
);
...
@@ -411,7 +425,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
...
@@ -411,7 +425,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
goto
err
;
goto
err
;
}
}
if
(
btrfs_snapshot
(
orig
->
dest
,
new
->
dest
)
<
0
)
{
if
(
btrfs_snapshot
(
orig
->
dest
,
new
->
dest
)
<
0
)
{
ERROR
(
"Error restoring %s to %s"
,
orig
->
dest
,
new
->
dest
);
ERROR
(
"Error restoring %s to %s"
,
orig
->
dest
,
new
->
dest
);
goto
err
;
goto
err
;
}
}
bdev_put
(
orig
);
bdev_put
(
orig
);
...
@@ -437,7 +452,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
...
@@ -437,7 +452,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
data
.
orig
=
orig
;
data
.
orig
=
orig
;
data
.
new
=
new
;
data
.
new
=
new
;
if
(
am_unpriv
())
if
(
am_unpriv
())
ret
=
userns_exec_1
(
c0
->
lxc_conf
,
rsync_rootfs_wrapper
,
&
data
,
"rsync_rootfs_wrapper"
);
ret
=
userns_exec_1
(
c0
->
lxc_conf
,
rsync_rootfs_wrapper
,
&
data
,
"rsync_rootfs_wrapper"
);
else
else
ret
=
rsync_rootfs
(
&
data
);
ret
=
rsync_rootfs
(
&
data
);
...
@@ -474,10 +490,13 @@ struct bdev *bdev_create(const char *dest, const char *type, const char *cname,
...
@@ -474,10 +490,13 @@ struct bdev *bdev_create(const char *dest, const char *type, const char *cname,
// try for the best backing store type, according to our
// try for the best backing store type, according to our
// opinionated preferences
// opinionated preferences
for
(
i
=
0
;
best_options
[
i
];
i
++
)
{
for
(
i
=
0
;
best_options
[
i
];
i
++
)
{
if
((
bdev
=
do_bdev_create
(
dest
,
best_options
[
i
],
cname
,
specs
)))
if
((
bdev
=
do_bdev_create
(
dest
,
best_options
[
i
],
cname
,
specs
)))
return
bdev
;
return
bdev
;
}
}
return
NULL
;
// 'dir' should never fail, so this shouldn't happen
return
NULL
;
// 'dir' should never fail, so this shouldn't
// happen
}
}
// -B lvm,dir
// -B lvm,dir
...
@@ -518,15 +537,18 @@ int bdev_destroy_wrapper(void *data)
...
@@ -518,15 +537,18 @@ int bdev_destroy_wrapper(void *data)
ERROR
(
"Failed to setgid to 0"
);
ERROR
(
"Failed to setgid to 0"
);
return
-
1
;
return
-
1
;
}
}
if
(
setgroups
(
0
,
NULL
)
<
0
)
if
(
setgroups
(
0
,
NULL
)
<
0
)
WARN
(
"Failed to clear groups"
);
WARN
(
"Failed to clear groups"
);
if
(
setuid
(
0
)
<
0
)
{
if
(
setuid
(
0
)
<
0
)
{
ERROR
(
"Failed to setuid to 0"
);
ERROR
(
"Failed to setuid to 0"
);
return
-
1
;
return
-
1
;
}
}
if
(
!
bdev_destroy
(
conf
))
if
(
!
bdev_destroy
(
conf
))
return
-
1
;
return
-
1
;
else
return
0
;
return
0
;
}
}
...
@@ -549,6 +571,7 @@ struct bdev *bdev_init(struct lxc_conf *conf, const char *src, const char *dst,
...
@@ -549,6 +571,7 @@ struct bdev *bdev_init(struct lxc_conf *conf, const char *src, const char *dst,
bdev
=
malloc
(
sizeof
(
struct
bdev
));
bdev
=
malloc
(
sizeof
(
struct
bdev
));
if
(
!
bdev
)
if
(
!
bdev
)
return
NULL
;
return
NULL
;
memset
(
bdev
,
0
,
sizeof
(
struct
bdev
));
memset
(
bdev
,
0
,
sizeof
(
struct
bdev
));
bdev
->
ops
=
q
->
ops
;
bdev
->
ops
=
q
->
ops
;
bdev
->
type
=
q
->
name
;
bdev
->
type
=
q
->
name
;
...
@@ -637,8 +660,10 @@ int detect_fs(struct bdev *bdev, char *type, int len)
...
@@ -637,8 +660,10 @@ int detect_fs(struct bdev *bdev, char *type, int len)
ret
=
pipe
(
p
);
ret
=
pipe
(
p
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
-
1
;
return
-
1
;
if
((
pid
=
fork
())
<
0
)
if
((
pid
=
fork
())
<
0
)
return
-
1
;
return
-
1
;
if
(
pid
>
0
)
{
if
(
pid
>
0
)
{
int
status
;
int
status
;
close
(
p
[
1
]);
close
(
p
[
1
]);
...
@@ -664,7 +689,7 @@ int detect_fs(struct bdev *bdev, char *type, int len)
...
@@ -664,7 +689,7 @@ int detect_fs(struct bdev *bdev, char *type, int len)
exit
(
1
);
exit
(
1
);
if
(
detect_shared_rootfs
())
{
if
(
detect_shared_rootfs
())
{
if
(
mount
(
NULL
,
"/"
,
NULL
,
MS_SLAVE
|
MS_REC
,
NULL
))
{
if
(
mount
(
NULL
,
"/"
,
NULL
,
MS_SLAVE
|
MS_REC
,
NULL
))
{
SYSERROR
(
"Failed to make / rslave"
);
SYSERROR
(
"Failed to make / rslave"
);
ERROR
(
"Continuing..."
);
ERROR
(
"Continuing..."
);
}
}
...
@@ -672,9 +697,11 @@ int detect_fs(struct bdev *bdev, char *type, int len)
...
@@ -672,9 +697,11 @@ int detect_fs(struct bdev *bdev, char *type, int len)
ret
=
mount_unknown_fs
(
srcdev
,
bdev
->
dest
,
bdev
->
mntopts
);
ret
=
mount_unknown_fs
(
srcdev
,
bdev
->
dest
,
bdev
->
mntopts
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"failed mounting %s onto %s to detect fstype"
,
srcdev
,
bdev
->
dest
);
ERROR
(
"failed mounting %s onto %s to detect fstype"
,
srcdev
,
bdev
->
dest
);
exit
(
1
);
exit
(
1
);
}
}
// if symlink, get the real dev name
// if symlink, get the real dev name
char
devpath
[
MAXPATHLEN
];
char
devpath
[
MAXPATHLEN
];
char
*
l
=
linkderef
(
srcdev
,
devpath
);
char
*
l
=
linkderef
(
srcdev
,
devpath
);
...
@@ -683,6 +710,7 @@ int detect_fs(struct bdev *bdev, char *type, int len)
...
@@ -683,6 +710,7 @@ int detect_fs(struct bdev *bdev, char *type, int len)
f
=
fopen
(
"/proc/self/mounts"
,
"r"
);
f
=
fopen
(
"/proc/self/mounts"
,
"r"
);
if
(
!
f
)
if
(
!
f
)
exit
(
1
);
exit
(
1
);
while
(
getline
(
&
line
,
&
linelen
,
f
)
!=
-
1
)
{
while
(
getline
(
&
line
,
&
linelen
,
f
)
!=
-
1
)
{
sp1
=
strchr
(
line
,
' '
);
sp1
=
strchr
(
line
,
' '
);
if
(
!
sp1
)
if
(
!
sp1
)
...
@@ -701,8 +729,10 @@ int detect_fs(struct bdev *bdev, char *type, int len)
...
@@ -701,8 +729,10 @@ int detect_fs(struct bdev *bdev, char *type, int len)
sp2
++
;
sp2
++
;
if
(
write
(
p
[
1
],
sp2
,
strlen
(
sp2
))
!=
strlen
(
sp2
))
if
(
write
(
p
[
1
],
sp2
,
strlen
(
sp2
))
!=
strlen
(
sp2
))
exit
(
1
);
exit
(
1
);
exit
(
0
);
exit
(
0
);
}
}
exit
(
1
);
exit
(
1
);
}
}
...
@@ -720,9 +750,10 @@ int do_mkfs(const char *path, const char *fstype)
...
@@ -720,9 +750,10 @@ int do_mkfs(const char *path, const char *fstype)
// If the file is not a block device, we don't want mkfs to ask
// If the file is not a block device, we don't want mkfs to ask
// us about whether to proceed.
// us about whether to proceed.
if
(
null_stdfds
()
<
0
)
if
(
null_stdfds
()
<
0
)
exit
(
1
);
exit
(
EXIT_FAILURE
);
execlp
(
"mkfs"
,
"mkfs"
,
"-t"
,
fstype
,
path
,
(
char
*
)
NULL
);
execlp
(
"mkfs"
,
"mkfs"
,
"-t"
,
fstype
,
path
,
(
char
*
)
NULL
);
exit
(
1
);
exit
(
EXIT_FAILURE
);
}
}
/*
/*
...
@@ -733,12 +764,15 @@ int is_blktype(struct bdev *b)
...
@@ -733,12 +764,15 @@ int is_blktype(struct bdev *b)
{
{
if
(
strcmp
(
b
->
type
,
"lvm"
)
==
0
)
if
(
strcmp
(
b
->
type
,
"lvm"
)
==
0
)
return
1
;
return
1
;
return
0
;
return
0
;
}
}
int
mount_unknown_fs
(
const
char
*
rootfs
,
const
char
*
target
,
int
mount_unknown_fs
(
const
char
*
rootfs
,
const
char
*
target
,
const
char
*
options
)
const
char
*
options
)
{
{
size_t
i
;
int
ret
;
struct
cbarg
{
struct
cbarg
{
const
char
*
rootfs
;
const
char
*
rootfs
;
const
char
*
target
;
const
char
*
target
;
...
@@ -759,11 +793,7 @@ int mount_unknown_fs(const char *rootfs, const char *target,
...
@@ -759,11 +793,7 @@ int mount_unknown_fs(const char *rootfs, const char *target,
"/proc/filesystems"
,
"/proc/filesystems"
,
};
};
size_t
i
;
for
(
i
=
0
;
i
<
sizeof
(
fsfile
)
/
sizeof
(
fsfile
[
0
]);
i
++
)
{
for
(
i
=
0
;
i
<
sizeof
(
fsfile
)
/
sizeof
(
fsfile
[
0
]);
i
++
)
{
int
ret
;
if
(
access
(
fsfile
[
i
],
F_OK
))
if
(
access
(
fsfile
[
i
],
F_OK
))
continue
;
continue
;
...
@@ -794,13 +824,16 @@ bool rootfs_is_blockdev(struct lxc_conf *conf)
...
@@ -794,13 +824,16 @@ bool rootfs_is_blockdev(struct lxc_conf *conf)
ret
=
stat
(
conf
->
rootfs
.
path
,
&
st
);
ret
=
stat
(
conf
->
rootfs
.
path
,
&
st
);
if
(
ret
==
0
&&
S_ISBLK
(
st
.
st_mode
))
if
(
ret
==
0
&&
S_ISBLK
(
st
.
st_mode
))
return
true
;
return
true
;
q
=
bdev_query
(
conf
,
conf
->
rootfs
.
path
);
q
=
bdev_query
(
conf
,
conf
->
rootfs
.
path
);
if
(
!
q
)
if
(
!
q
)
return
false
;
return
false
;
if
(
strcmp
(
q
->
name
,
"lvm"
)
==
0
||
if
(
strcmp
(
q
->
name
,
"lvm"
)
==
0
||
strcmp
(
q
->
name
,
"loop"
)
==
0
||
strcmp
(
q
->
name
,
"loop"
)
==
0
||
strcmp
(
q
->
name
,
"nbd"
)
==
0
)
strcmp
(
q
->
name
,
"nbd"
)
==
0
)
return
true
;
return
true
;
return
false
;
return
false
;
}
}
...
@@ -808,10 +841,11 @@ static struct bdev *do_bdev_create(const char *dest, const char *type,
...
@@ -808,10 +841,11 @@ static struct bdev *do_bdev_create(const char *dest, const char *type,
const
char
*
cname
,
struct
bdev_specs
*
specs
)
const
char
*
cname
,
struct
bdev_specs
*
specs
)
{
{
struct
bdev
*
bdev
=
bdev_get
(
type
);
struct
bdev
*
bdev
;
if
(
!
bdev
)
{
bdev
=
bdev_get
(
type
);
if
(
!
bdev
)
return
NULL
;
return
NULL
;
}
if
(
bdev
->
ops
->
create
(
bdev
,
dest
,
cname
,
specs
)
<
0
)
{
if
(
bdev
->
ops
->
create
(
bdev
,
dest
,
cname
,
specs
)
<
0
)
{
bdev_put
(
bdev
);
bdev_put
(
bdev
);
...
@@ -830,14 +864,18 @@ static struct bdev *bdev_get(const char *type)
...
@@ -830,14 +864,18 @@ static struct bdev *bdev_get(const char *type)
if
(
strcmp
(
bdevs
[
i
].
name
,
type
)
==
0
)
if
(
strcmp
(
bdevs
[
i
].
name
,
type
)
==
0
)
break
;
break
;
}
}
if
(
i
==
numbdevs
)
if
(
i
==
numbdevs
)
return
NULL
;
return
NULL
;
bdev
=
malloc
(
sizeof
(
struct
bdev
));
bdev
=
malloc
(
sizeof
(
struct
bdev
));
if
(
!
bdev
)
if
(
!
bdev
)
return
NULL
;
return
NULL
;
memset
(
bdev
,
0
,
sizeof
(
struct
bdev
));
memset
(
bdev
,
0
,
sizeof
(
struct
bdev
));
bdev
->
ops
=
bdevs
[
i
].
ops
;
bdev
->
ops
=
bdevs
[
i
].
ops
;
bdev
->
type
=
bdevs
[
i
].
name
;
bdev
->
type
=
bdevs
[
i
].
name
;
return
bdev
;
return
bdev
;
}
}
...
@@ -885,7 +923,7 @@ static const struct bdev_type *bdev_query(struct lxc_conf *conf,
...
@@ -885,7 +923,7 @@ static const struct bdev_type *bdev_query(struct lxc_conf *conf,
* the callback system, they can be pulled from there eventually, so we
* the callback system, they can be pulled from there eventually, so we
* don't need to pollute utils.c with these low level functions
* don't need to pollute utils.c with these low level functions
*/
*/
static
int
find_fstype_cb
(
char
*
buffer
,
void
*
data
)
static
int
find_fstype_cb
(
char
*
buffer
,
void
*
data
)
{
{
struct
cbarg
{
struct
cbarg
{
const
char
*
rootfs
;
const
char
*
rootfs
;
...
@@ -905,8 +943,8 @@ static int find_fstype_cb(char* buffer, void *data)
...
@@ -905,8 +943,8 @@ static int find_fstype_cb(char* buffer, void *data)
fstype
+=
lxc_char_left_gc
(
fstype
,
strlen
(
fstype
));
fstype
+=
lxc_char_left_gc
(
fstype
,
strlen
(
fstype
));
fstype
[
lxc_char_right_gc
(
fstype
,
strlen
(
fstype
))]
=
'\0'
;
fstype
[
lxc_char_right_gc
(
fstype
,
strlen
(
fstype
))]
=
'\0'
;
DEBUG
(
"trying to mount '%s'->'%s' with fstype '%s'"
,
DEBUG
(
"trying to mount '%s'->'%s' with fstype '%s'"
,
cbarg
->
rootfs
,
cbarg
->
rootfs
,
cbarg
->
target
,
fstype
);
cbarg
->
target
,
fstype
);
if
(
parse_mntopts
(
cbarg
->
options
,
&
mntflags
,
&
mntdata
)
<
0
)
{
if
(
parse_mntopts
(
cbarg
->
options
,
&
mntflags
,
&
mntdata
)
<
0
)
{
free
(
mntdata
);
free
(
mntdata
);
...
@@ -921,8 +959,8 @@ static int find_fstype_cb(char* buffer, void *data)
...
@@ -921,8 +959,8 @@ static int find_fstype_cb(char* buffer, void *data)
free
(
mntdata
);
free
(
mntdata
);
INFO
(
"mounted '%s' on '%s', with fstype '%s'"
,
INFO
(
"mounted '%s' on '%s', with fstype '%s'"
,
cbarg
->
rootfs
,
cbarg
->
rootfs
,
cbarg
->
target
,
fstype
);
cbarg
->
target
,
fstype
);
return
1
;
return
1
;
}
}
...
@@ -935,8 +973,10 @@ static char *linkderef(char *path, char *dest)
...
@@ -935,8 +973,10 @@ static char *linkderef(char *path, char *dest)
ret
=
stat
(
path
,
&
sbuf
);
ret
=
stat
(
path
,
&
sbuf
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
NULL
;
return
NULL
;
if
(
!
S_ISLNK
(
sbuf
.
st_mode
))
if
(
!
S_ISLNK
(
sbuf
.
st_mode
))
return
path
;
return
path
;
ret
=
readlink
(
path
,
dest
,
MAXPATHLEN
);
ret
=
readlink
(
path
,
dest
,
MAXPATHLEN
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
SYSERROR
(
"error reading link %s"
,
path
);
SYSERROR
(
"error reading link %s"
,
path
);
...
@@ -946,6 +986,7 @@ static char *linkderef(char *path, char *dest)
...
@@ -946,6 +986,7 @@ static char *linkderef(char *path, char *dest)
return
NULL
;
return
NULL
;
}
}
dest
[
ret
]
=
'\0'
;
dest
[
ret
]
=
'\0'
;
return
dest
;
return
dest
;
}
}
...
@@ -965,6 +1006,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
...
@@ -965,6 +1006,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
strcmp
(
b
->
type
,
"btrfs"
)
==
0
||
strcmp
(
b
->
type
,
"btrfs"
)
==
0
||
strcmp
(
b
->
type
,
"loop"
)
==
0
)
strcmp
(
b
->
type
,
"loop"
)
==
0
)
return
true
;
return
true
;
return
false
;
return
false
;
}
}
...
@@ -976,6 +1018,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
...
@@ -976,6 +1018,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
strcmp
(
t
,
"btrfs"
)
==
0
||
strcmp
(
t
,
"btrfs"
)
==
0
||
strcmp
(
t
,
"loop"
)
==
0
)
strcmp
(
t
,
"loop"
)
==
0
)
return
true
;
return
true
;
return
false
;
return
false
;
}
}
...
@@ -991,5 +1034,6 @@ bool is_valid_bdev_type(const char *type)
...
@@ -991,5 +1034,6 @@ bool is_valid_bdev_type(const char *type)
strcmp
(
type
,
"rbd"
)
==
0
||
strcmp
(
type
,
"rbd"
)
==
0
||
strcmp
(
type
,
"zfs"
)
==
0
)
strcmp
(
type
,
"zfs"
)
==
0
)
return
true
;
return
true
;
return
false
;
return
false
;
}
}
src/lxc/bdev/bdev.h
View file @
493de765
...
@@ -23,17 +23,13 @@
...
@@ -23,17 +23,13 @@
#ifndef __LXC_BDEV_H
#ifndef __LXC_BDEV_H
#define __LXC_BDEV_H
#define __LXC_BDEV_H
/* blockdev operations for:
* aufs, dir, raw, btrfs, overlayfs, aufs, lvm, loop, zfs, nbd (qcow2, raw, vdi, qed)
*/
#include
<lxc/lxccontainer.h>
#include
"config.h"
#include <stdint.h>
#include <stdint.h>
#include <sys/mount.h>
#include <sys/mount.h>
#include
"config.h"
#include
<lxc/lxccontainer.h>
/* define constants if the kernel/glibc headers don't define them */
#ifndef MS_DIRSYNC
#ifndef MS_DIRSYNC
#define MS_DIRSYNC 128
#define MS_DIRSYNC 128
#endif
#endif
...
@@ -73,18 +69,19 @@ struct bdev_ops {
...
@@ -73,18 +69,19 @@ struct bdev_ops {
int
(
*
create
)(
struct
bdev
*
bdev
,
const
char
*
dest
,
const
char
*
n
,
int
(
*
create
)(
struct
bdev
*
bdev
,
const
char
*
dest
,
const
char
*
n
,
struct
bdev_specs
*
specs
);
struct
bdev_specs
*
specs
);
/* given original mount, rename the paths for cloned container */
/* given original mount, rename the paths for cloned container */
int
(
*
clone_paths
)(
struct
bdev
*
orig
,
struct
bdev
*
new
,
const
char
*
oldname
,
int
(
*
clone_paths
)(
struct
bdev
*
orig
,
struct
bdev
*
new
,
const
char
*
cname
,
const
char
*
oldpath
,
const
char
*
lxcpath
,
const
char
*
oldname
,
const
char
*
cname
,
int
snap
,
uint64_t
newsize
,
struct
lxc_conf
*
conf
);
const
char
*
oldpath
,
const
char
*
lxcpath
,
int
snap
,
uint64_t
newsize
,
struct
lxc_conf
*
conf
);
bool
can_snapshot
;
bool
can_snapshot
;
bool
can_backup
;
bool
can_backup
;
};
};
/*
/*
* When lxc-start
(conf.c) is mounting a rootfs, then src will be the
* When lxc-start
is mounting a rootfs, then src will be the "lxc.rootfs" value,
*
'lxc.rootfs' value, dest will be mount dir (i.e. $libdir/lxc) When clone
*
dest will be mount dir (i.e. $libdir/lxc) When clone or create is doing so,
*
or create is doing so, then dest will be $lxcpath/$lxcname/rootfs, since
*
then dest will be $lxcpath/$lxcname/rootfs, since we may need to rsync from
*
we may need to rsync from
one to the other.
* one to the other.
* data is so far unused.
* data is so far unused.
*/
*/
struct
bdev
{
struct
bdev
{
...
@@ -93,10 +90,10 @@ struct bdev {
...
@@ -93,10 +90,10 @@ struct bdev {
char
*
src
;
char
*
src
;
char
*
dest
;
char
*
dest
;
char
*
mntopts
;
char
*
mntopts
;
/
/ turn the following into a union if need be
/
* Turn the following into a union if need be. */
/
/ lofd is the open fd for the mounted loopback file
/
* lofd is the open fd for the mounted loopback file. */
int
lofd
;
int
lofd
;
/
/ index for the connected nbd device
/
* index for the connected nbd device. */
int
nbd_idx
;
int
nbd_idx
;
};
};
...
@@ -104,9 +101,9 @@ bool bdev_is_dir(struct lxc_conf *conf, const char *path);
...
@@ -104,9 +101,9 @@ bool bdev_is_dir(struct lxc_conf *conf, const char *path);
bool
bdev_can_backup
(
struct
lxc_conf
*
conf
);
bool
bdev_can_backup
(
struct
lxc_conf
*
conf
);
/*
/*
* Instantiate a bdev object.
The src is used to determine which blockdev
* Instantiate a bdev object.
The src is used to determine which blockdev type
* t
ype this should be. The dst and data are optional, and will be used
* t
his should be. The dst and data are optional, and will be used in case of
*
in case of
mount/umount.
* mount/umount.
*
*
* Optionally, src can be 'dir:/var/lib/lxc/c1' or 'lvm:/dev/lxc/c1'. For
* Optionally, src can be 'dir:/var/lib/lxc/c1' or 'lvm:/dev/lxc/c1'. For
* other backing stores, this will allow additional options. In particular,
* other backing stores, this will allow additional options. In particular,
...
@@ -118,13 +115,13 @@ struct bdev *bdev_init(struct lxc_conf *conf, const char *src, const char *dst,
...
@@ -118,13 +115,13 @@ struct bdev *bdev_init(struct lxc_conf *conf, const char *src, const char *dst,
const
char
*
data
);
const
char
*
data
);
struct
bdev
*
bdev_copy
(
struct
lxc_container
*
c0
,
const
char
*
cname
,
struct
bdev
*
bdev_copy
(
struct
lxc_container
*
c0
,
const
char
*
cname
,
const
char
*
lxcpath
,
const
char
*
bdevtype
,
const
char
*
lxcpath
,
const
char
*
bdevtype
,
int
flags
,
int
flags
,
const
char
*
bdevdata
,
uint64_t
newsize
,
const
char
*
bdevdata
,
uint64_t
newsize
,
int
*
needs_rdep
);
int
*
needs_rdep
);
struct
bdev
*
bdev_create
(
const
char
*
dest
,
const
char
*
type
,
const
char
*
cname
,
struct
bdev
*
bdev_create
(
const
char
*
dest
,
const
char
*
type
,
struct
bdev_specs
*
specs
);
const
char
*
cname
,
struct
bdev_specs
*
specs
);
void
bdev_put
(
struct
bdev
*
bdev
);
void
bdev_put
(
struct
bdev
*
bdev
);
bool
bdev_destroy
(
struct
lxc_conf
*
conf
);
bool
bdev_destroy
(
struct
lxc_conf
*
conf
);
/* callback function to be used with userns_exec_1() */
/* callback function to be used with userns_exec_1() */
int
bdev_destroy_wrapper
(
void
*
data
);
int
bdev_destroy_wrapper
(
void
*
data
);
...
@@ -139,6 +136,7 @@ int is_blktype(struct bdev *b);
...
@@ -139,6 +136,7 @@ int is_blktype(struct bdev *b);
int
mount_unknown_fs
(
const
char
*
rootfs
,
const
char
*
target
,
int
mount_unknown_fs
(
const
char
*
rootfs
,
const
char
*
target
,
const
char
*
options
);
const
char
*
options
);
bool
rootfs_is_blockdev
(
struct
lxc_conf
*
conf
);
bool
rootfs_is_blockdev
(
struct
lxc_conf
*
conf
);
/*
/*
* these are really for qemu-nbd support, as container shutdown
* these are really for qemu-nbd support, as container shutdown
* must explicitly request device detach.
* must explicitly request device detach.
...
...
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