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
0e24c560
Unverified
Commit
0e24c560
authored
Jan 29, 2021
by
Stéphane Graber
Committed by
GitHub
Jan 29, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3638 from brauner/2021-01-28/fixes
attach: improve attach codepaths
parents
0fa84a8c
581b849a
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
155 additions
and
133 deletions
+155
-133
configure.ac
configure.ac
+12
-4
attach.c
src/lxc/attach.c
+0
-0
attach.h
src/lxc/attach.h
+1
-10
attach_options.h
src/lxc/attach_options.h
+1
-1
confile.c
src/lxc/confile.c
+1
-1
confile.h
src/lxc/confile.h
+6
-1
lsm.c
src/lxc/lsm/lsm.c
+1
-1
lsm.h
src/lxc/lsm/lsm.h
+1
-1
macro.h
src/lxc/macro.h
+13
-0
namespace.c
src/lxc/namespace.c
+8
-8
namespace.h
src/lxc/namespace.h
+1
-0
start.c
src/lxc/start.c
+14
-24
sync.c
src/lxc/sync.c
+63
-35
sync.h
src/lxc/sync.h
+32
-46
attach.c
src/tests/attach.c
+1
-1
No files found.
configure.ac
View file @
0e24c560
...
@@ -61,6 +61,18 @@ if test "x$valid_compiler" = "xno"; then
...
@@ -61,6 +61,18 @@ if test "x$valid_compiler" = "xno"; then
AC_MSG_ERROR([Sorry, your compiler is too old - please upgrade it])
AC_MSG_ERROR([Sorry, your compiler is too old - please upgrade it])
fi
fi
AC_PROG_GCC_TRADITIONAL
AC_ENABLE_SHARED
AC_ENABLE_STATIC
# Check binaries
AC_PROG_SED
case $CC in clang*)
AC_CHECK_TOOL([AR], llvm-ar)
AC_CHECK_TOOL([NM], llvm-nm)
AC_CHECK_TOOL([OBJCOPY], llvm-objcopy)
AC_CHECK_TOOL([RANLIB], llvm-ranlib)
esac
# libtool
# libtool
LT_INIT
LT_INIT
AC_SUBST([LIBTOOL_DEPS])
AC_SUBST([LIBTOOL_DEPS])
...
@@ -731,10 +743,6 @@ AC_CHECK_TYPES([struct rtnl_link_stats64], [], [], [[#include <linux/if_link.h>]
...
@@ -731,10 +743,6 @@ AC_CHECK_TYPES([struct rtnl_link_stats64], [], [], [[#include <linux/if_link.h>]
AX_PTHREAD
AX_PTHREAD
AC_SEARCH_LIBS(clock_gettime, [rt])
AC_SEARCH_LIBS(clock_gettime, [rt])
# Check for some standard binaries
AC_PROG_GCC_TRADITIONAL
AC_PROG_SED
# See if we support thread-local storage.
# See if we support thread-local storage.
LXC_CHECK_TLS
LXC_CHECK_TLS
...
...
src/lxc/attach.c
View file @
0e24c560
This diff is collapsed.
Click to expand it.
src/lxc/attach.h
View file @
0e24c560
...
@@ -11,16 +11,7 @@
...
@@ -11,16 +11,7 @@
#include "namespace.h"
#include "namespace.h"
struct
lxc_conf
;
struct
lxc_conf
;
struct
lxc_container
;
struct
lxc_proc_context_info
{
char
*
lsm_label
;
struct
lxc_container
*
container
;
signed
long
personality
;
unsigned
long
long
capability_mask
;
int
ns_inherited
;
int
ns_fd
[
LXC_NS_MAX
];
struct
lsm_ops
*
lsm_ops
;
};
__hidden
extern
int
lxc_attach
(
struct
lxc_container
*
container
,
lxc_attach_exec_t
exec_function
,
__hidden
extern
int
lxc_attach
(
struct
lxc_container
*
container
,
lxc_attach_exec_t
exec_function
,
void
*
exec_payload
,
lxc_attach_options_t
*
options
,
void
*
exec_payload
,
lxc_attach_options_t
*
options
,
...
...
src/lxc/attach_options.h
View file @
0e24c560
...
@@ -124,7 +124,7 @@ typedef struct lxc_attach_options_t {
...
@@ -124,7 +124,7 @@ typedef struct lxc_attach_options_t {
{ \
{ \
/* .attach_flags = */
LXC_ATTACH_DEFAULT, \
/* .attach_flags = */
LXC_ATTACH_DEFAULT, \
/* .namespaces = */
-1, \
/* .namespaces = */
-1, \
/* .personality = */
-1,
\
/* .personality = */
0xffffffff,
\
/* .initial_cwd = */
NULL, \
/* .initial_cwd = */
NULL, \
/* .uid = */
(uid_t)-1, \
/* .uid = */
(uid_t)-1, \
/* .gid = */
(gid_t)-1, \
/* .gid = */
(gid_t)-1, \
...
...
src/lxc/confile.c
View file @
0e24c560
...
@@ -3031,7 +3031,7 @@ signed long lxc_config_parse_arch(const char *arch)
...
@@ -3031,7 +3031,7 @@ signed long lxc_config_parse_arch(const char *arch)
return
pername
[
i
].
per
;
return
pername
[
i
].
per
;
#endif
#endif
return
-
1
;
return
LXC_ARCH_UNCHANGED
;
}
}
int
lxc_fill_elevated_privileges
(
char
*
flaglist
,
int
*
flags
)
int
lxc_fill_elevated_privileges
(
char
*
flaglist
,
int
*
flags
)
...
...
src/lxc/confile.h
View file @
0e24c560
...
@@ -78,7 +78,12 @@ __hidden extern bool lxc_config_define_load(struct lxc_list *defines, struct lxc
...
@@ -78,7 +78,12 @@ __hidden extern bool lxc_config_define_load(struct lxc_list *defines, struct lxc
__hidden
extern
void
lxc_config_define_free
(
struct
lxc_list
*
defines
);
__hidden
extern
void
lxc_config_define_free
(
struct
lxc_list
*
defines
);
/* needed for lxc-attach */
#define LXC_ARCH_UNCHANGED 0xffffffffL
/*
* Parse personality of the container. Returns LXC_ARCH_UNCHANGED if the
* personality is not know.
* (Used during attach.)
*/
__hidden
extern
signed
long
lxc_config_parse_arch
(
const
char
*
arch
);
__hidden
extern
signed
long
lxc_config_parse_arch
(
const
char
*
arch
);
__hidden
extern
int
lxc_fill_elevated_privileges
(
char
*
flaglist
,
int
*
flags
);
__hidden
extern
int
lxc_fill_elevated_privileges
(
char
*
flaglist
,
int
*
flags
);
...
...
src/lxc/lsm/lsm.c
View file @
0e24c560
...
@@ -21,7 +21,7 @@ __hidden extern struct lsm_ops *lsm_apparmor_ops_init(void);
...
@@ -21,7 +21,7 @@ __hidden extern struct lsm_ops *lsm_apparmor_ops_init(void);
__hidden
extern
struct
lsm_ops
*
lsm_selinux_ops_init
(
void
);
__hidden
extern
struct
lsm_ops
*
lsm_selinux_ops_init
(
void
);
__hidden
extern
struct
lsm_ops
*
lsm_nop_ops_init
(
void
);
__hidden
extern
struct
lsm_ops
*
lsm_nop_ops_init
(
void
);
struct
lsm_ops
*
lsm_init
(
void
)
struct
lsm_ops
*
lsm_init
_static
(
void
)
{
{
struct
lsm_ops
*
ops
=
NULL
;
struct
lsm_ops
*
ops
=
NULL
;
...
...
src/lxc/lsm/lsm.h
View file @
0e24c560
...
@@ -33,6 +33,6 @@ struct lsm_ops {
...
@@ -33,6 +33,6 @@ struct lsm_ops {
int
(
*
process_label_set_at
)(
struct
lsm_ops
*
ops
,
int
label_fd
,
const
char
*
label
,
bool
on_exec
);
int
(
*
process_label_set_at
)(
struct
lsm_ops
*
ops
,
int
label_fd
,
const
char
*
label
,
bool
on_exec
);
};
};
__hidden
extern
struct
lsm_ops
*
lsm_init
(
void
);
__hidden
extern
struct
lsm_ops
*
lsm_init
_static
(
void
);
#endif
/* __LXC_LSM_H */
#endif
/* __LXC_LSM_H */
src/lxc/macro.h
View file @
0e24c560
...
@@ -293,6 +293,19 @@
...
@@ -293,6 +293,19 @@
* +
* +
* \0 = 1
* \0 = 1
*/
*/
#define LXC_PROC_PID_LEN \
(6 + INTTYPE_TO_STRLEN(pid_t) + 1)
/* /proc/ = 6
* +
* <pid-as-str> = INTTYPE_TO_STRLEN(pid_t)
* +
* /fd/ = 4
* +
* <fd-as-str> = INTTYPE_TO_STRLEN(int)
* +
* \0 = 1
*/
#define LXC_PROC_PID_FD_LEN \
#define LXC_PROC_PID_FD_LEN \
(6 + INTTYPE_TO_STRLEN(pid_t) + 4 + INTTYPE_TO_STRLEN(int) + 1)
(6 + INTTYPE_TO_STRLEN(pid_t) + 4 + INTTYPE_TO_STRLEN(int) + 1)
...
...
src/lxc/namespace.c
View file @
0e24c560
...
@@ -38,14 +38,14 @@ lxc_log_define(namespace, lxc);
...
@@ -38,14 +38,14 @@ lxc_log_define(namespace, lxc);
* linux/fs/namespace.c:mntns_install().
* linux/fs/namespace.c:mntns_install().
*/
*/
const
struct
ns_info
ns_info
[
LXC_NS_MAX
]
=
{
const
struct
ns_info
ns_info
[
LXC_NS_MAX
]
=
{
[
LXC_NS_USER
]
=
{
"user"
,
CLONE_NEWUSER
,
"CLONE_NEWUSER"
,
"LXC_USER_NS"
},
[
LXC_NS_USER
]
=
{
"user"
,
"ns/user"
,
CLONE_NEWUSER
,
"CLONE_NEWUSER"
,
"LXC_USER_NS"
},
[
LXC_NS_MNT
]
=
{
"mnt"
,
CLONE_NEWNS
,
"CLONE_NEWNS"
,
"LXC_MNT_NS"
},
[
LXC_NS_MNT
]
=
{
"mnt"
,
"ns/mnt"
,
CLONE_NEWNS
,
"CLONE_NEWNS"
,
"LXC_MNT_NS"
},
[
LXC_NS_PID
]
=
{
"pid"
,
CLONE_NEWPID
,
"CLONE_NEWPID"
,
"LXC_PID_NS"
},
[
LXC_NS_PID
]
=
{
"pid"
,
"ns/pid"
,
CLONE_NEWPID
,
"CLONE_NEWPID"
,
"LXC_PID_NS"
},
[
LXC_NS_UTS
]
=
{
"uts"
,
CLONE_NEWUTS
,
"CLONE_NEWUTS"
,
"LXC_UTS_NS"
},
[
LXC_NS_UTS
]
=
{
"uts"
,
"ns/uts"
,
CLONE_NEWUTS
,
"CLONE_NEWUTS"
,
"LXC_UTS_NS"
},
[
LXC_NS_IPC
]
=
{
"ipc"
,
CLONE_NEWIPC
,
"CLONE_NEWIPC"
,
"LXC_IPC_NS"
},
[
LXC_NS_IPC
]
=
{
"ipc"
,
"ns/ipc"
,
CLONE_NEWIPC
,
"CLONE_NEWIPC"
,
"LXC_IPC_NS"
},
[
LXC_NS_NET
]
=
{
"net"
,
CLONE_NEWNET
,
"CLONE_NEWNET"
,
"LXC_NET_NS"
},
[
LXC_NS_NET
]
=
{
"net"
,
"ns/net"
,
CLONE_NEWNET
,
"CLONE_NEWNET"
,
"LXC_NET_NS"
},
[
LXC_NS_CGROUP
]
=
{
"cgroup"
,
CLONE_NEWCGROUP
,
"CLONE_NEWCGROUP"
,
"LXC_CGROUP_NS"
},
[
LXC_NS_CGROUP
]
=
{
"cgroup"
,
"ns/cgroup"
,
CLONE_NEWCGROUP
,
"CLONE_NEWCGROUP"
,
"LXC_CGROUP_NS"
},
[
LXC_NS_TIME
]
=
{
"time"
,
CLONE_NEWTIME
,
"CLONE_NEWTIME"
,
"LXC_TIME_NS"
},
[
LXC_NS_TIME
]
=
{
"time"
,
"ns/time"
,
CLONE_NEWTIME
,
"CLONE_NEWTIME"
,
"LXC_TIME_NS"
},
};
};
int
lxc_namespace_2_cloneflag
(
const
char
*
namespace
)
int
lxc_namespace_2_cloneflag
(
const
char
*
namespace
)
...
...
src/lxc/namespace.h
View file @
0e24c560
...
@@ -23,6 +23,7 @@ enum {
...
@@ -23,6 +23,7 @@ enum {
__hidden
extern
const
struct
ns_info
{
__hidden
extern
const
struct
ns_info
{
const
char
*
proc_name
;
const
char
*
proc_name
;
const
char
*
proc_path
;
int
clone_flag
;
int
clone_flag
;
const
char
*
flag_name
;
const
char
*
flag_name
;
const
char
*
env_name
;
const
char
*
env_name
;
...
...
src/lxc/start.c
View file @
0e24c560
...
@@ -728,7 +728,7 @@ int lxc_init(const char *name, struct lxc_handler *handler)
...
@@ -728,7 +728,7 @@ int lxc_init(const char *name, struct lxc_handler *handler)
if
(
status_fd
<
0
)
if
(
status_fd
<
0
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to open monitor status fd"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to open monitor status fd"
);
handler
->
lsm_ops
=
lsm_init
();
handler
->
lsm_ops
=
lsm_init
_static
();
TRACE
(
"Initialized LSM"
);
TRACE
(
"Initialized LSM"
);
/* Begin by setting the state to STARTING. */
/* Begin by setting the state to STARTING. */
...
@@ -1069,8 +1069,7 @@ static int do_start(void *data)
...
@@ -1069,8 +1069,7 @@ static int do_start(void *data)
/* Don't leak the pinfd to the container. */
/* Don't leak the pinfd to the container. */
close_prot_errno_disarm
(
handler
->
pinfd
);
close_prot_errno_disarm
(
handler
->
pinfd
);
ret
=
lxc_sync_wait_parent
(
handler
,
LXC_SYNC_STARTUP
);
if
(
!
lxc_sync_wait_parent
(
handler
,
START_SYNC_STARTUP
))
if
(
ret
<
0
)
goto
out_warn_father
;
goto
out_warn_father
;
/* Unshare CLONE_NEWNET after CLONE_NEWUSER. See
/* Unshare CLONE_NEWNET after CLONE_NEWUSER. See
...
@@ -1088,8 +1087,7 @@ static int do_start(void *data)
...
@@ -1088,8 +1087,7 @@ static int do_start(void *data)
/* Tell the parent task it can begin to configure the container and wait
/* Tell the parent task it can begin to configure the container and wait
* for it to finish.
* for it to finish.
*/
*/
ret
=
lxc_sync_barrier_parent
(
handler
,
LXC_SYNC_CONFIGURE
);
if
(
!
lxc_sync_barrier_parent
(
handler
,
START_SYNC_CONFIGURE
))
if
(
ret
<
0
)
goto
out_error
;
goto
out_error
;
if
(
handler
->
ns_clone_flags
&
CLONE_NEWNET
)
{
if
(
handler
->
ns_clone_flags
&
CLONE_NEWNET
)
{
...
@@ -1168,8 +1166,7 @@ static int do_start(void *data)
...
@@ -1168,8 +1166,7 @@ static int do_start(void *data)
}
}
/* Ask father to setup cgroups and wait for him to finish. */
/* Ask father to setup cgroups and wait for him to finish. */
ret
=
lxc_sync_barrier_parent
(
handler
,
LXC_SYNC_CGROUP
);
if
(
!
lxc_sync_barrier_parent
(
handler
,
START_SYNC_CGROUP
))
if
(
ret
<
0
)
goto
out_error
;
goto
out_error
;
/* Unshare cgroup namespace after we have setup our cgroups. If we do it
/* Unshare cgroup namespace after we have setup our cgroups. If we do it
...
@@ -1353,8 +1350,7 @@ static int do_start(void *data)
...
@@ -1353,8 +1350,7 @@ static int do_start(void *data)
}
}
}
}
ret
=
lxc_sync_barrier_parent
(
handler
,
LXC_SYNC_CGROUP_LIMITS
);
if
(
!
lxc_sync_barrier_parent
(
handler
,
START_SYNC_CGROUP_LIMITS
))
if
(
ret
<
0
)
goto
out_warn_father
;
goto
out_warn_father
;
/* Reset the environment variables the user requested in a clear
/* Reset the environment variables the user requested in a clear
...
@@ -1447,7 +1443,7 @@ out_warn_father:
...
@@ -1447,7 +1443,7 @@ out_warn_father:
* We want the parent to know something went wrong, so we return a
* We want the parent to know something went wrong, so we return a
* special error code.
* special error code.
*/
*/
lxc_sync_wake_parent
(
handler
,
LXC_
SYNC_ERROR
);
lxc_sync_wake_parent
(
handler
,
SYNC_ERROR
);
out_error:
out_error:
return
-
1
;
return
-
1
;
...
@@ -1630,8 +1626,7 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1630,8 +1626,7 @@ static int lxc_spawn(struct lxc_handler *handler)
share_ns
=
true
;
share_ns
=
true
;
}
}
ret
=
lxc_sync_init
(
handler
);
if
(
!
lxc_sync_init
(
handler
))
if
(
ret
<
0
)
return
-
1
;
return
-
1
;
ret
=
socketpair
(
AF_UNIX
,
SOCK_STREAM
|
SOCK_CLOEXEC
,
0
,
ret
=
socketpair
(
AF_UNIX
,
SOCK_STREAM
|
SOCK_CLOEXEC
,
0
,
...
@@ -1790,12 +1785,10 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1790,12 +1785,10 @@ static int lxc_spawn(struct lxc_handler *handler)
}
}
}
}
ret
=
lxc_sync_wake_child
(
handler
,
LXC_SYNC_STARTUP
);
if
(
!
lxc_sync_wake_child
(
handler
,
START_SYNC_STARTUP
))
if
(
ret
<
0
)
goto
out_delete_net
;
goto
out_delete_net
;
ret
=
lxc_sync_wait_child
(
handler
,
LXC_SYNC_CONFIGURE
);
if
(
!
lxc_sync_wait_child
(
handler
,
START_SYNC_CONFIGURE
))
if
(
ret
<
0
)
goto
out_delete_net
;
goto
out_delete_net
;
if
(
!
cgroup_ops
->
setup_limits_legacy
(
cgroup_ops
,
handler
->
conf
,
false
))
{
if
(
!
cgroup_ops
->
setup_limits_legacy
(
cgroup_ops
,
handler
->
conf
,
false
))
{
...
@@ -1862,10 +1855,9 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1862,10 +1855,9 @@ static int lxc_spawn(struct lxc_handler *handler)
}
}
/* Tell the child to continue its initialization. We'll get
/* Tell the child to continue its initialization. We'll get
*
LXC
_SYNC_CGROUP when it is ready for us to setup cgroups.
*
START
_SYNC_CGROUP when it is ready for us to setup cgroups.
*/
*/
ret
=
lxc_sync_barrier_child
(
handler
,
LXC_SYNC_POST_CONFIGURE
);
if
(
!
lxc_sync_barrier_child
(
handler
,
START_SYNC_POST_CONFIGURE
))
if
(
ret
<
0
)
goto
out_delete_net
;
goto
out_delete_net
;
if
(
!
lxc_list_empty
(
&
conf
->
limits
))
{
if
(
!
lxc_list_empty
(
&
conf
->
limits
))
{
...
@@ -1876,8 +1868,7 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1876,8 +1868,7 @@ static int lxc_spawn(struct lxc_handler *handler)
}
}
}
}
ret
=
lxc_sync_barrier_child
(
handler
,
LXC_SYNC_CGROUP_UNSHARE
);
if
(
!
lxc_sync_barrier_child
(
handler
,
START_SYNC_CGROUP_UNSHARE
))
if
(
ret
<
0
)
goto
out_delete_net
;
goto
out_delete_net
;
/*
/*
...
@@ -1937,12 +1928,11 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1937,12 +1928,11 @@ static int lxc_spawn(struct lxc_handler *handler)
/* Tell the child to complete its initialization and wait for it to exec
/* Tell the child to complete its initialization and wait for it to exec
* or return an error. (The child will never return
* or return an error. (The child will never return
*
LXC
_SYNC_READY_START+1. It will either close the sync pipe, causing
*
START
_SYNC_READY_START+1. It will either close the sync pipe, causing
* lxc_sync_barrier_child to return success, or return a different
* lxc_sync_barrier_child to return success, or return a different
* value, causing us to error out).
* value, causing us to error out).
*/
*/
ret
=
lxc_sync_barrier_child
(
handler
,
LXC_SYNC_READY_START
);
if
(
!
lxc_sync_barrier_child
(
handler
,
START_SYNC_READY_START
))
if
(
ret
<
0
)
goto
out_delete_net
;
goto
out_delete_net
;
if
(
handler
->
ns_clone_flags
&
CLONE_NEWNET
)
{
if
(
handler
->
ns_clone_flags
&
CLONE_NEWNET
)
{
...
...
src/lxc/sync.c
View file @
0e24c560
...
@@ -17,101 +17,129 @@
...
@@ -17,101 +17,129 @@
lxc_log_define
(
sync
,
lxc
);
lxc_log_define
(
sync
,
lxc
);
static
int
__
sync_wait
(
int
fd
,
int
sequence
)
bool
sync_wait
(
int
fd
,
int
sequence
)
{
{
int
sync
=
-
1
;
int
sync
=
-
1
;
ssize_t
ret
;
ssize_t
ret
;
ret
=
lxc_read_nointr
(
fd
,
&
sync
,
sizeof
(
sync
));
ret
=
lxc_read_nointr
(
fd
,
&
sync
,
sizeof
(
sync
));
if
(
ret
<
0
)
if
(
ret
<
0
)
return
log_error_errno
(
-
1
,
errno
,
"Sync wait failure"
);
return
log_error_errno
(
false
,
errno
,
"Sync wait failure"
);
if
(
!
ret
)
if
(
!
ret
)
return
0
;
return
true
;
if
((
size_t
)
ret
!=
sizeof
(
sync
))
if
((
size_t
)
ret
!=
sizeof
(
sync
))
return
log_error
(
-
1
,
"Unexpected sync size: %zu expected %zu"
,
(
size_t
)
ret
,
sizeof
(
sync
));
return
log_error
(
false
,
"Unexpected sync size: %zu expected %zu"
,
(
size_t
)
ret
,
sizeof
(
sync
));
if
(
sync
==
LXC_
SYNC_ERROR
)
if
(
sync
==
SYNC_ERROR
)
return
log_error
(
-
1
,
"An error occurred in another process (expected sequence number %d)"
,
sequence
);
return
log_error
(
false
,
"An error occurred in another process (expected sequence number %d)"
,
sequence
);
if
(
sync
!=
sequence
)
if
(
sync
!=
sequence
)
return
log_error
(
-
1
,
"Invalid sequence number %d. Expected sequence number %d"
,
sync
,
sequence
);
return
log_error
(
false
,
"Invalid sequence number %d. Expected sequence number %d"
,
sync
,
sequence
);
return
0
;
return
true
;
}
}
static
int
__
sync_wake
(
int
fd
,
int
sequence
)
bool
sync_wake
(
int
fd
,
int
sequence
)
{
{
int
sync
=
sequence
;
int
sync
=
sequence
;
if
(
lxc_write_nointr
(
fd
,
&
sync
,
sizeof
(
sync
))
<
0
)
if
(
lxc_write_nointr
(
fd
,
&
sync
,
sizeof
(
sync
))
<
0
)
return
log_error_errno
(
-
1
,
errno
,
"Sync wake failure"
);
return
log_error_errno
(
false
,
errno
,
"Sync wake failure"
);
return
0
;
return
true
;
}
}
static
int
__sync_barrier
(
int
fd
,
int
sequence
)
static
bool
__sync_barrier
(
int
fd
,
int
sequence
)
{
{
if
(
__
sync_wake
(
fd
,
sequence
))
if
(
!
sync_wake
(
fd
,
sequence
))
return
-
1
;
return
false
;
return
__
sync_wait
(
fd
,
sequence
+
1
);
return
sync_wait
(
fd
,
sequence
+
1
);
}
}
int
lxc_sync_barrier_parent
(
struct
lxc_handler
*
handler
,
int
sequence
)
static
inline
const
char
*
start_sync_to_string
(
int
state
)
{
switch
(
state
)
{
case
START_SYNC_STARTUP
:
return
"startup"
;
case
START_SYNC_CONFIGURE
:
return
"configure"
;
case
START_SYNC_POST_CONFIGURE
:
return
"post-configure"
;
case
START_SYNC_CGROUP
:
return
"cgroup"
;
case
START_SYNC_CGROUP_UNSHARE
:
return
"cgroup-unshare"
;
case
START_SYNC_CGROUP_LIMITS
:
return
"cgroup-limits"
;
case
START_SYNC_READY_START
:
return
"ready-start"
;
case
START_SYNC_RESTART
:
return
"restart"
;
case
START_SYNC_POST_RESTART
:
return
"post-restart"
;
case
SYNC_ERROR
:
return
"error"
;
default:
return
"invalid sync state"
;
}
}
bool
lxc_sync_barrier_parent
(
struct
lxc_handler
*
handler
,
int
sequence
)
{
{
TRACE
(
"Child waking parent with sequence %s and waiting for sequence %s"
,
TRACE
(
"Child waking parent with sequence %s and waiting for sequence %s"
,
s
ync_to_string
(
sequence
),
sync_to_string
(
sequence
+
1
));
s
tart_sync_to_string
(
sequence
),
start_
sync_to_string
(
sequence
+
1
));
return
__sync_barrier
(
handler
->
sync_sock
[
0
],
sequence
);
return
__sync_barrier
(
handler
->
sync_sock
[
0
],
sequence
);
}
}
int
lxc_sync_barrier_child
(
struct
lxc_handler
*
handler
,
int
sequence
)
bool
lxc_sync_barrier_child
(
struct
lxc_handler
*
handler
,
int
sequence
)
{
{
TRACE
(
"Parent waking child with sequence %s and waiting with sequence %s"
,
TRACE
(
"Parent waking child with sequence %s and waiting with sequence %s"
,
s
ync_to_string
(
sequence
),
sync_to_string
(
sequence
+
1
));
s
tart_sync_to_string
(
sequence
),
start_
sync_to_string
(
sequence
+
1
));
return
__sync_barrier
(
handler
->
sync_sock
[
1
],
sequence
);
return
__sync_barrier
(
handler
->
sync_sock
[
1
],
sequence
);
}
}
int
lxc_sync_wake_parent
(
struct
lxc_handler
*
handler
,
int
sequence
)
bool
lxc_sync_wake_parent
(
struct
lxc_handler
*
handler
,
int
sequence
)
{
{
TRACE
(
"Child waking parent with sequence %s"
,
sync_to_string
(
sequence
));
TRACE
(
"Child waking parent with sequence %s"
,
s
tart_s
ync_to_string
(
sequence
));
return
__
sync_wake
(
handler
->
sync_sock
[
0
],
sequence
);
return
sync_wake
(
handler
->
sync_sock
[
0
],
sequence
);
}
}
int
lxc_sync_wait_parent
(
struct
lxc_handler
*
handler
,
int
sequence
)
bool
lxc_sync_wait_parent
(
struct
lxc_handler
*
handler
,
int
sequence
)
{
{
TRACE
(
"Parent waiting for child with sequence %s"
,
sync_to_string
(
sequence
));
TRACE
(
"Parent waiting for child with sequence %s"
,
s
tart_s
ync_to_string
(
sequence
));
return
__
sync_wait
(
handler
->
sync_sock
[
0
],
sequence
);
return
sync_wait
(
handler
->
sync_sock
[
0
],
sequence
);
}
}
int
lxc_sync_wait_child
(
struct
lxc_handler
*
handler
,
int
sequence
)
bool
lxc_sync_wait_child
(
struct
lxc_handler
*
handler
,
int
sequence
)
{
{
TRACE
(
"Child waiting for parent with sequence %s"
,
sync_to_string
(
sequence
));
TRACE
(
"Child waiting for parent with sequence %s"
,
s
tart_s
ync_to_string
(
sequence
));
return
__
sync_wait
(
handler
->
sync_sock
[
1
],
sequence
);
return
sync_wait
(
handler
->
sync_sock
[
1
],
sequence
);
}
}
int
lxc_sync_wake_child
(
struct
lxc_handler
*
handler
,
int
sequence
)
bool
lxc_sync_wake_child
(
struct
lxc_handler
*
handler
,
int
sequence
)
{
{
TRACE
(
"Child waking parent with sequence %s"
,
sync_to_string
(
sequence
));
TRACE
(
"Child waking parent with sequence %s"
,
s
tart_s
ync_to_string
(
sequence
));
return
__
sync_wake
(
handler
->
sync_sock
[
1
],
sequence
);
return
sync_wake
(
handler
->
sync_sock
[
1
],
sequence
);
}
}
int
lxc_sync_init
(
struct
lxc_handler
*
handler
)
bool
lxc_sync_init
(
struct
lxc_handler
*
handler
)
{
{
int
ret
;
int
ret
;
ret
=
socketpair
(
AF_LOCAL
,
SOCK_STREAM
,
0
,
handler
->
sync_sock
);
ret
=
socketpair
(
AF_LOCAL
,
SOCK_STREAM
,
0
,
handler
->
sync_sock
);
if
(
ret
)
if
(
ret
)
return
log_error_errno
(
-
1
,
errno
,
"failed to create synchronization socketpair"
);
return
log_error_errno
(
false
,
errno
,
"failed to create synchronization socketpair"
);
/* Be sure we don't inherit this after the exec */
/* Be sure we don't inherit this after the exec */
ret
=
fcntl
(
handler
->
sync_sock
[
0
],
F_SETFD
,
FD_CLOEXEC
);
ret
=
fcntl
(
handler
->
sync_sock
[
0
],
F_SETFD
,
FD_CLOEXEC
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to make socket close-on-exec"
);
return
log_error_errno
(
false
,
errno
,
"Failed to make socket close-on-exec"
);
TRACE
(
"Initialized synchronization infrastructure"
);
TRACE
(
"Initialized synchronization infrastructure"
);
return
0
;
return
true
;
}
}
void
lxc_sync_fini_child
(
struct
lxc_handler
*
handler
)
void
lxc_sync_fini_child
(
struct
lxc_handler
*
handler
)
...
...
src/lxc/sync.h
View file @
0e24c560
...
@@ -3,60 +3,46 @@
...
@@ -3,60 +3,46 @@
#ifndef __LXC_SYNC_H
#ifndef __LXC_SYNC_H
#define __LXC_SYNC_H
#define __LXC_SYNC_H
#include <stdbool.h>
#include "compiler.h"
#include "compiler.h"
struct
lxc_handler
;
struct
lxc_handler
;
enum
{
enum
/* generic */
{
LXC_SYNC_STARTUP
=
0
,
SYNC_ERROR
=
-
1
/* Used to report errors from another process */
LXC_SYNC_CONFIGURE
=
1
,
};
LXC_SYNC_POST_CONFIGURE
=
2
,
LXC_SYNC_CGROUP
=
3
,
enum
/* start */
{
LXC_SYNC_CGROUP_UNSHARE
=
4
,
START_SYNC_STARTUP
=
0
,
LXC_SYNC_CGROUP_LIMITS
=
5
,
START_SYNC_CONFIGURE
=
1
,
LXC_SYNC_READY_START
=
6
,
START_SYNC_POST_CONFIGURE
=
2
,
LXC_SYNC_RESTART
=
7
,
START_SYNC_CGROUP
=
3
,
LXC_SYNC_POST_RESTART
=
8
,
START_SYNC_CGROUP_UNSHARE
=
4
,
LXC_SYNC_ERROR
=
-
1
/* Used to report errors from another process */
START_SYNC_CGROUP_LIMITS
=
5
,
START_SYNC_READY_START
=
6
,
START_SYNC_RESTART
=
7
,
START_SYNC_POST_RESTART
=
8
,
};
};
static
inline
const
char
*
sync_to_string
(
int
state
)
enum
/* attach */
{
{
ATTACH_SYNC_CGROUP
=
0
,
switch
(
state
)
{
};
case
LXC_SYNC_STARTUP
:
return
"startup"
;
#define ATTACH_SYNC_PID(x) (x)
case
LXC_SYNC_CONFIGURE
:
#define ATTACH_SYNC_LSM(x) (x)
return
"configure"
;
case
LXC_SYNC_POST_CONFIGURE
:
__hidden
extern
bool
lxc_sync_init
(
struct
lxc_handler
*
handler
);
return
"post-configure"
;
case
LXC_SYNC_CGROUP
:
return
"cgroup"
;
case
LXC_SYNC_CGROUP_UNSHARE
:
return
"cgroup-unshare"
;
case
LXC_SYNC_CGROUP_LIMITS
:
return
"cgroup-limits"
;
case
LXC_SYNC_READY_START
:
return
"ready-start"
;
case
LXC_SYNC_RESTART
:
return
"restart"
;
case
LXC_SYNC_POST_RESTART
:
return
"post-restart"
;
case
LXC_SYNC_ERROR
:
return
"error"
;
default:
return
"invalid sync state"
;
}
}
__hidden
extern
int
lxc_sync_init
(
struct
lxc_handler
*
handler
);
__hidden
extern
void
lxc_sync_fini
(
struct
lxc_handler
*
);
__hidden
extern
void
lxc_sync_fini
(
struct
lxc_handler
*
);
__hidden
extern
void
lxc_sync_fini_parent
(
struct
lxc_handler
*
);
__hidden
extern
void
lxc_sync_fini_parent
(
struct
lxc_handler
*
);
__hidden
extern
void
lxc_sync_fini_child
(
struct
lxc_handler
*
);
__hidden
extern
void
lxc_sync_fini_child
(
struct
lxc_handler
*
);
__hidden
extern
int
lxc_sync_wake_child
(
struct
lxc_handler
*
,
int
);
__hidden
extern
bool
lxc_sync_wake_child
(
struct
lxc_handler
*
,
int
);
__hidden
extern
int
lxc_sync_wait_child
(
struct
lxc_handler
*
,
int
);
__hidden
extern
bool
lxc_sync_wait_child
(
struct
lxc_handler
*
,
int
);
__hidden
extern
int
lxc_sync_wake_parent
(
struct
lxc_handler
*
,
int
);
__hidden
extern
bool
lxc_sync_wake_parent
(
struct
lxc_handler
*
,
int
);
__hidden
extern
int
lxc_sync_wait_parent
(
struct
lxc_handler
*
,
int
);
__hidden
extern
bool
lxc_sync_wait_parent
(
struct
lxc_handler
*
,
int
);
__hidden
extern
int
lxc_sync_barrier_parent
(
struct
lxc_handler
*
,
int
);
__hidden
extern
bool
lxc_sync_barrier_parent
(
struct
lxc_handler
*
,
int
);
__hidden
extern
int
lxc_sync_barrier_child
(
struct
lxc_handler
*
,
int
);
__hidden
extern
bool
lxc_sync_barrier_child
(
struct
lxc_handler
*
,
int
);
__hidden
extern
bool
sync_wait
(
int
fd
,
int
sequence
);
__hidden
extern
bool
sync_wake
(
int
fd
,
int
sequence
);
#endif
/* __LXC_SYNC_H */
#endif
/* __LXC_SYNC_H */
src/tests/attach.c
View file @
0e24c560
...
@@ -400,7 +400,7 @@ int main(int argc, char *argv[])
...
@@ -400,7 +400,7 @@ int main(int argc, char *argv[])
(
void
)
strlcpy
(
template
,
P_tmpdir
"/attach_XXXXXX"
,
sizeof
(
template
));
(
void
)
strlcpy
(
template
,
P_tmpdir
"/attach_XXXXXX"
,
sizeof
(
template
));
lsm_ops
=
lsm_init
();
lsm_ops
=
lsm_init
_static
();
i
=
lxc_make_tmpfile
(
template
,
false
);
i
=
lxc_make_tmpfile
(
template
,
false
);
if
(
i
<
0
)
{
if
(
i
<
0
)
{
...
...
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