mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 08:56:15 +09:00
Assorted systemd-machined fixes (#37622)
This commit is contained in:
@@ -1251,6 +1251,8 @@ node /org/freedesktop/login1/session/1 {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly u Leader = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly t LeaderPIDFDId = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly u Audit = ...;
|
||||
readonly s Type = '...';
|
||||
readonly s Class = '...';
|
||||
@@ -1351,6 +1353,8 @@ node /org/freedesktop/login1/session/1 {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Leader"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="LeaderPIDFDId"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Audit"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Type"/>
|
||||
@@ -1539,6 +1543,9 @@ node /org/freedesktop/login1/session/1 {
|
||||
|
||||
<para><varname>Leader</varname> encodes the PID of the process that registered the session.</para>
|
||||
|
||||
<para><varname>LeaderPIDFDId</varname> encodes the Linux pidfd inode ID of the process that registered
|
||||
the session.</para>
|
||||
|
||||
<para><varname>Audit</varname> encodes the Kernel Audit session ID of the session if auditing is
|
||||
available.</para>
|
||||
|
||||
@@ -1660,6 +1667,7 @@ node /org/freedesktop/login1/session/1 {
|
||||
<para><function>SetDisplay()</function> was added in version 252.</para>
|
||||
<para><function>SetTTY()</function> was added in version 254.</para>
|
||||
<para><function>SetClass()</function> was added in version 256.</para>
|
||||
<para><varname>LeaderPIDFDId</varname> was added in version 258.</para>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -513,6 +513,8 @@ node /org/freedesktop/machine1/machine/rawhide {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly u Leader = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly t LeaderPIDFDId = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s Class = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s RootDirectory = '...';
|
||||
@@ -603,6 +605,8 @@ node /org/freedesktop/machine1/machine/rawhide {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Leader"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="LeaderPIDFDId"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Class"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="RootDirectory"/>
|
||||
@@ -650,6 +654,9 @@ node /org/freedesktop/machine1/machine/rawhide {
|
||||
|
||||
<para><varname>Leader</varname> is the PID of the leader process of the machine.</para>
|
||||
|
||||
<para><varname>LeaderPIDFDId</varname> encodes the Linux pidfd inode ID of the leader process of the
|
||||
machine.</para>
|
||||
|
||||
<para><varname>Class</varname> is the class of the machine and is either the string "vm" (for real VMs
|
||||
based on virtualized hardware) or "container" (for lightweight userspace virtualization sharing the
|
||||
same kernel as the host).</para>
|
||||
@@ -717,6 +724,7 @@ $ gdbus introspect --system \
|
||||
<function>CopyToWithFlags()</function> were added in version 252.</para>
|
||||
<para><function>GetSSHInfo()</function>, <varname>VSockCID</varname>, <varname>SSHAddress</varname>
|
||||
and <varname>SSHPrivateKeyPath</varname> were added in version 256.</para>
|
||||
<para><varname>LeaderPIDFDId</varname> was added in version 258.</para>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "cgroup-util.h"
|
||||
#include "dirent-util.h"
|
||||
#include "env-file.h"
|
||||
#include "escape.h"
|
||||
#include "extract-word.h"
|
||||
#include "fd-util.h"
|
||||
#include "format-util.h"
|
||||
@@ -837,20 +836,7 @@ _public_ int sd_session_get_class(const char *session, char **class) {
|
||||
}
|
||||
|
||||
_public_ int sd_session_get_desktop(const char *session, char **desktop) {
|
||||
_cleanup_free_ char *escaped = NULL;
|
||||
int r;
|
||||
ssize_t l;
|
||||
|
||||
assert_return(desktop, -EINVAL);
|
||||
|
||||
r = session_get_string(session, "DESKTOP", &escaped);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
l = cunescape(escaped, 0, desktop);
|
||||
if (l < 0)
|
||||
return l;
|
||||
return 0;
|
||||
return session_get_string(session, "DESKTOP", desktop);
|
||||
}
|
||||
|
||||
_public_ int sd_session_get_display(const char *session, char **display) {
|
||||
|
||||
@@ -993,6 +993,7 @@ static const sd_bus_vtable session_vtable[] = {
|
||||
SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader.pid), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("LeaderPIDFDId", "t", bus_property_get_pidfdid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
|
||||
@@ -717,7 +717,8 @@ static const sd_bus_vtable machine_vtable[] = {
|
||||
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Machine, service), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Unit", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader.pid), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Machine, leader.pid), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("LeaderPIDFDId", "t", bus_property_get_pidfdid, offsetof(Machine, leader), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("NetworkInterfaces", "ai", property_get_netif, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
||||
@@ -145,8 +145,6 @@ Machine* machine_free(Machine *m) {
|
||||
}
|
||||
|
||||
int machine_save(Machine *m) {
|
||||
_cleanup_(unlink_and_freep) char *temp_path = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@@ -157,63 +155,47 @@ int machine_save(Machine *m) {
|
||||
if (!m->started)
|
||||
return 0;
|
||||
|
||||
_cleanup_(unlink_and_freep) char *sl = NULL; /* auto-unlink! */
|
||||
if (m->unit) {
|
||||
sl = strjoin("/run/systemd/machines/unit:", m->unit);
|
||||
if (!sl)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0, MKDIR_WARN_MODE);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
return log_error_errno(r, "Failed to create /run/systemd/machines/: %m");
|
||||
|
||||
r = fopen_temporary(m->state_file, &f, &temp_path);
|
||||
_cleanup_(unlink_and_freep) char *temp_path = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
r = fopen_tmpfile_linkable(m->state_file, O_WRONLY|O_CLOEXEC, &temp_path, &f);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
return log_error_errno(r, "Failed to create state file '%s': %m", m->state_file);
|
||||
|
||||
(void) fchmod(fileno(f), 0644);
|
||||
if (fchmod(fileno(f), 0644) < 0)
|
||||
return log_error_errno(errno, "Failed to set access mode for state file '%s' to 0644: %m", m->state_file);
|
||||
|
||||
fprintf(f,
|
||||
"# This is private data. Do not parse.\n"
|
||||
"NAME=%s\n",
|
||||
m->name);
|
||||
|
||||
if (m->unit) {
|
||||
_cleanup_free_ char *escaped = NULL;
|
||||
/* We continue to call this "SCOPE=" because it is internal only, and we want to stay compatible with old files */
|
||||
env_file_fputs_assignment(f, "SCOPE=", m->unit);
|
||||
env_file_fputs_assignment(f, "SCOPE_JOB=", m->scope_job);
|
||||
|
||||
escaped = cescape(m->unit);
|
||||
if (!escaped) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fprintf(f, "SCOPE=%s\n", escaped); /* We continue to call this "SCOPE=" because it is internal only, and we want to stay compatible with old files */
|
||||
}
|
||||
|
||||
if (m->scope_job)
|
||||
fprintf(f, "SCOPE_JOB=%s\n", m->scope_job);
|
||||
|
||||
if (m->service) {
|
||||
_cleanup_free_ char *escaped = NULL;
|
||||
|
||||
escaped = cescape(m->service);
|
||||
if (!escaped) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
fprintf(f, "SERVICE=%s\n", escaped);
|
||||
}
|
||||
|
||||
if (m->root_directory) {
|
||||
_cleanup_free_ char *escaped = NULL;
|
||||
|
||||
escaped = cescape(m->root_directory);
|
||||
if (!escaped) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
fprintf(f, "ROOT=%s\n", escaped);
|
||||
}
|
||||
env_file_fputs_assignment(f, "SERVICE=", m->service);
|
||||
env_file_fputs_assignment(f, "ROOT=", m->root_directory);
|
||||
|
||||
if (!sd_id128_is_null(m->id))
|
||||
fprintf(f, "ID=" SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->id));
|
||||
|
||||
if (pidref_is_set(&m->leader))
|
||||
if (pidref_is_set(&m->leader)) {
|
||||
fprintf(f, "LEADER="PID_FMT"\n", m->leader.pid);
|
||||
(void) pidref_acquire_pidfd_id(&m->leader);
|
||||
if (m->leader.fd_id != 0)
|
||||
fprintf(f, "LEADER_PIDFDID=%" PRIu64 "\n", m->leader.fd_id);
|
||||
}
|
||||
|
||||
if (m->class != _MACHINE_CLASS_INVALID)
|
||||
fprintf(f, "CLASS=%s\n", machine_class_to_string(m->class));
|
||||
@@ -226,56 +208,44 @@ int machine_save(Machine *m) {
|
||||
m->timestamp.monotonic);
|
||||
|
||||
if (m->n_netif > 0) {
|
||||
size_t i;
|
||||
|
||||
fputs("NETIF=", f);
|
||||
|
||||
for (i = 0; i < m->n_netif; i++) {
|
||||
if (i != 0)
|
||||
fputs("NETIF=\"", f);
|
||||
FOREACH_ARRAY(ifi, m->netif, m->n_netif) {
|
||||
if (*ifi != 0)
|
||||
fputc(' ', f);
|
||||
|
||||
fprintf(f, "%i", m->netif[i]);
|
||||
fprintf(f, "%i", *ifi);
|
||||
}
|
||||
|
||||
fputc('\n', f);
|
||||
fputs("\"\n", f);
|
||||
}
|
||||
|
||||
r = fflush_and_check(f);
|
||||
if (m->vsock_cid != 0)
|
||||
fprintf(f, "VSOCK_CID=%u\n", m->vsock_cid);
|
||||
|
||||
env_file_fputs_assignment(f, "SSH_ADDRESS=", m->ssh_address);
|
||||
env_file_fputs_assignment(f, "SSH_PRIVATE_KEY_PATH=", m->ssh_private_key_path);
|
||||
|
||||
r = flink_tmpfile(f, temp_path, m->state_file, LINK_TMPFILE_REPLACE);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
return log_error_errno(r, "Failed to move '%s' into place: %m", m->state_file);
|
||||
|
||||
if (rename(temp_path, m->state_file) < 0) {
|
||||
r = -errno;
|
||||
goto fail;
|
||||
}
|
||||
temp_path = mfree(temp_path); /* disarm auto-destroy: temporary file does not exist anymore */
|
||||
|
||||
temp_path = mfree(temp_path);
|
||||
|
||||
if (m->unit) {
|
||||
char *sl;
|
||||
|
||||
/* Create a symlink from the unit name to the machine
|
||||
* name, so that we can quickly find the machine for
|
||||
* each given unit. Ignore error. */
|
||||
sl = strjoina("/run/systemd/machines/unit:", m->unit);
|
||||
if (sl) {
|
||||
/* Create a symlink from the unit name to the machine name, so that we can quickly find the machine
|
||||
* for each given unit. Ignore error. */
|
||||
(void) symlink(m->name, sl);
|
||||
|
||||
/* disarm auto-removal */
|
||||
sl = mfree(sl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
(void) unlink(m->state_file);
|
||||
|
||||
return log_error_errno(r, "Failed to save machine data %s: %m", m->state_file);
|
||||
}
|
||||
|
||||
static void machine_unlink(Machine *m) {
|
||||
assert(m);
|
||||
|
||||
if (m->unit) {
|
||||
char *sl;
|
||||
|
||||
sl = strjoina("/run/systemd/machines/unit:", m->unit);
|
||||
const char *sl = strjoina("/run/systemd/machines/unit:", m->unit);
|
||||
(void) unlink(sl);
|
||||
}
|
||||
|
||||
@@ -284,7 +254,8 @@ static void machine_unlink(Machine *m) {
|
||||
}
|
||||
|
||||
int machine_load(Machine *m) {
|
||||
_cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL, *netif = NULL;
|
||||
_cleanup_free_ char *name = NULL, *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *leader_pidfdid = NULL,
|
||||
*class = NULL, *netif = NULL, *vsock_cid = NULL;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@@ -293,35 +264,55 @@ int machine_load(Machine *m) {
|
||||
return 0;
|
||||
|
||||
r = parse_env_file(NULL, m->state_file,
|
||||
"SCOPE", &m->unit,
|
||||
"SCOPE_JOB", &m->scope_job,
|
||||
"SERVICE", &m->service,
|
||||
"ROOT", &m->root_directory,
|
||||
"ID", &id,
|
||||
"LEADER", &leader,
|
||||
"CLASS", &class,
|
||||
"REALTIME", &realtime,
|
||||
"MONOTONIC", &monotonic,
|
||||
"NETIF", &netif);
|
||||
"NAME", &name,
|
||||
"SCOPE", &m->unit,
|
||||
"SCOPE_JOB", &m->scope_job,
|
||||
"SERVICE", &m->service,
|
||||
"ROOT", &m->root_directory,
|
||||
"ID", &id,
|
||||
"LEADER", &leader,
|
||||
"LEADER_PIDFDID", &leader_pidfdid,
|
||||
"CLASS", &class,
|
||||
"REALTIME", &realtime,
|
||||
"MONOTONIC", &monotonic,
|
||||
"NETIF", &netif,
|
||||
"VSOCK_CID", &vsock_cid,
|
||||
"SSH_ADDRESS", &m->ssh_address,
|
||||
"SSH_PRIVATE_KEY_PATH", &m->ssh_private_key_path);
|
||||
if (r == -ENOENT)
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read %s: %m", m->state_file);
|
||||
|
||||
if (!streq_ptr(name, m->name))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "State file '%s' for machine '%s' reports a different name '%s', refusing", m->state_file, m->name, name);
|
||||
|
||||
if (id)
|
||||
(void) sd_id128_from_string(id, &m->id);
|
||||
|
||||
pidref_done(&m->leader);
|
||||
if (leader) {
|
||||
pidref_done(&m->leader);
|
||||
r = pidref_set_pidstr(&m->leader, leader);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to set leader PID to '%s', ignoring: %m", leader);
|
||||
else if (leader_pidfdid) {
|
||||
uint64_t fd_id;
|
||||
r = safe_atou64(leader_pidfdid, &fd_id);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse leader pidfd ID, ignoring: %s", leader_pidfdid);
|
||||
else {
|
||||
(void) pidref_acquire_pidfd_id(&m->leader);
|
||||
|
||||
if (fd_id != m->leader.fd_id) {
|
||||
log_debug("Leader PID got recycled, ignoring.");
|
||||
pidref_done(&m->leader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (class) {
|
||||
MachineClass c;
|
||||
|
||||
c = machine_class_from_string(class);
|
||||
MachineClass c = machine_class_from_string(class);
|
||||
if (c >= 0)
|
||||
m->class = c;
|
||||
}
|
||||
@@ -331,13 +322,13 @@ int machine_load(Machine *m) {
|
||||
if (monotonic)
|
||||
(void) deserialize_usec(monotonic, &m->timestamp.monotonic);
|
||||
|
||||
m->netif = mfree(m->netif);
|
||||
m->n_netif = 0;
|
||||
if (netif) {
|
||||
_cleanup_free_ int *ni = NULL;
|
||||
size_t nr = 0;
|
||||
const char *p;
|
||||
|
||||
p = netif;
|
||||
for (;;) {
|
||||
for (const char *p = netif;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, 0);
|
||||
@@ -360,10 +351,17 @@ int machine_load(Machine *m) {
|
||||
ni[nr++] = r;
|
||||
}
|
||||
|
||||
free_and_replace(m->netif, ni);
|
||||
m->netif = TAKE_PTR(ni);
|
||||
m->n_netif = nr;
|
||||
}
|
||||
|
||||
m->vsock_cid = 0;
|
||||
if (vsock_cid) {
|
||||
r = safe_atou(vsock_cid, &m->vsock_cid);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse AF_VSOCK CID, ignoring: %s", vsock_cid);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -574,7 +572,7 @@ int machine_stop(Machine *m) {
|
||||
|
||||
r = manager_stop_unit(m->manager, m->unit, &error, &job);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to stop machine scope: %s", bus_error_message(&error, r));
|
||||
return log_error_errno(r, "Failed to stop machine unit: %s", bus_error_message(&error, r));
|
||||
|
||||
free_and_replace(m->scope_job, job);
|
||||
}
|
||||
@@ -611,22 +609,43 @@ int machine_finalize(Machine *m) {
|
||||
}
|
||||
|
||||
bool machine_may_gc(Machine *m, bool drop_not_started) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
if (m->class == MACHINE_HOST)
|
||||
return false;
|
||||
|
||||
if (!pidref_is_set(&m->leader))
|
||||
return true;
|
||||
|
||||
if (drop_not_started && !m->started)
|
||||
return true;
|
||||
|
||||
if (m->scope_job && manager_job_is_active(m->manager, m->scope_job))
|
||||
r = pidref_is_alive(&m->leader);
|
||||
if (r == -ESRCH)
|
||||
return true;
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Unable to determine if leader PID " PID_FMT " is still alive, assuming not: %m", m->leader.pid);
|
||||
if (r > 0)
|
||||
return false;
|
||||
|
||||
if (m->unit && manager_unit_is_active(m->manager, m->unit))
|
||||
return false;
|
||||
if (m->scope_job) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
|
||||
r = manager_job_is_active(m->manager, m->scope_job, &error);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to determine whether job '%s' is active, assuming it is: %s", m->scope_job, bus_error_message(&error, r));
|
||||
if (r != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m->unit) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
|
||||
r = manager_unit_is_active(m->manager, m->unit, &error);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to determine whether unit '%s' is active, assuming it is: %s", m->unit, bus_error_message(&error, r));
|
||||
if (r != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ static int method_create_or_register_machine(
|
||||
if (leader == 1)
|
||||
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
|
||||
|
||||
if (!isempty(root_directory) && !path_is_absolute(root_directory))
|
||||
if (!isempty(root_directory) && (!path_is_absolute(root_directory) || !path_is_valid(root_directory)))
|
||||
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Root directory must be empty or an absolute path");
|
||||
|
||||
if (leader == 0) {
|
||||
@@ -1262,7 +1262,7 @@ int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_erro
|
||||
return bus_call_method(manager->bus, bus_systemd_mgr, "KillUnit", error, NULL, "ssi", unit, "all", signo);
|
||||
}
|
||||
|
||||
int manager_unit_is_active(Manager *manager, const char *unit) {
|
||||
int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *reterr_error) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_free_ char *path = NULL;
|
||||
@@ -1294,6 +1294,7 @@ int manager_unit_is_active(Manager *manager, const char *unit) {
|
||||
BUS_ERROR_LOAD_FAILED))
|
||||
return false;
|
||||
|
||||
sd_bus_error_move(reterr_error, &error);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1304,7 +1305,7 @@ int manager_unit_is_active(Manager *manager, const char *unit) {
|
||||
return !STR_IN_SET(state, "inactive", "failed");
|
||||
}
|
||||
|
||||
int manager_job_is_active(Manager *manager, const char *path) {
|
||||
int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *reterr_error) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
int r;
|
||||
@@ -1329,6 +1330,7 @@ int manager_job_is_active(Manager *manager, const char *path) {
|
||||
if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
|
||||
return false;
|
||||
|
||||
sd_bus_error_move(reterr_error, &error);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
|
||||
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
|
||||
int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error);
|
||||
int manager_unref_unit(Manager *m, const char *unit, sd_bus_error *error);
|
||||
int manager_unit_is_active(Manager *manager, const char *unit);
|
||||
int manager_job_is_active(Manager *manager, const char *path);
|
||||
int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *reterr_errno);
|
||||
int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *reterr_errno);
|
||||
|
||||
int manager_find_machine_for_uid(Manager *m, uid_t host_uid, Machine **ret_machine, uid_t *ret_internal_uid);
|
||||
int manager_find_machine_for_gid(Manager *m, gid_t host_gid, Machine **ret_machine, gid_t *ret_internal_gid);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "bus-get-properties.h"
|
||||
#include "bus-message-util.h"
|
||||
#include "pidref.h"
|
||||
#include "rlimit-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
@@ -188,3 +189,23 @@ int bus_property_get_string_set(
|
||||
|
||||
return bus_message_append_string_set(reply, *s);
|
||||
}
|
||||
|
||||
int bus_property_get_pidfdid(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
PidRef *pidref = ASSERT_PTR(userdata);
|
||||
|
||||
assert(bus);
|
||||
assert(property);
|
||||
assert(reply);
|
||||
|
||||
(void) pidref_acquire_pidfd_id(pidref);
|
||||
|
||||
return sd_bus_message_append(reply, "t", pidref->fd_id);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,8 @@ int bus_property_get_rlimit(sd_bus *bus, const char *path, const char *interface
|
||||
|
||||
int bus_property_get_string_set(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
|
||||
|
||||
int bus_property_get_pidfdid(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
|
||||
|
||||
#define BUS_DEFINE_PROPERTY_GET_GLOBAL(function, bus_type, val) \
|
||||
int function(sd_bus *bus, \
|
||||
const char *path, \
|
||||
|
||||
Reference in New Issue
Block a user