]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: move most validation checks and configuration mangling into verify_arguments() 11083/head
authorLennart Poettering <lennart@poettering.net>
Thu, 6 Dec 2018 21:00:00 +0000 (22:00 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 10 Dec 2018 11:54:56 +0000 (12:54 +0100)
That's what the function is for after all, and only if it's done there
we can verify the effect of .nspawn files correctly too: after all we
should not just validate that everything configured on the command line
makes sense, but the stuff configured in the .nspawn files, too.

src/nspawn/nspawn.c

index a2fc93767f0287ae89b21b558b0015e22927a3f9..f4f7c1fd1fb981daa00e73a434de511a8da4e11e 100644 (file)
@@ -1257,16 +1257,37 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached("Unhandled option");
                 }
 
-        /* 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 (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))
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "--network-namespace-path cannot be combined with other network options.");
+        if (argc > optind) {
+                strv_free(arg_parameters);
+                arg_parameters = strv_copy(argv + optind);
+                if (!arg_parameters)
+                        return log_oom();
+
+                arg_settings_mask |= SETTING_START_MODE;
+        }
+
+        if (arg_ephemeral && arg_template && !arg_directory)
+                /* User asked for ephemeral execution but specified --template= instead of --directory=. Semantically
+                 * such an invocation makes some sense, see https://github.com/systemd/systemd/issues/3667. Let's
+                 * accept this here, and silently make "--ephemeral --template=" equivalent to "--ephemeral
+                 * --directory=". */
+                arg_directory = TAKE_PTR(arg_template);
+
+        arg_caps_retain = (arg_caps_retain | plus | (arg_private_network ? 1ULL << CAP_NET_ADMIN : 0)) & ~minus;
+
+        /* Load all settings from .nspawn files */
+        if (mask_no_settings)
+                arg_settings_mask = 0;
 
+        /* Don't load any settings from .nspawn files */
+        if (mask_all_settings)
+                arg_settings_mask = _SETTINGS_MASK_ALL;
+
+        return 1;
+}
+
+static int verify_arguments(void) {
+        int r;
 
         if (arg_userns_mode != USER_NAMESPACE_NO)
                 arg_mount_settings |= MOUNT_USE_USERNS;
@@ -1278,110 +1299,73 @@ static int parse_argv(int argc, char *argv[]) {
             !(arg_clone_ns_flags & CLONE_NEWUTS)) {
                 arg_register = false;
                 if (arg_start_mode != START_PID1)
-                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                               "--boot cannot be used without namespacing.");
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--boot cannot be used without namespacing.");
         }
 
         if (arg_userns_mode == USER_NAMESPACE_PICK)
                 arg_userns_chown = true;
 
+        if (arg_start_mode == START_BOOT && arg_kill_signal <= 0)
+                arg_kill_signal = SIGRTMIN+3;
+
         if (arg_keep_unit && arg_register && cg_pid_get_owner_uid(0, NULL) >= 0)
                 /* Save the user from accidentally registering either user-$SESSION.scope or user@.service.
                  * The latter is not technically a user session, but we don't need to labour the point. */
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "--keep-unit --register=yes may not be used when invoked from a user session.");
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--keep-unit --register=yes may not be used when invoked from a user session.");
 
         if (arg_directory && arg_image)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "--directory= and --image= may not be combined.");
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--directory= and --image= may not be combined.");
 
         if (arg_template && arg_image)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "--template= and --image= may not be combined.");
-
-        if (arg_ephemeral && arg_template && !arg_directory) {
-                /* User asked for ephemeral execution but specified --template= instead of --directory=. Semantically
-                 * such an invocation makes some sense, see https://github.com/systemd/systemd/issues/3667. Let's
-                 * accept this here, and silently make "--ephemeral --template=" equivalent to "--ephemeral
-                 * --directory=". */
-
-                arg_directory = TAKE_PTR(arg_template);
-        }
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--template= and --image= may not be combined.");
 
         if (arg_template && !(arg_directory || arg_machine))
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "--template= needs --directory= or --machine=.");
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--template= needs --directory= or --machine=.");
 
         if (arg_ephemeral && arg_template)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "--ephemeral and --template= may not be combined.");
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--ephemeral and --template= may not be combined.");
 
         if (arg_ephemeral && !IN_SET(arg_link_journal, LINK_NO, LINK_AUTO))
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "--ephemeral and --link-journal= may not be combined.");
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--ephemeral and --link-journal= may not be combined.");
 
         if (arg_userns_mode != USER_NAMESPACE_NO && !userns_supported())
-                return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
-                                       "--private-users= is not supported, kernel compiled without user namespace support.");
+                return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "--private-users= is not supported, kernel compiled without user namespace support.");
 
         if (arg_userns_chown && arg_read_only)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "--read-only and --private-users-chown may not be combined.");
-
-        if (arg_network_bridge && arg_network_zone)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "--network-bridge= and --network-zone= may not be combined.");
-
-        if (argc > optind) {
-                arg_parameters = strv_copy(argv + optind);
-                if (!arg_parameters)
-                        return log_oom();
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--read-only and --private-users-chown may not be combined.");
 
-                arg_settings_mask |= SETTING_START_MODE;
-        }
-
-        /* Load all settings from .nspawn files */
-        if (mask_no_settings)
-                arg_settings_mask = 0;
-
-        /* Don't load any settings from .nspawn files */
-        if (mask_all_settings)
-                arg_settings_mask = _SETTINGS_MASK_ALL;
-
-        arg_caps_retain = (arg_caps_retain | plus | (arg_private_network ? 1ULL << CAP_NET_ADMIN : 0)) & ~minus;
-
-        r = custom_mount_check_all();
-        if (r < 0)
-                return r;
+        /* 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 (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))
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--network-namespace-path cannot be combined with other network options.");
 
-        return 1;
-}
+        if (arg_network_bridge && arg_network_zone)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--network-bridge= and --network-zone= may not be combined.");
 
-static int verify_arguments(void) {
         if (arg_userns_mode != USER_NAMESPACE_NO && (arg_mount_settings & MOUNT_APPLY_APIVFS_NETNS) && !arg_private_network)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "Invalid namespacing settings. Mounting sysfs with --private-users requires --private-network.");
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid namespacing settings. Mounting sysfs with --private-users requires --private-network.");
 
         if (arg_userns_mode != USER_NAMESPACE_NO && !(arg_mount_settings & MOUNT_APPLY_APIVFS_RO))
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "Cannot combine --private-users with read-write mounts.");
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot combine --private-users with read-write mounts.");
 
         if (arg_volatile_mode != VOLATILE_NO && arg_read_only)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "Cannot combine --read-only with --volatile. Note that --volatile already implies a read-only base hierarchy.");
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot combine --read-only with --volatile. Note that --volatile already implies a read-only base hierarchy.");
 
         if (arg_expose_ports && !arg_private_network)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "Cannot use --port= without private networking.");
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot use --port= without private networking.");
 
 #if ! HAVE_LIBIPTC
         if (arg_expose_ports)
-                return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
-                                       "--port= is not supported, compiled without libiptc support.");
+                return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "--port= is not supported, compiled without libiptc support.");
 #endif
 
-        if (arg_start_mode == START_BOOT && arg_kill_signal <= 0)
-                arg_kill_signal = SIGRTMIN+3;
+        r = custom_mount_check_all();
+        if (r < 0)
+                return r;
 
         return 0;
 }