systemd-run: add new --property= switch that can set arbitrary properties for the unit that is created

The code for parsing these properties is shared with "systemctl
set-property", which means all the resource control settings are
immediately available.
This commit is contained in:
Lennart Poettering
2014-03-05 03:36:22 +01:00
parent 53ede806cb
commit df31a6c0fe
5 changed files with 234 additions and 182 deletions
+1 -158
View File
@@ -4019,163 +4019,6 @@ static int show(sd_bus *bus, char **args) {
return ret;
}
static int append_assignment(sd_bus_message *m, const char *assignment) {
const char *eq;
char *field;
int r;
assert(m);
assert(assignment);
eq = strchr(assignment, '=');
if (!eq) {
log_error("Not an assignment: %s", assignment);
return -EINVAL;
}
field = strndupa(assignment, eq - assignment);
eq ++;
r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
if (r < 0)
return bus_log_create_error(r);
if (streq(field, "CPUAccounting") ||
streq(field, "MemoryAccounting") ||
streq(field, "BlockIOAccounting")) {
r = parse_boolean(eq);
if (r < 0) {
log_error("Failed to parse boolean assignment %s.", assignment);
return -EINVAL;
}
r = sd_bus_message_append(m, "v", "b", r);
} else if (streq(field, "MemoryLimit")) {
off_t bytes;
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", (uint64_t) bytes);
} else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
uint64_t u;
r = safe_atou64(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 (streq(field, "DevicePolicy"))
r = sd_bus_message_append(m, "v", "s", eq);
else if (streq(field, "DeviceAllow")) {
if (isempty(eq))
r = sd_bus_message_append(m, "v", "a(ss)", 0);
else {
const char *path, *rwm;
char *e;
e = strchr(eq, ' ');
if (e) {
path = strndupa(eq, e - eq);
rwm = e+1;
} else {
path = eq;
rwm = "";
}
if (!path_startswith(path, "/dev")) {
log_error("%s is not a device file in /dev.", path);
return -EINVAL;
}
r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
}
} else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
if (isempty(eq))
r = sd_bus_message_append(m, "v", "a(st)", 0);
else {
const char *path, *bandwidth;
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_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, (uint64_t) bytes);
}
} else if (streq(field, "BlockIODeviceWeight")) {
if (isempty(eq))
r = sd_bus_message_append(m, "v", "a(st)", 0);
else {
const char *path, *weight;
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;
}
r = sd_bus_message_append(m, "v", "a(st)", path, u);
}
} else {
log_error("Unknown assignment %s.", assignment);
return -EINVAL;
}
if (r < 0)
return bus_log_create_error(r);
return 0;
}
static int set_property(sd_bus *bus, char **args) {
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -4210,7 +4053,7 @@ static int set_property(sd_bus *bus, char **args) {
if (r < 0)
return bus_log_create_error(r);
r = append_assignment(m, *i);
r = bus_append_unit_property_assignment(m, *i);
if (r < 0)
return r;