]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/unit.c
resolve: set IP_RECVERR
[thirdparty/systemd.git] / src / core / unit.c
index 6ca8f6a97f947003f5e46f5825bdfc383601ce70..0ce9318556ffc8dec593d5acd8685339a42ebee2 100644 (file)
@@ -93,7 +93,7 @@ Unit *unit_new(Manager *m, size_t size) {
         u->ref_uid = UID_INVALID;
         u->ref_gid = GID_INVALID;
         u->cpu_usage_last = NSEC_INFINITY;
-        u->cgroup_bpf_state = UNIT_CGROUP_BPF_INVALIDATED;
+        u->cgroup_invalidated_mask |= CGROUP_MASK_BPF_FIREWALL;
 
         u->ip_accounting_ingress_map_fd = -1;
         u->ip_accounting_egress_map_fd = -1;
@@ -666,6 +666,8 @@ void unit_free(Unit *u) {
         bpf_program_unref(u->ip_bpf_egress);
         bpf_program_unref(u->ip_bpf_egress_installed);
 
+        bpf_program_unref(u->bpf_device_control_installed);
+
         condition_free_list(u->conditions);
         condition_free_list(u->asserts);
 
@@ -1009,7 +1011,7 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
                                 return r;
                 }
 
-                r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_TMPFILES_SETUP_SERVICE, NULL, true, UNIT_DEPENDENCY_FILE);
+                r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_TMPFILES_SETUP_SERVICE, true, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
         }
@@ -1027,7 +1029,7 @@ 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. */
 
-        r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true, UNIT_DEPENDENCY_FILE);
+        r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, true, UNIT_DEPENDENCY_FILE);
         if (r < 0)
                 return r;
 
