]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/bus-unit-util.c
doc,core: Read{Write,Only}Paths= and InaccessiblePaths=
[thirdparty/systemd.git] / src / shared / bus-unit-util.c
index 2b755cea28bc390981454158f903106446c3fe8e..94ffa8af8721b373e6e4ed9b66c968f63f83e0e3 100644 (file)
@@ -83,18 +83,14 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
 
                 if (isempty(eq))
                         r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", USEC_INFINITY);
-                else if (endswith(eq, "%")) {
-                        double percent;
-
-                        if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
-                                log_error("CPU quota '%s' invalid.", eq);
+                else {
+                        r = parse_percent(eq);
+                        if (r <= 0) {
+                                log_error_errno(r, "CPU quota '%s' invalid.", eq);
                                 return -EINVAL;
                         }
 
-                        r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", (usec_t) percent * USEC_PER_SEC / 100);
-                } else {
-                        log_error("CPU quota needs to be in percent.");
-                        return -EINVAL;
+                        r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", (usec_t) r * USEC_PER_SEC / 100U);
                 }
 
                 goto finish;
@@ -110,6 +106,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 char *n;
                 usec_t t;
                 size_t l;
+
                 r = parse_sec(eq, &t);
                 if (r < 0)
                         return log_error_errno(r, "Failed to parse %s= parameter: %s", field, eq);
@@ -123,6 +120,34 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 strcpy(mempcpy(n, field, l - 3), "USec");
                 r = sd_bus_message_append(m, "sv", n, "t", t);
                 goto finish;
+
+        } else if (STR_IN_SET(field, "MemoryLow", "MemoryHigh", "MemoryMax", "MemoryLimit")) {
+                uint64_t bytes;
+
+                if (isempty(eq) || streq(eq, "infinity"))
+                        bytes = CGROUP_LIMIT_MAX;
+                else {
+                        r = parse_percent(eq);
+                        if (r >= 0) {
+                                char *n;
+
+                                /* When this is a percentage we'll convert this into a relative value in the range
+                                 * 0…UINT32_MAX and pass it in the MemoryLowByPhysicalMemory property (and related
+                                 * ones). This way the physical memory size can be determined server-side */
+
+                                n = strjoina(field, "ByPhysicalMemory");
+                                r = sd_bus_message_append(m, "sv", n, "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U));
+                                goto finish;
+
+                        } else {
+                                r = parse_size(eq, 1024, &bytes);
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to parse bytes specification %s", assignment);
+                        }
+                }
+
+                r = sd_bus_message_append(m, "sv", field, "t", bytes);
+                goto finish;
         }
 
         r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
@@ -154,11 +179,11 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 r = sd_bus_message_append(m, "sv", sn, "t", l.rlim_cur);
 
         } else if (STR_IN_SET(field,
-                       "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting",
+                       "CPUAccounting", "MemoryAccounting", "IOAccounting", "BlockIOAccounting", "TasksAccounting",
                        "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
                        "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit",
                        "PrivateTmp", "PrivateDevices", "PrivateNetwork", "NoNewPrivileges",
-                       "SyslogLevelPrefix", "Delegate", "RemainAfterElapse")) {
+                       "SyslogLevelPrefix", "Delegate", "RemainAfterElapse", "MemoryDenyWriteExecute")) {
 
                 r = parse_boolean(eq);
                 if (r < 0)
@@ -166,21 +191,6 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
 
                 r = sd_bus_message_append(m, "v", "b", r);
 
-        } else if (streq(field, "MemoryLimit")) {
-                uint64_t bytes;
-
-                if (isempty(eq) || streq(eq, "infinity"))
-                        bytes = (uint64_t) -1;
-                else {
-                        r = parse_size(eq, 1024, &bytes);
-                        if (r < 0) {
-                                log_error("Failed to parse bytes specification %s", assignment);
-                                return -EINVAL;
-                        }
-                }
-
-                r = sd_bus_message_append(m, "v", "t", bytes);
-
         } else if (streq(field, "TasksMax")) {
                 uint64_t n;
 
@@ -207,10 +217,21 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
 
                 r = sd_bus_message_append(m, "v", "t", u);
 
+        } else if (STR_IN_SET(field, "IOWeight", "StartupIOWeight")) {
+                uint64_t u;
+
+                r = cg_weight_parse(eq, &u);
+                if (r < 0) {
+                        log_error("Failed to parse %s value %s.", field, eq);
+                        return -EINVAL;
+                }
+
+                r = sd_bus_message_append(m, "v", "t", u);
+
         } else if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) {
                 uint64_t u;
 
-                r = cg_cpu_shares_parse(eq, &u);
+                r = cg_blkio_weight_parse(eq, &u);
                 if (r < 0) {
                         log_error("Failed to parse %s value %s.", field, eq);
                         return -EINVAL;
@@ -224,7 +245,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                               "StandardInput", "StandardOutput", "StandardError",
                               "Description", "Slice", "Type", "WorkingDirectory",
                               "RootDirectory", "SyslogIdentifier", "ProtectSystem",
-                              "ProtectHome"))
+                              "ProtectHome", "SELinuxContext"))
                 r = sd_bus_message_append(m, "v", "s", eq);
 
         else if (streq(field, "SyslogLevel")) {
@@ -273,7 +294,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                         r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
                 }
 
