int manager_start_scope(
Manager *manager,
const char *scope,
- pid_t pid,
+ const PidRef *pidref,
const char *slice,
const char *description,
char **wants,
assert(manager);
assert(scope);
- assert(pid > 1);
+ assert(pidref_is_set(pidref));
assert(job);
r = bus_message_new_method_call(manager->bus, &m, bus_systemd_mgr, "StartTransientUnit");
if (r < 0)
return r;
- r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
+ r = bus_append_scope_pidref(m, pidref);
if (r < 0)
return r;
int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, const char *requires_mounts_for, sd_bus_message *more_properties, sd_bus_error *error, char **job);
+int manager_start_scope(Manager *manager, const char *scope, const PidRef *pidref, const char *slice, const char *description, char **wants, char **after, const char *requires_mounts_for, sd_bus_message *more_properties, sd_bus_error *error, char **job);
int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, const char *job_mode, sd_bus_error *error, char **job);
int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error);
r = manager_start_scope(
s->manager,
scope,
- s->leader.pid,
+ &s->leader,
s->user->slice,
description,
/* These two have StopWhenUnneeded= set, hence add a dep towards them */
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-locator.h"
+#include "bus-unit-util.h"
#include "bus-util.h"
#include "env-file.h"
#include "errno-util.h"
if (r < 0)
return r;
- r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)",
- "PIDs", "au", 1, machine->leader.pid,
+ r = bus_append_scope_pidref(m, &machine->leader);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)",
"Delegate", "b", 1,
"CollectMode", "s", "inactive-or-failed",
"AddRef", "b", 1,
r = sd_bus_call(bus, m, 0, &error, NULL);
}
-
if (r < 0)
return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r));
unsigned n_mounts,
int kill_signal,
char **properties,
- sd_bus_message *properties_message) {
+ sd_bus_message *properties_message,
+ bool allow_pidfd) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
description = strjoina("Container ", machine_name);
- r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)(sv)",
- "PIDs", "au", 1, pid,
+ if (allow_pidfd) {
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_set_pid(&pidref, pid);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate PID reference: %m");
+
+ r = bus_append_scope_pidref(m, &pidref);
+ } else
+ r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)",
"Description", "s", description,
"Delegate", "b", 1,
"CollectMode", "s", "inactive-or-failed",
return bus_log_create_error(r);
r = sd_bus_call(bus, m, 0, &error, &reply);
- if (r < 0)
+ if (r < 0) {
+ /* If this failed with a property we couldn't write, this is quite likely because the server
+ * doesn't support PIDFDs yet, let's try without. */
+ if (allow_pidfd &&
+ sd_bus_error_has_names(&error, SD_BUS_ERROR_UNKNOWN_PROPERTY, SD_BUS_ERROR_PROPERTY_READ_ONLY))
+ return allocate_scope(bus, machine_name, pid, slice, mounts, n_mounts, kill_signal, properties, properties_message, /* allow_pidfd= */ false);
+
return log_error_errno(r, "Failed to allocate scope: %s", bus_error_message(&error, r));
+ }
r = sd_bus_message_read(reply, "o", &object);
if (r < 0)
int register_machine(sd_bus *bus, const char *machine_name, pid_t pid, const char *directory, sd_id128_t uuid, int local_ifindex, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, sd_bus_message *properties_message, bool keep_unit, const char *service);
int unregister_machine(sd_bus *bus, const char *machine_name);
-int allocate_scope(sd_bus *bus, const char *machine_name, pid_t pid, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, sd_bus_message *properties_message);
+int allocate_scope(sd_bus *bus, const char *machine_name, pid_t pid, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, sd_bus_message *properties_message, bool allow_pidfds);
int terminate_scope(sd_bus *bus, const char *machine_name);
arg_custom_mounts, arg_n_custom_mounts,
arg_kill_signal,
arg_property,
- arg_property_message);
+ arg_property_message,
+ /* allow_pidfds= */ true);
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, (uint32_t) getpid_cached());
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_set_self(&pidref);
+ if (r < 0)
+ return r;
+
+ r = bus_append_scope_pidref(m, &pidref);
if (r < 0)
return bus_log_create_error(r);
return 0;
}
+int bus_append_scope_pidref(sd_bus_message *m, const PidRef *pidref) {
+ assert(m);
+
+ if (!pidref_is_set(pidref))
+ return -ESRCH;
+
+ if (pidref->fd >= 0)
+ return sd_bus_message_append(
+ m, "(sv)",
+ "PIDFDs", "ah", 1, pidref->fd);
+
+ return sd_bus_message_append(
+ m, "(sv)",
+ "PIDs", "au", 1, pidref->pid);
+}
+
int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet) {
const char *type, *path, *source;
InstallChange *changes = NULL;
#include "sd-bus.h"
#include "install.h"
+#include "pidref.h"
#include "unit-def.h"
typedef struct UnitInfo {
int bus_append_unit_property_assignment(sd_bus_message *m, UnitType t, const char *assignment);
int bus_append_unit_property_assignment_many(sd_bus_message *m, UnitType t, char **l);
+int bus_append_scope_pidref(sd_bus_message *m, const PidRef *pidref);
+
int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet);
int unit_load_state(sd_bus *bus, const char *name, char **load_state);