X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fload-fragment.c;h=2e67eccc00bc1fe1e1e01a174cd053ed249ef6c2;hp=2b5c8e70dd29bf60699f3a5719b9c6653655a426;hb=4ce9faa9d283cbb4c46fd06138f6774579349fb7;hpb=52661efd21608dc7e0ac26b714a9254ed6180ddb diff --git a/src/load-fragment.c b/src/load-fragment.c index 2b5c8e70d..2e67eccc0 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -191,7 +191,6 @@ static int config_parse_listen( void *data, void *userdata) { - int r; SocketPort *p; Socket *s; @@ -217,7 +216,7 @@ static int config_parse_listen( } else { p->type = SOCKET_SOCKET; - if ((r = socket_address_parse(&p->address, rvalue)) < 0) { + if (socket_address_parse(&p->address, rvalue) < 0) { log_error("[%s:%u] Failed to parse address value, ignoring: %s", filename, line, rvalue); free(p); return 0; @@ -289,14 +288,14 @@ static int config_parse_nice( void *userdata) { ExecContext *c = data; - int priority, r; + int priority; assert(filename); assert(lvalue); assert(rvalue); assert(data); - if ((r = safe_atoi(rvalue, &priority)) < 0) { + if (safe_atoi(rvalue, &priority) < 0) { log_error("[%s:%u] Failed to parse nice priority, ignoring: %s. ", filename, line, rvalue); return 0; } @@ -307,7 +306,7 @@ static int config_parse_nice( } c->nice = priority; - c->nice_set = false; + c->nice_set = true; return 0; } @@ -322,14 +321,14 @@ static int config_parse_oom_score_adjust( void *userdata) { ExecContext *c = data; - int oa, r; + int oa; assert(filename); assert(lvalue); assert(rvalue); assert(data); - if ((r = safe_atoi(rvalue, &oa)) < 0) { + if (safe_atoi(rvalue, &oa) < 0) { log_error("[%s:%u] Failed to parse the OOM score adjust value, ignoring: %s", filename, line, rvalue); return 0; } @@ -433,7 +432,7 @@ static int config_parse_exec( k = 0; FOREACH_WORD_QUOTED(w, l, rvalue, state) { - if (strncmp(w, ";", l) == 0) + if (strncmp(w, ";", MAX(l, 1U)) == 0) break; k++; @@ -444,7 +443,7 @@ static int config_parse_exec( k = 0; FOREACH_WORD_QUOTED(w, l, rvalue, state) { - if (strncmp(w, ";", l) == 0) + if (strncmp(w, ";", MAX(l, 1U)) == 0) break; if (honour_argv0 && w == rvalue) { @@ -506,14 +505,13 @@ static int config_parse_usec( void *userdata) { usec_t *usec = data; - int r; assert(filename); assert(lvalue); assert(rvalue); assert(data); - if ((r = parse_usec(rvalue, usec)) < 0) { + if (parse_usec(rvalue, usec) < 0) { log_error("[%s:%u] Failed to parse time value, ignoring: %s", filename, line, rvalue); return 0; } @@ -893,14 +891,13 @@ static int config_parse_timer_slack_nsec( ExecContext *c = data; unsigned long u; - int r; assert(filename); assert(lvalue); assert(rvalue); assert(data); - if ((r = safe_atolu(rvalue, &u)) < 0) { + if (safe_atolu(rvalue, &u) < 0) { log_error("[%s:%u] Failed to parse time slack value, ignoring: %s", filename, line, rvalue); return 0; } @@ -921,14 +918,13 @@ static int config_parse_limit( struct rlimit **rl = data; unsigned long long u; - int r; assert(filename); assert(lvalue); assert(rvalue); assert(data); - if ((r = safe_atollu(rvalue, &u)) < 0) { + if (safe_atollu(rvalue, &u) < 0) { log_error("[%s:%u] Failed to parse resource value, ignoring: %s", filename, line, rvalue); return 0; } @@ -985,14 +981,14 @@ static int config_parse_sysv_priority( void *userdata) { int *priority = data; - int r, i; + int i; assert(filename); assert(lvalue); assert(rvalue); assert(data); - if ((r = safe_atoi(rvalue, &i)) < 0 || i < 0) { + if (safe_atoi(rvalue, &i) < 0 || i < 0) { log_error("[%s:%u] Failed to parse SysV start priority, ignoring: %s", filename, line, rvalue); return 0; } @@ -1002,6 +998,32 @@ static int config_parse_sysv_priority( } #endif +static int config_parse_fsck_passno( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + const char *rvalue, + void *data, + void *userdata) { + + int *passno = data; + int i; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &i) || i < 0) { + log_error("[%s:%u] Failed to parse fsck pass number, ignoring: %s", filename, line, rvalue); + return 0; + } + + *passno = (int) i; + return 0; +} + static DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode"); static int config_parse_kill_signal( @@ -1021,11 +1043,7 @@ static int config_parse_kill_signal( assert(rvalue); assert(sig); - if ((r = signal_from_string(rvalue)) <= 0) - if (startswith(rvalue, "SIG")) - r = signal_from_string(rvalue+3); - - if (r <= 0) { + if ((r = signal_from_string_try_harder(rvalue)) <= 0) { log_error("[%s:%u] Failed to parse kill signal, ignoring: %s", filename, line, rvalue); return 0; } @@ -1055,11 +1073,11 @@ static int config_parse_mount_flags( assert(data); FOREACH_WORD_QUOTED(w, l, rvalue, state) { - if (strncmp(w, "shared", l) == 0) + if (strncmp(w, "shared", MAX(l, 6U)) == 0) flags |= MS_SHARED; - else if (strncmp(w, "slave", l) == 0) + else if (strncmp(w, "slave", MAX(l, 5U)) == 0) flags |= MS_SLAVE; - else if (strncmp(w, "private", l) == 0) + else if (strncmp(w, "private", MAX(l, 7U)) == 0) flags |= MS_PRIVATE; else { log_error("[%s:%u] Failed to parse mount flags, ignoring: %s", filename, line, rvalue); @@ -1082,7 +1100,6 @@ static int config_parse_timer( Timer *t = data; usec_t u; - int r; TimerValue *v; TimerBase b; @@ -1096,7 +1113,7 @@ static int config_parse_timer( return 0; } - if ((r = parse_usec(rvalue, &u)) < 0) { + if (parse_usec(rvalue, &u) < 0) { log_error("[%s:%u] Failed to parse timer value, ignoring: %s", filename, line, rvalue); return 0; } @@ -1326,26 +1343,37 @@ static int config_parse_env_file( FILE *f; int r; char ***env = data; + bool ignore = false; assert(filename); assert(lvalue); assert(rvalue); assert(data); + if (rvalue[0] == '-') { + ignore = true; + rvalue++; + } + + if (!path_is_absolute(rvalue)) { + log_error("[%s:%u] Path '%s' is not absolute, ignoring.", filename, line, rvalue); + return 0; + } + if (!(f = fopen(rvalue, "re"))) { - log_error("[%s:%u] Failed to open environment file '%s', ignoring: %m", filename, line, rvalue); + if (!ignore) + log_error("[%s:%u] Failed to open environment file '%s', ignoring: %m", filename, line, rvalue); return 0; } while (!feof(f)) { - char l[LINE_MAX], *p; + char l[LINE_MAX], *p, *u; char **t; if (!fgets(l, sizeof(l), f)) { if (feof(f)) break; - r = -errno; log_error("[%s:%u] Failed to read environment file '%s', ignoring: %m", filename, line, rvalue); r = 0; goto finish; @@ -1359,7 +1387,21 @@ static int config_parse_env_file( if (strchr(COMMENTS, *p)) continue; - t = strv_env_set(*env, p); + if (!(u = normalize_env_assignment(p))) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + t = strv_append(*env, u); + free(u); + + if (!t) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + strv_free(*env); *env = t; } @@ -1383,7 +1425,6 @@ static int config_parse_ip_tos( void *userdata) { int *ip_tos = data, x; - int r; assert(filename); assert(lvalue); @@ -1391,7 +1432,7 @@ static int config_parse_ip_tos( assert(data); if ((x = ip_tos_from_string(rvalue)) < 0) - if ((r = safe_atoi(rvalue, &x)) < 0) { + if (safe_atoi(rvalue, &x) < 0) { log_error("[%s:%u] Failed to parse IP TOS value, ignoring: %s", filename, line, rvalue); return 0; } @@ -1422,11 +1463,12 @@ static int config_parse_condition_path( rvalue++; if (!path_is_absolute(rvalue)) { - log_error("[%s:%u] Path in condition not absolute: %s", filename, line, rvalue); + log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, rvalue); return 0; } - if (!(c = condition_new(CONDITION_PATH_EXISTS, rvalue, negate))) + if (!(c = condition_new(streq(lvalue, "ConditionPathExists") ? CONDITION_PATH_EXISTS : CONDITION_DIRECTORY_NOT_EMPTY, + rvalue, negate))) return -ENOMEM; LIST_PREPEND(Condition, conditions, u->meta.conditions, c); @@ -1461,6 +1503,71 @@ static int config_parse_condition_kernel( return 0; } +static int config_parse_condition_virt( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = data; + bool negate; + Condition *c; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((negate = rvalue[0] == '!')) + rvalue++; + + if (!(c = condition_new(CONDITION_VIRTUALIZATION, rvalue, negate))) + return -ENOMEM; + + LIST_PREPEND(Condition, conditions, u->meta.conditions, c); + return 0; +} + +static int config_parse_condition_null( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = data; + Condition *c; + bool negate; + int b; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((negate = rvalue[0] == '!')) + rvalue++; + + if ((b = parse_boolean(rvalue)) < 0) { + log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (!b) + negate = !negate; + + if (!(c = condition_new(CONDITION_NULL, NULL, negate))) + return -ENOMEM; + + LIST_PREPEND(Condition, conditions, u->meta.conditions, c); + return 0; +} + static DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier"); #define FOLLOW_MAX 8 @@ -1634,6 +1741,8 @@ static void dump_items(FILE *f, const ConfigItem *items) { { config_parse_ip_tos, "TOS" }, { config_parse_condition_path, "CONDITION" }, { config_parse_condition_kernel, "CONDITION" }, + { config_parse_condition_null, "CONDITION" }, + { config_parse_condition_virt, "CONDITION" }, }; assert(f); @@ -1733,6 +1842,7 @@ static int load_from_path(Unit *u, const char *path) { { "PAMName", config_parse_string_printf, &(context).pam_name, section }, \ { "KillMode", config_parse_kill_mode, &(context).kill_mode, section }, \ { "KillSignal", config_parse_kill_signal, &(context).kill_signal, section }, \ + { "SendSIGKILL", config_parse_bool, &(context).send_sigkill, section }, \ { "UtmpIdentifier", config_parse_string_printf, &(context).utmp_id, section } const ConfigItem items[] = { @@ -1743,20 +1853,22 @@ static int load_from_path(Unit *u, const char *path) { { "Requisite", config_parse_deps, UINT_TO_PTR(UNIT_REQUISITE), "Unit" }, { "RequisiteOverridable", config_parse_deps, UINT_TO_PTR(UNIT_REQUISITE_OVERRIDABLE), "Unit" }, { "Wants", config_parse_deps, UINT_TO_PTR(UNIT_WANTS), "Unit" }, + { "BindTo", config_parse_deps, UINT_TO_PTR(UNIT_BIND_TO), "Unit" }, { "Conflicts", config_parse_deps, UINT_TO_PTR(UNIT_CONFLICTS), "Unit" }, { "Before", config_parse_deps, UINT_TO_PTR(UNIT_BEFORE), "Unit" }, { "After", config_parse_deps, UINT_TO_PTR(UNIT_AFTER), "Unit" }, { "OnFailure", config_parse_deps, UINT_TO_PTR(UNIT_ON_FAILURE), "Unit" }, - { "RecursiveStop", config_parse_bool, &u->meta.recursive_stop, "Unit" }, { "StopWhenUnneeded", config_parse_bool, &u->meta.stop_when_unneeded, "Unit" }, { "RefuseManualStart", config_parse_bool, &u->meta.refuse_manual_start, "Unit" }, { "RefuseManualStop", config_parse_bool, &u->meta.refuse_manual_stop, "Unit" }, { "AllowIsolate", config_parse_bool, &u->meta.allow_isolate, "Unit" }, { "DefaultDependencies", config_parse_bool, &u->meta.default_dependencies, "Unit" }, - { "IgnoreDependencyFailure",config_parse_bool, &u->meta.ignore_dependency_failure, "Unit" }, { "JobTimeoutSec", config_parse_usec, &u->meta.job_timeout, "Unit" }, { "ConditionPathExists", config_parse_condition_path, u, "Unit" }, + { "ConditionDirectoryNotEmpty", config_parse_condition_path, u, "Unit" }, { "ConditionKernelCommandLine", config_parse_condition_kernel, u, "Unit" }, + { "ConditionVirtualization",config_parse_condition_virt, u, "Unit" }, + { "ConditionNull", config_parse_condition_null, u, "Unit" }, { "PIDFile", config_parse_path, &u->service.pid_file, "Service" }, { "ExecStartPre", config_parse_exec, u->service.exec_command+SERVICE_EXEC_START_PRE, "Service" }, @@ -1772,6 +1884,7 @@ static int load_from_path(Unit *u, const char *path) { { "PermissionsStartOnly", config_parse_bool, &u->service.permissions_start_only, "Service" }, { "RootDirectoryStartOnly", config_parse_bool, &u->service.root_directory_start_only, "Service" }, { "RemainAfterExit", config_parse_bool, &u->service.remain_after_exit, "Service" }, + { "GuessMainPID", config_parse_bool, &u->service.guess_main_pid, "Service" }, #ifdef HAVE_SYSV_COMPAT { "SysVStartPriority", config_parse_sysv_priority, &u->service.sysv_start_priority, "Service" }, #else @@ -1781,6 +1894,7 @@ static int load_from_path(Unit *u, const char *path) { { "BusName", config_parse_string_printf, &u->service.bus_name, "Service" }, { "NotifyAccess", config_parse_notify_access, &u->service.notify_access, "Service" }, { "Sockets", config_parse_service_sockets, &u->service, "Service" }, + { "FsckPassNo", config_parse_fsck_passno, &u->service.fsck_passno, "Service" }, EXEC_CONTEXT_CONFIG_ITEMS(u->service.exec_context, "Service"), { "ListenStream", config_parse_listen, &u->socket, "Socket" }, @@ -1825,6 +1939,8 @@ static int load_from_path(Unit *u, const char *path) { { "What", config_parse_path, &u->swap.parameters_fragment.what, "Swap" }, { "Priority", config_parse_int, &u->swap.parameters_fragment.priority, "Swap" }, + { "TimeoutSec", config_parse_usec, &u->swap.timeout_usec, "Swap" }, + EXEC_CONTEXT_CONFIG_ITEMS(u->swap.exec_context, "Swap"), { "OnActiveSec", config_parse_timer, &u->timer, "Timer" }, { "OnBootSec", config_parse_timer, &u->timer, "Timer" },