diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-11-17 14:11:12 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-11-17 20:41:52 +0100 |
commit | 9c8d1e1a712d443c456147e15ee906035b5fa0f7 (patch) | |
tree | fc0d687d889efcfb6284b3ecc38d0194f98d3d4c /src/run | |
parent | 7c65093ae351d82a04a3e03582e8faedee798adc (diff) |
run: when automatically generating names for transient units, use unique bus ID, fallback to random
Previously we used the process ID to generate transient unit names.
However, that is problematic as PIDs get reused easily, and applying
them to remote systems makes little sense.
Fortunately, each bus peer gets a unique, non-reusable ID assigned when
attaching to a bus, hence let's use that, if we can. In some cases we
cannot however, because we connect directly to PID's private socket, and
thus are not a proper bus peer with a unique ID. In that case generate a
random UUID to name the unit after.
Diffstat (limited to 'src/run')
-rw-r--r-- | src/run/run.c | 71 |
1 files changed, 64 insertions, 7 deletions
diff --git a/src/run/run.c b/src/run/run.c index df6a4f0074..9f096b75b7 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -687,6 +687,51 @@ static int transient_timer_set_properties(sd_bus_message *m) { return 0; } +static int make_unit_name(sd_bus *bus, UnitType t, char **ret) { + const char *unique, *id; + char *p; + int r; + + assert(bus); + assert(t >= 0); + assert(t < _UNIT_TYPE_MAX); + + r = sd_bus_get_unique_name(bus, &unique); + if (r < 0) { + sd_id128_t rnd; + + /* We couldn't get the unique name, which is a pretty + * common case if we are connected to systemd + * directly. In that case, just pick a random uuid as + * name */ + + r = sd_id128_randomize(&rnd); + if (r < 0) + return log_error_errno(r, "Failed to generate random run unit name: %m"); + + if (asprintf(ret, "run-r" SD_ID128_FORMAT_STR ".%s", SD_ID128_FORMAT_VAL(rnd), unit_type_to_string(t)) < 0) + return log_oom(); + + return 0; + } + + /* We managed to get the unique name, then let's use that to + * name our transient units. */ + + id = startswith(unique, ":1."); + if (!id) { + log_error("Unique name %s has unexpected format.", unique); + return -EINVAL; + } + + p = strjoin("run-u", id, ".", unit_type_to_string(t), NULL); + if (!p) + return log_oom(); + + *ret = p; + return 0; +} + static int start_transient_service( sd_bus *bus, char **argv) { @@ -763,8 +808,11 @@ static int start_transient_service( r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".service", &service); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); - } else if (asprintf(&service, "run-"PID_FMT".service", getpid()) < 0) - return log_oom(); + } else { + r = make_unit_name(bus, UNIT_SERVICE, &service); + if (r < 0) + return r; + } r = sd_bus_message_new_method_call( bus, @@ -882,8 +930,11 @@ static int start_transient_scope( r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".scope", &scope); if (r < 0) return log_error_errno(r, "Failed to mangle scope name: %m"); - } else if (asprintf(&scope, "run-"PID_FMT".scope", getpid()) < 0) - return log_oom(); + } else { + r = make_unit_name(bus, UNIT_SCOPE, &scope); + if (r < 0) + return r; + } r = sd_bus_message_new_method_call( bus, @@ -1052,9 +1103,15 @@ static int start_transient_timer( break; } - } else if ((asprintf(&service, "run-"PID_FMT".service", getpid()) < 0) || - (asprintf(&timer, "run-"PID_FMT".timer", getpid()) < 0)) - return log_oom(); + } else { + r = make_unit_name(bus, UNIT_SERVICE, &service); + if (r < 0) + return r; + + r = unit_name_change_suffix(service, ".timer", &timer); + if (r < 0) + return log_error_errno(r, "Failed to change unit suffix: %m"); + } r = sd_bus_message_new_method_call( bus, |