chiark / gitweb /
shut up gcc complaining about freeing a const variable
[elogind.git] / src / systemctl / systemctl.c
index a635891bc015fc94124c71a875fc9dc86e1991d2..57e5bb941b50338db49ce2a6fd16872640318dc3 100644 (file)
@@ -1495,6 +1495,7 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me
         } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
                 uint32_t id;
                 const char *path, *result, *unit;
+                char *r;
 
                 if (dbus_message_get_args(message, &error,
                                           DBUS_TYPE_UINT32, &id,
@@ -1503,7 +1504,11 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me
                                           DBUS_TYPE_STRING, &result,
                                           DBUS_TYPE_INVALID)) {
 
-                        free(set_remove(d->set, (char*) path));
+                        r = set_remove(d->set, (char*) path);
+                        if (!r)
+                                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+                        free(r);
 
                         if (!isempty(result))
                                 d->result = strdup(result);
@@ -1523,7 +1528,11 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me
                         /* Compatibility with older systemd versions <
                          * 183 during upgrades. This should be dropped
                          * one day. */
-                        free(set_remove(d->set, (char*) path));
+                        r = set_remove(d->set, (char*) path);
+                        if (!r)
+                                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+                        free(r);
 
                         if (*result)
                                 d->result = strdup(result);
@@ -3315,6 +3324,24 @@ static int print_property(const char *name, DBusMessageIter *iter) {
                         }
                         return 0;
 
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "BlockIODeviceWeight")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *path;
+                                uint64_t weight;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &weight, false) >= 0)
+                                        printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
+
+                                dbus_message_iter_next(&sub);
+                        }
+                        return 0;
+
                 } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
                         DBusMessageIter sub, sub2;
 
@@ -3685,6 +3712,11 @@ static int append_assignment(DBusMessageIter *iter, const char *assignment) {
                                 rwm = "";
                         }
 
+                        if (!path_startswith(path, "/dev")) {
+                                log_error("%s is not a device file in /dev.", path);
+                                return -EINVAL;
+                        }
+
                         if (!dbus_message_iter_open_container(&sub2, DBUS_TYPE_STRUCT, NULL, &sub3) ||
                             !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &path) ||
                             !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &rwm) ||
@@ -3695,6 +3727,94 @@ static int append_assignment(DBusMessageIter *iter, const char *assignment) {
                 if (!dbus_message_iter_close_container(&sub, &sub2))
                         return log_oom();
 
+        } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
+                DBusMessageIter sub2;
+
+                if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a(st)", &sub) ||
+                    !dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "(st)", &sub2))
+                        return log_oom();
+
+                if (!isempty(eq)) {
+                        const char *path, *bandwidth;
+                        DBusMessageIter sub3;
+                        uint64_t u;
+                        off_t bytes;
+                        char *e;
+
+                        e = strchr(eq, ' ');
+                        if (e) {
+                                path = strndupa(eq, e - eq);
+                                bandwidth = e+1;
+                        } else {
+                                log_error("Failed to parse %s value %s.", field, eq);
+                                return -EINVAL;
+                        }
+
+                        if (!path_startswith(path, "/dev")) {
+                                log_error("%s is not a device file in /dev.", path);
+                                return -EINVAL;
+                        }
+
+                        r = parse_bytes(bandwidth, &bytes);
+                        if (r < 0) {
+                                log_error("Failed to parse byte value %s.", bandwidth);
+                                return -EINVAL;
+                        }
+
+                        u = (uint64_t) bytes;
+
+                        if (!dbus_message_iter_open_container(&sub2, DBUS_TYPE_STRUCT, NULL, &sub3) ||
+                            !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &path) ||
+                            !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_UINT64, &u) ||
+                            !dbus_message_iter_close_container(&sub2, &sub3))
+                                return log_oom();
+                }
+
+                if (!dbus_message_iter_close_container(&sub, &sub2))
+                        return log_oom();
+
+        } else if (streq(field, "BlockIODeviceWeight")) {
+                DBusMessageIter sub2;
+
+                if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a(st)", &sub) ||
+                    !dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "(st)", &sub2))
+                        return log_oom();
+
+                if (!isempty(eq)) {
+                        const char *path, *weight;
+                        DBusMessageIter sub3;
+                        uint64_t u;
+                        char *e;
+
+                        e = strchr(eq, ' ');
+                        if (e) {
+                                path = strndupa(eq, e - eq);
+                                weight = e+1;
+                        } else {
+                                log_error("Failed to parse %s value %s.", field, eq);
+                                return -EINVAL;
+                        }
+
+                        if (!path_startswith(path, "/dev")) {
+                                log_error("%s is not a device file in /dev.", path);
+                                return -EINVAL;
+                        }
+
+                        r = safe_atou64(weight, &u);
+                        if (r < 0) {
+                                log_error("Failed to parse %s value %s.", field, weight);
+                                return -EINVAL;
+                        }
+                        if (!dbus_message_iter_open_container(&sub2, DBUS_TYPE_STRUCT, NULL, &sub3) ||
+                            !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &path) ||
+                            !dbus_message_iter_append_basic(&sub3, DBUS_TYPE_UINT64, &u) ||
+                            !dbus_message_iter_close_container(&sub2, &sub3))
+                                return log_oom();
+                }
+
+                if (!dbus_message_iter_close_container(&sub, &sub2))
+                        return log_oom();
+
         } else {
                 log_error("Unknown assignment %s.", assignment);
                 return -EINVAL;