return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Network interface name not valid: %s", optarg);
+ r = test_network_interface_initialized(optarg);
+ if (r < 0)
+ return r;
+
if (strv_extend(&arg_network_interfaces, optarg) < 0)
return log_oom();
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"MACVLAN network interface name not valid: %s", optarg);
+ r = test_network_interface_initialized(optarg);
+ if (r < 0)
+ return r;
+
if (strv_extend(&arg_network_macvlan, optarg) < 0)
return log_oom();
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"IPVLAN network interface name not valid: %s", optarg);
+ r = test_network_interface_initialized(optarg);
+ if (r < 0)
+ return r;
+
if (strv_extend(&arg_network_ipvlan, optarg) < 0)
return log_oom();
if (arg_userns_chown && arg_volatile_mode != VOLATILE_NO)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--volatile= and --private-users-chown may not be combined.");
- /* If --network-namespace-path is given with any other network-related option, we need to error out,
- * to avoid conflicts between different network options. */
+ /* If --network-namespace-path is given with any other network-related option (except --private-network),
+ * we need to error out, to avoid conflicts between different network options. */
if (arg_network_namespace_path &&
(arg_network_interfaces || arg_network_macvlan ||
arg_network_ipvlan || arg_network_veth_extra ||
arg_network_bridge || arg_network_zone ||
- arg_network_veth || arg_private_network))
+ arg_network_veth))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--network-namespace-path= cannot be combined with other network options.");
if (arg_network_bridge && arg_network_zone)
static int setup_journal(const char *directory) {
_cleanup_free_ char *d = NULL;
+ char id[SD_ID128_STRING_MAX];
const char *dirname, *p, *q;
sd_id128_t this_id;
- char id[33];
bool try;
int r;
FDSet *fds) {
_cleanup_free_ char *home = NULL;
- char as_uuid[37];
+ char as_uuid[ID128_UUID_STRING_MAX];
size_t n_env = 1;
const char *envp[] = {
"PATH=" DEFAULT_PATH_COMPAT,
"/",
arg_custom_mounts,
arg_n_custom_mounts,
- false,
- 0,
0,
arg_selinux_apifs_context,
- true);
+ MOUNT_NON_ROOT_ONLY | MOUNT_IN_USERNS);
if (r < 0)
return r;
int netns_fd) {
_cleanup_close_ int fd = -1;
+ const char *p;
pid_t pid;
ssize_t l;
int r;
return r;
directory = "/run/systemd/nspawn-root";
-
- } else if (!dissected_image) {
- /* Turn directory into bind mount (we need that so that we can move the bind mount to root
- * later on). */
- r = mount_verbose(LOG_ERR, directory, directory, NULL, MS_BIND|MS_REC, NULL);
- if (r < 0)
- return r;
}
r = setup_pivot_root(
r = setup_volatile_mode(
directory,
arg_volatile_mode,
- arg_userns_mode != USER_NAMESPACE_NO,
arg_uid_shift,
- arg_uid_range,
arg_selinux_apifs_context);
if (r < 0)
return r;
+ r = mount_custom(
+ directory,
+ arg_custom_mounts,
+ arg_n_custom_mounts,
+ arg_uid_shift,
+ arg_selinux_apifs_context,
+ MOUNT_ROOT_ONLY);
+ if (r < 0)
+ return r;
+
+ /* Make sure we always have a mount that we can move to root later on. */
+ if (!path_is_mount_point(directory, NULL, 0)) {
+ r = mount_verbose(LOG_ERR, directory, directory, NULL, MS_BIND|MS_REC, NULL);
+ if (r < 0)
+ return r;
+ }
+
if (dissected_image) {
/* Now we know the uid shift, let's now mount everything else that might be in the image. */
r = dissected_image_mount(dissected_image, directory, arg_uid_shift,
* inside the container that create a new mount namespace.
* See https://github.com/systemd/systemd/issues/3860
* Further submounts (such as /dev) done after this will inherit the
- * shared propagation mode. */
+ * shared propagation mode.
+ *
+ * IMPORTANT: Do not overmount the root directory anymore from now on to
+ * enable moving the root directory mount to root later on.
+ * https://github.com/systemd/systemd/issues/3847#issuecomment-562735251
+ */
r = mount_verbose(LOG_ERR, NULL, directory, NULL, MS_SHARED|MS_REC, NULL);
if (r < 0)
return r;
return r;
(void) dev_setup(directory, arg_uid_shift, arg_uid_shift);
- (void) make_inaccessible_nodes(directory, arg_uid_shift, arg_uid_shift);
+
+ p = prefix_roota(directory, "/run/systemd");
+ (void) make_inaccessible_nodes(p, arg_uid_shift, arg_uid_shift);
r = setup_pts(directory);
if (r < 0)
directory,
arg_custom_mounts,
arg_n_custom_mounts,
- arg_userns_mode != USER_NAMESPACE_NO,
arg_uid_shift,
- arg_uid_range,
arg_selinux_apifs_context,
- false);
+ MOUNT_NON_ROOT_ONLY);
if (r < 0)
return r;