summaryrefslogtreecommitdiff
path: root/src/core/dbus-cgroup.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-11-19 21:12:59 +0100
committerLennart Poettering <lennart@poettering.net>2013-11-20 20:52:36 +0100
commit718db96199eb307751264e4163555662c9a389fa (patch)
tree9ec8467596ba1acba76bb6273c7797baf68c1a00 /src/core/dbus-cgroup.c
parent3febea3a0b0a968ea281e7959c1654cbaf95c9bf (diff)
core: convert PID 1 to libsystemd-bus
This patch converts PID 1 to libsystemd-bus and thus drops the dependency on libdbus. The only remaining code using libdbus is a test case that validates our bus marshalling against libdbus' marshalling, and this dependency can be turned off. This patch also adds a couple of things to libsystem-bus, that are necessary to make the port work: - Synthesizing of "Disconnected" messages when bus connections are severed. - Support for attaching multiple vtables for the same interface on the same path. This patch also fixes the SetDefaultTarget() and GetDefaultTarget() bus calls which used an inappropriate signature. As a side effect we will now generate PropertiesChanged messages which carry property contents, rather than just invalidation information.
Diffstat (limited to 'src/core/dbus-cgroup.c')
-rw-r--r--src/core/dbus-cgroup.c347
1 files changed, 155 insertions, 192 deletions
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index f198357637..4dbb83a769 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -19,147 +19,159 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <dbus/dbus.h>
-
+#include "bus-util.h"
#include "path-util.h"
+#include "cgroup-util.h"
+#include "cgroup.h"
#include "dbus-cgroup.h"
-static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_cgroup_append_device_policy, cgroup_device_policy, CGroupDevicePolicy);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy);
+
+static int property_get_blockio_device_weight(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ sd_bus_error *error,
+ void *userdata) {
-static int bus_cgroup_append_device_weights(DBusMessageIter *i, const char *property, void *data) {
- DBusMessageIter sub, sub2;
- CGroupContext *c = data;
+ CGroupContext *c = userdata;
CGroupBlockIODeviceWeight *w;
+ int r;
- assert(i);
- assert(property);
+ assert(bus);
+ assert(reply);
assert(c);
- if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(st)", &sub))
- return -ENOMEM;
+ r = sd_bus_message_open_container(reply, 'a', "(st)");
+ if (r < 0)
+ return r;
LIST_FOREACH(device_weights, w, c->blockio_device_weights) {
-
- if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
- !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &w->path) ||
- !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &w->weight) ||
- !dbus_message_iter_close_container(&sub, &sub2))
- return -ENOMEM;
+ r = sd_bus_message_append(reply, "(st)", w->path, w->weight);
+ if (r < 0)
+ return r;
}
- if (!dbus_message_iter_close_container(i, &sub))
- return -ENOMEM;
-
- return 0;
+ return sd_bus_message_close_container(reply);
}
-static int bus_cgroup_append_device_bandwidths(DBusMessageIter *i, const char *property, void *data) {
- DBusMessageIter sub, sub2;
- CGroupContext *c = data;
+static int property_get_blockio_device_bandwidths(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ sd_bus_error *error,
+ void *userdata) {
+
+ CGroupContext *c = userdata;
CGroupBlockIODeviceBandwidth *b;
+ int r;
- assert(i);
- assert(property);
+ assert(bus);
+ assert(reply);
assert(c);
- if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(st)", &sub))
- return -ENOMEM;
+ r = sd_bus_message_open_container(reply, 'a', "(st)");
+ if (r < 0)
+ return r;
LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
if (streq(property, "BlockIOReadBandwidth") != b->read)
continue;
- if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
- !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &b->path) ||
- !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &b->bandwidth) ||
- !dbus_message_iter_close_container(&sub, &sub2))
- return -ENOMEM;
+ r = sd_bus_message_append(reply, "(st)", b->path, b->bandwidth);
+ if (r < 0)
+ return r;
}
- if (!dbus_message_iter_close_container(i, &sub))
- return -ENOMEM;
-
- return 0;
+ return sd_bus_message_close_container(reply);
}
-static int bus_cgroup_append_device_allow(DBusMessageIter *i, const char *property, void *data) {
- DBusMessageIter sub, sub2;
- CGroupContext *c = data;
+static int property_get_device_allow(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ sd_bus_error *error,
+ void *userdata) {
+
+ CGroupContext *c = userdata;
CGroupDeviceAllow *a;
+ int r;
- assert(i);
- assert(property);
+ assert(bus);
+ assert(reply);
assert(c);
- if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(ss)", &sub))
- return -ENOMEM;
+ r = sd_bus_message_open_container(reply, 'a', "(ss)");
+ if (r < 0)
+ return r;
LIST_FOREACH(device_allow, a, c->device_allow) {
- const char *rwm;
- char buf[4];
unsigned k = 0;
+ char rwm[4];
if (a->r)
- buf[k++] = 'r';
+ rwm[k++] = 'r';
if (a->w)
- buf[k++] = 'w';
+ rwm[k++] = 'w';
if (a->m)
- buf[k++] = 'm';
+ rwm[k++] = 'm';
- buf[k] = 0;
- rwm = buf;
+ rwm[k] = 0;
- if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
- !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->path) ||
- !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &rwm) ||
- !dbus_message_iter_close_container(&sub, &sub2))
- return -ENOMEM;
+ r = sd_bus_message_append(reply, "(ss)", a->path, rwm);
+ if (r < 0)
+ return r;
}
- if (!dbus_message_iter_close_container(i, &sub))
- return -ENOMEM;
-
- return 0;
+ return sd_bus_message_close_container(reply);
}
-const BusProperty bus_cgroup_context_properties[] = {
- { "CPUAccounting", bus_property_append_bool, "b", offsetof(CGroupContext, cpu_accounting) },
- { "CPUShares", bus_property_append_ul, "t", offsetof(CGroupContext, cpu_shares) },
- { "BlockIOAccounting", bus_property_append_bool, "b", offsetof(CGroupContext, blockio_accounting) },
- { "BlockIOWeight", bus_property_append_ul, "t", offsetof(CGroupContext, blockio_weight) },
- { "BlockIODeviceWeight", bus_cgroup_append_device_weights, "a(st)", 0 },
- { "BlockIOReadBandwidth", bus_cgroup_append_device_bandwidths, "a(st)", 0 },
- { "BlockIOWriteBandwidth", bus_cgroup_append_device_bandwidths, "a(st)", 0 },
- { "MemoryAccounting", bus_property_append_bool, "b", offsetof(CGroupContext, memory_accounting) },
- { "MemoryLimit", bus_property_append_uint64, "t", offsetof(CGroupContext, memory_limit) },
- { "DevicePolicy", bus_cgroup_append_device_policy, "s", offsetof(CGroupContext, device_policy) },
- { "DeviceAllow", bus_cgroup_append_device_allow, "a(ss)", 0 },
- {}
+const sd_bus_vtable bus_cgroup_vtable[] = {
+ SD_BUS_VTABLE_START(0),
+ SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, cpu_accounting), 0),
+ SD_BUS_PROPERTY("CPUShares", "t", bus_property_get_ulong, offsetof(CGroupContext, cpu_shares), 0),
+ SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, blockio_accounting), 0),
+ SD_BUS_PROPERTY("BlockIOWeight", "t", bus_property_get_ulong, offsetof(CGroupContext, blockio_weight), 0),
+ SD_BUS_PROPERTY("BlockIODeviceWeight", "a(st)", property_get_blockio_device_weight, 0, 0),
+ SD_BUS_PROPERTY("BlockIOReadBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
+ SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
+ SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, memory_accounting), 0),
+ SD_BUS_PROPERTY("MemoryLimit", "t", NULL, offsetof(CGroupContext, memory_limit), 0),
+ SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0),
+ SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0),
+ SD_BUS_VTABLE_END
};
int bus_cgroup_set_property(
Unit *u,
CGroupContext *c,
const char *name,
- DBusMessageIter *i,
+ sd_bus_message *message,
UnitSetPropertiesMode mode,
- DBusError *error) {
+ sd_bus_error *error) {
+
+ int r;
- assert(name);
assert(u);
assert(c);
- assert(i);
+ assert(name);
+ assert(message);
if (streq(name, "CPUAccounting")) {
+ int b;
- if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN)
- return -EINVAL;
+ r = sd_bus_message_read(message, "b", &b);
+ if (r < 0)
+ return r;
if (mode != UNIT_CHECK) {
- dbus_bool_t b;
- dbus_message_iter_get_basic(i, &b);
-
c->cpu_accounting = b;
unit_write_drop_in_private(u, mode, name, b ? "CPUAccounting=yes" : "CPUAccounting=no");
}
@@ -170,14 +182,13 @@ int bus_cgroup_set_property(
uint64_t u64;
unsigned long ul;
- if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64)
- return -EINVAL;
+ r = sd_bus_message_read(message, "t", &u64);
+ if (r < 0)
+ return r;
- dbus_message_iter_get_basic(i, &u64);
ul = (unsigned long) u64;
-
- if (u64 <= 0 || u64 != (uint64_t) ul)
- return -EINVAL;
+ if (ul <= 0 || (uint64_t) ul != u64)
+ return sd_bus_error_set_errnof(error, EINVAL, "CPUShares value out of range");
if (mode != UNIT_CHECK) {
c->cpu_shares = ul;
@@ -187,14 +198,13 @@ int bus_cgroup_set_property(
return 1;
} else if (streq(name, "BlockIOAccounting")) {
+ int b;
- if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN)
- return -EINVAL;
+ r = sd_bus_message_read(message, "b", &b);
+ if (r < 0)
+ return r;
if (mode != UNIT_CHECK) {
- dbus_bool_t b;
- dbus_message_iter_get_basic(i, &b);
-
c->blockio_accounting = b;
unit_write_drop_in_private(u, mode, name, b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no");
}
@@ -205,14 +215,13 @@ int bus_cgroup_set_property(
uint64_t u64;
unsigned long ul;
- if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64)
- return -EINVAL;
+ r = sd_bus_message_read(message, "t", &u64);
+ if (r < 0)
+ return r;
- dbus_message_iter_get_basic(i, &u64);
ul = (unsigned long) u64;
-
- if (u64 < 10 || u64 > 1000)
- return -EINVAL;
+ if (ul < 10 || ul > 1000)
+ return sd_bus_error_set_errnof(error, EINVAL, "BlockIOWeight value out of range");
if (mode != UNIT_CHECK) {
c->blockio_weight = ul;
@@ -222,42 +231,31 @@ int bus_cgroup_set_property(
return 1;
} else if (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth")) {
- DBusMessageIter sub;
- unsigned n = 0;
+ const char *path;
bool read = true;
+ unsigned n = 0;
+ uint64_t u64;
if (streq(name, "BlockIOWriteBandwidth"))
read = false;
- if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(i) != DBUS_TYPE_STRUCT)
- return -EINVAL;
-
- dbus_message_iter_recurse(i, &sub);
- while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
- DBusMessageIter sub2;
- const char *path;
- uint64_t u64;
+ r = sd_bus_message_enter_container(message, 'a', "(st)");
+ if (r < 0)
+ return r;
- 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, &u64, false) < 0)
- return -EINVAL;
+ while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) {
if (mode != UNIT_CHECK) {
- CGroupBlockIODeviceBandwidth *a = NULL;
- CGroupBlockIODeviceBandwidth *b;
- bool exist = false;
+ CGroupBlockIODeviceBandwidth *a = NULL, *b;
LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
if (path_equal(path, b->path) && read == b->read) {
a = b;
- exist = true;
break;
}
}
- if (!exist) {
+ if (!a) {
a = new0(CGroupBlockIODeviceBandwidth, 1);
if (!a)
return -ENOMEM;
@@ -268,23 +266,22 @@ int bus_cgroup_set_property(
free(a);
return -ENOMEM;
}
+
+ LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, a);
}
a->bandwidth = u64;
-
- if (!exist)
- LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, a);
}
n++;
- dbus_message_iter_next(&sub);
}
+ if (r < 0)
+ return r;
if (mode != UNIT_CHECK) {
+ CGroupBlockIODeviceBandwidth *a, *next;
_cleanup_free_ char *buf = NULL;
_cleanup_fclose_ FILE *f = NULL;
- CGroupBlockIODeviceBandwidth *a;
- CGroupBlockIODeviceBandwidth *next;
size_t size = 0;
if (n == 0) {
@@ -316,44 +313,32 @@ int bus_cgroup_set_property(
return 1;
} else if (streq(name, "BlockIODeviceWeight")) {
- DBusMessageIter sub;
+ const char *path;
+ uint64_t u64;
unsigned n = 0;
- if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(i) != DBUS_TYPE_STRUCT)
- return -EINVAL;
+ r = sd_bus_message_enter_container(message, 'a', "(st)");
+ if (r < 0)
+ return r;
- dbus_message_iter_recurse(i, &sub);
- while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
- DBusMessageIter sub2;
- const char *path;
- uint64_t u64;
+ while (( r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) {
unsigned long ul;
- 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, &u64, false) < 0)
- return -EINVAL;
-
ul = (unsigned long) u64;
if (ul < 10 || ul > 1000)
- return -EINVAL;
+ return sd_bus_error_set_errnof(error, EINVAL, "BlockIODeviceWeight out of range");
if (mode != UNIT_CHECK) {
- CGroupBlockIODeviceWeight *a = NULL;
- CGroupBlockIODeviceWeight *b;
- bool exist = false;
+ CGroupBlockIODeviceWeight *a = NULL, *b;
LIST_FOREACH(device_weights, b, c->blockio_device_weights) {
if (path_equal(b->path, path)) {
a = b;
- exist = true;
break;
}
}
- if (!exist) {
+ if (!a) {
a = new0(CGroupBlockIODeviceWeight, 1);
if (!a)
return -ENOMEM;
@@ -363,16 +348,13 @@ int bus_cgroup_set_property(
free(a);
return -ENOMEM;
}
+ LIST_PREPEND(device_weights,c->blockio_device_weights, a);
}
a->weight = ul;
-
- if (!exist)
- LIST_PREPEND(device_weights,c->blockio_device_weights, a);
}
n++;
- dbus_message_iter_next(&sub);
}
if (mode != UNIT_CHECK) {
@@ -401,14 +383,13 @@ int bus_cgroup_set_property(
return 1;
} else if (streq(name, "MemoryAccounting")) {
+ int b;
- if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN)
- return -EINVAL;
+ r = sd_bus_message_read(message, "b", &b);
+ if (r < 0)
+ return r;
if (mode != UNIT_CHECK) {
- dbus_bool_t b;
- dbus_message_iter_get_basic(i, &b);
-
c->memory_accounting = b;
unit_write_drop_in_private(u, mode, name, b ? "MemoryAccounting=yes" : "MemoryAccounting=no");
}
@@ -416,14 +397,13 @@ int bus_cgroup_set_property(
return 1;
} else if (streq(name, "MemoryLimit")) {
+ uint64_t limit;
- if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64)
- return -EINVAL;
+ r = sd_bus_message_read(message, "t", &limit);
+ if (r < 0)
+ return r;
if (mode != UNIT_CHECK) {
- uint64_t limit;
- dbus_message_iter_get_basic(i, &limit);
-
c->memory_limit = limit;
unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64, name, limit);
}
@@ -434,10 +414,10 @@ int bus_cgroup_set_property(
const char *policy;
CGroupDevicePolicy p;
- if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING)
- return -EINVAL;
+ r = sd_bus_message_read(message, "s", &policy);
+ if (r < 0)
+ return r;
- dbus_message_iter_get_basic(i, &policy);
p = cgroup_device_policy_from_string(policy);
if (p < 0)
return -EINVAL;
@@ -454,51 +434,35 @@ int bus_cgroup_set_property(
return 1;
} else if (streq(name, "DeviceAllow")) {
- DBusMessageIter sub;
+ const char *path, *rwm;
unsigned n = 0;
- if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(i) != DBUS_TYPE_STRUCT)
- return -EINVAL;
-
- dbus_message_iter_recurse(i, &sub);
- while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
- DBusMessageIter sub2;
- const char *path, *rwm;
+ r = sd_bus_message_enter_container(message, 'a', "(ss)");
+ if (r < 0)
+ return r;
- dbus_message_iter_recurse(&sub, &sub2);
+ while ((r = sd_bus_message_read(message, "(ss)", &path, &rwm)) > 0) {
- if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &rwm, false) < 0)
- return -EINVAL;
-
- if (!path_startswith(path, "/dev")) {
- dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "DeviceAllow= requires device node");
- return -EINVAL;
- }
+ if (!path_startswith(path, "/dev"))
+ return sd_bus_error_set_errnof(error, EINVAL, "DeviceAllow= requires device node");
if (isempty(rwm))
rwm = "rwm";
- if (!in_charset(rwm, "rwm")) {
- dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "DeviceAllow= requires combination of rwm flags");
- return -EINVAL;
- }
+ if (!in_charset(rwm, "rwm"))
+ return sd_bus_error_set_errnof(error, EINVAL, "DeviceAllow= requires combination of rwm flags");
if (mode != UNIT_CHECK) {
- CGroupDeviceAllow *a = NULL;
- CGroupDeviceAllow *b;
- bool exist = false;
+ CGroupDeviceAllow *a = NULL, *b;
LIST_FOREACH(device_allow, b, c->device_allow) {
if (path_equal(b->path, path)) {
a = b;
- exist = true;
break;
}
}
- if (!exist) {
+ if (!a) {
a = new0(CGroupDeviceAllow, 1);
if (!a)
return -ENOMEM;
@@ -508,18 +472,17 @@ int bus_cgroup_set_property(
free(a);
return -ENOMEM;
}
+
+ LIST_PREPEND(device_allow, c->device_allow, a);
}
a->r = !!strchr(rwm, 'r');
a->w = !!strchr(rwm, 'w');
a->m = !!strchr(rwm, 'm');
- if (!exist)
- LIST_PREPEND(device_allow, c->device_allow, a);
}
n++;
- dbus_message_iter_next(&sub);
}
if (mode != UNIT_CHECK) {