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
8db6be1b
Unverified
Commit
8db6be1b
authored
Feb 14, 2021
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
start: rework namespace preservation and path creation for hooks
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
3bcf3ba0
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
112 additions
and
92 deletions
+112
-92
macro.h
src/lxc/macro.h
+18
-0
namespace.h
src/lxc/namespace.h
+13
-12
start.c
src/lxc/start.c
+74
-80
start.h
src/lxc/start.h
+7
-0
No files found.
src/lxc/macro.h
View file @
8db6be1b
...
@@ -339,6 +339,24 @@
...
@@ -339,6 +339,24 @@
*/
*/
#define LXC_LSMATTRLEN (6 + INTTYPE_TO_STRLEN(pid_t) + 6 + 8 + 1)
#define LXC_LSMATTRLEN (6 + INTTYPE_TO_STRLEN(pid_t) + 6 + 8 + 1)
/* MAX_NS_PROC_NAME = MAX_NS_PROC_NAME
* +
* : = 1
* +
* /proc/ = 6
* +
* <pid-as_str> = INTTYPE_TO_STRLEN(pid_t)
* +
* /fd/ = 4
* +
* <int-as-str> = INTTYPE_TO_STRLEN(int)
* +
* \0 = 1
*/
#define LXC_EXPOSE_NAMESPACE_LEN \
(MAX_NS_PROC_NAME + 1 + 6 + INTTYPE_TO_STRLEN(pid_t) + 4 + \
INTTYPE_TO_STRLEN(int) + 1)
#define LXC_CMD_DATA_MAX (PATH_MAX * 2)
#define LXC_CMD_DATA_MAX (PATH_MAX * 2)
/* loop devices */
/* loop devices */
...
...
src/lxc/namespace.h
View file @
8db6be1b
...
@@ -9,20 +9,21 @@
...
@@ -9,20 +9,21 @@
#include "compiler.h"
#include "compiler.h"
enum
{
typedef
enum
lxc_namespace_t
{
LXC_NS_USER
,
LXC_NS_USER
=
0
,
LXC_NS_MNT
,
LXC_NS_MNT
=
1
,
LXC_NS_PID
,
LXC_NS_PID
=
2
,
LXC_NS_UTS
,
LXC_NS_UTS
=
3
,
LXC_NS_IPC
,
LXC_NS_IPC
=
4
,
LXC_NS_NET
,
LXC_NS_NET
=
5
,
LXC_NS_CGROUP
,
LXC_NS_CGROUP
=
6
,
LXC_NS_TIME
,
LXC_NS_TIME
=
7
,
LXC_NS_MAX
LXC_NS_MAX
=
8
};
}
lxc_namespace_t
;
__hidden
extern
const
struct
ns_info
{
__hidden
extern
const
struct
ns_info
{
const
char
*
proc_name
;
#define MAX_NS_PROC_NAME 6
const
char
proc_name
[
MAX_NS_PROC_NAME
];
const
char
*
proc_path
;
const
char
*
proc_path
;
int
clone_flag
;
int
clone_flag
;
const
char
*
flag_name
;
const
char
*
flag_name
;
...
...
src/lxc/start.c
View file @
8db6be1b
...
@@ -112,23 +112,37 @@ static void lxc_put_nsfds(struct lxc_handler *handler)
...
@@ -112,23 +112,37 @@ static void lxc_put_nsfds(struct lxc_handler *handler)
}
}
}
}
static
int
lxc_try_preserve_ns
(
const
int
pid
,
const
char
*
ns
)
static
int
lxc_try_preserve_namespace
(
struct
lxc_handler
*
handler
,
lxc_namespace_t
idx
,
const
char
*
ns
)
{
{
int
fd
;
__do_close
int
fd
=
-
EBADF
;
int
ret
;
fd
=
lxc_preserve_ns
(
pid
,
ns
);
fd
=
lxc_preserve_ns
(
handler
->
pid
,
ns
);
if
(
fd
<
0
)
{
if
(
fd
<
0
)
{
if
(
errno
!=
ENOENT
)
if
(
errno
!=
ENOENT
)
return
log_error_errno
(
-
EINVAL
,
return
log_error_errno
(
-
EINVAL
,
errno
,
errno
,
"Failed to preserve %s namespace"
,
"Failed to preserve %s namespace"
,
ns
);
ns
);
return
log_warn_errno
(
-
EOPNOTSUPP
,
return
log_warn_errno
(
-
EOPNOTSUPP
,
errno
,
errno
,
"Kernel does not support preserving %s namespaces"
,
"Kernel does not support preserving %s namespaces"
,
ns
);
ns
);
}
}
return
fd
;
ret
=
strnprintf
(
handler
->
nsfd_paths
[
idx
],
sizeof
(
handler
->
nsfd_paths
[
idx
]),
"%s:/proc/%d/fd/%d"
,
ns_info
[
idx
].
proc_name
,
handler
->
monitor_pid
,
fd
);
/* Legacy style argument passing as arguments to hooks. */
handler
->
hook_argv
[
handler
->
hook_argc
]
=
handler
->
nsfd_paths
[
idx
];
handler
->
hook_argc
++
;
if
(
ret
<
0
)
return
ret_errno
(
EIO
);
DEBUG
(
"Preserved %s namespace via fd %d and stashed path as %s"
,
ns_info
[
idx
].
proc_name
,
fd
,
handler
->
nsfd_paths
[
idx
]);
handler
->
nsfd
[
idx
]
=
move_fd
(
fd
);
return
0
;
}
}
/* lxc_try_preserve_namespaces: open /proc/@pid/ns/@ns for each namespace
/* lxc_try_preserve_namespaces: open /proc/@pid/ns/@ns for each namespace
...
@@ -136,35 +150,30 @@ static int lxc_try_preserve_ns(const int pid, const char *ns)
...
@@ -136,35 +150,30 @@ static int lxc_try_preserve_ns(const int pid, const char *ns)
* Return true on success, false on failure.
* Return true on success, false on failure.
*/
*/
static
bool
lxc_try_preserve_namespaces
(
struct
lxc_handler
*
handler
,
static
bool
lxc_try_preserve_namespaces
(
struct
lxc_handler
*
handler
,
int
ns_clone_flags
,
pid_t
pid
)
int
ns_clone_flags
)
{
{
int
i
;
for
(
lxc_namespace_t
ns_idx
=
0
;
ns_idx
<
LXC_NS_MAX
;
ns_idx
++
)
handler
->
nsfd
[
ns_idx
]
=
-
EBADF
;
for
(
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
for
(
lxc_namespace_t
ns_idx
=
0
;
ns_idx
<
LXC_NS_MAX
;
ns_idx
++
)
{
handler
->
nsfd
[
i
]
=
-
EBADF
;
int
ret
;
for
(
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
{
int
fd
;
if
((
ns_clone_flags
&
ns_info
[
i
].
clone_flag
)
==
0
)
if
((
ns_clone_flags
&
ns_info
[
ns_idx
].
clone_flag
)
==
0
)
continue
;
continue
;
fd
=
lxc_try_preserve_ns
(
pid
,
ns_info
[
i
].
proc_name
);
ret
=
lxc_try_preserve_namespace
(
handler
,
ns_idx
,
if
(
fd
<
0
)
{
ns_info
[
ns_idx
].
proc_name
);
if
(
ret
<
0
)
{
/* Do not fail to start container on kernels that do
/* Do not fail to start container on kernels that do
* not support interacting with namespaces through
* not support interacting with namespaces through
* /proc.
* /proc.
*/
*/
if
(
fd
==
-
EOPNOTSUPP
)
if
(
ret
==
-
EOPNOTSUPP
)
continue
;
continue
;
lxc_put_nsfds
(
handler
);
lxc_put_nsfds
(
handler
);
return
false
;
return
false
;
}
}
handler
->
nsfd
[
i
]
=
fd
;
DEBUG
(
"Preserved %s namespace via fd %d"
,
ns_info
[
i
].
proc_name
,
handler
->
nsfd
[
i
]);
}
}
return
true
;
return
true
;
...
@@ -666,8 +675,18 @@ struct lxc_handler *lxc_init_handler(struct lxc_handler *old,
...
@@ -666,8 +675,18 @@ struct lxc_handler *lxc_init_handler(struct lxc_handler *old,
if
(
handler
->
conf
->
reboot
==
REBOOT_NONE
)
if
(
handler
->
conf
->
reboot
==
REBOOT_NONE
)
lxc_list_init
(
&
handler
->
conf
->
state_clients
);
lxc_list_init
(
&
handler
->
conf
->
state_clients
);
for
(
int
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
for
(
lxc_namespace_t
idx
=
0
;
idx
<
LXC_NS_MAX
;
idx
++
)
{
handler
->
nsfd
[
i
]
=
-
EBADF
;
handler
->
nsfd
[
idx
]
=
-
EBADF
;
if
(
handler
->
conf
->
reboot
==
REBOOT_NONE
)
continue
;
handler
->
nsfd_paths
[
idx
][
0
]
=
'\0'
;
handler
->
hook_argv
[
idx
]
=
NULL
;
if
(
handler
->
hook_argc
!=
0
)
handler
->
hook_argc
=
0
;
}
handler
->
name
=
name
;
handler
->
name
=
name
;
if
(
daemonize
)
if
(
daemonize
)
...
@@ -845,13 +864,30 @@ out_restore_sigmask:
...
@@ -845,13 +864,30 @@ out_restore_sigmask:
return
-
1
;
return
-
1
;
}
}
void
lxc_expose_namespace_environment
(
const
struct
lxc_handler
*
handler
)
{
for
(
lxc_namespace_t
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
{
int
ret
;
const
char
*
fd_path
;
if
(
handler
->
nsfd
[
i
]
<
0
)
continue
;
fd_path
=
handler
->
nsfd_paths
[
i
]
+
strcspn
(
handler
->
nsfd_paths
[
i
],
"/"
);
ret
=
setenv
(
ns_info
[
i
].
env_name
,
fd_path
,
1
);
if
(
ret
<
0
)
SYSERROR
(
"Failed to set environment variable %s=%s"
,
ns_info
[
i
].
env_name
,
fd_path
);
else
TRACE
(
"Set environment variable %s=%s"
,
ns_info
[
i
].
env_name
,
fd_path
);
}
}
void
lxc_end
(
struct
lxc_handler
*
handler
)
void
lxc_end
(
struct
lxc_handler
*
handler
)
{
{
int
ret
;
int
ret
;
pid_t
self
;
struct
lxc_list
*
cur
,
*
next
;
struct
lxc_list
*
cur
,
*
next
;
char
*
namespaces
[
LXC_NS_MAX
+
1
];
size_t
namespace_count
=
0
;
const
char
*
name
=
handler
->
name
;
const
char
*
name
=
handler
->
name
;
struct
cgroup_ops
*
cgroup_ops
=
handler
->
cgroup_ops
;
struct
cgroup_ops
*
cgroup_ops
=
handler
->
cgroup_ops
;
...
@@ -860,39 +896,9 @@ void lxc_end(struct lxc_handler *handler)
...
@@ -860,39 +896,9 @@ void lxc_end(struct lxc_handler *handler)
*/
*/
lxc_set_state
(
name
,
handler
,
STOPPING
);
lxc_set_state
(
name
,
handler
,
STOPPING
);
self
=
lxc_raw_getpid
();
/* Passing information to hooks via environment variables. */
for
(
int
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
{
if
(
handler
->
conf
->
hooks_version
>
0
)
if
(
handler
->
nsfd
[
i
]
<
0
)
lxc_expose_namespace_environment
(
handler
);
continue
;
if
(
handler
->
conf
->
hooks_version
==
0
)
ret
=
asprintf
(
&
namespaces
[
namespace_count
],
"%s:/proc/%d/fd/%d"
,
ns_info
[
i
].
proc_name
,
self
,
handler
->
nsfd
[
i
]);
else
ret
=
asprintf
(
&
namespaces
[
namespace_count
],
"/proc/%d/fd/%d"
,
self
,
handler
->
nsfd
[
i
]);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to allocate memory"
);
break
;
}
if
(
handler
->
conf
->
hooks_version
==
0
)
{
namespace_count
++
;
continue
;
}
ret
=
setenv
(
ns_info
[
i
].
env_name
,
namespaces
[
namespace_count
],
1
);
if
(
ret
<
0
)
SYSERROR
(
"Failed to set environment variable %s=%s"
,
ns_info
[
i
].
env_name
,
namespaces
[
namespace_count
]);
else
TRACE
(
"Set environment variable %s=%s"
,
ns_info
[
i
].
env_name
,
namespaces
[
namespace_count
]);
namespace_count
++
;
}
namespaces
[
namespace_count
]
=
NULL
;
if
(
handler
->
conf
->
reboot
>
REBOOT_NONE
)
{
if
(
handler
->
conf
->
reboot
>
REBOOT_NONE
)
{
ret
=
setenv
(
"LXC_TARGET"
,
"reboot"
,
1
);
ret
=
setenv
(
"LXC_TARGET"
,
"reboot"
,
1
);
...
@@ -907,15 +913,12 @@ void lxc_end(struct lxc_handler *handler)
...
@@ -907,15 +913,12 @@ void lxc_end(struct lxc_handler *handler)
}
}
if
(
handler
->
conf
->
hooks_version
==
0
)
if
(
handler
->
conf
->
hooks_version
==
0
)
ret
=
run_lxc_hooks
(
name
,
"stop"
,
handler
->
conf
,
namespaces
);
ret
=
run_lxc_hooks
(
name
,
"stop"
,
handler
->
conf
,
handler
->
hook_argv
);
else
else
ret
=
run_lxc_hooks
(
name
,
"stop"
,
handler
->
conf
,
NULL
);
ret
=
run_lxc_hooks
(
name
,
"stop"
,
handler
->
conf
,
NULL
);
if
(
ret
<
0
)
if
(
ret
<
0
)
ERROR
(
"Failed to run
\"
lxc.hook.stop
\"
hook"
);
ERROR
(
"Failed to run
\"
lxc.hook.stop
\"
hook"
);
while
(
namespace_count
--
)
free
(
namespaces
[
namespace_count
]);
handler
->
lsm_ops
->
cleanup
(
handler
->
lsm_ops
,
handler
->
conf
,
handler
->
lxcpath
);
handler
->
lsm_ops
->
cleanup
(
handler
->
lsm_ops
,
handler
->
conf
,
handler
->
lxcpath
);
if
(
cgroup_ops
)
{
if
(
cgroup_ops
)
{
...
@@ -1761,7 +1764,7 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1761,7 +1764,7 @@ static int lxc_spawn(struct lxc_handler *handler)
if
(
handler
->
ns_on_clone_flags
&
ns_info
[
i
].
clone_flag
)
if
(
handler
->
ns_on_clone_flags
&
ns_info
[
i
].
clone_flag
)
INFO
(
"Cloned %s"
,
ns_info
[
i
].
flag_name
);
INFO
(
"Cloned %s"
,
ns_info
[
i
].
flag_name
);
if
(
!
lxc_try_preserve_namespaces
(
handler
,
handler
->
ns_on_clone_flags
,
handler
->
pid
))
{
if
(
!
lxc_try_preserve_namespaces
(
handler
,
handler
->
ns_on_clone_flags
))
{
ERROR
(
"Failed to preserve cloned namespaces for lxc.hook.stop"
);
ERROR
(
"Failed to preserve cloned namespaces for lxc.hook.stop"
);
goto
out_delete_net
;
goto
out_delete_net
;
}
}
...
@@ -1822,15 +1825,12 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1822,15 +1825,12 @@ static int lxc_spawn(struct lxc_handler *handler)
/* If not done yet, we're now ready to preserve the network namespace */
/* If not done yet, we're now ready to preserve the network namespace */
if
(
handler
->
nsfd
[
LXC_NS_NET
]
<
0
)
{
if
(
handler
->
nsfd
[
LXC_NS_NET
]
<
0
)
{
ret
=
lxc_try_preserve_n
s
(
handler
->
pid
,
"net"
);
ret
=
lxc_try_preserve_n
amespace
(
handler
,
LXC_NS_NET
,
"net"
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
if
(
ret
!=
-
EOPNOTSUPP
)
{
if
(
ret
!=
-
EOPNOTSUPP
)
{
SYSERROR
(
"Failed to preserve net namespace"
);
SYSERROR
(
"Failed to preserve net namespace"
);
goto
out_delete_net
;
goto
out_delete_net
;
}
}
}
else
{
handler
->
nsfd
[
LXC_NS_NET
]
=
ret
;
DEBUG
(
"Preserved net namespace via fd %d"
,
ret
);
}
}
}
}
ret
=
lxc_netns_set_nsid
(
handler
->
nsfd
[
LXC_NS_NET
]);
ret
=
lxc_netns_set_nsid
(
handler
->
nsfd
[
LXC_NS_NET
]);
...
@@ -1896,15 +1896,12 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1896,15 +1896,12 @@ static int lxc_spawn(struct lxc_handler *handler)
if
(
handler
->
ns_unshare_flags
&
CLONE_NEWCGROUP
)
{
if
(
handler
->
ns_unshare_flags
&
CLONE_NEWCGROUP
)
{
/* Now we're ready to preserve the cgroup namespace */
/* Now we're ready to preserve the cgroup namespace */
ret
=
lxc_try_preserve_n
s
(
handler
->
pid
,
"cgroup"
);
ret
=
lxc_try_preserve_n
amespace
(
handler
,
LXC_NS_CGROUP
,
"cgroup"
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
if
(
ret
!=
-
EOPNOTSUPP
)
{
if
(
ret
!=
-
EOPNOTSUPP
)
{
SYSERROR
(
"Failed to preserve cgroup namespace"
);
SYSERROR
(
"Failed to preserve cgroup namespace"
);
goto
out_delete_net
;
goto
out_delete_net
;
}
}
}
else
{
handler
->
nsfd
[
LXC_NS_CGROUP
]
=
ret
;
DEBUG
(
"Preserved cgroup namespace via fd %d"
,
ret
);
}
}
}
}
...
@@ -1913,15 +1910,12 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1913,15 +1910,12 @@ static int lxc_spawn(struct lxc_handler *handler)
if
(
handler
->
ns_unshare_flags
&
CLONE_NEWTIME
)
{
if
(
handler
->
ns_unshare_flags
&
CLONE_NEWTIME
)
{
/* Now we're ready to preserve the cgroup namespace */
/* Now we're ready to preserve the cgroup namespace */
ret
=
lxc_try_preserve_n
s
(
handler
->
pid
,
"time"
);
ret
=
lxc_try_preserve_n
amespace
(
handler
,
LXC_NS_TIME
,
"time"
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
if
(
ret
!=
-
EOPNOTSUPP
)
{
if
(
ret
!=
-
EOPNOTSUPP
)
{
SYSERROR
(
"Failed to preserve time namespace"
);
SYSERROR
(
"Failed to preserve time namespace"
);
goto
out_delete_net
;
goto
out_delete_net
;
}
}
}
else
{
handler
->
nsfd
[
LXC_NS_TIME
]
=
ret
;
DEBUG
(
"Preserved time namespace via fd %d"
,
ret
);
}
}
}
}
...
...
src/lxc/start.h
View file @
8db6be1b
...
@@ -127,6 +127,12 @@ struct lxc_handler {
...
@@ -127,6 +127,12 @@ struct lxc_handler {
/* Static memory, don't free. */
/* Static memory, don't free. */
struct
lsm_ops
*
lsm_ops
;
struct
lsm_ops
*
lsm_ops
;
/* The namespace idx is guaranteed to match the stashed namespace path. */
char
nsfd_paths
[
LXC_NS_MAX
+
1
][
LXC_EXPOSE_NAMESPACE_LEN
];
/* The namesace idx is _not_ guaranteed to match the stashed namespace path. */
lxc_namespace_t
hook_argc
;
char
*
hook_argv
[
LXC_NS_MAX
+
1
];
};
};
struct
execute_args
{
struct
execute_args
{
...
@@ -172,5 +178,6 @@ __hidden extern int __lxc_start(struct lxc_handler *, struct lxc_operations *, v
...
@@ -172,5 +178,6 @@ __hidden extern int __lxc_start(struct lxc_handler *, struct lxc_operations *, v
bool
,
int
*
);
bool
,
int
*
);
__hidden
extern
int
resolve_clone_flags
(
struct
lxc_handler
*
handler
);
__hidden
extern
int
resolve_clone_flags
(
struct
lxc_handler
*
handler
);
__hidden
extern
void
lxc_expose_namespace_environment
(
const
struct
lxc_handler
*
handler
);
#endif
#endif
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