summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-11-17 14:11:12 +0100
committerLennart Poettering <lennart@poettering.net>2015-11-17 20:41:52 +0100
commit9c8d1e1a712d443c456147e15ee906035b5fa0f7 (patch)
treefc0d687d889efcfb6284b3ecc38d0194f98d3d4c
parent7c65093ae351d82a04a3e03582e8faedee798adc (diff)
downloadsystemd-9c8d1e1a712d443c456147e15ee906035b5fa0f7.tar.gz
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.
-rw-r--r--src/run/run.c71
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,