]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pid1: parse CPUAffinity= in incremental fashion
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 24 May 2019 06:35:51 +0000 (08:35 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 29 May 2019 08:29:28 +0000 (10:29 +0200)
This makes the handling of this option match what we do in unit files. I think
consistency is important here. (As it happens, it is the only option in
system.conf that is "non-atomic", i.e. where there's a list of things which can
be split over multiple assignments. All other options are single-valued, so
there's no issue of how to handle multiple assignments.)

man/systemd-system.conf.xml
man/systemd.exec.xml
src/core/main.c

index 41baff8bfe65b882386a39c13753c5be87f98597..f5d419c5196a4b30ba3bd46b5250a9bdf5419a58 100644 (file)
       <varlistentry>
         <term><varname>CPUAffinity=</varname></term>
 
-        <listitem><para>Configures the CPU affinity for the service manager as well as the default CPU affinity for all
-        forked off processes. Takes a list of CPU indices or ranges separated by either whitespace or commas. CPU
-        ranges are specified by the lower and upper CPU indices separated by a dash. Individual services may override
-        the CPU affinity for their processes with the <varname>CPUAffinity=</varname> setting in unit files, see
+        <listitem><para>Configures the CPU affinity for the service manager as well as the default CPU
+        affinity for all forked off processes. Takes a list of CPU indices or ranges separated by either
+        whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated by a
+        dash. This option may be specified more than once, in which case the specified CPU affinity masks are
+        merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have
+        no effect. Individual services may override the CPU affinity for their processes with the
+        <varname>CPUAffinity=</varname> setting in unit files, see
         <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
       </varlistentry>
 
index 719c2c5ff3f864460a7c41506c4e0eedeceadcd4..d65b842f44c00954c8b1a168d1e11b85d62cd756 100644 (file)
@@ -754,7 +754,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
 
         <listitem><para>Controls the CPU affinity of the executed processes. Takes a list of CPU indices or ranges
         separated by either whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated
-        by a dash.  This option may be specified more than once, in which case the specified CPU affinity masks are
+        by a dash. This option may be specified more than once, in which case the specified CPU affinity masks are
         merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have no
         effect. See
         <citerefentry><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
index 67a62a5ad27b10fd14d261597d2d87875941c890..1f8356675765b782be1d908c1da9c22b08fc6aad 100644 (file)
@@ -139,6 +139,8 @@ static sd_id128_t arg_machine_id = {};
 static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
 static OOMPolicy arg_default_oom_policy = OOM_STOP;
 
+static CPUSet arg_cpu_affinity = {};
+
 _noreturn_ static void freeze_or_exit_or_reboot(void) {
 
         /* If we are running in a container, let's prefer exiting, after all we can propagate an exit code to
@@ -567,17 +569,11 @@ static int config_parse_cpu_affinity2(
                 void *data,
                 void *userdata) {
 
-        _cleanup_(cpu_set_reset) CPUSet c = {};
-        int r;
+        CPUSet *affinity = data;
 
-        r = parse_cpu_set_full(rvalue, &c, true, unit, filename, line, lvalue);
-        if (r < 0)
-                return r;
+        assert(affinity);
 
-        if (sched_setaffinity(0, c.allocated, c.set) < 0)
-                log_warning_errno(errno, "Failed to set CPU affinity: %m");
-
-        // FIXME: parsing and execution should be seperated.
+        (void) parse_cpu_set_extend(rvalue, affinity, true, unit, filename, line, lvalue);
 
         return 0;
 }
@@ -719,7 +715,7 @@ static int parse_config_file(void) {
                 { "Manager", "CrashShell",                config_parse_bool,             0, &arg_crash_shell                       },
                 { "Manager", "CrashReboot",               config_parse_bool,             0, &arg_crash_reboot                      },
                 { "Manager", "ShowStatus",                config_parse_show_status,      0, &arg_show_status                       },
-                { "Manager", "CPUAffinity",               config_parse_cpu_affinity2,    0, NULL                                   },
+                { "Manager", "CPUAffinity",               config_parse_cpu_affinity2,    0, &arg_cpu_affinity                      },
                 { "Manager", "JoinControllers",           config_parse_warn_compat,      DISABLED_CONFIGURATION, NULL              },
                 { "Manager", "RuntimeWatchdogSec",        config_parse_sec,              0, &arg_runtime_watchdog                  },
                 { "Manager", "ShutdownWatchdogSec",       config_parse_sec,              0, &arg_shutdown_watchdog                 },
@@ -1733,6 +1729,21 @@ static void initialize_core_pattern(bool skip_setup) {
                 log_warning_errno(r, "Failed to write '%s' to /proc/sys/kernel/core_pattern, ignoring: %m", arg_early_core_pattern);
 }
 
+static void update_cpu_affinity(bool skip_setup) {
+        _cleanup_free_ char *mask = NULL;
+
+        if (skip_setup || !arg_cpu_affinity.set)
+                return;
+
+        assert(arg_cpu_affinity.allocated > 0);
+
+        mask = cpu_set_to_string(&arg_cpu_affinity);
+        log_debug("Setting CPU affinity to %s.", strnull(mask));
+
+        if (sched_setaffinity(0, arg_cpu_affinity.allocated, arg_cpu_affinity.set) < 0)
+                log_warning_errno(errno, "Failed to set CPU affinity: %m");
+}
+
 static void do_reexecute(
                 int argc,
                 char *argv[],
@@ -1905,6 +1916,8 @@ static int invoke_main_loop(
 
                         set_manager_defaults(m);
 
+                        update_cpu_affinity(false);
+
                         if (saved_log_level >= 0)
                                 manager_override_log_level(m, saved_log_level);
                         if (saved_log_target >= 0)
@@ -2063,6 +2076,8 @@ static int initialize_runtime(
         if (arg_action != ACTION_RUN)
                 return 0;
 
+        update_cpu_affinity(skip_setup);
+
         if (arg_system) {
                 /* Make sure we leave a core dump without panicking the kernel. */
                 install_crash_handler();
@@ -2195,6 +2210,8 @@ static void free_arguments(void) {
         arg_confirm_spawn = mfree(arg_confirm_spawn);
         arg_default_environment = strv_free(arg_default_environment);
         arg_syscall_archs = set_free(arg_syscall_archs);
+
+        cpu_set_reset(&arg_cpu_affinity);
 }
 
 static int load_configuration(int argc, char **argv, const char **ret_error_message) {