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
15090139
Unverified
Commit
15090139
authored
Dec 21, 2017
by
Serge Hallyn
Committed by
GitHub
Dec 21, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2042 from brauner/2017-12-15/bugfixes
start: tweaks + bugfixes
parents
da5f5e3f
c3184275
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
250 additions
and
73 deletions
+250
-73
Makefile.am
src/lxc/Makefile.am
+2
-2
af_unix.c
src/lxc/af_unix.c
+2
-1
attach.c
src/lxc/attach.c
+1
-1
cgfs.c
src/lxc/cgroups/cgfs.c
+2
-2
cgmanager.c
src/lxc/cgroups/cgmanager.c
+10
-6
console.c
src/lxc/console.c
+1
-1
apparmor.c
src/lxc/lsm/apparmor.c
+2
-2
lxc_init.c
src/lxc/lxc_init.c
+12
-11
lxc_monitord.c
src/lxc/lxc_monitord.c
+1
-1
lxc_user_nic.c
src/lxc/lxc_user_nic.c
+9
-4
lxccontainer.c
src/lxc/lxccontainer.c
+3
-3
namespace.c
src/lxc/namespace.c
+17
-0
namespace.h
src/lxc/namespace.h
+74
-1
network.c
src/lxc/network.c
+2
-2
start.c
src/lxc/start.c
+18
-11
utils.c
src/lxc/utils.c
+1
-12
utils.h
src/lxc/utils.h
+11
-1
lxc_raw_clone.c
src/tests/lxc_raw_clone.c
+82
-12
No files found.
src/lxc/Makefile.am
View file @
15090139
...
@@ -290,7 +290,7 @@ lxc_create_SOURCES = tools/lxc_create.c tools/arguments.c
...
@@ -290,7 +290,7 @@ lxc_create_SOURCES = tools/lxc_create.c tools/arguments.c
lxc_snapshot_SOURCES
=
tools/lxc_snapshot.c tools/arguments.c
lxc_snapshot_SOURCES
=
tools/lxc_snapshot.c tools/arguments.c
lxc_usernsexec_SOURCES
=
tools/lxc_usernsexec.c tools/arguments.c
lxc_usernsexec_SOURCES
=
tools/lxc_usernsexec.c tools/arguments.c
lxc_checkpoint_SOURCES
=
tools/lxc_checkpoint.c tools/arguments.c
lxc_checkpoint_SOURCES
=
tools/lxc_checkpoint.c tools/arguments.c
lxc_user_nic_SOURCES
=
lxc_user_nic.c n
etwork.c network.h
tools/arguments.c
lxc_user_nic_SOURCES
=
lxc_user_nic.c n
amespace.c network.c
tools/arguments.c
lxc_monitord_SOURCES
=
lxc_monitord.c tools/arguments.c
lxc_monitord_SOURCES
=
lxc_monitord.c tools/arguments.c
if
ENABLE_DEPRECATED
if
ENABLE_DEPRECATED
...
@@ -304,7 +304,7 @@ endif
...
@@ -304,7 +304,7 @@ endif
if
HAVE_STATIC_LIBCAP
if
HAVE_STATIC_LIBCAP
sbin_PROGRAMS
+=
init.lxc.static
sbin_PROGRAMS
+=
init.lxc.static
init_lxc_static_SOURCES
=
lxc_init.c error.c log.c initutils.c caps.c parse.c
init_lxc_static_SOURCES
=
lxc_init.c error.c log.c initutils.c caps.c parse.c
namespace.c
if
!HAVE_GETLINE
if
!HAVE_GETLINE
if
HAVE_FGETLN
if
HAVE_FGETLN
...
...
src/lxc/af_unix.c
View file @
15090139
...
@@ -34,6 +34,7 @@
...
@@ -34,6 +34,7 @@
#include <sys/un.h>
#include <sys/un.h>
#include "log.h"
#include "log.h"
#include "utils.h"
lxc_log_define
(
lxc_af_unix
,
lxc
);
lxc_log_define
(
lxc_af_unix
,
lxc
);
...
@@ -217,7 +218,7 @@ int lxc_abstract_unix_send_credential(int fd, void *data, size_t size)
...
@@ -217,7 +218,7 @@ int lxc_abstract_unix_send_credential(int fd, void *data, size_t size)
struct
iovec
iov
;
struct
iovec
iov
;
struct
cmsghdr
*
cmsg
;
struct
cmsghdr
*
cmsg
;
struct
ucred
cred
=
{
struct
ucred
cred
=
{
.
pid
=
getpid
(),
.
uid
=
getuid
(),
.
gid
=
getgid
(),
.
pid
=
lxc_raw_
getpid
(),
.
uid
=
getuid
(),
.
gid
=
getgid
(),
};
};
char
cmsgbuf
[
CMSG_SPACE
(
sizeof
(
cred
))]
=
{
0
};
char
cmsgbuf
[
CMSG_SPACE
(
sizeof
(
cred
))]
=
{
0
};
char
buf
[
1
]
=
{
0
};
char
buf
[
1
]
=
{
0
};
...
...
src/lxc/attach.c
View file @
15090139
...
@@ -1121,7 +1121,7 @@ int lxc_attach(const char *name, const char *lxcpath,
...
@@ -1121,7 +1121,7 @@ int lxc_attach(const char *name, const char *lxcpath,
}
}
}
}
pid
=
syscall
(
SYS_getpid
);
pid
=
lxc_raw_getpid
(
);
for
(
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
{
for
(
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
{
int
j
,
saved_errno
;
int
j
,
saved_errno
;
...
...
src/lxc/cgroups/cgfs.c
View file @
15090139
...
@@ -764,7 +764,7 @@ static struct cgroup_process_info *lxc_cgroup_process_info_get_self(struct cgrou
...
@@ -764,7 +764,7 @@ static struct cgroup_process_info *lxc_cgroup_process_info_get_self(struct cgrou
struct
cgroup_process_info
*
i
;
struct
cgroup_process_info
*
i
;
i
=
lxc_cgroup_process_info_getx
(
"/proc/self/cgroup"
,
meta
);
i
=
lxc_cgroup_process_info_getx
(
"/proc/self/cgroup"
,
meta
);
if
(
!
i
)
if
(
!
i
)
i
=
lxc_cgroup_process_info_get
(
getpid
(),
meta
);
i
=
lxc_cgroup_process_info_get
(
lxc_raw_
getpid
(),
meta
);
return
i
;
return
i
;
}
}
...
@@ -2480,7 +2480,7 @@ static bool cgfs_escape(void *hdata)
...
@@ -2480,7 +2480,7 @@ static bool cgfs_escape(void *hdata)
if
(
!
f
)
if
(
!
f
)
goto
out
;
goto
out
;
written
=
fprintf
(
f
,
"%d
\n
"
,
getpid
());
written
=
fprintf
(
f
,
"%d
\n
"
,
lxc_raw_
getpid
());
fclose
(
f
);
fclose
(
f
);
if
(
written
<
0
)
{
if
(
written
<
0
)
{
SYSERROR
(
"writing tasks failed
\n
"
);
SYSERROR
(
"writing tasks failed
\n
"
);
...
...
src/lxc/cgroups/cgmanager.c
View file @
15090139
...
@@ -44,6 +44,7 @@
...
@@ -44,6 +44,7 @@
#include "error.h"
#include "error.h"
#include "commands.h"
#include "commands.h"
#include "list.h"
#include "list.h"
#include "namespace.h"
#include "conf.h"
#include "conf.h"
#include "utils.h"
#include "utils.h"
#include "log.h"
#include "log.h"
...
@@ -303,7 +304,7 @@ static bool lxc_cgmanager_create(const char *controller, const char *cgroup_path
...
@@ -303,7 +304,7 @@ static bool lxc_cgmanager_create(const char *controller, const char *cgroup_path
static
bool
cgm_escape
(
void
*
hdata
)
static
bool
cgm_escape
(
void
*
hdata
)
{
{
bool
ret
=
true
,
cgm_needs_disconnect
=
false
;
bool
ret
=
true
,
cgm_needs_disconnect
=
false
;
pid_t
me
=
getpid
();
pid_t
me
=
lxc_raw_
getpid
();
char
**
slist
=
subsystems
;
char
**
slist
=
subsystems
;
int
i
;
int
i
;
...
@@ -359,6 +360,7 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path,
...
@@ -359,6 +360,7 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path,
uid_t
newuid
)
uid_t
newuid
)
{
{
int
sv
[
2
]
=
{
-
1
,
-
1
},
optval
=
1
,
ret
=
-
1
;
int
sv
[
2
]
=
{
-
1
,
-
1
},
optval
=
1
,
ret
=
-
1
;
pid_t
pid_self
;
char
buf
[
1
];
char
buf
[
1
];
struct
pollfd
fds
;
struct
pollfd
fds
;
...
@@ -395,7 +397,9 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path,
...
@@ -395,7 +397,9 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path,
ERROR
(
"Error getting reply from server over socketpair"
);
ERROR
(
"Error getting reply from server over socketpair"
);
goto
out
;
goto
out
;
}
}
if
(
send_creds
(
sv
[
0
],
getpid
(),
getuid
(),
getgid
()))
{
pid_self
=
lxc_raw_getpid
();
if
(
send_creds
(
sv
[
0
],
pid_self
,
getuid
(),
getgid
()))
{
SYSERROR
(
"Error sending pid over SCM_CREDENTIAL"
);
SYSERROR
(
"Error sending pid over SCM_CREDENTIAL"
);
goto
out
;
goto
out
;
}
}
...
@@ -410,7 +414,7 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path,
...
@@ -410,7 +414,7 @@ static int do_chown_cgroup(const char *controller, const char *cgroup_path,
ERROR
(
"Error getting reply from server over socketpair"
);
ERROR
(
"Error getting reply from server over socketpair"
);
goto
out
;
goto
out
;
}
}
if
(
send_creds
(
sv
[
0
],
getpid
()
,
newuid
,
0
))
{
if
(
send_creds
(
sv
[
0
],
pid_self
,
newuid
,
0
))
{
SYSERROR
(
"Error sending pid over SCM_CREDENTIAL"
);
SYSERROR
(
"Error sending pid over SCM_CREDENTIAL"
);
goto
out
;
goto
out
;
}
}
...
@@ -898,7 +902,7 @@ static void do_cgm_get(const char *name, const char *lxcpath, const char *filena
...
@@ -898,7 +902,7 @@ static void do_cgm_get(const char *name, const char *lxcpath, const char *filena
exit
(
1
);
exit
(
1
);
}
}
*
cglast
=
'\0'
;
*
cglast
=
'\0'
;
if
(
!
lxc_cgmanager_enter
(
getpid
(),
controller
,
cgroup
,
abs_cgroup_supported
()))
{
if
(
!
lxc_cgmanager_enter
(
lxc_raw_
getpid
(),
controller
,
cgroup
,
abs_cgroup_supported
()))
{
WARN
(
"Failed to enter container cgroup %s:%s"
,
controller
,
cgroup
);
WARN
(
"Failed to enter container cgroup %s:%s"
,
controller
,
cgroup
);
ret
=
write
(
outp
,
&
len
,
sizeof
(
len
));
ret
=
write
(
outp
,
&
len
,
sizeof
(
len
));
if
(
ret
!=
sizeof
(
len
))
if
(
ret
!=
sizeof
(
len
))
...
@@ -1038,7 +1042,7 @@ static void do_cgm_set(const char *name, const char *lxcpath, const char *filena
...
@@ -1038,7 +1042,7 @@ static void do_cgm_set(const char *name, const char *lxcpath, const char *filena
exit
(
1
);
exit
(
1
);
}
}
*
cglast
=
'\0'
;
*
cglast
=
'\0'
;
if
(
!
lxc_cgmanager_enter
(
getpid
(),
controller
,
cgroup
,
abs_cgroup_supported
()))
{
if
(
!
lxc_cgmanager_enter
(
lxc_raw_
getpid
(),
controller
,
cgroup
,
abs_cgroup_supported
()))
{
ERROR
(
"Failed to enter container cgroup %s:%s"
,
controller
,
cgroup
);
ERROR
(
"Failed to enter container cgroup %s:%s"
,
controller
,
cgroup
);
ret
=
write
(
outp
,
&
retval
,
sizeof
(
retval
));
ret
=
write
(
outp
,
&
retval
,
sizeof
(
retval
));
if
(
ret
!=
sizeof
(
retval
))
if
(
ret
!=
sizeof
(
retval
))
...
@@ -1278,7 +1282,7 @@ static bool verify_final_subsystems(const char *cgroup_use)
...
@@ -1278,7 +1282,7 @@ static bool verify_final_subsystems(const char *cgroup_use)
}
}
cgroup_pattern
=
lxc_global_config_value
(
"lxc.cgroup.pattern"
);
cgroup_pattern
=
lxc_global_config_value
(
"lxc.cgroup.pattern"
);
i
=
snprintf
(
tmpnam
,
50
,
"lxcprobe-%d"
,
getpid
());
i
=
snprintf
(
tmpnam
,
50
,
"lxcprobe-%d"
,
lxc_raw_
getpid
());
if
(
i
<
0
||
i
>=
50
)
{
if
(
i
<
0
||
i
>=
50
)
{
ERROR
(
"Attack - format string modified?"
);
ERROR
(
"Attack - format string modified?"
);
return
false
;
return
false
;
...
...
src/lxc/console.c
View file @
15090139
...
@@ -414,7 +414,7 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd)
...
@@ -414,7 +414,7 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd)
console
->
peerpty
.
busy
=
sockfd
;
console
->
peerpty
.
busy
=
sockfd
;
lxc_console_mainloop_add_peer
(
console
);
lxc_console_mainloop_add_peer
(
console
);
DEBUG
(
"%d %s peermaster:%d sockfd:%d"
,
getpid
(),
__FUNCTION__
,
console
->
peerpty
.
master
,
sockfd
);
DEBUG
(
"%d %s peermaster:%d sockfd:%d"
,
lxc_raw_
getpid
(),
__FUNCTION__
,
console
->
peerpty
.
master
,
sockfd
);
return
0
;
return
0
;
err1
:
err1
:
...
...
src/lxc/lsm/apparmor.c
View file @
15090139
...
@@ -135,7 +135,7 @@ again:
...
@@ -135,7 +135,7 @@ again:
*/
*/
static
bool
apparmor_am_unconfined
(
void
)
static
bool
apparmor_am_unconfined
(
void
)
{
{
char
*
p
=
apparmor_process_label_get
(
getpid
());
char
*
p
=
apparmor_process_label_get
(
lxc_raw_
getpid
());
bool
ret
=
false
;
bool
ret
=
false
;
if
(
!
p
||
strcmp
(
p
,
"unconfined"
)
==
0
)
if
(
!
p
||
strcmp
(
p
,
"unconfined"
)
==
0
)
ret
=
true
;
ret
=
true
;
...
@@ -186,7 +186,7 @@ static int apparmor_process_label_set(const char *inlabel, struct lxc_conf *conf
...
@@ -186,7 +186,7 @@ static int apparmor_process_label_set(const char *inlabel, struct lxc_conf *conf
return
0
;
return
0
;
}
}
curlabel
=
apparmor_process_label_get
(
getpid
());
curlabel
=
apparmor_process_label_get
(
lxc_raw_
getpid
());
if
(
!
aa_stacking_supported
()
&&
aa_needs_transition
(
curlabel
))
{
if
(
!
aa_stacking_supported
()
&&
aa_needs_transition
(
curlabel
))
{
/* we're already confined, and stacking isn't supported */
/* we're already confined, and stacking isn't supported */
...
...
src/lxc/lxc_init.c
View file @
15090139
...
@@ -40,12 +40,13 @@
...
@@ -40,12 +40,13 @@
#include "error.h"
#include "error.h"
#include "initutils.h"
#include "initutils.h"
#include "log.h"
#include "log.h"
#include "namespace.h"
#include "parse.h"
#include "parse.h"
#include "version.h"
#include "version.h"
/* option keys for long only options */
/* option keys for long only options */
#define OPT_USAGE 0x1000
#define OPT_USAGE 0x1000
#define OPT_VERSION OPT_USAGE - 1
#define OPT_VERSION OPT_USAGE - 1
#define QUOTE(macro) #macro
#define QUOTE(macro) #macro
#define QUOTEVAL(macro) QUOTE(macro)
#define QUOTEVAL(macro) QUOTE(macro)
...
@@ -61,14 +62,14 @@ static void interrupt_handler(int sig)
...
@@ -61,14 +62,14 @@ static void interrupt_handler(int sig)
}
}
static
struct
option
long_options
[]
=
{
static
struct
option
long_options
[]
=
{
{
"name"
,
required_argument
,
0
,
'n'
},
{
"name"
,
required_argument
,
0
,
'n'
},
{
"help"
,
no_argument
,
0
,
'h'
},
{
"help"
,
no_argument
,
0
,
'h'
},
{
"usage"
,
no_argument
,
0
,
OPT_USAGE
},
{
"usage"
,
no_argument
,
0
,
OPT_USAGE
},
{
"version"
,
no_argument
,
0
,
OPT_VERSION
},
{
"version"
,
no_argument
,
0
,
OPT_VERSION
},
{
"quiet"
,
no_argument
,
0
,
'q'
},
{
"quiet"
,
no_argument
,
0
,
'q'
},
{
"logfile"
,
required_argument
,
0
,
'o'
},
{
"logfile"
,
required_argument
,
0
,
'o'
},
{
"logpriority"
,
required_argument
,
0
,
'l'
},
{
"logpriority"
,
required_argument
,
0
,
'l'
},
{
"lxcpath"
,
required_argument
,
0
,
'P'
},
{
"lxcpath"
,
required_argument
,
0
,
'P'
},
{
0
,
0
,
0
,
0
}
{
0
,
0
,
0
,
0
}
};
};
static
char
short_options
[]
=
"n:hqo:l:P:"
;
static
char
short_options
[]
=
"n:hqo:l:P:"
;
...
@@ -359,7 +360,7 @@ int main(int argc, char *argv[])
...
@@ -359,7 +360,7 @@ int main(int argc, char *argv[])
case
SIGPWR
:
case
SIGPWR
:
case
SIGTERM
:
case
SIGTERM
:
if
(
!
shutdown
)
{
if
(
!
shutdown
)
{
pid_t
mypid
=
getpid
();
pid_t
mypid
=
lxc_raw_
getpid
();
shutdown
=
1
;
shutdown
=
1
;
prevent_forking
();
prevent_forking
();
...
@@ -375,7 +376,7 @@ int main(int argc, char *argv[])
...
@@ -375,7 +376,7 @@ int main(int argc, char *argv[])
}
}
break
;
break
;
case
SIGALRM
:
{
case
SIGALRM
:
{
pid_t
mypid
=
getpid
();
pid_t
mypid
=
lxc_raw_
getpid
();
prevent_forking
();
prevent_forking
();
if
(
mypid
!=
1
)
{
if
(
mypid
!=
1
)
{
...
...
src/lxc/lxc_monitord.c
View file @
15090139
...
@@ -427,7 +427,7 @@ int main(int argc, char *argv[])
...
@@ -427,7 +427,7 @@ int main(int argc, char *argv[])
}
}
NOTICE
(
"lxc-monitord with pid %d is now monitoring lxcpath %s."
,
NOTICE
(
"lxc-monitord with pid %d is now monitoring lxcpath %s."
,
getpid
(),
mon
.
lxcpath
);
lxc_raw_
getpid
(),
mon
.
lxcpath
);
for
(;;)
{
for
(;;)
{
ret
=
lxc_mainloop
(
&
mon
.
descr
,
1000
*
30
);
ret
=
lxc_mainloop
(
&
mon
.
descr
,
1000
*
30
);
if
(
ret
)
{
if
(
ret
)
{
...
...
src/lxc/lxc_user_nic.c
View file @
15090139
...
@@ -46,6 +46,7 @@
...
@@ -46,6 +46,7 @@
#include <sys/types.h>
#include <sys/types.h>
#include "config.h"
#include "config.h"
#include "namespace.h"
#include "network.h"
#include "network.h"
#include "utils.h"
#include "utils.h"
...
@@ -814,14 +815,16 @@ static char *lxc_secure_rename_in_ns(int pid, char *oldname, char *newname,
...
@@ -814,14 +815,16 @@ static char *lxc_secure_rename_in_ns(int pid, char *oldname, char *newname,
int
*
container_veth_ifidx
)
int
*
container_veth_ifidx
)
{
{
int
ret
;
int
ret
;
pid_t
pid_self
;
uid_t
ruid
,
suid
,
euid
;
uid_t
ruid
,
suid
,
euid
;
char
ifname
[
IFNAMSIZ
];
char
ifname
[
IFNAMSIZ
];
char
*
string_ret
=
NULL
,
*
name
=
NULL
;
char
*
string_ret
=
NULL
,
*
name
=
NULL
;
int
fd
=
-
1
,
ifindex
=
-
1
,
ofd
=
-
1
;
int
fd
=
-
1
,
ifindex
=
-
1
,
ofd
=
-
1
;
ofd
=
lxc_preserve_ns
(
getpid
(),
"net"
);
pid_self
=
lxc_raw_getpid
();
ofd
=
lxc_preserve_ns
(
pid_self
,
"net"
);
if
(
ofd
<
0
)
{
if
(
ofd
<
0
)
{
usernic_error
(
"Failed opening network namespace path for %d"
,
getpid
()
);
usernic_error
(
"Failed opening network namespace path for %d"
,
pid_self
);
return
NULL
;
return
NULL
;
}
}
...
@@ -993,13 +996,15 @@ struct user_nic_args {
...
@@ -993,13 +996,15 @@ struct user_nic_args {
static
bool
is_privileged_over_netns
(
int
netns_fd
)
static
bool
is_privileged_over_netns
(
int
netns_fd
)
{
{
int
ret
;
int
ret
;
pid_t
pid_self
;
uid_t
euid
,
ruid
,
suid
;
uid_t
euid
,
ruid
,
suid
;
bool
bret
=
false
;
bool
bret
=
false
;
int
ofd
=
-
1
;
int
ofd
=
-
1
;
ofd
=
lxc_preserve_ns
(
getpid
(),
"net"
);
pid_self
=
lxc_raw_getpid
();
ofd
=
lxc_preserve_ns
(
pid_self
,
"net"
);
if
(
ofd
<
0
)
{
if
(
ofd
<
0
)
{
usernic_error
(
"Failed opening network namespace path for %d"
,
getpid
()
);
usernic_error
(
"Failed opening network namespace path for %d"
,
pid_self
);
return
false
;
return
false
;
}
}
...
...
src/lxc/lxccontainer.c
View file @
15090139
...
@@ -941,7 +941,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
...
@@ -941,7 +941,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
/* become session leader */
/* become session leader */
ret
=
setsid
();
ret
=
setsid
();
if
(
ret
<
0
)
if
(
ret
<
0
)
TRACE
(
"Process %d is already process group leader"
,
getpid
());
TRACE
(
"Process %d is already process group leader"
,
lxc_raw_
getpid
());
}
else
{
}
else
{
if
(
!
am_single_threaded
())
{
if
(
!
am_single_threaded
())
{
ERROR
(
"Cannot start non-daemonized container when threaded"
);
ERROR
(
"Cannot start non-daemonized container when threaded"
);
...
@@ -966,7 +966,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
...
@@ -966,7 +966,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
return
false
;
return
false
;
}
}
if
(
fprintf
(
pid_fp
,
"%d
\n
"
,
getpid
())
<
0
)
{
if
(
fprintf
(
pid_fp
,
"%d
\n
"
,
lxc_raw_
getpid
())
<
0
)
{
SYSERROR
(
"Failed to write '%s'"
,
c
->
pidfile
);
SYSERROR
(
"Failed to write '%s'"
,
c
->
pidfile
);
fclose
(
pid_fp
);
fclose
(
pid_fp
);
pid_fp
=
NULL
;
pid_fp
=
NULL
;
...
@@ -4451,7 +4451,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
...
@@ -4451,7 +4451,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
return
false
;
return
false
;
}
}
pid_outside
=
getpid
();
pid_outside
=
lxc_raw_
getpid
();
pid
=
fork
();
pid
=
fork
();
if
(
pid
<
0
)
{
if
(
pid
<
0
)
{
ERROR
(
"Failed to fork"
);
ERROR
(
"Failed to fork"
);
...
...
src/lxc/namespace.c
View file @
15090139
...
@@ -127,6 +127,23 @@ pid_t lxc_raw_clone(unsigned long flags)
...
@@ -127,6 +127,23 @@ pid_t lxc_raw_clone(unsigned long flags)
#endif
#endif
}
}
pid_t
lxc_raw_clone_cb
(
int
(
*
fn
)(
void
*
),
void
*
args
,
unsigned
long
flags
)
{
pid_t
pid
;
pid
=
lxc_raw_clone
(
flags
);
if
(
pid
<
0
)
return
-
1
;
/* exit() is not thread-safe and might mess with the parent's signal
* handlers and other stuff when exec() fails.
*/
if
(
pid
==
0
)
_exit
(
fn
(
args
));
return
pid
;
}
/* Leave the user namespace at the first position in the array of structs so
/* Leave the user namespace at the first position in the array of structs so
* that we always attach to it first when iterating over the struct and using
* that we always attach to it first when iterating over the struct and using
* setns() to switch namespaces. This especially affects lxc_attach(): Suppose
* setns() to switch namespaces. This especially affects lxc_attach(): Suppose
...
...
src/lxc/namespace.h
View file @
15090139
...
@@ -23,8 +23,9 @@
...
@@ -23,8 +23,9 @@
#ifndef __LXC_NAMESPACE_H
#ifndef __LXC_NAMESPACE_H
#define __LXC_NAMESPACE_H
#define __LXC_NAMESPACE_H
#include <sys/syscall.h>
#include <sched.h>
#include <sched.h>
#include <unistd.h>
#include <sys/syscall.h>
#include "config.h"
#include "config.h"
...
@@ -112,11 +113,83 @@ int clone(int (*fn)(void *), void *child_stack,
...
@@ -112,11 +113,83 @@ int clone(int (*fn)(void *), void *child_stack,
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */
);
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */
);
#endif
#endif
/**
* lxc_clone() - create a new process
*
* - allocate stack:
* This function allocates a new stack the size of page and passes it to the
* kernel.
*
* - support all CLONE_*flags:
* This function supports all CLONE_* flags. If in doubt or not sufficiently
* familiar with process creation in the kernel and interactions with libcs
* this function should be used.
*
* - pthread_atfork() handlers depending on libc:
* Whether this function runs pthread_atfork() handlers depends on the
* corresponding libc wrapper. glibc currently does not run pthread_atfork()
* handlers but does not guarantee that they are not. Other libcs might or
* might not run pthread_atfork() handlers. If you require guarantees please
* refer to the lxc_raw_clone*() functions below.
*
* - should call lxc_raw_getpid():
* The child should use lxc_raw_getpid() to retrieve its pid.
*/
extern
pid_t
lxc_clone
(
int
(
*
fn
)(
void
*
),
void
*
arg
,
int
flags
);
extern
pid_t
lxc_clone
(
int
(
*
fn
)(
void
*
),
void
*
arg
,
int
flags
);
/**
* lxc_raw_clone() - create a new process
*
* - fork() behavior:
* This function returns 0 in the child and > 0 in the parent.
*
* - copy-on-write:
* This function does not allocate a new stack and relies on copy-on-write
* semantics.
*
* - supports subset of ClONE_* flags:
* lxc_raw_clone() intentionally only supports a subset of the flags available
* to the actual system call. Please refer to the implementation what flags
* cannot be used. Also, please don't assume that just because a flag isn't
* explicitly checked for as being unsupported that it is supported. If in
* doubt or not sufficiently familiar with process creation in the kernel and
* interactions with libcs this function should be used.
*
* - no pthread_atfork() handlers:
* This function circumvents - as much as this this is possible - any libc
* wrappers and thus does not run any pthread_atfork() handlers. Make sure
* that this is safe to do in the context you are trying to call this
* function.
*
* - must call lxc_raw_getpid():
* The child must use lxc_raw_getpid() to retrieve its pid.
*/
extern
pid_t
lxc_raw_clone
(
unsigned
long
flags
);
extern
pid_t
lxc_raw_clone
(
unsigned
long
flags
);
/**
* lxc_raw_clone_cb() - create a new process
*
* - non-fork() behavior:
* Function does return pid of the child or -1 on error. Pass in a callback
* function via the "fn" argument that gets executed in the child process. The
* "args" argument is passed to "fn".
*
* All other comments that apply to lxc_raw_clone() apply to lxc_raw_clone_cb()
* as well.
*/
extern
pid_t
lxc_raw_clone_cb
(
int
(
*
fn
)(
void
*
),
void
*
args
,
unsigned
long
flags
);
extern
int
lxc_namespace_2_cloneflag
(
const
char
*
namespace
);
extern
int
lxc_namespace_2_cloneflag
(
const
char
*
namespace
);
extern
int
lxc_namespace_2_ns_idx
(
const
char
*
namespace
);
extern
int
lxc_namespace_2_ns_idx
(
const
char
*
namespace
);
extern
int
lxc_fill_namespace_flags
(
char
*
flaglist
,
int
*
flags
);
extern
int
lxc_fill_namespace_flags
(
char
*
flaglist
,
int
*
flags
);
/**
* Because of older glibc's pid cache (up to 2.25) whenever clone() is called
* the child must must retrieve it's own pid via lxc_raw_getpid().
*/
static
inline
pid_t
lxc_raw_getpid
(
void
)
{
return
(
pid_t
)
syscall
(
SYS_getpid
);
}
#endif
#endif
src/lxc/network.c
View file @
15090139
...
@@ -2369,7 +2369,7 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
...
@@ -2369,7 +2369,7 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
}
}
ret
=
snprintf
(
netns_path
,
sizeof
(
netns_path
),
"/proc/%d/fd/%d"
,
ret
=
snprintf
(
netns_path
,
sizeof
(
netns_path
),
"/proc/%d/fd/%d"
,
getpid
(),
handler
->
nsfd
[
LXC_NS_NET
]);
lxc_raw_
getpid
(),
handler
->
nsfd
[
LXC_NS_NET
]);
if
(
ret
<
0
||
ret
>=
sizeof
(
netns_path
))
if
(
ret
<
0
||
ret
>=
sizeof
(
netns_path
))
return
false
;
return
false
;
...
@@ -2693,7 +2693,7 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
...
@@ -2693,7 +2693,7 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
TRACE
(
"Moving physical network devices back to parent network namespace"
);
TRACE
(
"Moving physical network devices back to parent network namespace"
);
oldfd
=
lxc_preserve_ns
(
getpid
(),
"net"
);
oldfd
=
lxc_preserve_ns
(
lxc_raw_
getpid
(),
"net"
);
if
(
oldfd
<
0
)
{
if
(
oldfd
<
0
)
{
SYSERROR
(
"Failed to preserve network namespace"
);
SYSERROR
(
"Failed to preserve network namespace"
);
return
-
1
;
return
-
1
;
...
...
src/lxc/start.c
View file @
15090139
...
@@ -726,7 +726,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
...
@@ -726,7 +726,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
*/
*/
lxc_set_state
(
name
,
handler
,
STOPPING
);
lxc_set_state
(
name
,
handler
,
STOPPING
);
self
=
getpid
();
self
=
lxc_raw_
getpid
();
for
(
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
{
for
(
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
{
if
(
handler
->
nsfd
[
i
]
<
0
)
if
(
handler
->
nsfd
[
i
]
<
0
)
continue
;
continue
;
...
@@ -784,11 +784,6 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
...
@@ -784,11 +784,6 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
cgroup_destroy
(
handler
);
cgroup_destroy
(
handler
);
/* This function will try to connect to the legacy lxc-monitord state
* server and only exists for backwards compatibility.
*/
lxc_monitor_send_state
(
name
,
STOPPED
,
handler
->
lxcpath
);
if
(
handler
->
conf
->
reboot
==
0
)
{
if
(
handler
->
conf
->
reboot
==
0
)
{
/* For all new state clients simply close the command socket.
/* For all new state clients simply close the command socket.
* This will inform all state clients that the container is
* This will inform all state clients that the container is
...
@@ -798,6 +793,18 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
...
@@ -798,6 +793,18 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
*/
*/
close
(
handler
->
conf
->
maincmd_fd
);
close
(
handler
->
conf
->
maincmd_fd
);
handler
->
conf
->
maincmd_fd
=
-
1
;
handler
->
conf
->
maincmd_fd
=
-
1
;
TRACE
(
"Closed command socket"
);
/* This function will try to connect to the legacy lxc-monitord
* state server and only exists for backwards compatibility.
*/
lxc_monitor_send_state
(
name
,
STOPPED
,
handler
->
lxcpath
);
/* The command socket is closed so no one can acces the command
* socket anymore so there's no need to lock it.
*/
handler
->
state
=
STOPPED
;
TRACE
(
"Set container state to
\"
STOPPED
\"
"
);
}
else
{
}
else
{
lxc_set_state
(
name
,
handler
,
STOPPED
);
lxc_set_state
(
name
,
handler
,
STOPPED
);
}
}
...
@@ -1006,7 +1013,7 @@ static int do_start(void *data)
...
@@ -1006,7 +1013,7 @@ static int do_start(void *data)
}
}
if
(
handler
->
clone_flags
&
CLONE_NEWCGROUP
)
{
if
(
handler
->
clone_flags
&
CLONE_NEWCGROUP
)
{
fd
=
lxc_preserve_ns
(
syscall
(
SYS_getpid
),
"cgroup"
);
fd
=
lxc_preserve_ns
(
lxc_raw_getpid
(
),
"cgroup"
);
if
(
fd
<
0
)
{
if
(
fd
<
0
)
{
ERROR
(
"%s - Failed to preserve cgroup namespace"
,
strerror
(
errno
));
ERROR
(
"%s - Failed to preserve cgroup namespace"
,
strerror
(
errno
));
close
(
handler
->
data_sock
[
0
]);
close
(
handler
->
data_sock
[
0
]);
...
@@ -1263,8 +1270,8 @@ int resolve_clone_flags(struct lxc_handler *handler)
...
@@ -1263,8 +1270,8 @@ int resolve_clone_flags(struct lxc_handler *handler)
* not reset anymore.
* not reset anymore.
* However, if for whatever reason you - dear commiter - somehow need to get the
* However, if for whatever reason you - dear commiter - somehow need to get the
* pid of the dummy intermediate process for do_share_ns() you need to call
* pid of the dummy intermediate process for do_share_ns() you need to call
*
syscall(__NR_getpid) directly. The next lxc_clone() call does not employ
*
lxc_raw_getpid(). The next lxc_raw_clone() call does not employ CLONE_VM and
*
CLONE_VM and
will be fine.
* will be fine.
*/
*/
static
inline
int
do_share_ns
(
void
*
arg
)
static
inline
int
do_share_ns
(
void
*
arg
)
{
{
...
@@ -1284,7 +1291,7 @@ static inline int do_share_ns(void *arg)
...
@@ -1284,7 +1291,7 @@ static inline int do_share_ns(void *arg)
flags
=
handler
->
on_clone_flags
;
flags
=
handler
->
on_clone_flags
;
flags
|=
CLONE_PARENT
;
flags
|=
CLONE_PARENT
;
handler
->
pid
=
lxc_
clone
(
do_start
,
handler
,
flags
);
handler
->
pid
=
lxc_
raw_clone_cb
(
do_start
,
handler
,
flags
);
if
(
handler
->
pid
<
0
)
if
(
handler
->
pid
<
0
)
return
-
1
;
return
-
1
;
...
@@ -1414,7 +1421,7 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1414,7 +1421,7 @@ static int lxc_spawn(struct lxc_handler *handler)
goto
out_delete_net
;
goto
out_delete_net
;
}
}
}
else
{
}
else
{
handler
->
pid
=
lxc_
clone
(
do_start
,
handler
,
handler
->
on_clone_flags
);
handler
->
pid
=
lxc_
raw_clone_cb
(
do_start
,
handler
,
handler
->
on_clone_flags
);
}
}
if
(
handler
->
pid
<
0
)
{
if
(
handler
->
pid
<
0
)
{
SYSERROR
(
LXC_CLONE_ERROR
);
SYSERROR
(
LXC_CLONE_ERROR
);
...
...
src/lxc/utils.c
View file @
15090139
...
@@ -1701,7 +1701,7 @@ int lxc_mount_proc_if_needed(const char *rootfs)
...
@@ -1701,7 +1701,7 @@ int lxc_mount_proc_if_needed(const char *rootfs)
return
-
1
;
return
-
1
;
}
}
mypid
=
getpid
();
mypid
=
lxc_raw_
getpid
();
INFO
(
"I am %d, /proc/self points to
\"
%s
\"
"
,
mypid
,
link
);
INFO
(
"I am %d, /proc/self points to
\"
%s
\"
"
,
mypid
,
link
);
if
(
lxc_safe_int
(
link
,
&
link_to_pid
)
<
0
)
if
(
lxc_safe_int
(
link
,
&
link_to_pid
)
<
0
)
...
@@ -2389,17 +2389,6 @@ int lxc_make_tmpfile(char *template, bool rm)
...
@@ -2389,17 +2389,6 @@ int lxc_make_tmpfile(char *template, bool rm)
return
fd
;
return
fd
;
}
}
uint64_t
lxc_getpagesize
(
void
)
{
int64_t
pgsz
;
pgsz
=
sysconf
(
_SC_PAGESIZE
);
if
(
pgsz
<=
0
)
pgsz
=
1
<<
12
;
return
pgsz
;
}
int
parse_byte_size_string
(
const
char
*
s
,
int64_t
*
converted
)
int
parse_byte_size_string
(
const
char
*
s
,
int64_t
*
converted
)
{
{
int
ret
,
suffix_len
;
int
ret
,
suffix_len
;
...
...
src/lxc/utils.h
View file @
15090139
...
@@ -519,7 +519,17 @@ extern bool has_fs_type(const char *path, fs_type_magic magic_val);
...
@@ -519,7 +519,17 @@ extern bool has_fs_type(const char *path, fs_type_magic magic_val);
extern
bool
is_fs_type
(
const
struct
statfs
*
fs
,
fs_type_magic
magic_val
);
extern
bool
is_fs_type
(
const
struct
statfs
*
fs
,
fs_type_magic
magic_val
);
extern
bool
lxc_nic_exists
(
char
*
nic
);
extern
bool
lxc_nic_exists
(
char
*
nic
);
extern
int
lxc_make_tmpfile
(
char
*
template
,
bool
rm
);
extern
int
lxc_make_tmpfile
(
char
*
template
,
bool
rm
);
extern
uint64_t
lxc_getpagesize
(
void
);
static
inline
uint64_t
lxc_getpagesize
(
void
)
{
int64_t
pgsz
;
pgsz
=
sysconf
(
_SC_PAGESIZE
);
if
(
pgsz
<=
0
)
pgsz
=
1
<<
12
;
return
pgsz
;
}
/* If n is not a power of 2 this function will return the next power of 2
/* If n is not a power of 2 this function will return the next power of 2
* greater than that number. Note that this function always returns the *next*
* greater than that number. Note that this function always returns the *next*
...
...
src/tests/lxc_raw_clone.c
View file @
15090139
...
@@ -116,9 +116,16 @@ int main(int argc, char *argv[])
...
@@ -116,9 +116,16 @@ int main(int argc, char *argv[])
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
pid
=
lxc_raw_clone
(
CLONE_NEWUSER
|
CLONE_NEWCGROUP
|
CLONE_NEWNS
|
flags
|=
CLONE_NEWUSER
;
CLONE_NEWIPC
|
CLONE_NEWNET
|
CLONE_NEWIPC
|
if
(
cgns_supported
())
CLONE_NEWPID
|
CLONE_NEWUTS
);
flags
|=
CLONE_NEWCGROUP
;
flags
|=
CLONE_NEWNS
;
flags
|=
CLONE_NEWIPC
;
flags
|=
CLONE_NEWNET
;
flags
|=
CLONE_NEWIPC
;
flags
|=
CLONE_NEWPID
;
flags
|=
CLONE_NEWUTS
;
pid
=
lxc_raw_clone
(
flags
);
if
(
pid
<
0
)
{
if
(
pid
<
0
)
{
lxc_error
(
"%s
\n
"
,
"Failed to call lxc_raw_clone(CLONE_NEWUSER "
lxc_error
(
"%s
\n
"
,
"Failed to call lxc_raw_clone(CLONE_NEWUSER "
"| CLONE_NEWCGROUP | CLONE_NEWNS | "
"| CLONE_NEWCGROUP | CLONE_NEWNS | "
...
@@ -138,15 +145,6 @@ int main(int argc, char *argv[])
...
@@ -138,15 +145,6 @@ int main(int argc, char *argv[])
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
flags
|=
CLONE_NEWUSER
;
if
(
cgns_supported
())
flags
|=
CLONE_NEWCGROUP
;
flags
|=
CLONE_NEWNS
;
flags
|=
CLONE_NEWIPC
;
flags
|=
CLONE_NEWNET
;
flags
|=
CLONE_NEWIPC
;
flags
|=
CLONE_NEWPID
;
flags
|=
CLONE_NEWUTS
;
pid
=
lxc_raw_clone
(
flags
);
pid
=
lxc_raw_clone
(
flags
);
if
(
pid
<
0
)
{
if
(
pid
<
0
)
{
lxc_error
(
"%s
\n
"
,
"Failed to call lxc_raw_clone(CLONE_NEWUSER "
lxc_error
(
"%s
\n
"
,
"Failed to call lxc_raw_clone(CLONE_NEWUSER "
...
@@ -165,9 +163,81 @@ int main(int argc, char *argv[])
...
@@ -165,9 +163,81 @@ int main(int argc, char *argv[])
status
=
wait_for_pid
(
pid
);
status
=
wait_for_pid
(
pid
);
if
(
status
==
0
)
{
if
(
status
==
0
)
{
lxc_error
(
"%s
\n
"
,
"Failed to retrieve correct exit status"
);
lxc_error
(
"%s
\n
"
,
"Failed to retrieve correct exit status"
);
exit
(
EXIT_FAILURE
);
}
pid
=
lxc_raw_clone
(
CLONE_VFORK
);
if
(
pid
<
0
)
{
lxc_error
(
"%s
\n
"
,
"Failed to call lxc_raw_clone(CLONE_VFORK);"
);
exit
(
EXIT_FAILURE
);
}
if
(
pid
==
0
)
{
lxc_error
(
"%s
\n
"
,
"Child will exit(EXIT_SUCCESS)"
);
exit
(
EXIT_SUCCESS
);
exit
(
EXIT_SUCCESS
);
}
}
status
=
wait_for_pid
(
pid
);
if
(
status
!=
0
)
{
lxc_error
(
"%s
\n
"
,
"Failed to retrieve correct exit status"
);
exit
(
EXIT_FAILURE
);
}
pid
=
lxc_raw_clone
(
CLONE_VFORK
);
if
(
pid
<
0
)
{
lxc_error
(
"%s
\n
"
,
"Failed to call lxc_raw_clone(CLONE_VFORK);"
);
exit
(
EXIT_FAILURE
);
}
if
(
pid
==
0
)
{
lxc_error
(
"%s
\n
"
,
"Child will exit(EXIT_FAILURE)"
);
exit
(
EXIT_FAILURE
);
}
status
=
wait_for_pid
(
pid
);
if
(
status
==
0
)
{
lxc_error
(
"%s
\n
"
,
"Failed to retrieve correct exit status"
);
exit
(
EXIT_FAILURE
);
}
pid
=
lxc_raw_clone
(
CLONE_FILES
);
if
(
pid
<
0
)
{
lxc_error
(
"%s
\n
"
,
"Failed to call lxc_raw_clone(CLONE_FILES);"
);
exit
(
EXIT_FAILURE
);
}
if
(
pid
==
0
)
{
lxc_error
(
"%s
\n
"
,
"Child will exit(EXIT_SUCCESS)"
);
exit
(
EXIT_SUCCESS
);
}
status
=
wait_for_pid
(
pid
);
if
(
status
!=
0
)
{
lxc_error
(
"%s
\n
"
,
"Failed to retrieve correct exit status"
);
exit
(
EXIT_FAILURE
);
}
pid
=
lxc_raw_clone
(
CLONE_FILES
);
if
(
pid
<
0
)
{
lxc_error
(
"%s
\n
"
,
"Failed to call lxc_raw_clone(CLONE_FILES);"
);
exit
(
EXIT_FAILURE
);
}
if
(
pid
==
0
)
{
lxc_error
(
"%s
\n
"
,
"Child will exit(EXIT_FAILURE)"
);
exit
(
EXIT_FAILURE
);
}
status
=
wait_for_pid
(
pid
);
if
(
status
==
0
)
{
lxc_error
(
"%s
\n
"
,
"Failed to retrieve correct exit status"
);
exit
(
EXIT_FAILURE
);
}
lxc_debug
(
"%s
\n
"
,
"All lxc_raw_clone() tests successful"
);
lxc_debug
(
"%s
\n
"
,
"All lxc_raw_clone() tests successful"
);
exit
(
EXIT_SUCCESS
);
exit
(
EXIT_SUCCESS
);
}
}
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