summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fixme6
-rw-r--r--src/bus-errors.h1
-rw-r--r--src/dbus.c17
-rw-r--r--src/manager.c20
-rw-r--r--src/manager.h2
-rw-r--r--src/special.h1
6 files changed, 42 insertions, 5 deletions
diff --git a/fixme b/fixme
index 58fb81e772..c986d74a9a 100644
--- a/fixme
+++ b/fixme
@@ -80,6 +80,12 @@ v9:
* fix terminal setup
+* figure out ssh disconnect hang
+
+* home.mount failing should not be able to cancel umount.target (IgnoreDependencyFailure=yes borked?)
+
+* disallow further dbus+socket activation on shutdown
+
External:
* place /etc/inittab with explaining blurb.
diff --git a/src/bus-errors.h b/src/bus-errors.h
index a63350cc23..2db1b77f22 100644
--- a/src/bus-errors.h
+++ b/src/bus-errors.h
@@ -41,6 +41,7 @@
#define BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE "org.freedesktop.systemd1.TransactionIsDestructive"
#define BUS_ERROR_TRANSACTION_JOBS_CONFLICTING "org.freedesktop.systemd1.TransactionJobsConflicting"
#define BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC "org.freedesktop.systemd1.TransactionOrderIsCyclic"
+#define BUS_ERROR_SHUTTING_DOWN "org.freedesktop.systemd1.ShuttingDown"
static inline const char *bus_error(const DBusError *e, int r) {
if (e && e->message)
diff --git a/src/dbus.c b/src/dbus.c
index 952806bb2a..8c969eab63 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -43,6 +43,7 @@
#include "dbus-timer.h"
#include "dbus-path.h"
#include "bus-errors.h"
+#include "special.h"
#define CONNECTIONS_MAX 52
@@ -383,13 +384,19 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBus
log_debug("Got D-Bus activation request for %s", name);
- r = manager_load_unit(m, name, NULL, &error, &u);
+ if (manager_unit_pending_inactive(m, SPECIAL_DBUS_SERVICE) ||
+ manager_unit_pending_inactive(m, SPECIAL_DBUS_SOCKET)) {
+ r = -EADDRNOTAVAIL;
+ dbus_set_error(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
+ } else {
+ r = manager_load_unit(m, name, NULL, &error, &u);
- if (r >= 0 && u->meta.refuse_manual_start)
- r = -EPERM;
+ if (r >= 0 && u->meta.refuse_manual_start)
+ r = -EPERM;
- if (r >= 0)
- r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
+ if (r >= 0)
+ r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
+ }
if (r < 0) {
const char *id, *text;
diff --git a/src/manager.c b/src/manager.c
index 517473b802..ff1c70b484 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -2584,6 +2584,26 @@ int manager_set_console(Manager *m, const char *console) {
return 0;
}
+bool manager_unit_pending_inactive(Manager *m, const char *name) {
+ Unit *u;
+
+ assert(m);
+ assert(name);
+
+ /* Returns true if the unit is inactive or going down */
+
+ if (!(u = manager_get_unit(m, name)))
+ return true;
+
+ if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
+ return true;
+
+ if (u->meta.job && u->meta.job->type == JOB_STOP)
+ return true;
+
+ return false;
+}
+
static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
[MANAGER_SYSTEM] = "system",
[MANAGER_SESSION] = "session"
diff --git a/src/manager.h b/src/manager.h
index 77c2076497..445537239c 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -259,6 +259,8 @@ void manager_reset_failed(Manager *m);
void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success);
+bool manager_unit_pending_inactive(Manager *m, const char *name);
+
const char *manager_running_as_to_string(ManagerRunningAs i);
ManagerRunningAs manager_running_as_from_string(const char *s);
diff --git a/src/special.h b/src/special.h
index 0cc5cc647b..d0359db1f5 100644
--- a/src/special.h
+++ b/src/special.h
@@ -59,6 +59,7 @@
#define SPECIAL_POWEROFF_TARGET "poweroff.target"
#define SPECIAL_REBOOT_TARGET "reboot.target"
#define SPECIAL_DBUS_SERVICE "dbus.service"
+#define SPECIAL_DBUS_SOCKET "dbus.socket"
#define SPECIAL_GETTY_TARGET "getty.target"
#define SPECIAL_SERIAL_GETTY_SERVICE "serial-getty@.service"