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
a14bf84f
Commit
a14bf84f
authored
Dec 20, 2015
by
Serge Hallyn
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #724 from brauner/2015-12-12/split_bdev_into_modules
split bdev into modules
parents
fbc617e8
5c484f79
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
932 additions
and
763 deletions
+932
-763
Makefile.am
src/lxc/Makefile.am
+4
-3
bdev.c
src/lxc/bdev/bdev.c
+74
-522
bdev.h
src/lxc/bdev/bdev.h
+1
-3
lxc-btrfs.h
src/lxc/bdev/lxc-btrfs.h
+0
-0
overlay.c
src/lxc/bdev/overlay.c
+723
-0
overlay.h
src/lxc/bdev/overlay.h
+93
-0
cgfs.c
src/lxc/cgfs.c
+1
-1
cgmanager.c
src/lxc/cgmanager.c
+1
-1
conf.c
src/lxc/conf.c
+4
-104
criu.c
src/lxc/criu.c
+1
-1
lxc_copy.c
src/lxc/lxc_copy.c
+1
-1
lxc_create.c
src/lxc/lxc_create.c
+1
-1
lxc_snapshot.c
src/lxc/lxc_snapshot.c
+1
-1
lxccontainer.c
src/lxc/lxccontainer.c
+26
-124
start.c
src/lxc/start.c
+1
-1
No files found.
src/lxc/Makefile.am
View file @
a14bf84f
...
@@ -6,7 +6,9 @@ pkginclude_HEADERS = \
...
@@ -6,7 +6,9 @@ pkginclude_HEADERS = \
noinst_HEADERS
=
\
noinst_HEADERS
=
\
arguments.h
\
arguments.h
\
attach.h
\
attach.h
\
bdev.h
\
bdev/bdev.h
\
bdev/lxc-btrfs.h
\
bdev/overlay.h
\
caps.h
\
caps.h
\
cgroup.h
\
cgroup.h
\
conf.h
\
conf.h
\
...
@@ -16,7 +18,6 @@ noinst_HEADERS = \
...
@@ -16,7 +18,6 @@ noinst_HEADERS = \
list.h
\
list.h
\
log.h
\
log.h
\
lxc.h
\
lxc.h
\
lxc-btrfs.h
\
lxclock.h
\
lxclock.h
\
monitor.h
\
monitor.h
\
namespace.h
\
namespace.h
\
...
@@ -60,7 +61,7 @@ endif
...
@@ -60,7 +61,7 @@ endif
liblxc_so_SOURCES
=
\
liblxc_so_SOURCES
=
\
arguments.c arguments.h
\
arguments.c arguments.h
\
bdev
.c bdev.h
lxc-btrfs.h
\
bdev
/bdev.c bdev/bdev.h bdev/overlay.c bdev/overlay.h bdev/
lxc-btrfs.h
\
commands.c commands.h
\
commands.c commands.h
\
start.c start.h
\
start.c start.h
\
execute.c
\
execute.c
\
...
...
src/lxc/bdev.c
→
src/lxc/bdev
/bdev
.c
View file @
a14bf84f
...
@@ -27,33 +27,38 @@
...
@@ -27,33 +27,38 @@
* I'm doing by calling out to userspace should sometimes be done through
* I'm doing by calling out to userspace should sometimes be done through
* libraries like liblvm2
* libraries like liblvm2
*/
*/
#define _GNU_SOURCE
#define _GNU_SOURCE
#include <stdio.h>
#include <dirent.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <grp.h>
#include <unistd.h>
#include <errno.h>
#include <errno.h>
#include <
sched
.h>
#include <
fcntl
.h>
#include <
sys/mount
.h>
#include <
grp
.h>
#include <
sys/wait
.h>
#include <
inttypes
.h>
#include <libgen.h>
#include <libgen.h>
#include <sched.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <linux/loop.h>
#include <linux/loop.h>
#include <
dire
nt.h>
#include <
sys/mou
nt.h>
#include <sys/prctl.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include "
lxc
.h"
#include "
bdev
.h"
#include "config.h"
#include "config.h"
#include "conf.h"
#include "conf.h"
#include "bdev.h"
#include "log.h"
#include "error.h"
#include "error.h"
#include "utils.h"
#include "log.h"
#include "namespace.h"
#include "lxc.h"
#include "parse.h"
#include "lxclock.h"
#include "lxclock.h"
#include "lxc-btrfs.h"
#include "lxc-btrfs.h"
#include "namespace.h"
#include "overlay.h"
/* overlay */
#include "parse.h"
#include "utils.h"
#ifndef BLKGETSIZE64
#ifndef BLKGETSIZE64
#define BLKGETSIZE64 _IOR(0x12,114,size_t)
#define BLKGETSIZE64 _IOR(0x12,114,size_t)
...
@@ -72,17 +77,13 @@
...
@@ -72,17 +77,13 @@
lxc_log_define
(
bdev
,
lxc
);
lxc_log_define
(
bdev
,
lxc
);
struct
ovl_rsync_data
{
struct
bdev
*
orig
;
struct
bdev
*
new
;
};
struct
rsync_data_char
{
struct
rsync_data_char
{
char
*
src
;
char
*
src
;
char
*
dest
;
char
*
dest
;
};
};
static
int
do_rsync
(
const
char
*
src
,
const
char
*
dest
)
/* the bulk of this needs to become a common helper */
int
do_rsync
(
const
char
*
src
,
const
char
*
dest
)
{
{
// call out to rsync
// call out to rsync
pid_t
pid
;
pid_t
pid
;
...
@@ -107,6 +108,48 @@ static int do_rsync(const char *src, const char *dest)
...
@@ -107,6 +108,48 @@ static int do_rsync(const char *src, const char *dest)
exit
(
1
);
exit
(
1
);
}
}
/* the bulk of this needs to become a common helper */
char
*
dir_new_path
(
char
*
src
,
const
char
*
oldname
,
const
char
*
name
,
const
char
*
oldpath
,
const
char
*
lxcpath
)
{
char
*
ret
,
*
p
,
*
p2
;
int
l1
,
l2
,
nlen
;
nlen
=
strlen
(
src
)
+
1
;
l1
=
strlen
(
oldpath
);
p
=
src
;
/* if src starts with oldpath, look for oldname only after
* that path */
if
(
strncmp
(
src
,
oldpath
,
l1
)
==
0
)
{
p
+=
l1
;
nlen
+=
(
strlen
(
lxcpath
)
-
l1
);
}
l2
=
strlen
(
oldname
);
while
((
p
=
strstr
(
p
,
oldname
))
!=
NULL
)
{
p
+=
l2
;
nlen
+=
strlen
(
name
)
-
l2
;
}
ret
=
malloc
(
nlen
);
if
(
!
ret
)
return
NULL
;
p
=
ret
;
if
(
strncmp
(
src
,
oldpath
,
l1
)
==
0
)
{
p
+=
sprintf
(
p
,
"%s"
,
lxcpath
);
src
+=
l1
;
}
while
((
p2
=
strstr
(
src
,
oldname
))
!=
NULL
)
{
strncpy
(
p
,
src
,
p2
-
src
);
// copy text up to oldname
p
+=
p2
-
src
;
// move target pointer (p)
p
+=
sprintf
(
p
,
"%s"
,
name
);
// print new name in place of oldname
src
=
p2
+
l2
;
// move src to end of oldname
}
sprintf
(
p
,
"%s"
,
src
);
// copy the rest of src
return
ret
;
}
/*
/*
* return block size of dev->src in units of bytes
* return block size of dev->src in units of bytes
*/
*/
...
@@ -404,48 +447,6 @@ static int dir_umount(struct bdev *bdev)
...
@@ -404,48 +447,6 @@ static int dir_umount(struct bdev *bdev)
return
umount
(
bdev
->
dest
);
return
umount
(
bdev
->
dest
);
}
}
/* the bulk of this needs to become a common helper */
static
char
*
dir_new_path
(
char
*
src
,
const
char
*
oldname
,
const
char
*
name
,
const
char
*
oldpath
,
const
char
*
lxcpath
)
{
char
*
ret
,
*
p
,
*
p2
;
int
l1
,
l2
,
nlen
;
nlen
=
strlen
(
src
)
+
1
;
l1
=
strlen
(
oldpath
);
p
=
src
;
/* if src starts with oldpath, look for oldname only after
* that path */
if
(
strncmp
(
src
,
oldpath
,
l1
)
==
0
)
{
p
+=
l1
;
nlen
+=
(
strlen
(
lxcpath
)
-
l1
);
}
l2
=
strlen
(
oldname
);
while
((
p
=
strstr
(
p
,
oldname
))
!=
NULL
)
{
p
+=
l2
;
nlen
+=
strlen
(
name
)
-
l2
;
}
ret
=
malloc
(
nlen
);
if
(
!
ret
)
return
NULL
;
p
=
ret
;
if
(
strncmp
(
src
,
oldpath
,
l1
)
==
0
)
{
p
+=
sprintf
(
p
,
"%s"
,
lxcpath
);
src
+=
l1
;
}
while
((
p2
=
strstr
(
src
,
oldname
))
!=
NULL
)
{
strncpy
(
p
,
src
,
p2
-
src
);
// copy text up to oldname
p
+=
p2
-
src
;
// move target pointer (p)
p
+=
sprintf
(
p
,
"%s"
,
name
);
// print new name in place of oldname
src
=
p2
+
l2
;
// move src to end of oldname
}
sprintf
(
p
,
"%s"
,
src
);
// copy the rest of src
return
ret
;
}
/*
/*
* for a simple directory bind mount, we substitute the old container
* for a simple directory bind mount, we substitute the old container
* name and paths for the new
* name and paths for the new
...
@@ -2321,158 +2322,6 @@ static const struct bdev_ops loop_ops = {
...
@@ -2321,158 +2322,6 @@ static const struct bdev_ops loop_ops = {
.
can_backup
=
true
,
.
can_backup
=
true
,
};
};
//
// overlayfs ops
//
static
int
overlayfs_detect
(
const
char
*
path
)
{
if
(
strncmp
(
path
,
"overlayfs:"
,
10
)
==
0
)
return
1
;
// take their word for it
return
0
;
}
static
char
*
overlayfs_name
;
static
char
*
detect_overlayfs_name
(
void
)
{
char
*
v
=
"overlayfs"
;
char
*
line
=
NULL
;
size_t
len
=
0
;
FILE
*
f
=
fopen
(
"/proc/filesystems"
,
"r"
);
if
(
!
f
)
return
v
;
while
(
getline
(
&
line
,
&
len
,
f
)
!=
-
1
)
{
if
(
strcmp
(
line
,
"nodev
\t
overlay
\n
"
)
==
0
)
{
v
=
"overlay"
;
break
;
}
}
fclose
(
f
);
free
(
line
);
return
v
;
}
//
// XXXXXXX plain directory bind mount ops
//
static
int
overlayfs_mount
(
struct
bdev
*
bdev
)
{
char
*
options
,
*
dup
,
*
lower
,
*
upper
;
char
*
options_work
,
*
work
,
*
lastslash
;
int
lastslashidx
;
int
len
,
len2
;
unsigned
long
mntflags
;
char
*
mntdata
;
int
ret
,
ret2
;
if
(
strcmp
(
bdev
->
type
,
"overlayfs"
))
return
-
22
;
if
(
!
bdev
->
src
||
!
bdev
->
dest
)
return
-
22
;
if
(
!
overlayfs_name
)
overlayfs_name
=
detect_overlayfs_name
();
// separately mount it first
// mount -t overlayfs -oupperdir=${upper},lowerdir=${lower} lower dest
dup
=
alloca
(
strlen
(
bdev
->
src
)
+
1
);
strcpy
(
dup
,
bdev
->
src
);
if
(
!
(
lower
=
strchr
(
dup
,
':'
)))
return
-
22
;
if
(
!
(
upper
=
strchr
(
++
lower
,
':'
)))
return
-
22
;
*
upper
=
'\0'
;
upper
++
;
// if delta doesn't yet exist, create it
if
(
mkdir_p
(
upper
,
0755
)
<
0
&&
errno
!=
EEXIST
)
return
-
22
;
// overlayfs.v22 or higher needs workdir option
// if upper is /var/lib/lxc/c2/delta0,
// then workdir is /var/lib/lxc/c2/olwork
lastslash
=
strrchr
(
upper
,
'/'
);
if
(
!
lastslash
)
return
-
22
;
lastslash
++
;
lastslashidx
=
lastslash
-
upper
;
work
=
alloca
(
lastslashidx
+
7
);
strncpy
(
work
,
upper
,
lastslashidx
+
7
);
strcpy
(
work
+
lastslashidx
,
"olwork"
);
if
(
parse_mntopts
(
bdev
->
mntopts
,
&
mntflags
,
&
mntdata
)
<
0
)
{
free
(
mntdata
);
return
-
22
;
}
if
(
mkdir_p
(
work
,
0755
)
<
0
&&
errno
!=
EEXIST
)
{
free
(
mntdata
);
return
-
22
;
}
// TODO We should check whether bdev->src is a blockdev, and if so
// but for now, only support overlays of a basic directory
if
(
mntdata
)
{
len
=
strlen
(
lower
)
+
strlen
(
upper
)
+
strlen
(
"upperdir=,lowerdir=,"
)
+
strlen
(
mntdata
)
+
1
;
options
=
alloca
(
len
);
ret
=
snprintf
(
options
,
len
,
"upperdir=%s,lowerdir=%s,%s"
,
upper
,
lower
,
mntdata
);
len2
=
strlen
(
lower
)
+
strlen
(
upper
)
+
strlen
(
work
)
+
strlen
(
"upperdir=,lowerdir=,workdir="
)
+
strlen
(
mntdata
)
+
1
;
options_work
=
alloca
(
len2
);
ret2
=
snprintf
(
options
,
len2
,
"upperdir=%s,lowerdir=%s,workdir=%s,%s"
,
upper
,
lower
,
work
,
mntdata
);
}
else
{
len
=
strlen
(
lower
)
+
strlen
(
upper
)
+
strlen
(
"upperdir=,lowerdir="
)
+
1
;
options
=
alloca
(
len
);
ret
=
snprintf
(
options
,
len
,
"upperdir=%s,lowerdir=%s"
,
upper
,
lower
);
len2
=
strlen
(
lower
)
+
strlen
(
upper
)
+
strlen
(
work
)
+
strlen
(
"upperdir=,lowerdir=,workdir="
)
+
1
;
options_work
=
alloca
(
len2
);
ret2
=
snprintf
(
options_work
,
len2
,
"upperdir=%s,lowerdir=%s,workdir=%s"
,
upper
,
lower
,
work
);
}
if
(
ret
<
0
||
ret
>=
len
||
ret2
<
0
||
ret2
>=
len2
)
{
free
(
mntdata
);
return
-
1
;
}
// mount without workdir option for overlayfs before v21
ret
=
mount
(
lower
,
bdev
->
dest
,
overlayfs_name
,
MS_MGC_VAL
|
mntflags
,
options
);
if
(
ret
<
0
)
{
INFO
(
"overlayfs: error mounting %s onto %s options %s. retry with workdir"
,
lower
,
bdev
->
dest
,
options
);
// retry with workdir option for overlayfs v22 and higher
ret
=
mount
(
lower
,
bdev
->
dest
,
overlayfs_name
,
MS_MGC_VAL
|
mntflags
,
options_work
);
if
(
ret
<
0
)
SYSERROR
(
"overlayfs: error mounting %s onto %s options %s"
,
lower
,
bdev
->
dest
,
options_work
);
else
INFO
(
"overlayfs: mounted %s onto %s options %s"
,
lower
,
bdev
->
dest
,
options_work
);
}
else
INFO
(
"overlayfs: mounted %s onto %s options %s"
,
lower
,
bdev
->
dest
,
options
);
return
ret
;
}
static
int
overlayfs_umount
(
struct
bdev
*
bdev
)
{
if
(
strcmp
(
bdev
->
type
,
"overlayfs"
))
return
-
22
;
if
(
!
bdev
->
src
||
!
bdev
->
dest
)
return
-
22
;
return
umount
(
bdev
->
dest
);
}
static
int
rsync_delta
(
struct
rsync_data_char
*
data
)
static
int
rsync_delta
(
struct
rsync_data_char
*
data
)
{
{
if
(
setgid
(
0
)
<
0
)
{
if
(
setgid
(
0
)
<
0
)
{
...
@@ -2499,303 +2348,14 @@ static int rsync_delta_wrapper(void *data)
...
@@ -2499,303 +2348,14 @@ static int rsync_delta_wrapper(void *data)
return
rsync_delta
(
arg
);
return
rsync_delta
(
arg
);
}
}
static
int
ovl_rsync
(
struct
ovl_rsync_data
*
data
)
/* overlay */
{
static
const
struct
bdev_ops
ovl_ops
=
{
int
ret
;
.
detect
=
&
ovl_detect
,
.
mount
=
&
ovl_mount
,
if
(
setgid
(
0
)
<
0
)
{
.
umount
=
&
ovl_umount
,
ERROR
(
"Failed to setgid to 0"
);
.
clone_paths
=
&
ovl_clonepaths
,
return
-
1
;
.
destroy
=
&
ovl_destroy
,
}
.
create
=
&
ovl_create
,
if
(
setgroups
(
0
,
NULL
)
<
0
)
WARN
(
"Failed to clear groups"
);
if
(
setuid
(
0
)
<
0
)
{
ERROR
(
"Failed to setuid to 0"
);
return
-
1
;
}
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
{
SYSERROR
(
"Unable to unshare mounts ns"
);
return
-
1
;
}
if
(
detect_shared_rootfs
())
{
if
(
mount
(
NULL
,
"/"
,
NULL
,
MS_SLAVE
|
MS_REC
,
NULL
))
{
SYSERROR
(
"Failed to make / rslave"
);
ERROR
(
"Continuing..."
);
}
}
if
(
overlayfs_mount
(
data
->
orig
)
<
0
)
{
ERROR
(
"Failed mounting original container fs"
);
return
-
1
;
}
if
(
overlayfs_mount
(
data
->
new
)
<
0
)
{
ERROR
(
"Failed mounting new container fs"
);
return
-
1
;
}
ret
=
do_rsync
(
data
->
orig
->
dest
,
data
->
new
->
dest
);
overlayfs_umount
(
data
->
new
);
overlayfs_umount
(
data
->
orig
);
if
(
ret
<
0
)
{
ERROR
(
"rsyncing %s to %s"
,
data
->
orig
->
dest
,
data
->
new
->
dest
);
return
-
1
;
}
return
0
;
}
static
int
ovl_rsync_wrapper
(
void
*
data
)
{
struct
ovl_rsync_data
*
arg
=
data
;
return
ovl_rsync
(
arg
);
}
static
int
ovl_do_rsync
(
struct
bdev
*
orig
,
struct
bdev
*
new
,
struct
lxc_conf
*
conf
)
{
int
ret
=
-
1
;
struct
ovl_rsync_data
rdata
;
rdata
.
orig
=
orig
;
rdata
.
new
=
new
;
if
(
am_unpriv
())
ret
=
userns_exec_1
(
conf
,
ovl_rsync_wrapper
,
&
rdata
);
else
ret
=
ovl_rsync
(
&
rdata
);
if
(
ret
)
ERROR
(
"copying overlayfs delta"
);
return
ret
;
}
static
int
overlayfs_clonepaths
(
struct
bdev
*
orig
,
struct
bdev
*
new
,
const
char
*
oldname
,
const
char
*
cname
,
const
char
*
oldpath
,
const
char
*
lxcpath
,
int
snap
,
uint64_t
newsize
,
struct
lxc_conf
*
conf
)
{
if
(
!
snap
)
{
ERROR
(
"overlayfs is only for snapshot clones"
);
return
-
22
;
}
if
(
!
orig
->
src
||
!
orig
->
dest
)
return
-
1
;
new
->
dest
=
dir_new_path
(
orig
->
dest
,
oldname
,
cname
,
oldpath
,
lxcpath
);
if
(
!
new
->
dest
)
return
-
1
;
if
(
mkdir_p
(
new
->
dest
,
0755
)
<
0
)
return
-
1
;
if
(
am_unpriv
()
&&
chown_mapped_root
(
new
->
dest
,
conf
)
<
0
)
WARN
(
"Failed to update ownership of %s"
,
new
->
dest
);
if
(
strcmp
(
orig
->
type
,
"dir"
)
==
0
)
{
char
*
delta
,
*
lastslash
;
char
*
work
;
int
ret
,
len
,
lastslashidx
;
// if we have /var/lib/lxc/c2/rootfs, then delta will be
// /var/lib/lxc/c2/delta0
lastslash
=
strrchr
(
new
->
dest
,
'/'
);
if
(
!
lastslash
)
return
-
22
;
if
(
strlen
(
lastslash
)
<
7
)
return
-
22
;
lastslash
++
;
lastslashidx
=
lastslash
-
new
->
dest
;
delta
=
malloc
(
lastslashidx
+
7
);
if
(
!
delta
)
return
-
1
;
strncpy
(
delta
,
new
->
dest
,
lastslashidx
+
1
);
strcpy
(
delta
+
lastslashidx
,
"delta0"
);
if
((
ret
=
mkdir
(
delta
,
0755
))
<
0
)
{
SYSERROR
(
"error: mkdir %s"
,
delta
);
free
(
delta
);
return
-
1
;
}
if
(
am_unpriv
()
&&
chown_mapped_root
(
delta
,
conf
)
<
0
)
WARN
(
"Failed to update ownership of %s"
,
delta
);
// make workdir for overlayfs.v22 or higher
// workdir is /var/lib/lxc/c2/olwork
// it is used to prepare files before atomically swithing with destination,
// and needs to be on the same filesystem as upperdir,
// so it's OK for it to be empty.
work
=
malloc
(
lastslashidx
+
7
);
if
(
!
work
)
{
free
(
delta
);
return
-
1
;
}
strncpy
(
work
,
new
->
dest
,
lastslashidx
+
1
);
strcpy
(
work
+
lastslashidx
,
"olwork"
);
if
(
mkdir
(
work
,
0755
)
<
0
)
{
SYSERROR
(
"error: mkdir %s"
,
work
);
free
(
delta
);
free
(
work
);
return
-
1
;
}
if
(
am_unpriv
()
&&
chown_mapped_root
(
work
,
conf
)
<
0
)
WARN
(
"Failed to update ownership of %s"
,
work
);
free
(
work
);
// the src will be 'overlayfs:lowerdir:upperdir'
len
=
strlen
(
delta
)
+
strlen
(
orig
->
src
)
+
12
;
new
->
src
=
malloc
(
len
);
if
(
!
new
->
src
)
{
free
(
delta
);
return
-
ENOMEM
;
}
ret
=
snprintf
(
new
->
src
,
len
,
"overlayfs:%s:%s"
,
orig
->
src
,
delta
);
free
(
delta
);
if
(
ret
<
0
||
ret
>=
len
)
return
-
ENOMEM
;
}
else
if
(
strcmp
(
orig
->
type
,
"overlayfs"
)
==
0
)
{
// What exactly do we want to do here?
// I think we want to use the original lowerdir, with a
// private delta which is originally rsynced from the
// original delta
char
*
osrc
,
*
odelta
,
*
nsrc
,
*
ndelta
,
*
work
;
char
*
lastslash
;
int
len
,
ret
,
lastslashidx
;
if
(
!
(
osrc
=
strdup
(
orig
->
src
)))
return
-
22
;
nsrc
=
strchr
(
osrc
,
':'
)
+
1
;
if
(
nsrc
!=
osrc
+
10
||
(
odelta
=
strchr
(
nsrc
,
':'
))
==
NULL
)
{
free
(
osrc
);
return
-
22
;
}
*
odelta
=
'\0'
;
odelta
++
;
ndelta
=
dir_new_path
(
odelta
,
oldname
,
cname
,
oldpath
,
lxcpath
);
if
(
!
ndelta
)
{
free
(
osrc
);
return
-
ENOMEM
;
}
if
((
ret
=
mkdir
(
ndelta
,
0755
))
<
0
&&
errno
!=
EEXIST
)
{
SYSERROR
(
"error: mkdir %s"
,
ndelta
);
free
(
osrc
);
free
(
ndelta
);
return
-
1
;
}
if
(
am_unpriv
()
&&
chown_mapped_root
(
ndelta
,
conf
)
<
0
)
WARN
(
"Failed to update ownership of %s"
,
ndelta
);
// make workdir for overlayfs.v22 or higher
// for details, see above.
lastslash
=
strrchr
(
ndelta
,
'/'
);
if
(
!
lastslash
)
return
-
1
;
lastslash
++
;
lastslashidx
=
lastslash
-
ndelta
;
work
=
malloc
(
lastslashidx
+
7
);
if
(
!
work
)
return
-
1
;
strncpy
(
work
,
ndelta
,
lastslashidx
+
1
);
strcpy
(
work
+
lastslashidx
,
"olwork"
);
if
((
mkdir
(
work
,
0755
)
<
0
)
&&
errno
!=
EEXIST
)
{
SYSERROR
(
"error: mkdir %s"
,
work
);
free
(
work
);
return
-
1
;
}
if
(
am_unpriv
()
&&
chown_mapped_root
(
work
,
conf
)
<
0
)
WARN
(
"Failed to update ownership of %s"
,
work
);
free
(
work
);
len
=
strlen
(
nsrc
)
+
strlen
(
ndelta
)
+
12
;
new
->
src
=
malloc
(
len
);
if
(
!
new
->
src
)
{
free
(
osrc
);
free
(
ndelta
);
return
-
ENOMEM
;
}
ret
=
snprintf
(
new
->
src
,
len
,
"overlayfs:%s:%s"
,
nsrc
,
ndelta
);
free
(
osrc
);
free
(
ndelta
);
if
(
ret
<
0
||
ret
>=
len
)
return
-
ENOMEM
;
return
ovl_do_rsync
(
orig
,
new
,
conf
);
}
else
{
ERROR
(
"overlayfs clone of %s container is not yet supported"
,
orig
->
type
);
// Note, supporting this will require overlayfs_mount supporting
// mounting of the underlay. No big deal, just needs to be done.
return
-
1
;
}
return
0
;
}
static
int
overlayfs_destroy
(
struct
bdev
*
orig
)
{
char
*
upper
;
if
(
strncmp
(
orig
->
src
,
"overlayfs:"
,
10
)
!=
0
)
return
-
22
;
upper
=
strchr
(
orig
->
src
+
10
,
':'
);
if
(
!
upper
)
return
-
22
;
upper
++
;
return
lxc_rmdir_onedev
(
upper
,
NULL
);
}
/*
* to say 'lxc-create -t ubuntu -n o1 -B overlayfs' means you want
* $lxcpath/$lxcname/rootfs to have the created container, while all
* changes after starting the container are written to
* $lxcpath/$lxcname/delta0
*/
static
int
overlayfs_create
(
struct
bdev
*
bdev
,
const
char
*
dest
,
const
char
*
n
,
struct
bdev_specs
*
specs
)
{
char
*
delta
;
int
ret
,
len
=
strlen
(
dest
),
newlen
;
if
(
len
<
8
||
strcmp
(
dest
+
len
-
7
,
"/rootfs"
)
!=
0
)
return
-
1
;
if
(
!
(
bdev
->
dest
=
strdup
(
dest
)))
{
ERROR
(
"Out of memory"
);
return
-
1
;
}
delta
=
alloca
(
strlen
(
dest
)
+
1
);
strcpy
(
delta
,
dest
);
strcpy
(
delta
+
len
-
6
,
"delta0"
);
if
(
mkdir_p
(
delta
,
0755
)
<
0
)
{
ERROR
(
"Error creating %s"
,
delta
);
return
-
1
;
}
/* overlayfs:lower:upper */
newlen
=
(
2
*
len
)
+
strlen
(
"overlayfs:"
)
+
2
;
bdev
->
src
=
malloc
(
newlen
);
if
(
!
bdev
->
src
)
{
ERROR
(
"Out of memory"
);
return
-
1
;
}
ret
=
snprintf
(
bdev
->
src
,
newlen
,
"overlayfs:%s:%s"
,
dest
,
delta
);
if
(
ret
<
0
||
ret
>=
newlen
)
return
-
1
;
if
(
mkdir_p
(
bdev
->
dest
,
0755
)
<
0
)
{
ERROR
(
"Error creating %s"
,
bdev
->
dest
);
return
-
1
;
}
return
0
;
}
static
const
struct
bdev_ops
overlayfs_ops
=
{
.
detect
=
&
overlayfs_detect
,
.
mount
=
&
overlayfs_mount
,
.
umount
=
&
overlayfs_umount
,
.
clone_paths
=
&
overlayfs_clonepaths
,
.
destroy
=
&
overlayfs_destroy
,
.
create
=
&
overlayfs_create
,
.
can_snapshot
=
true
,
.
can_snapshot
=
true
,
.
can_backup
=
true
,
.
can_backup
=
true
,
};
};
...
@@ -3403,7 +2963,7 @@ static const struct bdev_type bdevs[] = {
...
@@ -3403,7 +2963,7 @@ static const struct bdev_type bdevs[] = {
{.
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
=
&
ov
erlayfs
_ops
,},
{.
name
=
"overlayfs"
,
.
ops
=
&
ov
l
_ops
,},
{.
name
=
"loop"
,
.
ops
=
&
loop_ops
,},
{.
name
=
"loop"
,
.
ops
=
&
loop_ops
,},
{.
name
=
"nbd"
,
.
ops
=
&
nbd_ops
,},
{.
name
=
"nbd"
,
.
ops
=
&
nbd_ops
,},
};
};
...
@@ -3818,14 +3378,6 @@ struct bdev *bdev_create(const char *dest, const char *type,
...
@@ -3818,14 +3378,6 @@ struct bdev *bdev_create(const char *dest, const char *type,
return
do_bdev_create
(
dest
,
type
,
cname
,
specs
);
return
do_bdev_create
(
dest
,
type
,
cname
,
specs
);
}
}
char
*
overlay_getlower
(
char
*
p
)
{
char
*
p1
=
strchr
(
p
,
':'
);
if
(
p1
)
*
p1
=
'\0'
;
return
p
;
}
bool
rootfs_is_blockdev
(
struct
lxc_conf
*
conf
)
bool
rootfs_is_blockdev
(
struct
lxc_conf
*
conf
)
{
{
const
struct
bdev_type
*
q
;
const
struct
bdev_type
*
q
;
...
...
src/lxc/bdev.h
→
src/lxc/bdev
/bdev
.h
View file @
a14bf84f
...
@@ -27,11 +27,11 @@
...
@@ -27,11 +27,11 @@
* aufs, dir, raw, btrfs, overlayfs, aufs, lvm, loop, zfs, nbd (qcow2, raw, vdi, qed)
* aufs, dir, raw, btrfs, overlayfs, aufs, lvm, loop, zfs, nbd (qcow2, raw, vdi, qed)
*/
*/
#include "config.h"
#include <stdint.h>
#include <stdint.h>
#include <lxc/lxccontainer.h>
#include <lxc/lxccontainer.h>
#include <sys/mount.h>
#include <sys/mount.h>
#include "config.h"
/* define constants if the kernel/glibc headers don't define them */
/* define constants if the kernel/glibc headers don't define them */
#ifndef MS_DIRSYNC
#ifndef MS_DIRSYNC
...
@@ -97,8 +97,6 @@ struct bdev {
...
@@ -97,8 +97,6 @@ struct bdev {
int
nbd_idx
;
int
nbd_idx
;
};
};
char
*
overlay_getlower
(
char
*
p
);
bool
bdev_is_dir
(
struct
lxc_conf
*
conf
,
const
char
*
path
);
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
);
...
...
src/lxc/lxc-btrfs.h
→
src/lxc/
bdev/
lxc-btrfs.h
View file @
a14bf84f
File moved
src/lxc/bdev/overlay.c
0 → 100644
View file @
a14bf84f
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <daniel.lezcano at free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bdev.h"
#include "conf.h"
#include "confile.h"
#include "log.h"
#include "lxccontainer.h"
#include "overlay.h"
#include "utils.h"
lxc_log_define
(
overlay
,
lxc
);
static
char
*
ovl_name
;
struct
ovl_rsync_data
{
struct
bdev
*
orig
;
struct
bdev
*
new
;
};
/* defined in lxccontainer.c: needs to become common helper */
extern
int
do_rsync
(
const
char
*
src
,
const
char
*
dest
);
/* defined in lxccontainer.c: needs to become common helper */
extern
char
*
dir_new_path
(
char
*
src
,
const
char
*
oldname
,
const
char
*
name
,
const
char
*
oldpath
,
const
char
*
lxcpath
);
static
char
*
ovl_detect_name
(
void
);
static
int
ovl_do_rsync
(
struct
bdev
*
orig
,
struct
bdev
*
new
,
struct
lxc_conf
*
conf
);
static
int
ovl_rsync
(
struct
ovl_rsync_data
*
data
);
static
int
ovl_rsync_wrapper
(
void
*
data
);
int
ovl_clonepaths
(
struct
bdev
*
orig
,
struct
bdev
*
new
,
const
char
*
oldname
,
const
char
*
cname
,
const
char
*
oldpath
,
const
char
*
lxcpath
,
int
snap
,
uint64_t
newsize
,
struct
lxc_conf
*
conf
)
{
if
(
!
snap
)
{
ERROR
(
"overlayfs is only for snapshot clones"
);
return
-
22
;
}
if
(
!
orig
->
src
||
!
orig
->
dest
)
return
-
1
;
new
->
dest
=
dir_new_path
(
orig
->
dest
,
oldname
,
cname
,
oldpath
,
lxcpath
);
if
(
!
new
->
dest
)
return
-
1
;
if
(
mkdir_p
(
new
->
dest
,
0755
)
<
0
)
return
-
1
;
if
(
am_unpriv
()
&&
chown_mapped_root
(
new
->
dest
,
conf
)
<
0
)
WARN
(
"Failed to update ownership of %s"
,
new
->
dest
);
if
(
strcmp
(
orig
->
type
,
"dir"
)
==
0
)
{
char
*
delta
,
*
lastslash
;
char
*
work
;
int
ret
,
len
,
lastslashidx
;
/*
* if we have
* /var/lib/lxc/c2/rootfs
* then delta will be
* /var/lib/lxc/c2/delta0
*/
lastslash
=
strrchr
(
new
->
dest
,
'/'
);
if
(
!
lastslash
)
return
-
22
;
if
(
strlen
(
lastslash
)
<
7
)
return
-
22
;
lastslash
++
;
lastslashidx
=
lastslash
-
new
->
dest
;
delta
=
malloc
(
lastslashidx
+
7
);
if
(
!
delta
)
return
-
1
;
strncpy
(
delta
,
new
->
dest
,
lastslashidx
+
1
);
strcpy
(
delta
+
lastslashidx
,
"delta0"
);
if
((
ret
=
mkdir
(
delta
,
0755
))
<
0
)
{
SYSERROR
(
"error: mkdir %s"
,
delta
);
free
(
delta
);
return
-
1
;
}
if
(
am_unpriv
()
&&
chown_mapped_root
(
delta
,
conf
)
<
0
)
WARN
(
"Failed to update ownership of %s"
,
delta
);
/*
* Make workdir for overlayfs.v22 or higher:
* The workdir will be
* /var/lib/lxc/c2/olwork
* and is used to prepare files before they are atomically
* switched to the overlay destination. Workdirs need to be on
* the same filesystem as the upperdir so it's OK for it to be
* empty.
*/
work
=
malloc
(
lastslashidx
+
7
);
if
(
!
work
)
{
free
(
delta
);
return
-
1
;
}
strncpy
(
work
,
new
->
dest
,
lastslashidx
+
1
);
strcpy
(
work
+
lastslashidx
,
"olwork"
);
if
(
mkdir
(
work
,
0755
)
<
0
)
{
SYSERROR
(
"error: mkdir %s"
,
work
);
free
(
delta
);
free
(
work
);
return
-
1
;
}
if
(
am_unpriv
()
&&
chown_mapped_root
(
work
,
conf
)
<
0
)
WARN
(
"Failed to update ownership of %s"
,
work
);
free
(
work
);
// the src will be 'overlayfs:lowerdir:upperdir'
len
=
strlen
(
delta
)
+
strlen
(
orig
->
src
)
+
12
;
new
->
src
=
malloc
(
len
);
if
(
!
new
->
src
)
{
free
(
delta
);
return
-
ENOMEM
;
}
ret
=
snprintf
(
new
->
src
,
len
,
"overlayfs:%s:%s"
,
orig
->
src
,
delta
);
free
(
delta
);
if
(
ret
<
0
||
ret
>=
len
)
return
-
ENOMEM
;
}
else
if
(
strcmp
(
orig
->
type
,
"overlayfs"
)
==
0
)
{
/*
* What exactly do we want to do here? I think we want to use
* the original lowerdir, with a private delta which is
* originally rsynced from the original delta
*/
char
*
osrc
,
*
odelta
,
*
nsrc
,
*
ndelta
,
*
work
;
char
*
lastslash
;
int
len
,
ret
,
lastslashidx
;
if
(
!
(
osrc
=
strdup
(
orig
->
src
)))
return
-
22
;
nsrc
=
strchr
(
osrc
,
':'
)
+
1
;
if
(
nsrc
!=
osrc
+
10
||
(
odelta
=
strchr
(
nsrc
,
':'
))
==
NULL
)
{
free
(
osrc
);
return
-
22
;
}
*
odelta
=
'\0'
;
odelta
++
;
ndelta
=
dir_new_path
(
odelta
,
oldname
,
cname
,
oldpath
,
lxcpath
);
if
(
!
ndelta
)
{
free
(
osrc
);
return
-
ENOMEM
;
}
if
((
ret
=
mkdir
(
ndelta
,
0755
))
<
0
&&
errno
!=
EEXIST
)
{
SYSERROR
(
"error: mkdir %s"
,
ndelta
);
free
(
osrc
);
free
(
ndelta
);
return
-
1
;
}
if
(
am_unpriv
()
&&
chown_mapped_root
(
ndelta
,
conf
)
<
0
)
WARN
(
"Failed to update ownership of %s"
,
ndelta
);
/*
* make workdir for overlayfs.v22 or higher (see comment further
* up)
*/
lastslash
=
strrchr
(
ndelta
,
'/'
);
if
(
!
lastslash
)
return
-
1
;
lastslash
++
;
lastslashidx
=
lastslash
-
ndelta
;
work
=
malloc
(
lastslashidx
+
7
);
if
(
!
work
)
return
-
1
;
strncpy
(
work
,
ndelta
,
lastslashidx
+
1
);
strcpy
(
work
+
lastslashidx
,
"olwork"
);
if
((
mkdir
(
work
,
0755
)
<
0
)
&&
errno
!=
EEXIST
)
{
SYSERROR
(
"error: mkdir %s"
,
work
);
free
(
work
);
return
-
1
;
}
if
(
am_unpriv
()
&&
chown_mapped_root
(
work
,
conf
)
<
0
)
WARN
(
"Failed to update ownership of %s"
,
work
);
free
(
work
);
len
=
strlen
(
nsrc
)
+
strlen
(
ndelta
)
+
12
;
new
->
src
=
malloc
(
len
);
if
(
!
new
->
src
)
{
free
(
osrc
);
free
(
ndelta
);
return
-
ENOMEM
;
}
ret
=
snprintf
(
new
->
src
,
len
,
"overlayfs:%s:%s"
,
nsrc
,
ndelta
);
free
(
osrc
);
free
(
ndelta
);
if
(
ret
<
0
||
ret
>=
len
)
return
-
ENOMEM
;
return
ovl_do_rsync
(
orig
,
new
,
conf
);
}
else
{
ERROR
(
"overlayfs clone of %s container is not yet supported"
,
orig
->
type
);
/*
* Note, supporting this will require ovl_mount supporting
* mounting of the underlay. No big deal, just needs to be done.
*/
return
-
1
;
}
return
0
;
}
/*
* to say 'lxc-create -t ubuntu -n o1 -B overlayfs' means you want
* $lxcpath/$lxcname/rootfs to have the created container, while all
* changes after starting the container are written to
* $lxcpath/$lxcname/delta0
*/
int
ovl_create
(
struct
bdev
*
bdev
,
const
char
*
dest
,
const
char
*
n
,
struct
bdev_specs
*
specs
)
{
char
*
delta
;
int
ret
,
len
=
strlen
(
dest
),
newlen
;
if
(
len
<
8
||
strcmp
(
dest
+
len
-
7
,
"/rootfs"
)
!=
0
)
return
-
1
;
if
(
!
(
bdev
->
dest
=
strdup
(
dest
)))
{
ERROR
(
"Out of memory"
);
return
-
1
;
}
delta
=
alloca
(
strlen
(
dest
)
+
1
);
strcpy
(
delta
,
dest
);
strcpy
(
delta
+
len
-
6
,
"delta0"
);
if
(
mkdir_p
(
delta
,
0755
)
<
0
)
{
ERROR
(
"Error creating %s"
,
delta
);
return
-
1
;
}
// overlayfs:lower:upper
newlen
=
(
2
*
len
)
+
strlen
(
"overlayfs:"
)
+
2
;
bdev
->
src
=
malloc
(
newlen
);
if
(
!
bdev
->
src
)
{
ERROR
(
"Out of memory"
);
return
-
1
;
}
ret
=
snprintf
(
bdev
->
src
,
newlen
,
"overlayfs:%s:%s"
,
dest
,
delta
);
if
(
ret
<
0
||
ret
>=
newlen
)
return
-
1
;
if
(
mkdir_p
(
bdev
->
dest
,
0755
)
<
0
)
{
ERROR
(
"Error creating %s"
,
bdev
->
dest
);
return
-
1
;
}
return
0
;
}
int
ovl_destroy
(
struct
bdev
*
orig
)
{
char
*
upper
;
if
(
strncmp
(
orig
->
src
,
"overlayfs:"
,
10
)
!=
0
)
return
-
22
;
upper
=
strchr
(
orig
->
src
+
10
,
':'
);
if
(
!
upper
)
return
-
22
;
upper
++
;
return
lxc_rmdir_onedev
(
upper
,
NULL
);
}
int
ovl_detect
(
const
char
*
path
)
{
if
(
strncmp
(
path
,
"overlayfs:"
,
10
)
==
0
)
return
1
;
// take their word for it
return
0
;
}
char
*
ovl_getlower
(
char
*
p
)
{
char
*
p1
=
strchr
(
p
,
':'
);
if
(
p1
)
*
p1
=
'\0'
;
return
p
;
}
int
ovl_mount
(
struct
bdev
*
bdev
)
{
char
*
options
,
*
dup
,
*
lower
,
*
upper
;
char
*
options_work
,
*
work
,
*
lastslash
;
int
lastslashidx
;
int
len
,
len2
;
unsigned
long
mntflags
;
char
*
mntdata
;
int
ret
,
ret2
;
if
(
strcmp
(
bdev
->
type
,
"overlayfs"
))
return
-
22
;
if
(
!
bdev
->
src
||
!
bdev
->
dest
)
return
-
22
;
if
(
!
ovl_name
)
ovl_name
=
ovl_detect_name
();
/*
* separately mount it first:
* mount -t overlayfs * -oupperdir=${upper},lowerdir=${lower} lower dest
*/
dup
=
alloca
(
strlen
(
bdev
->
src
)
+
1
);
strcpy
(
dup
,
bdev
->
src
);
if
(
!
(
lower
=
strchr
(
dup
,
':'
)))
return
-
22
;
if
(
!
(
upper
=
strchr
(
++
lower
,
':'
)))
return
-
22
;
*
upper
=
'\0'
;
upper
++
;
// if delta doesn't yet exist, create it
if
(
mkdir_p
(
upper
,
0755
)
<
0
&&
errno
!=
EEXIST
)
return
-
22
;
/*
* overlayfs.v22 or higher needs workdir option:
* if upper is
* /var/lib/lxc/c2/delta0
* then workdir is
* /var/lib/lxc/c2/olwork
*/
lastslash
=
strrchr
(
upper
,
'/'
);
if
(
!
lastslash
)
return
-
22
;
lastslash
++
;
lastslashidx
=
lastslash
-
upper
;
work
=
alloca
(
lastslashidx
+
7
);
strncpy
(
work
,
upper
,
lastslashidx
+
7
);
strcpy
(
work
+
lastslashidx
,
"olwork"
);
if
(
parse_mntopts
(
bdev
->
mntopts
,
&
mntflags
,
&
mntdata
)
<
0
)
{
free
(
mntdata
);
return
-
22
;
}
if
(
mkdir_p
(
work
,
0755
)
<
0
&&
errno
!=
EEXIST
)
{
free
(
mntdata
);
return
-
22
;
}
/*
* TODO:
* We should check whether bdev->src is a blockdev but for now only
* support overlays of a basic directory
*/
if
(
mntdata
)
{
len
=
strlen
(
lower
)
+
strlen
(
upper
)
+
strlen
(
"upperdir=,lowerdir=,"
)
+
strlen
(
mntdata
)
+
1
;
options
=
alloca
(
len
);
ret
=
snprintf
(
options
,
len
,
"upperdir=%s,lowerdir=%s,%s"
,
upper
,
lower
,
mntdata
);
len2
=
strlen
(
lower
)
+
strlen
(
upper
)
+
strlen
(
work
)
+
strlen
(
"upperdir=,lowerdir=,workdir="
)
+
strlen
(
mntdata
)
+
1
;
options_work
=
alloca
(
len2
);
ret2
=
snprintf
(
options
,
len2
,
"upperdir=%s,lowerdir=%s,workdir=%s,%s"
,
upper
,
lower
,
work
,
mntdata
);
}
else
{
len
=
strlen
(
lower
)
+
strlen
(
upper
)
+
strlen
(
"upperdir=,lowerdir="
)
+
1
;
options
=
alloca
(
len
);
ret
=
snprintf
(
options
,
len
,
"upperdir=%s,lowerdir=%s"
,
upper
,
lower
);
len2
=
strlen
(
lower
)
+
strlen
(
upper
)
+
strlen
(
work
)
+
strlen
(
"upperdir=,lowerdir=,workdir="
)
+
1
;
options_work
=
alloca
(
len2
);
ret2
=
snprintf
(
options_work
,
len2
,
"upperdir=%s,lowerdir=%s,workdir=%s"
,
upper
,
lower
,
work
);
}
if
(
ret
<
0
||
ret
>=
len
||
ret2
<
0
||
ret2
>=
len2
)
{
free
(
mntdata
);
return
-
1
;
}
// mount without workdir option for overlayfs before v21
ret
=
mount
(
lower
,
bdev
->
dest
,
ovl_name
,
MS_MGC_VAL
|
mntflags
,
options
);
if
(
ret
<
0
)
{
INFO
(
"overlayfs: error mounting %s onto %s options %s. retry with workdir"
,
lower
,
bdev
->
dest
,
options
);
// retry with workdir option for overlayfs v22 and higher
ret
=
mount
(
lower
,
bdev
->
dest
,
ovl_name
,
MS_MGC_VAL
|
mntflags
,
options_work
);
if
(
ret
<
0
)
SYSERROR
(
"overlayfs: error mounting %s onto %s options %s"
,
lower
,
bdev
->
dest
,
options_work
);
else
INFO
(
"overlayfs: mounted %s onto %s options %s"
,
lower
,
bdev
->
dest
,
options_work
);
}
else
{
INFO
(
"overlayfs: mounted %s onto %s options %s"
,
lower
,
bdev
->
dest
,
options
);
}
return
ret
;
}
int
ovl_umount
(
struct
bdev
*
bdev
)
{
if
(
strcmp
(
bdev
->
type
,
"overlayfs"
))
return
-
22
;
if
(
!
bdev
->
src
||
!
bdev
->
dest
)
return
-
22
;
return
umount
(
bdev
->
dest
);
}
char
*
ovl_get_rootfs
(
const
char
*
rootfs_path
,
size_t
*
rootfslen
)
{
char
*
rootfsdir
=
NULL
;
char
*
s1
=
NULL
;
char
*
s2
=
NULL
;
char
*
s3
=
NULL
;
if
(
!
rootfs_path
||
!
rootfslen
)
return
NULL
;
s1
=
strdup
(
rootfs_path
);
if
(
!
s1
)
return
NULL
;
if
((
s2
=
strstr
(
s1
,
":/"
)))
{
s2
=
s2
+
1
;
if
((
s3
=
strstr
(
s2
,
":/"
)))
*
s3
=
'\0'
;
rootfsdir
=
strdup
(
s2
);
if
(
!
rootfsdir
)
{
free
(
s1
);
return
NULL
;
}
}
if
(
!
rootfsdir
)
rootfsdir
=
s1
;
else
free
(
s1
);
*
rootfslen
=
strlen
(
rootfsdir
);
return
rootfsdir
;
}
int
ovl_mkdir
(
const
struct
mntent
*
mntent
,
const
struct
lxc_rootfs
*
rootfs
,
const
char
*
lxc_name
,
const
char
*
lxc_path
)
{
char
lxcpath
[
MAXPATHLEN
];
char
*
rootfsdir
=
NULL
;
char
*
upperdir
=
NULL
;
char
*
workdir
=
NULL
;
char
**
opts
=
NULL
;
int
fret
=
-
1
;
int
ret
=
0
;
size_t
arrlen
=
0
;
size_t
dirlen
=
0
;
size_t
i
;
size_t
len
=
0
;
size_t
rootfslen
=
0
;
if
(
!
rootfs
->
path
||
!
lxc_name
||
!
lxc_path
)
goto
err
;
opts
=
lxc_string_split
(
mntent
->
mnt_opts
,
','
);
if
(
opts
)
arrlen
=
lxc_array_len
((
void
**
)
opts
);
else
goto
err
;
for
(
i
=
0
;
i
<
arrlen
;
i
++
)
{
if
(
strstr
(
opts
[
i
],
"upperdir="
)
&&
(
strlen
(
opts
[
i
])
>
(
len
=
strlen
(
"upperdir="
))))
upperdir
=
opts
[
i
]
+
len
;
else
if
(
strstr
(
opts
[
i
],
"workdir="
)
&&
(
strlen
(
opts
[
i
])
>
(
len
=
strlen
(
"workdir="
))))
workdir
=
opts
[
i
]
+
len
;
}
ret
=
snprintf
(
lxcpath
,
MAXPATHLEN
,
"%s/%s"
,
lxc_path
,
lxc_name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
goto
err
;
rootfsdir
=
ovl_get_rootfs
(
rootfs
->
path
,
&
rootfslen
);
if
(
!
rootfsdir
)
goto
err
;
dirlen
=
strlen
(
lxcpath
);
/*
* We neither allow users to create upperdirs and workdirs outside the
* containerdir nor inside the rootfs. The latter might be debatable.
*/
if
(
upperdir
)
if
((
strncmp
(
upperdir
,
lxcpath
,
dirlen
)
==
0
)
&&
(
strncmp
(
upperdir
,
rootfsdir
,
rootfslen
)
!=
0
))
if
(
mkdir_p
(
upperdir
,
0755
)
<
0
)
{
WARN
(
"Failed to create upperdir"
);
}
if
(
workdir
)
if
((
strncmp
(
workdir
,
lxcpath
,
dirlen
)
==
0
)
&&
(
strncmp
(
workdir
,
rootfsdir
,
rootfslen
)
!=
0
))
if
(
mkdir_p
(
workdir
,
0755
)
<
0
)
{
WARN
(
"Failed to create workdir"
);
}
fret
=
0
;
err:
free
(
rootfsdir
);
lxc_free_array
((
void
**
)
opts
,
free
);
return
fret
;
}
/*
* To be called from lxcapi_clone() in lxccontainer.c: When we clone a container
* with overlay lxc.mount.entry entries we need to update absolute paths for
* upper- and workdir. This update is done in two locations:
* lxc_conf->unexpanded_config and lxc_conf->mount_list. Both updates are done
* independent of each other since lxc_conf->mountlist may container more mount
* entries (e.g. from other included files) than lxc_conf->unexpanded_config .
*/
int
ovl_update_abs_paths
(
struct
lxc_conf
*
lxc_conf
,
const
char
*
lxc_path
,
const
char
*
lxc_name
,
const
char
*
newpath
,
const
char
*
newname
)
{
char
new_upper
[
MAXPATHLEN
];
char
new_work
[
MAXPATHLEN
];
char
old_upper
[
MAXPATHLEN
];
char
old_work
[
MAXPATHLEN
];
char
*
cleanpath
=
NULL
;
int
i
;
int
fret
=
-
1
;
int
ret
=
0
;
struct
lxc_list
*
iterator
;
const
char
*
ovl_dirs
[]
=
{
"br"
,
"upperdir"
,
"workdir"
};
cleanpath
=
strdup
(
newpath
);
if
(
!
cleanpath
)
goto
err
;
remove_trailing_slashes
(
cleanpath
);
/*
* We have to update lxc_conf->unexpanded_config separately from
* lxc_conf->mount_list.
*/
for
(
i
=
0
;
i
<
sizeof
(
ovl_dirs
)
/
sizeof
(
ovl_dirs
[
0
]);
i
++
)
{
if
(
!
clone_update_unexp_ovl_paths
(
lxc_conf
,
lxc_path
,
newpath
,
lxc_name
,
newname
,
ovl_dirs
[
i
]))
goto
err
;
}
ret
=
snprintf
(
old_work
,
MAXPATHLEN
,
"workdir=%s/%s"
,
lxc_path
,
lxc_name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
goto
err
;
ret
=
snprintf
(
new_work
,
MAXPATHLEN
,
"workdir=%s/%s"
,
cleanpath
,
newname
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
goto
err
;
lxc_list_for_each
(
iterator
,
&
lxc_conf
->
mount_list
)
{
char
*
mnt_entry
=
NULL
;
char
*
new_mnt_entry
=
NULL
;
char
*
tmp
=
NULL
;
char
*
tmp_mnt_entry
=
NULL
;
mnt_entry
=
iterator
->
elem
;
if
(
strstr
(
mnt_entry
,
"overlay"
))
tmp
=
"upperdir"
;
else
if
(
strstr
(
mnt_entry
,
"aufs"
))
tmp
=
"br"
;
if
(
!
tmp
)
continue
;
ret
=
snprintf
(
old_upper
,
MAXPATHLEN
,
"%s=%s/%s"
,
tmp
,
lxc_path
,
lxc_name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
goto
err
;
ret
=
snprintf
(
new_upper
,
MAXPATHLEN
,
"%s=%s/%s"
,
tmp
,
cleanpath
,
newname
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
goto
err
;
if
(
strstr
(
mnt_entry
,
old_upper
))
{
tmp_mnt_entry
=
lxc_string_replace
(
old_upper
,
new_upper
,
mnt_entry
);
}
if
(
strstr
(
mnt_entry
,
old_work
))
{
if
(
tmp_mnt_entry
)
new_mnt_entry
=
lxc_string_replace
(
old_work
,
new_work
,
tmp_mnt_entry
);
else
new_mnt_entry
=
lxc_string_replace
(
old_work
,
new_work
,
mnt_entry
);
}
if
(
new_mnt_entry
)
{
free
(
iterator
->
elem
);
iterator
->
elem
=
strdup
(
new_mnt_entry
);
}
else
if
(
tmp_mnt_entry
)
{
free
(
iterator
->
elem
);
iterator
->
elem
=
strdup
(
tmp_mnt_entry
);
}
free
(
new_mnt_entry
);
free
(
tmp_mnt_entry
);
}
fret
=
0
;
err:
free
(
cleanpath
);
return
fret
;
}
static
int
ovl_rsync
(
struct
ovl_rsync_data
*
data
)
{
int
ret
;
if
(
setgid
(
0
)
<
0
)
{
ERROR
(
"Failed to setgid to 0"
);
return
-
1
;
}
if
(
setgroups
(
0
,
NULL
)
<
0
)
WARN
(
"Failed to clear groups"
);
if
(
setuid
(
0
)
<
0
)
{
ERROR
(
"Failed to setuid to 0"
);
return
-
1
;
}
if
(
unshare
(
CLONE_NEWNS
)
<
0
)
{
SYSERROR
(
"Unable to unshare mounts ns"
);
return
-
1
;
}
if
(
detect_shared_rootfs
())
{
if
(
mount
(
NULL
,
"/"
,
NULL
,
MS_SLAVE
|
MS_REC
,
NULL
))
{
SYSERROR
(
"Failed to make / rslave"
);
ERROR
(
"Continuing..."
);
}
}
if
(
ovl_mount
(
data
->
orig
)
<
0
)
{
ERROR
(
"Failed mounting original container fs"
);
return
-
1
;
}
if
(
ovl_mount
(
data
->
new
)
<
0
)
{
ERROR
(
"Failed mounting new container fs"
);
return
-
1
;
}
ret
=
do_rsync
(
data
->
orig
->
dest
,
data
->
new
->
dest
);
ovl_umount
(
data
->
new
);
ovl_umount
(
data
->
orig
);
if
(
ret
<
0
)
{
ERROR
(
"rsyncing %s to %s"
,
data
->
orig
->
dest
,
data
->
new
->
dest
);
return
-
1
;
}
return
0
;
}
static
char
*
ovl_detect_name
(
void
)
{
char
*
v
=
"overlayfs"
;
char
*
line
=
NULL
;
size_t
len
=
0
;
FILE
*
f
=
fopen
(
"/proc/filesystems"
,
"r"
);
if
(
!
f
)
return
v
;
while
(
getline
(
&
line
,
&
len
,
f
)
!=
-
1
)
{
if
(
strcmp
(
line
,
"nodev
\t
overlay
\n
"
)
==
0
)
{
v
=
"overlay"
;
break
;
}
}
fclose
(
f
);
free
(
line
);
return
v
;
}
static
int
ovl_do_rsync
(
struct
bdev
*
orig
,
struct
bdev
*
new
,
struct
lxc_conf
*
conf
)
{
int
ret
=
-
1
;
struct
ovl_rsync_data
rdata
;
rdata
.
orig
=
orig
;
rdata
.
new
=
new
;
if
(
am_unpriv
())
ret
=
userns_exec_1
(
conf
,
ovl_rsync_wrapper
,
&
rdata
);
else
ret
=
ovl_rsync
(
&
rdata
);
if
(
ret
)
ERROR
(
"copying overlayfs delta"
);
return
ret
;
}
static
int
ovl_rsync_wrapper
(
void
*
data
)
{
struct
ovl_rsync_data
*
arg
=
data
;
return
ovl_rsync
(
arg
);
}
src/lxc/bdev/overlay.h
0 → 100644
View file @
a14bf84f
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <daniel.lezcano at free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __LXC_OVERLAY_H
#define __LXC_OVERLAY_H
#include <grp.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#if IS_BIONIC
#include <../include/lxcmntent.h>
#else
#include <mntent.h>
#endif
/* defined in bdev.h */
struct
bdev
;
/* defined in lxccontainer.h */
struct
bdev_specs
;
/* defined conf.h */
struct
lxc_conf
;
/* defined in conf.h */
struct
lxc_rootfs
;
/*
* Functions associated with an overlay bdev struct.
*/
int
ovl_clonepaths
(
struct
bdev
*
orig
,
struct
bdev
*
new
,
const
char
*
oldname
,
const
char
*
cname
,
const
char
*
oldpath
,
const
char
*
lxcpath
,
int
snap
,
uint64_t
newsize
,
struct
lxc_conf
*
conf
);
int
ovl_create
(
struct
bdev
*
bdev
,
const
char
*
dest
,
const
char
*
n
,
struct
bdev_specs
*
specs
);
int
ovl_destroy
(
struct
bdev
*
orig
);
int
ovl_detect
(
const
char
*
path
);
int
ovl_mount
(
struct
bdev
*
bdev
);
int
ovl_umount
(
struct
bdev
*
bdev
);
/*
* To be called from lxcapi_clone() in lxccontainer.c: When we clone a container
* with overlay lxc.mount.entry entries we need to update absolute paths for
* upper- and workdir. This update is done in two locations:
* lxc_conf->unexpanded_config and lxc_conf->mount_list. Both updates are done
* independent of each other since lxc_conf->mountlist may container more mount
* entries (e.g. from other included files) than lxc_conf->unexpanded_config .
*/
int
ovl_update_abs_paths
(
struct
lxc_conf
*
lxc_conf
,
const
char
*
lxc_path
,
const
char
*
lxc_name
,
const
char
*
newpath
,
const
char
*
newname
);
/*
* To be called from functions in lxccontainer.c: Get lower directory for
* overlay rootfs.
*/
char
*
ovl_getlower
(
char
*
p
);
/*
* Get rootfs path for overlay backed containers. Allocated memory must be freed
* by caller.
*/
char
*
ovl_get_rootfs
(
const
char
*
rootfs_path
,
size_t
*
rootfslen
);
/*
* Create upper- and workdirs for overlay mounts.
*/
int
ovl_mkdir
(
const
struct
mntent
*
mntent
,
const
struct
lxc_rootfs
*
rootfs
,
const
char
*
lxc_name
,
const
char
*
lxc_path
);
#endif
/* __LXC_OVERLAY_H */
src/lxc/cgfs.c
View file @
a14bf84f
...
@@ -43,7 +43,7 @@
...
@@ -43,7 +43,7 @@
#include "list.h"
#include "list.h"
#include "conf.h"
#include "conf.h"
#include "utils.h"
#include "utils.h"
#include "bdev.h"
#include "bdev
/bdev
.h"
#include "log.h"
#include "log.h"
#include "cgroup.h"
#include "cgroup.h"
#include "start.h"
#include "start.h"
...
...
src/lxc/cgmanager.c
View file @
a14bf84f
...
@@ -46,7 +46,7 @@
...
@@ -46,7 +46,7 @@
#include "list.h"
#include "list.h"
#include "conf.h"
#include "conf.h"
#include "utils.h"
#include "utils.h"
#include "bdev.h"
#include "bdev
/bdev
.h"
#include "log.h"
#include "log.h"
#include "cgroup.h"
#include "cgroup.h"
#include "start.h"
#include "start.h"
...
...
src/lxc/conf.c
View file @
a14bf84f
...
@@ -71,7 +71,8 @@
...
@@ -71,7 +71,8 @@
#include "conf.h"
#include "conf.h"
#include "log.h"
#include "log.h"
#include "caps.h"
/* for lxc_caps_last_cap() */
#include "caps.h"
/* for lxc_caps_last_cap() */
#include "bdev.h"
#include "bdev/bdev.h"
#include "bdev/overlay.h"
#include "cgroup.h"
#include "cgroup.h"
#include "lxclock.h"
#include "lxclock.h"
#include "namespace.h"
#include "namespace.h"
...
@@ -1815,107 +1816,6 @@ static void cull_mntent_opt(struct mntent *mntent)
...
@@ -1815,107 +1816,6 @@ static void cull_mntent_opt(struct mntent *mntent)
}
}
}
}
static
char
*
ovl_get_rootfs_dir
(
const
char
*
rootfs_path
,
size_t
*
rootfslen
)
{
char
*
rootfsdir
=
NULL
;
char
*
s1
=
NULL
;
char
*
s2
=
NULL
;
char
*
s3
=
NULL
;
if
(
!
rootfs_path
||
!
rootfslen
)
return
NULL
;
s1
=
strdup
(
rootfs_path
);
if
(
!
s1
)
return
NULL
;
if
((
s2
=
strstr
(
s1
,
":/"
)))
{
s2
=
s2
+
1
;
if
((
s3
=
strstr
(
s2
,
":/"
)))
*
s3
=
'\0'
;
rootfsdir
=
strdup
(
s2
);
if
(
!
rootfsdir
)
{
free
(
s1
);
return
NULL
;
}
}
if
(
!
rootfsdir
)
rootfsdir
=
s1
;
else
free
(
s1
);
*
rootfslen
=
strlen
(
rootfsdir
);
return
rootfsdir
;
}
static
int
mount_entry_create_overlay_dirs
(
const
struct
mntent
*
mntent
,
const
struct
lxc_rootfs
*
rootfs
,
const
char
*
lxc_name
,
const
char
*
lxc_path
)
{
char
lxcpath
[
MAXPATHLEN
];
char
*
rootfsdir
=
NULL
;
char
*
upperdir
=
NULL
;
char
*
workdir
=
NULL
;
char
**
opts
=
NULL
;
int
fret
=
-
1
;
int
ret
=
0
;
size_t
arrlen
=
0
;
size_t
dirlen
=
0
;
size_t
i
;
size_t
len
=
0
;
size_t
rootfslen
=
0
;
if
(
!
rootfs
->
path
||
!
lxc_name
||
!
lxc_path
)
goto
err
;
opts
=
lxc_string_split
(
mntent
->
mnt_opts
,
','
);
if
(
opts
)
arrlen
=
lxc_array_len
((
void
**
)
opts
);
else
goto
err
;
for
(
i
=
0
;
i
<
arrlen
;
i
++
)
{
if
(
strstr
(
opts
[
i
],
"upperdir="
)
&&
(
strlen
(
opts
[
i
])
>
(
len
=
strlen
(
"upperdir="
))))
upperdir
=
opts
[
i
]
+
len
;
else
if
(
strstr
(
opts
[
i
],
"workdir="
)
&&
(
strlen
(
opts
[
i
])
>
(
len
=
strlen
(
"workdir="
))))
workdir
=
opts
[
i
]
+
len
;
}
ret
=
snprintf
(
lxcpath
,
MAXPATHLEN
,
"%s/%s"
,
lxc_path
,
lxc_name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
goto
err
;
rootfsdir
=
ovl_get_rootfs_dir
(
rootfs
->
path
,
&
rootfslen
);
if
(
!
rootfsdir
)
goto
err
;
dirlen
=
strlen
(
lxcpath
);
/* We neither allow users to create upperdirs and workdirs outside the
* containerdir nor inside the rootfs. The latter might be debatable. */
if
(
upperdir
)
if
((
strncmp
(
upperdir
,
lxcpath
,
dirlen
)
==
0
)
&&
(
strncmp
(
upperdir
,
rootfsdir
,
rootfslen
)
!=
0
))
if
(
mkdir_p
(
upperdir
,
0755
)
<
0
)
{
WARN
(
"Failed to create upperdir"
);
}
if
(
workdir
)
if
((
strncmp
(
workdir
,
lxcpath
,
dirlen
)
==
0
)
&&
(
strncmp
(
workdir
,
rootfsdir
,
rootfslen
)
!=
0
))
if
(
mkdir_p
(
workdir
,
0755
)
<
0
)
{
WARN
(
"Failed to create workdir"
);
}
fret
=
0
;
err:
free
(
rootfsdir
);
lxc_free_array
((
void
**
)
opts
,
free
);
return
fret
;
}
static
int
mount_entry_create_aufs_dirs
(
const
struct
mntent
*
mntent
,
static
int
mount_entry_create_aufs_dirs
(
const
struct
mntent
*
mntent
,
const
struct
lxc_rootfs
*
rootfs
,
const
struct
lxc_rootfs
*
rootfs
,
const
char
*
lxc_name
,
const
char
*
lxc_name
,
...
@@ -1958,7 +1858,7 @@ static int mount_entry_create_aufs_dirs(const struct mntent *mntent,
...
@@ -1958,7 +1858,7 @@ static int mount_entry_create_aufs_dirs(const struct mntent *mntent,
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
goto
err
;
goto
err
;
rootfsdir
=
ovl_get_rootfs
_dir
(
rootfs
->
path
,
&
rootfslen
);
rootfsdir
=
ovl_get_rootfs
(
rootfs
->
path
,
&
rootfslen
);
if
(
!
rootfsdir
)
if
(
!
rootfsdir
)
goto
err
;
goto
err
;
...
@@ -1987,7 +1887,7 @@ static int mount_entry_create_dir_file(const struct mntent *mntent,
...
@@ -1987,7 +1887,7 @@ static int mount_entry_create_dir_file(const struct mntent *mntent,
FILE
*
pathfile
=
NULL
;
FILE
*
pathfile
=
NULL
;
if
(
strncmp
(
mntent
->
mnt_type
,
"overlay"
,
7
)
==
0
)
{
if
(
strncmp
(
mntent
->
mnt_type
,
"overlay"
,
7
)
==
0
)
{
if
(
mount_entry_create_overlay_dirs
(
mntent
,
rootfs
,
lxc_name
,
lxc_path
)
<
0
)
if
(
ovl_mkdir
(
mntent
,
rootfs
,
lxc_name
,
lxc_path
)
<
0
)
return
-
1
;
return
-
1
;
}
else
if
(
strncmp
(
mntent
->
mnt_type
,
"aufs"
,
4
)
==
0
)
{
}
else
if
(
strncmp
(
mntent
->
mnt_type
,
"aufs"
,
4
)
==
0
)
{
if
(
mount_entry_create_aufs_dirs
(
mntent
,
rootfs
,
lxc_name
,
lxc_path
)
<
0
)
if
(
mount_entry_create_aufs_dirs
(
mntent
,
rootfs
,
lxc_name
,
lxc_path
)
<
0
)
...
...
src/lxc/criu.c
View file @
a14bf84f
...
@@ -34,7 +34,7 @@
...
@@ -34,7 +34,7 @@
#include "config.h"
#include "config.h"
#include "bdev.h"
#include "bdev
/bdev
.h"
#include "cgroup.h"
#include "cgroup.h"
#include "conf.h"
#include "conf.h"
#include "commands.h"
#include "commands.h"
...
...
src/lxc/lxc_copy.c
View file @
a14bf84f
...
@@ -44,7 +44,7 @@
...
@@ -44,7 +44,7 @@
#include "conf.h"
#include "conf.h"
#include "state.h"
#include "state.h"
#include "utils.h"
#include "utils.h"
#include "bdev.h"
#include "bdev
/bdev
.h"
#ifndef HAVE_GETSUBOPT
#ifndef HAVE_GETSUBOPT
#include <../include/getsubopt.h>
#include <../include/getsubopt.h>
...
...
src/lxc/lxc_create.c
View file @
a14bf84f
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
#include "lxc.h"
#include "lxc.h"
#include "log.h"
#include "log.h"
#include "bdev.h"
#include "bdev
/bdev
.h"
#include "arguments.h"
#include "arguments.h"
#include "utils.h"
#include "utils.h"
...
...
src/lxc/lxc_snapshot.c
View file @
a14bf84f
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
#include "lxc.h"
#include "lxc.h"
#include "log.h"
#include "log.h"
#include "bdev.h"
#include "bdev
/bdev
.h"
#include "arguments.h"
#include "arguments.h"
#include "utils.h"
#include "utils.h"
...
...
src/lxc/lxccontainer.c
View file @
a14bf84f
...
@@ -19,48 +19,46 @@
...
@@ -19,48 +19,46 @@
*/
*/
#define _GNU_SOURCE
#define _GNU_SOURCE
#include <sys/mman.h>
#include <assert.h>
#include <assert.h>
#include <stdarg.h>
#include <dirent.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include <errno.h>
#include <errno.h>
#include <fcntl.h>
#include <fcntl.h>
#include <sched.h>
#include <grp.h>
#include <dirent.h>
#include <sched.h>
#include <arpa/inet.h>
#include <libgen.h>
#include <libgen.h>
#include <pthread.h>
#include <sched.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdint.h>
#include <grp.h>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <lxc/lxccontainer.h>
#include "attach.h"
#include <lxc/version.h>
#include "bdev/bdev.h"
#include <lxc/network.h>
#include "bdev/overlay.h"
#include "cgroup.h"
#include "config.h"
#include "lxc.h"
#include "state.h"
#include "conf.h"
#include "conf.h"
#include "config.h"
#include "commands.h"
#include "confile.h"
#include "confile.h"
#include "console.h"
#include "console.h"
#include "cgroup.h"
#include "commands.h"
#include "criu.h"
#include "criu.h"
#include "log.h"
#include "log.h"
#include "
bdev
.h"
#include "
lxc
.h"
#include "
utils
.h"
#include "
lxccontainer
.h"
#include "
attach
.h"
#include "
lxclock
.h"
#include "monitor.h"
#include "monitor.h"
#include "namespace.h"
#include "namespace.h"
#include "network.h"
#include "network.h"
#include "lxclock.h"
#include "sync.h"
#include "sync.h"
#include "state.h"
#include "utils.h"
#include "version.h"
#if HAVE_IFADDRS_H
#if HAVE_IFADDRS_H
#include <ifaddrs.h>
#include <ifaddrs.h>
...
@@ -1095,9 +1093,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
...
@@ -1095,9 +1093,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
* the template
* the template
*/
*/
if
(
strncmp
(
src
,
"overlayfs:"
,
10
)
==
0
)
if
(
strncmp
(
src
,
"overlayfs:"
,
10
)
==
0
)
src
=
ov
erlay
_getlower
(
src
+
10
);
src
=
ov
l
_getlower
(
src
+
10
);
if
(
strncmp
(
src
,
"aufs:"
,
5
)
==
0
)
if
(
strncmp
(
src
,
"aufs:"
,
5
)
==
0
)
src
=
ov
erlay
_getlower
(
src
+
5
);
src
=
ov
l
_getlower
(
src
+
5
);
bdev
=
bdev_init
(
c
->
lxc_conf
,
src
,
c
->
lxc_conf
->
rootfs
.
mount
,
NULL
);
bdev
=
bdev_init
(
c
->
lxc_conf
,
src
,
c
->
lxc_conf
->
rootfs
.
mount
,
NULL
);
if
(
!
bdev
)
{
if
(
!
bdev
)
{
...
@@ -2997,102 +2995,6 @@ static int create_file_dirname(char *path, struct lxc_conf *conf)
...
@@ -2997,102 +2995,6 @@ static int create_file_dirname(char *path, struct lxc_conf *conf)
return
ret
;
return
ret
;
}
}
/* When we clone a container with overlay lxc.mount.entry entries we need to
* update absolute paths for upper- and workdir. This update is done in two
* locations: lxc_conf->unexpanded_config and lxc_conf->mount_list. Both updates
* are done independent of each other since lxc_conf->mountlist may container
* more mount entries (e.g. from other included files) than
* lxc_conf->unexpanded_config . */
static
int
update_ovl_paths
(
struct
lxc_conf
*
lxc_conf
,
const
char
*
lxc_path
,
const
char
*
lxc_name
,
const
char
*
newpath
,
const
char
*
newname
)
{
char
new_upper
[
MAXPATHLEN
];
char
new_work
[
MAXPATHLEN
];
char
old_upper
[
MAXPATHLEN
];
char
old_work
[
MAXPATHLEN
];
char
*
cleanpath
=
NULL
;
int
i
;
int
fret
=
-
1
;
int
ret
=
0
;
struct
lxc_list
*
iterator
;
const
char
*
ovl_dirs
[]
=
{
"br"
,
"upperdir"
,
"workdir"
};
cleanpath
=
strdup
(
newpath
);
if
(
!
cleanpath
)
goto
err
;
remove_trailing_slashes
(
cleanpath
);
/* We have to update lxc_conf->unexpanded_config separately from
* lxc_conf->mount_list. */
for
(
i
=
0
;
i
<
sizeof
(
ovl_dirs
)
/
sizeof
(
ovl_dirs
[
0
]);
i
++
)
{
if
(
!
clone_update_unexp_ovl_paths
(
lxc_conf
,
lxc_path
,
newpath
,
lxc_name
,
newname
,
ovl_dirs
[
i
]))
goto
err
;
}
ret
=
snprintf
(
old_work
,
MAXPATHLEN
,
"workdir=%s/%s"
,
lxc_path
,
lxc_name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
goto
err
;
ret
=
snprintf
(
new_work
,
MAXPATHLEN
,
"workdir=%s/%s"
,
cleanpath
,
newname
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
goto
err
;
lxc_list_for_each
(
iterator
,
&
lxc_conf
->
mount_list
)
{
char
*
mnt_entry
=
NULL
;
char
*
new_mnt_entry
=
NULL
;
char
*
tmp
=
NULL
;
char
*
tmp_mnt_entry
=
NULL
;
mnt_entry
=
iterator
->
elem
;
if
(
strstr
(
mnt_entry
,
"overlay"
))
tmp
=
"upperdir"
;
else
if
(
strstr
(
mnt_entry
,
"aufs"
))
tmp
=
"br"
;
if
(
!
tmp
)
continue
;
ret
=
snprintf
(
old_upper
,
MAXPATHLEN
,
"%s=%s/%s"
,
tmp
,
lxc_path
,
lxc_name
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
goto
err
;
ret
=
snprintf
(
new_upper
,
MAXPATHLEN
,
"%s=%s/%s"
,
tmp
,
cleanpath
,
newname
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
goto
err
;
if
(
strstr
(
mnt_entry
,
old_upper
))
{
tmp_mnt_entry
=
lxc_string_replace
(
old_upper
,
new_upper
,
mnt_entry
);
}
if
(
strstr
(
mnt_entry
,
old_work
))
{
if
(
tmp_mnt_entry
)
new_mnt_entry
=
lxc_string_replace
(
old_work
,
new_work
,
tmp_mnt_entry
);
else
new_mnt_entry
=
lxc_string_replace
(
old_work
,
new_work
,
mnt_entry
);
}
if
(
new_mnt_entry
)
{
free
(
iterator
->
elem
);
iterator
->
elem
=
strdup
(
new_mnt_entry
);
}
else
if
(
tmp_mnt_entry
)
{
free
(
iterator
->
elem
);
iterator
->
elem
=
strdup
(
tmp_mnt_entry
);
}
free
(
new_mnt_entry
);
free
(
tmp_mnt_entry
);
}
fret
=
0
;
err:
free
(
cleanpath
);
return
fret
;
}
static
struct
lxc_container
*
do_lxcapi_clone
(
struct
lxc_container
*
c
,
const
char
*
newname
,
static
struct
lxc_container
*
do_lxcapi_clone
(
struct
lxc_container
*
c
,
const
char
*
newname
,
const
char
*
lxcpath
,
int
flags
,
const
char
*
lxcpath
,
int
flags
,
const
char
*
bdevtype
,
const
char
*
bdevdata
,
uint64_t
newsize
,
const
char
*
bdevtype
,
const
char
*
bdevdata
,
uint64_t
newsize
,
...
@@ -3223,7 +3125,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
...
@@ -3223,7 +3125,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
}
}
// update absolute paths for overlay mount directories
// update absolute paths for overlay mount directories
if
(
update_ovl
_paths
(
c2
->
lxc_conf
,
c
->
config_path
,
c
->
name
,
lxcpath
,
newname
)
<
0
)
if
(
ovl_update_abs
_paths
(
c2
->
lxc_conf
,
c
->
config_path
,
c
->
name
,
lxcpath
,
newname
)
<
0
)
goto
out
;
goto
out
;
// We've now successfully created c2's storage, so clear it out if we
// We've now successfully created c2's storage, so clear it out if we
...
...
src/lxc/start.c
View file @
a14bf84f
...
@@ -69,7 +69,7 @@
...
@@ -69,7 +69,7 @@
#include "namespace.h"
#include "namespace.h"
#include "lxcseccomp.h"
#include "lxcseccomp.h"
#include "caps.h"
#include "caps.h"
#include "bdev.h"
#include "bdev
/bdev
.h"
#include "lsm/lsm.h"
#include "lsm/lsm.h"
#include "lxclock.h"
#include "lxclock.h"
...
...
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