X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=load-fragment.c;h=deebba3e82f34bb11c0c1aec85048e48c8200fb5;hp=5e98ae832483ef07f262e202c1adac217d766322;hb=ea5652c296f325eceea351c19bf81a783cea4537;hpb=4f2d528d3bb25cebf8d3ebe83d8193ab4016cb90 diff --git a/load-fragment.c b/load-fragment.c index 5e98ae832..deebba3e8 100644 --- a/load-fragment.c +++ b/load-fragment.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "unit.h" #include "strv.h" @@ -97,7 +99,7 @@ static int config_parse_deps( if (!k) return -ENOMEM; - r = unit_add_dependency_by_name(u, d, k, NULL); + r = unit_add_dependency_by_name(u, d, k, NULL, true); free(k); if (r < 0) @@ -149,6 +151,38 @@ static int config_parse_names( return 0; } +static int config_parse_description( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + char *k; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (!(k = unit_full_printf(u, rvalue))) + return -ENOMEM; + + free(u->meta.description); + + if (*k) + u->meta.description = k; + else { + free(k); + u->meta.description = NULL; + } + + return 0; +} + static int config_parse_listen( const char *filename, unsigned line, @@ -410,7 +444,6 @@ static int config_parse_usec( void *userdata) { usec_t *usec = data; - unsigned long long u; int r; assert(filename); @@ -418,17 +451,11 @@ static int config_parse_usec( assert(rvalue); assert(data); - if ((r = safe_atollu(rvalue, &u)) < 0) { + if ((r = parse_usec(rvalue, usec)) < 0) { log_error("[%s:%u] Failed to parse time value: %s", filename, line, rvalue); return r; } - /* We actually assume the user configures seconds. Later on we - * might choose to support suffixes for time values, to - * configure bigger or smaller units */ - - *usec = u * USEC_PER_SEC; - return 0; } @@ -909,6 +936,43 @@ static int config_parse_sysv_priority( DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode"); +static int config_parse_mount_flags( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + char *w; + size_t l; + char *state; + unsigned long flags = 0; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + FOREACH_WORD(w, l, rvalue, state) { + if (strncmp(w, "shared", l) == 0) + flags |= MS_SHARED; + else if (strncmp(w, "slave", l) == 0) + flags |= MS_SLAVE; + else if (strncmp(w, "private", l) == 0) + flags |= MS_PRIVATE; + else { + log_error("[%s:%u] Failed to parse mount flags: %s", filename, line, rvalue); + return -EINVAL; + } + } + + c->mount_flags = flags; + return 0; +} + #define FOLLOW_MAX 8 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) { @@ -1063,7 +1127,11 @@ static void dump_items(FILE *f, const ConfigItem *items) { { config_parse_kill_mode, "KILLMODE" }, { config_parse_listen, "SOCKET [...]" }, { config_parse_socket_bind, "SOCKETBIND" }, - { config_parse_bindtodevice, "NETWORKINTERFACE" } + { config_parse_bindtodevice, "NETWORKINTERFACE" }, + { config_parse_usec, "SECONDS" }, + { config_parse_path_strv, "PATH [...]" }, + { config_parse_mount_flags, "MOUNTFLAG [...]" }, + { config_parse_description, "DESCRIPTION" }, }; assert(f); @@ -1103,7 +1171,8 @@ static int load_from_path(Unit *u, const char *path) { [UNIT_DEVICE] = "Device", [UNIT_MOUNT] = "Mount", [UNIT_AUTOMOUNT] = "Automount", - [UNIT_SNAPSHOT] = "Snapshot" + [UNIT_SNAPSHOT] = "Snapshot", + [UNIT_SWAP] = "Swap" }; #define EXEC_CONTEXT_CONFIG_ITEMS(context, section) \ @@ -1149,21 +1218,26 @@ static int load_from_path(Unit *u, const char *path) { { "LimitNICE", config_parse_limit, &(context).rlimit[RLIMIT_NICE], section }, \ { "LimitRTPRIO", config_parse_limit, &(context).rlimit[RLIMIT_RTPRIO], section }, \ { "LimitRTTIME", config_parse_limit, &(context).rlimit[RLIMIT_RTTIME], section }, \ - { "ControlGroup", config_parse_cgroup, u, section } + { "ControlGroup", config_parse_cgroup, u, section }, \ + { "ReadWriteDirectories", config_parse_path_strv, &(context).read_write_dirs, section }, \ + { "ReadOnlyDirectories", config_parse_path_strv, &(context).read_only_dirs, section }, \ + { "InaccessibleDirectories",config_parse_path_strv, &(context).inaccessible_dirs, section }, \ + { "PrivateTmp", config_parse_bool, &(context).private_tmp, section }, \ + { "MountFlags", config_parse_mount_flags, &(context), section } const ConfigItem items[] = { - { "Names", config_parse_names, u, "Meta" }, - { "Description", config_parse_string, &u->meta.description, "Meta" }, - { "Requires", config_parse_deps, UINT_TO_PTR(UNIT_REQUIRES), "Meta" }, - { "RequiresOverridable", config_parse_deps, UINT_TO_PTR(UNIT_REQUIRES_OVERRIDABLE), "Meta" }, - { "Requisite", config_parse_deps, UINT_TO_PTR(UNIT_REQUISITE), "Meta" }, - { "RequisiteOverridable", config_parse_deps, UINT_TO_PTR(UNIT_REQUISITE_OVERRIDABLE), "Meta" }, - { "Wants", config_parse_deps, UINT_TO_PTR(UNIT_WANTS), "Meta" }, - { "Conflicts", config_parse_deps, UINT_TO_PTR(UNIT_CONFLICTS), "Meta" }, - { "Before", config_parse_deps, UINT_TO_PTR(UNIT_BEFORE), "Meta" }, - { "After", config_parse_deps, UINT_TO_PTR(UNIT_AFTER), "Meta" }, - { "RecursiveStop", config_parse_bool, &u->meta.recursive_stop, "Meta" }, - { "StopWhenUnneeded", config_parse_bool, &u->meta.stop_when_unneeded, "Meta" }, + { "Names", config_parse_names, u, "Unit" }, + { "Description", config_parse_description, u, "Unit" }, + { "Requires", config_parse_deps, UINT_TO_PTR(UNIT_REQUIRES), "Unit" }, + { "RequiresOverridable", config_parse_deps, UINT_TO_PTR(UNIT_REQUIRES_OVERRIDABLE), "Unit" }, + { "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" }, + { "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" }, + { "RecursiveStop", config_parse_bool, &u->meta.recursive_stop, "Unit" }, + { "StopWhenUnneeded", config_parse_bool, &u->meta.stop_when_unneeded, "Unit" }, { "PIDFile", config_parse_path, &u->service.pid_file, "Service" }, { "ExecStartPre", config_parse_exec, u->service.exec_command+SERVICE_EXEC_START_PRE, "Service" }, @@ -1182,6 +1256,7 @@ static int load_from_path(Unit *u, const char *path) { { "SysVStartPriority", config_parse_sysv_priority, &u->service.sysv_start_priority, "Service" }, { "KillMode", config_parse_kill_mode, &u->service.kill_mode, "Service" }, { "NonBlocking", config_parse_bool, &u->service.exec_context.non_blocking, "Service" }, + { "BusName", config_parse_string, &u->service.bus_name, "Service" }, EXEC_CONTEXT_CONFIG_ITEMS(u->service.exec_context, "Service"), { "ListenStream", config_parse_listen, &u->socket, "Socket" }, @@ -1210,6 +1285,11 @@ static int load_from_path(Unit *u, const char *path) { { "KillMode", config_parse_kill_mode, &u->mount.kill_mode, "Mount" }, EXEC_CONTEXT_CONFIG_ITEMS(u->mount.exec_context, "Mount"), + { "Where", config_parse_path, &u->automount.where, "Automount" }, + + { "What", config_parse_path, &u->swap.parameters_fragment.what, "Swap" }, + { "Priority", config_parse_int, &u->swap.parameters_fragment.priority, "Swap" }, + { NULL, NULL, NULL, NULL } }; @@ -1232,7 +1312,7 @@ static int load_from_path(Unit *u, const char *path) { assert(u); assert(path); - sections[0] = "Meta"; + sections[0] = "Unit"; sections[1] = section_table[u->meta.type]; sections[2] = NULL;