Hi Michael,

Michael Biebl <[email protected]> writes:
> could be a bit misleading. It might be a good idea to both list the
> service, for which the action was denied, and the action. Something like
>
> "final.target is queued, ignoring $action request for $service"
True, fixed.

The new message looks like this:
10:35:37.864754109 final.target is queued, ignoring reload request for unit 
samba.service

-- 
Best regards,
Michael
--- systemd-44.orig/src/manager.c	2012-10-16 10:12:22.000000000 +0200
+++ systemd-44/src/manager.c	2012-10-16 10:26:52.239646195 +0200
@@ -1700,6 +1700,8 @@
 int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, DBusError *e, Job **_ret) {
         int r;
         Job *ret;
+        Job *j;
+        Iterator i;
 
         assert(m);
         assert(type < _JOB_TYPE_MAX);
@@ -1711,6 +1713,30 @@
                 return -EINVAL;
         }
 
+        if (type == JOB_RELOAD || type == JOB_RELOAD_OR_START || type == JOB_RESTART || type == JOB_TRY_RESTART) {
+                /* If final.target is queued (happens on poweroff, reboot and
+                 * halt), we will not accept new reload jobs. They would not be
+                 * executed ever anyways (since the shutdown comes first), but
+                 * they block the shutdown process: when systemd tries to stop
+                 * a unit such as [email protected], that unit might invoke a
+                 * systemctl reload command, which blockingly waits (but only
+                 * gets executed after all other queued units for the shutdown
+                 * have been executed).
+                 *
+                 * See http://bugs.debian.org/624599 and
+                 *     http://bugs.debian.org/635777 */
+                HASHMAP_FOREACH(j, m->jobs, i) {
+                        assert(j->installed);
+
+                        if (strcmp(j->unit->id, "final.target") == 0) {
+                                log_debug("final.target is queued, ignoring %s request for unit %s", job_type_to_string(type), unit->id);
+                                dbus_set_error(e, BUS_ERROR_INVALID_JOB_MODE, "final.target is queued, ignoring %s request for unit %s", job_type_to_string(type), unit->id);
+                                return -EINVAL;
+                        }
+                }
+        }
+
+
         if (mode == JOB_ISOLATE && !unit->allow_isolate) {
                 dbus_set_error(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
                 return -EPERM;

Reply via email to