@@ -1398,7 +1400,7 @@ static int unit_add_slice_dependencies(Unit *u) {
         if (unit_has_name(u, SPECIAL_ROOT_SLICE))
                 return 0;
 
-        return unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_ROOT_SLICE, NULL, true, mask);
+        return unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_ROOT_SLICE, true, mask);
 }
 
 static int unit_add_mount_dependencies(Unit *u) {
@@ -1722,7 +1724,9 @@ int unit_start_limit_test(Unit *u) {
         log_unit_warning(u, "Start request repeated too quickly.");
         u->start_limit_hit = true;
 
-        return emergency_action(u->manager, u->start_limit_action, u->reboot_arg, "unit failed");
+        return emergency_action(u->manager, u->start_limit_action,
+                                EMERGENCY_ACTION_IS_WATCHDOG|EMERGENCY_ACTION_WARN,
+                                u->reboot_arg, "unit failed");
 }
 
 bool unit_shall_confirm_spawn(Unit *u) {
@@ -1998,7 +2002,7 @@ bool unit_is_unneeded(Unit *u) {
                  * restart, then don't clean this one up. */
 
                 HASHMAP_FOREACH_KEY(v, other, u->dependencies[deps[j]], i) {
-                        if (u->job)
+                        if (other->job)
                                 return false;
 
                         if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
@@ -2444,43 +2448,36 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag
                         if (!(flags & UNIT_NOTIFY_WILL_AUTO_RESTART))
                                 unit_start_on_failure(u);
                 }
-        }
 
-        if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
+                if (UNIT_IS_ACTIVE_OR_RELOADING(ns) && !UNIT_IS_ACTIVE_OR_RELOADING(os)) {
+                        /* This unit just finished starting up */
 
-                if (u->type == UNIT_SERVICE &&
-                    !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
-                    !MANAGER_IS_RELOADING(m)) {
-                        /* Write audit record if we have just finished starting up */
-                        manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
-                        u->in_audit = true;
-                }
+                        if (u->type == UNIT_SERVICE) {
+                                /* Write audit record if we have just finished starting up */
+                                manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
+                                u->in_audit = true;
+                        }
 
-                if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
                         manager_send_unit_plymouth(m, u);
+                }
 
-        } else {
-
-                if (UNIT_IS_INACTIVE_OR_FAILED(ns) &&
-                    !UNIT_IS_INACTIVE_OR_FAILED(os)
-                    && !MANAGER_IS_RELOADING(m)) {
-
+                if (UNIT_IS_INACTIVE_OR_FAILED(ns) && !UNIT_IS_INACTIVE_OR_FAILED(os)) {
                         /* This unit just stopped/failed. */
+
                         if (u->type == UNIT_SERVICE) {
 
-                                /* Hmm, if there was no start record written
-                                 * write it now, so that we always have a nice
-                                 * pair */
-                                if (!u->in_audit) {
+                                if (u->in_audit) {
+                                        /* Write audit record if we have just finished shutting down */
+                                        manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
+                                        u->in_audit = false;
+                                } else {
+                                        /* Hmm, if there was no start record written write it now, so that we always
+                                         * have a nice pair */
                                         manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
 
                                         if (ns == UNIT_INACTIVE)
                                                 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
-                                } else
-                                        /* Write audit record if we have just finished shutting down */
-                                        manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
-
-                                u->in_audit = false;
+                                }
                         }
 
                         /* Write a log message about consumed resources */
@@ -2503,9 +2500,11 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag
                 unit_check_binds_to(u);
 
                 if (os != UNIT_FAILED && ns == UNIT_FAILED)
-                        (void) emergency_action(u->manager, u->failure_action, u->reboot_arg, "unit failed");
+                        (void) emergency_action(u->manager, u->failure_action, 0,
+                                                u->reboot_arg, "unit failed");
                 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && ns == UNIT_INACTIVE)
-                        (void) emergency_action(u->manager, u->success_action, u->reboot_arg, "unit succeeded");
+                        (void) emergency_action(u->manager, u->success_action, 0,
+                                                u->reboot_arg, "unit succeeded");
         }
 
         unit_add_to_dbus_queue(u);
@@ -2894,17 +2893,14 @@ int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit
         return unit_add_dependency(u, e, other, add_reference, mask);
 }
 
-static int resolve_template(Unit *u, const char *name, const char*path, char **buf, const char **ret) {
+static int resolve_template(Unit *u, const char *name, char **buf, const char **ret) {
         int r;
 
         assert(u);
-        assert(name || path);
+        assert(name);
         assert(buf);
         assert(ret);
 
-        if (!name)
-                name = basename(path);
-
         if (!unit_name_is_valid(name, UNIT_NAME_TEMPLATE)) {
                 *buf = NULL;
                 *ret = name;
@@ -2929,38 +2925,38 @@ static int resolve_template(Unit *u, const char *name, const char*path, char **b
         return 0;
 }
 
-int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference, UnitDependencyMask mask) {
+int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, bool add_reference, UnitDependencyMask mask) {
         _cleanup_free_ char *buf = NULL;
         Unit *other;
         int r;
 
         assert(u);
-        assert(name || path);
+        assert(name);
 
-        r = resolve_template(u, name, path, &buf, &name);
+        r = resolve_template(u, name, &buf, &name);
         if (r < 0)
                 return r;
 
-        r = manager_load_unit(u->manager, name, path, NULL, &other);
+        r = manager_load_unit(u->manager, name, NULL, NULL, &other);
         if (r < 0)
                 return r;
 
         return unit_add_dependency(u, d, other, add_reference, mask);
 }
 
-int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference, UnitDependencyMask mask) {
+int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, bool add_reference, UnitDependencyMask mask) {
         _cleanup_free_ char *buf = NULL;
         Unit *other;
         int r;
 
         assert(u);
-        assert(name || path);
+        assert(name);
 
-        r = resolve_template(u, name, path, &buf, &name);
+        r = resolve_template(u, name, &buf, &name);
         if (r < 0)
                 return r;
 
-        r = manager_load_unit(u->manager, name, path, NULL, &other);
+        r = manager_load_unit(u->manager, name, NULL, NULL, &other);
         if (r < 0)
                 return r;
 
@@ -3248,6 +3244,8 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
 
         unit_serialize_item(u, f, "transient", yes_no(u->transient));
 
+        unit_serialize_item(u, f, "in-audit", yes_no(u->in_audit));
+
         unit_serialize_item(u, f, "exported-invocation-id", yes_no(u->exported_invocation_id));
         unit_serialize_item(u, f, "exported-log-level-max", yes_no(u->exported_log_level_max));
         unit_serialize_item(u, f, "exported-log-extra-fields", yes_no(u->exported_log_extra_fields));
@@ -3261,7 +3259,7 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
         unit_serialize_item(u, f, "cgroup-realized", yes_no(u->cgroup_realized));
         (void) unit_serialize_cgroup_mask(f, "cgroup-realized-mask", u->cgroup_realized_mask);
         (void) unit_serialize_cgroup_mask(f, "cgroup-enabled-mask", u->cgroup_enabled_mask);
-        unit_serialize_item_format(u, f, "cgroup-bpf-realized", "%i", u->cgroup_bpf_state);
+        (void) unit_serialize_cgroup_mask(f, "cgroup-invalidated-mask", u->cgroup_invalidated_mask);
 
         if (uid_is_valid(u->ref_uid))
                 unit_serialize_item_format(u, f, "ref-uid", UID_FMT, u->ref_uid);
@@ -3486,6 +3484,16 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
 
                         continue;
 
+                } else if (streq(l, "in-audit")) {
+
+                        r = parse_boolean(v);
+                        if (r < 0)
+                                log_unit_debug(u, "Failed to parse in-audit bool %s, ignoring.", v);
+                        else
+                                u->in_audit = r;
+
+                        continue;
+
                 } else if (streq(l, "exported-invocation-id")) {
 
                         r = parse_boolean(v);
@@ -3566,18 +3574,11 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
                                 log_unit_debug(u, "Failed to parse cgroup-enabled-mask %s, ignoring.", v);
                         continue;
 
-                } else if (streq(l, "cgroup-bpf-realized")) {
-                        int i;
+                } else if (streq(l, "cgroup-invalidated-mask")) {
 
-                        r = safe_atoi(v, &i);
+                        r = cg_mask_from_string(v, &u->cgroup_invalidated_mask);
                         if (r < 0)
-                                log_unit_debug(u, "Failed to parse cgroup BPF state %s, ignoring.", v);
-                        else
-                                u->cgroup_bpf_state =
-                                        i < 0 ? UNIT_CGROUP_BPF_INVALIDATED :
-                                        i > 0 ? UNIT_CGROUP_BPF_ON :
-                                        UNIT_CGROUP_BPF_OFF;
-
+                                log_unit_debug(u, "Failed to parse cgroup-invalidated-mask %s, ignoring.", v);
                         continue;
 
                 } else if (streq(l, "ref-uid")) {
@@ -3600,6 +3601,8 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
                         else
                                 unit_ref_uid_gid(u, UID_INVALID, gid);
 
+                        continue;
+
                 } else if (streq(l, "ref")) {
 
                         r = strv_extend(&u->deserialized_refs, v);
@@ -4509,8 +4512,8 @@ static int operation_to_signal(KillContext *c, KillOperation k) {
         case KILL_KILL:
                 return c->final_kill_signal;
 
-        case KILL_ABORT:
-                return SIGABRT;
+        case KILL_WATCHDOG:
+                return c->watchdog_signal;
 
         default:
                 assert_not_reached("KillOperation unknown");
@@ -5281,7 +5284,7 @@ void unit_export_state_files(Unit *u) {
         if (!MANAGER_IS_SYSTEM(u->manager))
                 return;
 
-        if (u->manager->test_run_flags != 0)
+        if (MANAGER_IS_TEST_RUN(u->manager))
                 return;
 
         /* Exports a couple of unit properties to /run/systemd/units/, so that journald can quickly query this data