-        } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
+        } else if (cgroup_io_limit_type_from_string(field) >= 0 || STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
 
                 if (isempty(eq))
                         r = sd_bus_message_append(m, "v", "a(st)", 0);
@@ -295,16 +316,20 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                                 return -EINVAL;
                         }
 
-                        r = parse_size(bandwidth, 1000, &bytes);
-                        if (r < 0) {
-                                log_error("Failed to parse byte value %s.", bandwidth);
-                                return -EINVAL;
+                        if (streq(bandwidth, "infinity")) {
+                                bytes = CGROUP_LIMIT_MAX;
+                        } else {
+                                r = parse_size(bandwidth, 1000, &bytes);
+                                if (r < 0) {
+                                        log_error("Failed to parse byte value %s.", bandwidth);
+                                        return -EINVAL;
+                                }
                         }
 
                         r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes);
                 }
 
-        } else if (streq(field, "BlockIODeviceWeight")) {
+        } else if (STR_IN_SET(field, "IODeviceWeight", "BlockIODeviceWeight")) {
 
                 if (isempty(eq))
                         r = sd_bus_message_append(m, "v", "a(st)", 0);
@@ -331,7 +356,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                                 log_error("Failed to parse %s value %s.", field, weight);
                                 return -EINVAL;
                         }
-                        r = sd_bus_message_append(m, "v", "a(st)", path, u);
+                        r = sd_bus_message_append(m, "v", "a(st)", 1, path, u);
                 }
 
         } else if (streq(field, "Nice")) {
@@ -428,7 +453,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 }
 
                 r = sd_bus_message_append(m, "v", "i", oa);
-        } else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories")) {
+        } else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
+                              "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
                 const char *p;
 
                 r = sd_bus_message_open_container(m, 'v', "as");
@@ -850,6 +876,11 @@ int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, Un
         const char *type, *path, *source;
         int r;
 
+        /* changes is dereferenced when calling unit_file_dump_changes() later,
+         * so we have to make sure this is not NULL. */
+        assert(changes);
+        assert(n_changes);
+
         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
         if (r < 0)
                 return bus_log_parse_error(r);
@@ -1072,7 +1103,7 @@ static int dump_processes(
                         }
 
                         more = i+1 < n || cg->children;
-                        special = draw_special_char(more ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT);
+                        special = special_glyph(more ? TREE_BRANCH : TREE_RIGHT);
 
                         fprintf(stdout, "%s%s%*"PID_PRI" %s\n",
                                 prefix,
@@ -1093,7 +1124,8 @@ static int dump_processes(
                 assert(n == cg->n_children);
                 qsort_safe(children, n, sizeof(struct CGroupInfo*), cgroup_info_compare_func);
 
-                n_columns = MAX(LESS_BY(n_columns, 2U), 20U);
+                if (n_columns != 0)
+                        n_columns = MAX(LESS_BY(n_columns, 2U), 20U);
 
                 for (i = 0; i < n; i++) {
                         _cleanup_free_ char *pp = NULL;
@@ -1108,14 +1140,14 @@ static int dump_processes(
                         name++;
 
                         more = i+1 < n;
-                        special = draw_special_char(more ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT);
+                        special = special_glyph(more ? TREE_BRANCH : TREE_RIGHT);
 
                         fputs(prefix, stdout);
                         fputs(special, stdout);
                         fputs(name, stdout);
                         fputc('\n', stdout);
 
-                        special = draw_special_char(more ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE);
+                        special = special_glyph(more ? TREE_VERTICAL : TREE_SPACE);
 
                         pp = strappend(prefix, special);
                         if (!pp)
@@ -1199,7 +1231,7 @@ static int dump_extra_processes(
 
                 fprintf(stdout, "%s%s %*" PID_PRI " %s\n",
                         prefix,
-                        draw_special_char(DRAW_TRIANGULAR_BULLET),
+                        special_glyph(TRIANGULAR_BULLET),
                         width, pids[k],
                         name);
         }