X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fload-fragment.c;h=74454abe49888bce1232ce9504e0fc07a9aa589d;hp=2b10d72ab331893ed07e19de08290eafa6b54f8e;hb=ddca82aca08712a302cfabdbe59f73ee9ed3f73a;hpb=c2756a68401102786be343712c0c35acbd73d28d diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 2b10d72ab..74454abe4 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -99,9 +99,12 @@ int config_parse_unit_deps(const char* unit, if (!t) return log_oom(); - k = unit_name_printf(u, t); - if (!k) - return log_oom(); + r = unit_name_printf(u, t, &k); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", strerror(-r)); + continue; + } r = unit_add_dependency_by_name(u, d, k, NULL, true); if (r < 0) @@ -124,16 +127,17 @@ int config_parse_unit_string_printf(const char *unit, Unit *u = userdata; _cleanup_free_ char *k = NULL; + int r; assert(filename); assert(lvalue); assert(rvalue); assert(u); - k = unit_full_printf(u, rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + r = unit_full_printf(u, rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); return config_parse_string(unit, filename, line, section, lvalue, ltype, k ? k : rvalue, data, userdata); @@ -151,16 +155,17 @@ int config_parse_unit_strv_printf(const char *unit, Unit *u = userdata; _cleanup_free_ char *k = NULL; + int r; assert(filename); assert(lvalue); assert(rvalue); assert(u); - k = unit_full_printf(u, rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + r = unit_full_printf(u, rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); return config_parse_strv(unit, filename, line, section, lvalue, ltype, k ? k : rvalue, data, userdata); @@ -178,16 +183,17 @@ int config_parse_unit_path_printf(const char *unit, Unit *u = userdata; _cleanup_free_ char *k = NULL; + int r; assert(filename); assert(lvalue); assert(rvalue); assert(u); - k = unit_full_printf(u, rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + r = unit_full_printf(u, rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); return config_parse_path(unit, filename, line, section, lvalue, ltype, k ? k : rvalue, data, userdata); @@ -205,6 +211,7 @@ int config_parse_socket_listen(const char *unit, SocketPort *p, *tail; Socket *s; + int r; assert(filename); assert(lvalue); @@ -226,32 +233,31 @@ int config_parse_socket_listen(const char *unit, if (ltype != SOCKET_SOCKET) { p->type = ltype; - p->path = unit_full_printf(UNIT(s), rvalue); - if (!p->path) { + r = unit_full_printf(UNIT(s), rvalue, &p->path); + if (r < 0) { p->path = strdup(rvalue); if (!p->path) { free(p); return log_oom(); } else - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); } path_kill_slashes(p->path); } else if (streq(lvalue, "ListenNetlink")) { _cleanup_free_ char *k = NULL; - int r; p->type = SOCKET_SOCKET; - k = unit_full_printf(UNIT(s), rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + r = unit_full_printf(UNIT(s), rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); r = socket_address_parse_netlink(&p->address, k ? k : rvalue); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, + log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse address value, ignoring: %s", rvalue); free(p); return 0; @@ -259,17 +265,16 @@ int config_parse_socket_listen(const char *unit, } else { _cleanup_free_ char *k = NULL; - int r; p->type = SOCKET_SOCKET; - k = unit_full_printf(UNIT(s), rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + r = unit_full_printf(UNIT(s), rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r)); r = socket_address_parse(&p->address, k ? k : rvalue); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, + log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse address value, ignoring: %s", rvalue); free(p); return 0; @@ -1230,11 +1235,12 @@ int config_parse_trigger_unit( return 0; } - p = unit_name_printf(u, rvalue); - if (!p) - return log_oom(); + r = unit_name_printf(u, rvalue, &p); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", strerror(-r)); - type = unit_name_to_type(p); + type = unit_name_to_type(p ?: rvalue); if (type < 0) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Unit type not valid, ignoring: %s", rvalue); @@ -1247,10 +1253,10 @@ int config_parse_trigger_unit( return 0; } - r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_TRIGGERS, p, NULL, true); + r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_TRIGGERS, p ?: rvalue, NULL, true); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to add trigger on %s, ignoring: %s", p, strerror(-r)); + "Failed to add trigger on %s, ignoring: %s", p ?: rvalue, strerror(-r)); return 0; } @@ -1271,6 +1277,7 @@ int config_parse_path_spec(const char *unit, PathSpec *s; PathType b; _cleanup_free_ char *k = NULL; + int r; assert(filename); assert(lvalue); @@ -1290,13 +1297,13 @@ int config_parse_path_spec(const char *unit, return 0; } - k = unit_full_printf(UNIT(p), rvalue); - if (!k) { + r = unit_full_printf(UNIT(p), rvalue, &k); + if (r < 0) { k = strdup(rvalue); if (!k) return log_oom(); else - log_syntax(unit, LOG_ERR, filename, line, EINVAL, + log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); } @@ -1344,19 +1351,20 @@ int config_parse_socket_service(const char *unit, dbus_error_init(&error); - p = unit_name_printf(UNIT(s), rvalue); - if (!p) - return log_oom(); + r = unit_name_printf(UNIT(s), rvalue, &p); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", rvalue); - if (!endswith(p, ".service")) { + if (!endswith(p ?: rvalue, ".service")) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Unit must be of type service, ignoring: %s", rvalue); return 0; } - r = manager_load_unit(UNIT(s)->manager, p, NULL, &error, &x); + r = manager_load_unit(UNIT(s)->manager, p ?: rvalue, NULL, &error, &x); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error(&error, r)); dbus_error_free(&error); @@ -1395,23 +1403,24 @@ int config_parse_service_sockets(const char *unit, if (!t) return log_oom(); - k = unit_name_printf(UNIT(s), t); - if (!k) - return log_oom(); + r = unit_name_printf(UNIT(s), t, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", strerror(-r)); - if (!endswith(k, ".socket")) { + if (!endswith(k ?: t, ".socket")) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Unit must be of type socket, ignoring: %s", k); + "Unit must be of type socket, ignoring: %s", k ?: t); continue; } - r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k, NULL, true); + r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k ?: t, NULL, true); if (r < 0) log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to add dependency on %s, ignoring: %s", - k, strerror(-r)); + k ?: t, strerror(-r)); - r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k, NULL, true); + r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k ?: t, NULL, true); if (r < 0) return r; } @@ -1463,7 +1472,8 @@ int config_parse_unit_env_file(const char *unit, char ***env = data; Unit *u = userdata; - _cleanup_free_ char *s = NULL; + _cleanup_free_ char *n = NULL; + const char *s; int r; assert(filename); @@ -1478,10 +1488,12 @@ int config_parse_unit_env_file(const char *unit, return 0; } - s = unit_full_printf(u, rvalue); - if (!s) - return log_oom(); + r = unit_full_printf(u, rvalue, &n); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to resolve specifiers, ignoring: %s", rvalue); + s = n ?: rvalue; if (!path_is_absolute(s[0] == '-' ? s + 1 : s)) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Path '%s' is not absolute, ignoring.", s); @@ -1509,6 +1521,7 @@ int config_parse_environ(const char *unit, char*** env = data, *w, *state; size_t l; _cleanup_free_ char *k = NULL; + int r; assert(filename); assert(lvalue); @@ -1522,11 +1535,15 @@ int config_parse_environ(const char *unit, return 0; } - if (u) - k = unit_full_printf(u, rvalue); - else - k = strdup(rvalue); + if (u) { + r = unit_full_printf(u, rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", rvalue); + } + if (!k) + k = strdup(rvalue); if (!k) return log_oom(); @@ -1598,6 +1615,7 @@ int config_parse_unit_condition_path(const char *unit, bool trigger, negate; Condition *c; _cleanup_free_ char *p = NULL; + int r; assert(filename); assert(lvalue); @@ -1619,9 +1637,15 @@ int config_parse_unit_condition_path(const char *unit, if (negate) rvalue++; - p = unit_full_printf(u, rvalue); - if (!p) - return log_oom(); + r = unit_full_printf(u, rvalue, &p); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", rvalue); + if (!p) { + p = strdup(rvalue); + if (!p) + return log_oom(); + } if (!path_is_absolute(p)) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, @@ -1652,6 +1676,7 @@ int config_parse_unit_condition_string(const char *unit, bool trigger, negate; Condition *c; _cleanup_free_ char *s = NULL; + int r; assert(filename); assert(lvalue); @@ -1673,9 +1698,15 @@ int config_parse_unit_condition_string(const char *unit, if (negate) rvalue++; - s = unit_full_printf(u, rvalue); - if (!s) - return log_oom(); + r = unit_full_printf(u, rvalue, &s); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, + "Failed to resolve specifiers, ignoring: %s", rvalue); + if (!s) { + s = strdup(rvalue); + if (!s) + return log_oom(); + } c = condition_new(cond, s, trigger, negate); if (!c) @@ -1929,21 +1960,26 @@ int config_parse_unit_slice( assert(rvalue); assert(u); - k = unit_name_printf(u, rvalue); - if (!k) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, + r = unit_name_printf(u, rvalue, &k); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + if (!k) { + k = strdup(rvalue); + if (!k) + return log_oom(); + } - r = manager_load_unit(u->manager, k ? k : rvalue, NULL, NULL, &slice); + r = manager_load_unit(u->manager, k, NULL, NULL, &slice); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to load slice unit %s. Ignoring.", k ? k : rvalue); + "Failed to load slice unit %s. Ignoring.", k); return 0; } if (slice->type != UNIT_SLICE) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Slice unit %s is not a slice. Ignoring.", k ? k : rvalue); + "Slice unit %s is not a slice. Ignoring.", k); return 0; } @@ -2000,14 +2036,11 @@ int config_parse_memory_limit( void *userdata) { CGroupContext *c = data; - uint64_t *limit; off_t bytes; int r; - limit = streq(lvalue, "MemoryLimit") ? &c->memory_limit : &c->memory_soft_limit; - if (isempty(rvalue)) { - *limit = (uint64_t) -1; + c->memory_limit = (uint64_t) -1; return 0; } @@ -2020,7 +2053,7 @@ int config_parse_memory_limit( return 0; } - *limit = (uint64_t) bytes; + c->memory_limit = (uint64_t) bytes; return 0; } @@ -2094,7 +2127,44 @@ int config_parse_blockio_weight( void *data, void *userdata) { + CGroupContext *c = data; + unsigned long lu; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + c->blockio_weight = 1000; + return 0; + } + + r = safe_atolu(rvalue, &lu); + if (r < 0 || lu < 10 || lu > 1000) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Block IO weight '%s' invalid. Ignoring.", rvalue); + return 0; + } + + c->blockio_weight = lu; + + return 0; +} + +int config_parse_blockio_device_weight( + const char *unit, + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + _cleanup_free_ char *path = NULL; + CGroupBlockIODeviceWeight *w; CGroupContext *c = data; unsigned long lu; const char *weight; @@ -2106,8 +2176,6 @@ int config_parse_blockio_weight( assert(rvalue); if (isempty(rvalue)) { - c->blockio_weight = 1000; - while (c->blockio_device_weights) cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights); @@ -2116,23 +2184,23 @@ int config_parse_blockio_weight( n = strcspn(rvalue, WHITESPACE); weight = rvalue + n; - if (*weight) { - /* Two params, first device name, then weight */ - path = strndup(rvalue, n); - if (!path) - return log_oom(); + if (!*weight) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Expected block device and device weight. Ignoring."); + return 0; + } - if (!path_startswith(path, "/dev")) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid device node path '%s'. Ignoring.", path); - return 0; - } + path = strndup(rvalue, n); + if (!path) + return log_oom(); - weight += strspn(weight, WHITESPACE); - } else - /* One param, only weight */ - weight = rvalue; + if (!path_startswith(path, "/dev")) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Invalid device node path '%s'. Ignoring.", path); + return 0; + } + weight += strspn(weight, WHITESPACE); r = safe_atolu(weight, &lu); if (r < 0 || lu < 10 || lu > 1000) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, @@ -2140,23 +2208,17 @@ int config_parse_blockio_weight( return 0; } - if (!path) - c->blockio_weight = lu; - else { - CGroupBlockIODeviceWeight *w; - - w = new0(CGroupBlockIODeviceWeight, 1); - if (!w) - return log_oom(); - w->path = path; - path = NULL; + w = new0(CGroupBlockIODeviceWeight, 1); + if (!w) + return log_oom(); - w->weight = lu; + w->path = path; + path = NULL; - LIST_PREPEND(CGroupBlockIODeviceWeight, device_weights, c->blockio_device_weights, w); - } + w->weight = lu; + LIST_PREPEND(CGroupBlockIODeviceWeight, device_weights, c->blockio_device_weights, w); return 0; } @@ -2176,6 +2238,7 @@ int config_parse_blockio_bandwidth( CGroupContext *c = data; const char *bandwidth; off_t bytes; + bool read; size_t n; int r; @@ -2183,9 +2246,14 @@ int config_parse_blockio_bandwidth( assert(lvalue); assert(rvalue); + read = streq("BlockIOReadBandwidth", lvalue); + if (isempty(rvalue)) { - while (c->blockio_device_bandwidths) - cgroup_context_free_blockio_device_bandwidth(c, c->blockio_device_bandwidths); + CGroupBlockIODeviceBandwidth *next; + + LIST_FOREACH_SAFE (device_bandwidths, b, next, c->blockio_device_bandwidths) + if (b->read == read) + cgroup_context_free_blockio_device_bandwidth(c, b); return 0; } @@ -2224,6 +2292,7 @@ int config_parse_blockio_bandwidth( b->path = path; path = NULL; b->bandwidth = (uint64_t) bytes; + b->read = read; LIST_PREPEND(CGroupBlockIODeviceBandwidth, device_bandwidths, c->blockio_device_bandwidths, b); @@ -2618,6 +2687,23 @@ void unit_dump_config_items(FILE *f) { { config_parse_unit_condition_string, "CONDITION" }, { config_parse_unit_condition_null, "CONDITION" }, { config_parse_unit_slice, "SLICE" }, + { config_parse_documentation, "URL" }, + { config_parse_service_timeout, "SECONDS" }, + { config_parse_start_limit_action, "ACTION" }, + { config_parse_set_status, "STATUS" }, + { config_parse_service_sockets, "SOCKETS" }, + { config_parse_fsck_passno, "PASSNO" }, + { config_parse_environ, "ENVIRON" }, + { config_parse_syscall_filter, "SYSCALL" }, + { config_parse_cpu_shares, "SHARES" }, + { config_parse_memory_limit, "LIMIT" }, + { config_parse_device_allow, "DEVICE" }, + { config_parse_device_policy, "POLICY" }, + { config_parse_blockio_bandwidth, "BANDWIDTH" }, + { config_parse_blockio_weight, "WEIGHT" }, + { config_parse_blockio_device_weight, "DEVICEWEIGHT" }, + { config_parse_long, "LONG" }, + { config_parse_socket_service, "SERVICE" }, }; const char *prev = NULL;