X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fbusname.c;h=e6063669e3abe66dd16414befaf715db9d6b4807;hb=68a8723c8592c06b2c978f391cb47db266d9d6de;hp=c45265658c21468c30cba21c0cee089446aebd97;hpb=e821075a23fdfa3ca7738fc30bb2d4c430fe10c0;p=elogind.git diff --git a/src/core/busname.c b/src/core/busname.c index c45265658..e6063669e 100644 --- a/src/core/busname.c +++ b/src/core/busname.c @@ -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 = {