chiark / gitweb /
sd-dhcp-client: log positive error number
[elogind.git] / src / core / busname.c
index c45265658c21468c30cba21c0cee089446aebd97..e6063669e3abe66dd16414befaf715db9d6b4807 100644 (file)
@@ -29,6 +29,7 @@
 
 static const UnitActiveState state_translation_table[_BUSNAME_STATE_MAX] = {
         [BUSNAME_DEAD] = UNIT_INACTIVE,
+        [BUSNAME_REGISTERED] = UNIT_ACTIVE,
         [BUSNAME_LISTENING] = UNIT_ACTIVE,
         [BUSNAME_RUNNING] = UNIT_ACTIVE,
         [BUSNAME_FAILED] = UNIT_FAILED
@@ -43,6 +44,8 @@ static void busname_init(Unit *u) {
         assert(u->load_state == UNIT_STUB);
 
         n->starter_fd = -1;
+        n->accept_fd = true;
+        n->activating = true;
 }
 
 static void busname_done(Unit *u) {
@@ -56,11 +59,7 @@ static void busname_done(Unit *u) {
         unit_ref_unset(&n->service);
 
         n->event_source = sd_event_source_unref(n->event_source);
-
-        if (n->starter_fd >= 0) {
-                close_nointr_nofail(n->starter_fd);
-                n->starter_fd = -1;
-        }
+        n->starter_fd = safe_close(n->starter_fd);
 }
 
 static int busname_add_default_default_dependencies(BusName *n) {
@@ -99,20 +98,22 @@ static int busname_add_extras(BusName *n) {
                         return r;
         }
 
-        if (!UNIT_DEREF(n->service)) {
-                Unit *x;
+        if (n->activating) {
+                if (!UNIT_DEREF(n->service)) {
+                        Unit *x;
 
-                r = unit_load_related_unit(u, ".service", &x);
+                        r = unit_load_related_unit(u, ".service", &x);
+                        if (r < 0)
+                                return r;
+
+                        unit_ref_set(&n->service, x);
+                }
+
+                r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(n->service), true);
                 if (r < 0)
                         return r;
-
-                unit_ref_set(&n->service, x);
         }
 
-        r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(n->service), true);
-        if (r < 0)
-                return r;
-
         if (u->default_dependencies) {
                 r = busname_add_default_default_dependencies(n);
                 if (r < 0)
@@ -122,8 +123,6 @@ static int busname_add_extras(BusName *n) {
         return 0;
 }
 
-
-
 static int busname_verify(BusName *n) {
         char *e;
 
@@ -176,10 +175,14 @@ static void busname_dump(Unit *u, FILE *f, const char *prefix) {
         fprintf(f,
                 "%sBus Name State: %s\n"
                 "%sResult: %s\n"
-                "%sName: %s\n",
+                "%sName: %s\n"
+                "%sActivating: %s\n"
+                "%sAccept FD: %s\n",
                 prefix, busname_state_to_string(n->state),
                 prefix, busname_result_to_string(n->result),
-                prefix, n->name);
+                prefix, n->name,
+                prefix, yes_no(n->activating),
+                prefix, yes_no(n->accept_fd));
 }
 
 static void busname_unwatch_fd(BusName *n) {
@@ -197,11 +200,12 @@ static void busname_unwatch_fd(BusName *n) {
 static void busname_close_fd(BusName *n) {
         assert(n);
 
+        busname_unwatch_fd(n);
+
         if (n->starter_fd <= 0)
                 return;
 
-        close_nointr_nofail(n->starter_fd);
-        n->starter_fd = -1;
+        n->starter_fd = safe_close(n->starter_fd);
 }
 
 static int busname_watch_fd(BusName *n) {
@@ -215,7 +219,7 @@ static int busname_watch_fd(BusName *n) {
         if (n->event_source)
                 r = sd_event_source_set_enabled(n->event_source, SD_EVENT_ON);
         else
-                r = sd_event_add_io(UNIT(n)->manager->event, n->starter_fd, EPOLLIN, busname_dispatch_io, n, &n->event_source);
+                r = sd_event_add_io(UNIT(n)->manager->event, &n->event_source, n->starter_fd, EPOLLIN, busname_dispatch_io, n);
         if (r < 0) {
                 log_warning_unit(UNIT(n)->id, "Failed to watch starter fd: %s", strerror(-r));
                 busname_unwatch_fd(n);
@@ -231,7 +235,10 @@ static int busname_open_fd(BusName *n) {
         if (n->starter_fd >= 0)
                 return 0;
 
-        n->starter_fd = bus_kernel_create_starter(UNIT(n)->manager->running_as == SYSTEMD_SYSTEM ? "system" : "user", n->name);
+        n->starter_fd = bus_kernel_create_starter(
+                        UNIT(n)->manager->running_as == SYSTEMD_SYSTEM ? "system" : "user",
+                        n->name, n->activating, n->accept_fd, n->policy);
+
         if (n->starter_fd < 0) {
                 log_warning_unit(UNIT(n)->id, "Failed to create starter fd: %s", strerror(-n->starter_fd));
                 return n->starter_fd;
@@ -250,7 +257,7 @@ static void busname_set_state(BusName *n, BusNameState state) {
         if (state != BUSNAME_LISTENING)
                 busname_unwatch_fd(n);
 
-        if (!IN_SET(state, BUSNAME_LISTENING, BUSNAME_RUNNING))
+        if (!IN_SET(state, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING))
                 busname_close_fd(n);
 
         if (state != old_state)
@@ -270,7 +277,7 @@ static int busname_coldplug(Unit *u) {
         if (n->deserialized_state == n->state)
                 return 0;
 
-        if (IN_SET(n->deserialized_state, BUSNAME_LISTENING, BUSNAME_RUNNING)) {
+        if (IN_SET(n->deserialized_state, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING)) {
                 r = busname_open_fd(n);
                 if (r < 0)
                         return r;
@@ -302,17 +309,23 @@ static void busname_enter_listening(BusName *n) {
 
         r = busname_open_fd(n);
         if (r < 0) {
-                log_warning_unit(UNIT(n)->id, "%s failed to listen on bus names: %s", UNIT(n)->id, strerror(-r));
+                log_warning_unit(UNIT(n)->id, "%s failed to %s: %s", UNIT(n)->id,
+                                 n->activating ? "listen on bus name" : "register policy for name",
+                                 strerror(-r));
                 goto fail;
         }
 
-        r = busname_watch_fd(n);
-        if (r < 0) {
-                log_warning_unit(UNIT(n)->id, "%s failed to watch names: %s", UNIT(n)->id, strerror(-r));
-                goto fail;
-        }
+        if (n->activating) {
+                r = busname_watch_fd(n);
+                if (r < 0) {
+                        log_warning_unit(UNIT(n)->id, "%s failed to watch names: %s", UNIT(n)->id, strerror(-r));
+                        goto fail;
+                }
+
+                busname_set_state(n, BUSNAME_LISTENING);
+        } else
+                busname_set_state(n, BUSNAME_REGISTERED);
 
-        busname_set_state(n, BUSNAME_LISTENING);
         return;
 
 fail:
@@ -328,11 +341,19 @@ static void busname_enter_running(BusName *n) {
 
         assert(n);
 
+        if (!n->activating)
+                return;
+
         /* We don't take conenctions anymore if we are supposed to
          * shut down anyway */
 
         if (unit_stop_pending(UNIT(n))) {
                 log_debug_unit(UNIT(n)->id, "Suppressing activation request on %s since unit stop is scheduled.", UNIT(n)->id);
+
+                /* Flush all queued activation reqeuest by closing and reopening the connection */
+                bus_kernel_drop_one(n->starter_fd);
+
+                busname_enter_listening(n);
                 return;
         }
 
@@ -363,7 +384,7 @@ static int busname_start(Unit *u) {
 
         assert(n);
 
-        if (UNIT_ISSET(n->service)) {
+        if (n->activating && UNIT_ISSET(n->service)) {
                 Service *service;
 
                 service = SERVICE(UNIT_DEREF(n->service));
@@ -386,7 +407,7 @@ static int busname_stop(Unit *u) {
         BusName *n = BUSNAME(u);
 
         assert(n);
-        assert(n->state == BUSNAME_LISTENING || n->state == BUSNAME_RUNNING);
+        assert(IN_SET(n->state, BUSNAME_REGISTERED, BUSNAME_LISTENING, BUSNAME_RUNNING));
 
         busname_enter_dead(n, BUSNAME_SUCCESS);
         return 0;
@@ -446,8 +467,7 @@ static int busname_deserialize_item(Unit *u, const char *key, const char *value,
                 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
                         log_debug_unit(u->id, "Failed to parse starter fd value %s", value);
                 else {
-                        if (n->starter_fd >= 0)
-                                close_nointr_nofail(n->starter_fd);
+                        safe_close(n->starter_fd);
                         n->starter_fd = fdset_remove(fds, fd);
                 }
         } else
@@ -519,23 +539,19 @@ static void busname_trigger_notify(Unit *u, Unit *other) {
 
         s = SERVICE(other);
 
-        if (s->state == SERVICE_FAILED) {
-                if (s->result == SERVICE_FAILURE_START_LIMIT)
-                        busname_enter_dead(n, BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT);
-                else
-                        busname_enter_listening(n);
-        }
-
-        if (IN_SET(n->state,
-                   SERVICE_DEAD,
-                   SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
-                   SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
-                   SERVICE_AUTO_RESTART))
+        if (s->state == SERVICE_FAILED && s->result == SERVICE_FAILURE_START_LIMIT)
+                busname_enter_dead(n, BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT);
+        else if (IN_SET(s->state,
+                        SERVICE_DEAD, SERVICE_FAILED,
+                        SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
+                        SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
+                        SERVICE_AUTO_RESTART))
                 busname_enter_listening(n);
 }
 
 static const char* const busname_state_table[_BUSNAME_STATE_MAX] = {
         [BUSNAME_DEAD] = "dead",
+        [BUSNAME_REGISTERED] = "registered",
         [BUSNAME_LISTENING] = "listening",
         [BUSNAME_RUNNING] = "running",
         [BUSNAME_FAILED] = "failed"
@@ -546,10 +562,19 @@ DEFINE_STRING_TABLE_LOOKUP(busname_state, BusNameState);
 static const char* const busname_result_table[_BUSNAME_RESULT_MAX] = {
         [BUSNAME_SUCCESS] = "success",
         [BUSNAME_FAILURE_RESOURCES] = "resources",
+        [BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(busname_result, BusNameResult);
 
+static const char* const busname_policy_access_table[_BUSNAME_POLICY_ACCESS_MAX] = {
+        [BUSNAME_POLICY_ACCESS_SEE] = "see",
+        [BUSNAME_POLICY_ACCESS_TALK] = "talk",
+        [BUSNAME_POLICY_ACCESS_OWN] = "own",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(busname_policy_access, BusNamePolicyAccess);
+
 const UnitVTable busname_vtable = {
         .object_size = sizeof(BusName),
 
@@ -582,7 +607,6 @@ const UnitVTable busname_vtable = {
 
         .bus_interface = "org.freedesktop.systemd1.BusName",
         .bus_vtable = bus_busname_vtable,
-        .bus_changing_properties = bus_busname_changing_properties,
 
         .status_message_formats = {
                 .finished_start_job = {