systemctl: restore ability to directly connect to PID1 from systemctl
This commit is contained in:
parent
3f41e1e595
commit
41dd15e474
2
TODO
2
TODO
|
@ -48,7 +48,7 @@ Features:
|
|||
|
||||
* add field to transient units that indicate whether systemd or somebody else saves/restores its settings, for integration with libvirt
|
||||
|
||||
* direct connections to PID 1/XDG_RUNTIME_DIR, wait filter, reboot() filter unification, unify dispatch table in systemctl_main() and friends, convert all to bus_log_create_error()
|
||||
* wait filter, reboot() filter unification, unify dispatch table in systemctl_main() and friends, convert all to bus_log_create_error()
|
||||
|
||||
* bus: access policy as vtable flag
|
||||
|
||||
|
|
|
@ -440,6 +440,46 @@ int bus_open_system_systemd(sd_bus **_bus) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int bus_open_user_systemd(sd_bus **_bus) {
|
||||
_cleanup_bus_unref_ sd_bus *bus = NULL;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
const char *e;
|
||||
int r;
|
||||
|
||||
/* If we are supposed to talk to the instance, try via
|
||||
* XDG_RUNTIME_DIR first, then fallback to normal bus
|
||||
* access */
|
||||
|
||||
assert(_bus);
|
||||
|
||||
e = secure_getenv("XDG_RUNTIME_DIR");
|
||||
if (e) {
|
||||
if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
r = sd_bus_new(&bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_set_address(bus, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_start(bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = bus_check_peercred(bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*_bus = bus;
|
||||
bus = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bus_print_property(const char *name, sd_bus_message *property, bool all) {
|
||||
char type;
|
||||
const char *contents;
|
||||
|
@ -924,6 +964,41 @@ int bus_open_transport(BusTransport transport, const char *host, bool user, sd_b
|
|||
return r;
|
||||
}
|
||||
|
||||
int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
|
||||
int r;
|
||||
|
||||
assert(transport >= 0);
|
||||
assert(transport < _BUS_TRANSPORT_MAX);
|
||||
assert(bus);
|
||||
|
||||
assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
|
||||
assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -ENOTSUP);
|
||||
|
||||
switch (transport) {
|
||||
|
||||
case BUS_TRANSPORT_LOCAL:
|
||||
if (user)
|
||||
r = bus_open_user_systemd(bus);
|
||||
else
|
||||
r = bus_open_system_systemd(bus);
|
||||
|
||||
break;
|
||||
|
||||
case BUS_TRANSPORT_REMOTE:
|
||||
r = sd_bus_open_system_remote(host, bus);
|
||||
break;
|
||||
|
||||
case BUS_TRANSPORT_CONTAINER:
|
||||
r = sd_bus_open_system_container(host, bus);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached("Hmm, unknown transport type.");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int bus_property_get_bool(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
|
|
|
@ -63,8 +63,10 @@ int bus_verify_polkit_async(sd_bus *bus, Hashmap **registry, sd_bus_message *m,
|
|||
void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry);
|
||||
|
||||
int bus_open_system_systemd(sd_bus **_bus);
|
||||
int bus_open_user_systemd(sd_bus **_bus);
|
||||
|
||||
int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus);
|
||||
int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus);
|
||||
|
||||
int bus_print_property(const char *name, sd_bus_message *property, bool all);
|
||||
int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all);
|
||||
|
|
|
@ -5354,7 +5354,7 @@ static int talk_initctl(void) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int systemctl_main(sd_bus *bus, int argc, char *argv[], const int r) {
|
||||
static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
|
||||
|
||||
static const struct {
|
||||
const char* verb;
|
||||
|
@ -5505,14 +5505,14 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], const int r) {
|
|||
if (((!streq(verbs[i].verb, "reboot") &&
|
||||
!streq(verbs[i].verb, "halt") &&
|
||||
!streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
|
||||
log_error("Failed to get D-Bus connection: %s", strerror (-r));
|
||||
log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (!bus && !avoid_bus()) {
|
||||
log_error("Failed to get D-Bus connection: %s", strerror (-r));
|
||||
log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
@ -5764,13 +5764,11 @@ int main(int argc, char*argv[]) {
|
|||
goto finish;
|
||||
}
|
||||
|
||||
if (!avoid_bus()) {
|
||||
r = bus_open_transport(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
|
||||
if (r < 0) {
|
||||
log_error("Failed to create bus connection: %s", strerror(-r));
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
if (!avoid_bus())
|
||||
r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
|
||||
|
||||
/* systemctl_main() will print an error message for the bus
|
||||
* connection, but only if it needs to */
|
||||
|
||||
switch (arg_action) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue