chiark / gitweb /
unit: make ignoring in snapshots a per unit property, instead of a per unit type...
[elogind.git] / src / unit.c
index 6fd4dc6cb0a58bccfbea51100ff22b5f3e2341e3..9bb4e56073ab042a9ee89641c22b3cee35c816ed 100644 (file)
@@ -118,8 +118,10 @@ int unit_add_name(Unit *u, const char *text) {
         if ((r = unit_name_to_instance(s, &i)) < 0)
                 goto fail;
 
-        if (i && unit_vtable[t]->no_instances)
+        if (i && unit_vtable[t]->no_instances) {
+                r = -EINVAL;
                 goto fail;
+        }
 
         /* Ensure that this unit is either instanced or not instanced,
          * but not both. */
@@ -368,7 +370,7 @@ void unit_free(Unit *u) {
                 u->meta.manager->n_in_gc_queue--;
         }
 
-        cgroup_bonding_free_list(u->meta.cgroup_bondings);
+        cgroup_bonding_free_list(u->meta.cgroup_bondings, u->meta.manager->n_serializing <= 0);
 
         free(u->meta.description);
         free(u->meta.fragment_path);
@@ -567,11 +569,8 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
         /* If syslog or kernel logging is requested, make sure our own
          * logging daemon is run first. */
 
-        if ((r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_LOGGER_SOCKET, NULL, true)) < 0)
-                return r;
-
         if (u->meta.manager->running_as == MANAGER_SYSTEM)
-                if ((r = unit_add_dependency_by_name(u, UNIT_REQUIRES, SPECIAL_LOGGER_SOCKET, NULL, true)) < 0)
+                if ((r = unit_add_two_dependencies_by_name(u, UNIT_REQUIRES, UNIT_AFTER, SPECIAL_LOGGER_SOCKET, NULL, true)) < 0)
                         return r;
 
         return 0;
@@ -666,11 +665,17 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                         "%s\tStopWhenUnneeded: %s\n"
                         "%s\tRefuseManualStart: %s\n"
                         "%s\tRefuseManualStop: %s\n"
-                        "%s\tDefaultDependencies: %s\n",
+                        "%s\tDefaultDependencies: %s\n"
+                        "%s\tOnFailureIsolate: %s\n"
+                        "%s\tIgnoreOnIsolate: %s\n"
+                        "%s\tIgnoreOnSnapshot: %s\n",
                         prefix, yes_no(u->meta.stop_when_unneeded),
                         prefix, yes_no(u->meta.refuse_manual_start),
                         prefix, yes_no(u->meta.refuse_manual_stop),
-                        prefix, yes_no(u->meta.default_dependencies));
+                        prefix, yes_no(u->meta.default_dependencies),
+                        prefix, yes_no(u->meta.on_failure_isolate),
+                        prefix, yes_no(u->meta.ignore_on_isolate),
+                        prefix, yes_no(u->meta.ignore_on_snapshot));
 
                 LIST_FOREACH(by_unit, b, u->meta.cgroup_bondings)
                         fprintf(f, "%s\tControlGroup: %s:%s\n",
@@ -815,6 +820,16 @@ int unit_load(Unit *u) {
                 if ((r = unit_add_default_dependencies(u)) < 0)
                         goto fail;
 
+        if (u->meta.on_failure_isolate &&
+            set_size(u->meta.dependencies[UNIT_ON_FAILURE]) > 1) {
+
+                log_error("More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.",
+                          u->meta.id);
+
+                r = -EINVAL;
+                goto fail;
+        }
+
         assert((u->meta.load_state != UNIT_MERGED) == !u->meta.merged_into);
 
         unit_add_to_dbus_queue(unit_follow_merge(u));
@@ -1096,8 +1111,17 @@ void unit_trigger_on_failure(Unit *u) {
 
         assert(u);
 
-        SET_FOREACH(other, u->meta.dependencies[UNIT_ON_FAILURE], i)
-                manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
+        if (set_size(u->meta.dependencies[UNIT_ON_FAILURE]) <= 0)
+                return;
+
+        log_info("Triggering OnFailure= dependencies of %s.", u->meta.id);
+
+        SET_FOREACH(other, u->meta.dependencies[UNIT_ON_FAILURE], i) {
+                int r;
+
+                if ((r = manager_add_job(u->meta.manager, JOB_START, other, u->meta.on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL)) < 0)
+                        log_error("Failed to enqueue OnFailure= job: %s", strerror(-r));
+        }
 }
 
 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
@@ -1858,6 +1882,9 @@ int unit_add_default_cgroups(Unit *u) {
         /* Adds in the default cgroups, if they weren't specified
          * otherwise. */
 
+        if (!u->meta.manager->cgroup_hierarchy)
+                return 0;
+
         if ((r = unit_add_one_default_cgroup(u, NULL)) < 0)
                 return r;
 
@@ -2134,7 +2161,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
                 return 0;
 
         for (;;) {
-                char line[1024], *l, *v;
+                char line[LINE_MAX], *l, *v;
                 size_t k;
 
                 if (!fgets(line, sizeof(line), f)) {
@@ -2242,7 +2269,7 @@ int unit_coldplug(Unit *u) {
                         return r;
 
         if (u->meta.deserialized_job >= 0) {
-                if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_IGNORE_DEPENDENCIES, false, NULL, NULL)) < 0)
+                if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL)) < 0)
                         return r;
 
                 u->meta.deserialized_job = _JOB_TYPE_INVALID;