X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-terminal%2Fsysview.c;h=550f0305af0e2590d5b40b3745707c72b1da04d1;hb=e0952d9d021234e79f3a70f33a9e5d201872a417;hp=70a6ca726c5184ec3decea93b37708c6309dff53;hpb=bfd6d8a322414a7ebd1a64a717c1834e6cb00d7d;p=elogind.git diff --git a/src/libsystemd-terminal/sysview.c b/src/libsystemd-terminal/sysview.c index 70a6ca726..550f0305a 100644 --- a/src/libsystemd-terminal/sysview.c +++ b/src/libsystemd-terminal/sysview.c @@ -27,9 +27,7 @@ #include #include #include "bus-util.h" -#include "event-util.h" #include "macro.h" -#include "set.h" #include "sysview.h" #include "sysview-internal.h" #include "udev-util.h" @@ -295,8 +293,8 @@ static int session_take_control_fn(sd_bus *bus, r = context_raise_session_control(session->seat->context, session, error); if (r < 0) - log_debug("sysview: callback failed while signalling session control '%d' on session '%s': %s", - error, session->name, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while signalling session control '%d' on session '%s': %m", + error, session->name); return 0; } @@ -365,8 +363,8 @@ void sysview_session_release_control(sysview_session *session) { r = sd_bus_send(session->seat->context->sysbus, m, NULL); if (r < 0 && r != -ENOTCONN) - log_debug("sysview: %s: cannot send ReleaseControl: %s", - session->name, strerror(-r)); + log_debug_errno(r, "sysview: %s: cannot send ReleaseControl: %m", + session->name); } /* @@ -476,6 +474,14 @@ static int context_raise(sysview_context *c, sysview_event *event, int def) { return c->running ? c->event_fn(c, c->userdata, event) : def; } +static int context_raise_settle(sysview_context *c) { + sysview_event event = { + .type = SYSVIEW_EVENT_SETTLE, + }; + + return context_raise(c, &event, 0); +} + static int context_raise_seat_add(sysview_context *c, sysview_seat *seat) { sysview_event event = { .type = SYSVIEW_EVENT_SEAT_ADD, @@ -587,6 +593,21 @@ static int context_raise_session_refresh(sysview_context *c, sysview_session *se return context_raise(c, &event, 0); } +static void context_settle(sysview_context *c) { + int r; + + if (c->n_probe <= 0 || --c->n_probe > 0) + return; + + log_debug("sysview: settle"); + + c->settled = true; + + r = context_raise_settle(c); + if (r < 0) + log_debug_errno(r, "sysview: callback failed on settle: %m"); +} + static void context_add_device(sysview_context *c, sysview_device *device) { sysview_session *session; Iterator i; @@ -604,8 +625,8 @@ static void context_add_device(sysview_context *c, sysview_device *device) { r = context_raise_session_attach(c, session, device); if (r < 0) - log_debug("sysview: callback failed while attaching device '%s' to session '%s': %s", - device->name, session->name, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while attaching device '%s' to session '%s': %m", + device->name, session->name); } } @@ -625,8 +646,8 @@ static void context_remove_device(sysview_context *c, sysview_device *device) { r = context_raise_session_detach(c, session, device); if (r < 0) - log_debug("sysview: callback failed while detaching device '%s' from session '%s': %s", - device->name, session->name, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while detaching device '%s' from session '%s': %m", + device->name, session->name); } sysview_device_free(device); @@ -648,8 +669,8 @@ static void context_change_device(sysview_context *c, sysview_device *device, st r = context_raise_session_refresh(c, session, device, ud); if (r < 0) - log_debug("sysview: callback failed while changing device '%s' on session '%s': %s", - device->name, session->name, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while changing device '%s' on session '%s': %m", + device->name, session->name); } } @@ -683,8 +704,8 @@ static void context_add_session(sysview_context *c, sysview_seat *seat, const ch session->public = true; r = context_raise_session_add(c, session); if (r < 0) { - log_debug("sysview: callback failed while adding session '%s': %s", - session->name, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while adding session '%s': %m", + session->name); session->public = false; goto error; } @@ -692,8 +713,8 @@ static void context_add_session(sysview_context *c, sysview_seat *seat, const ch HASHMAP_FOREACH(device, seat->device_map, i) { r = context_raise_session_attach(c, session, device); if (r < 0) - log_debug("sysview: callback failed while attaching device '%s' to new session '%s': %s", - device->name, session->name, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while attaching device '%s' to new session '%s': %m", + device->name, session->name); } } @@ -701,8 +722,8 @@ static void context_add_session(sysview_context *c, sysview_seat *seat, const ch error: if (r < 0) - log_debug("sysview: error while adding session '%s': %s", - id, strerror(-r)); + log_debug_errno(r, "sysview: error while adding session '%s': %m", + id); } static void context_remove_session(sysview_context *c, sysview_session *session) { @@ -719,15 +740,15 @@ static void context_remove_session(sysview_context *c, sysview_session *session) HASHMAP_FOREACH(device, session->seat->device_map, i) { r = context_raise_session_detach(c, session, device); if (r < 0) - log_debug("sysview: callback failed while detaching device '%s' from old session '%s': %s", - device->name, session->name, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while detaching device '%s' from old session '%s': %m", + device->name, session->name); } session->public = false; r = context_raise_session_remove(c, session); if (r < 0) - log_debug("sysview: callback failed while removing session '%s': %s", - session->name, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while removing session '%s': %m", + session->name); } if (!session->custom) @@ -756,8 +777,8 @@ static void context_add_seat(sysview_context *c, const char *id) { seat->public = true; r = context_raise_seat_add(c, seat); if (r < 0) { - log_debug("sysview: callback failed while adding seat '%s': %s", - seat->name, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while adding seat '%s': %m", + seat->name); seat->public = false; } @@ -765,8 +786,8 @@ static void context_add_seat(sysview_context *c, const char *id) { error: if (r < 0) - log_debug("sysview: error while adding seat '%s': %s", - id, strerror(-r)); + log_debug_errno(r, "sysview: error while adding seat '%s': %m", + id); } static void context_remove_seat(sysview_context *c, sysview_seat *seat) { @@ -789,8 +810,8 @@ static void context_remove_seat(sysview_context *c, sysview_seat *seat) { seat->public = false; r = context_raise_seat_remove(c, seat); if (r < 0) - log_debug("sysview: callback failed while removing seat '%s': %s", - seat->name, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while removing seat '%s': %m", + seat->name); } sysview_seat_free(seat); @@ -975,11 +996,9 @@ static int context_ud_hotplug(sysview_context *c, struct udev_device *d) { return 0; r = device_new_ud(&device, seat, type, d); - if (r < 0) { - log_debug("sysview: cannot create device for udev-device '%s': %s", - syspath, strerror(-r)); - return r; - } + if (r < 0) + return log_debug_errno(r, "sysview: cannot create device for udev-device '%s': %m", + syspath); context_add_device(c, device); } @@ -1083,8 +1102,8 @@ static int context_ud_scan(sysview_context *c) { d = udev_device_new_from_syspath(c->ud, name); if (!d) { r = errno > 0 ? -errno : -EFAULT; - log_debug("sysview: cannot create udev-device for %s: %s", - name, strerror(-r)); + log_debug_errno(r, "sysview: cannot create udev-device for %s: %m", + name); continue; } @@ -1102,11 +1121,8 @@ static int context_ld_seat_new(sysview_context *c, sd_bus_message *signal) { int r; r = sd_bus_message_read(signal, "so", &id, &path); - if (r < 0) { - log_debug("sysview: cannot parse SeatNew from logind: %s", - strerror(-r)); - return r; - } + if (r < 0) + return log_debug_errno(r, "sysview: cannot parse SeatNew from logind: %m"); context_add_seat(c, id); return 0; @@ -1118,11 +1134,8 @@ static int context_ld_seat_removed(sysview_context *c, sd_bus_message *signal) { int r; r = sd_bus_message_read(signal, "so", &id, &path); - if (r < 0) { - log_debug("sysview: cannot parse SeatRemoved from logind: %s", - strerror(-r)); - return r; - } + if (r < 0) + return log_debug_errno(r, "sysview: cannot parse SeatRemoved from logind: %m"); seat = sysview_find_seat(c, id); if (!seat) @@ -1140,11 +1153,8 @@ static int context_ld_session_new(sysview_context *c, sd_bus_message *signal) { int r; r = sd_bus_message_read(signal, "so", &id, &path); - if (r < 0) { - log_debug("sysview: cannot parse SessionNew from logind: %s", - strerror(-r)); - return r; - } + if (r < 0) + return log_debug_errno(r, "sysview: cannot parse SessionNew from logind: %m"); /* * As the dbus message didn't contain enough information, we @@ -1177,17 +1187,16 @@ static int context_ld_session_new(sysview_context *c, sd_bus_message *signal) { r = context_raise_session_filter(c, id, seatid, username, uid); if (r < 0) - log_debug("sysview: callback failed while filtering session '%s': %s", - id, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while filtering session '%s': %m", + id); else if (r > 0) context_add_session(c, seat, id); return 0; error: - log_debug("sysview: failed retrieving information for new session '%s': %s", - id, strerror(-r)); - return r; + return log_debug_errno(r, "sysview: failed retrieving information for new session '%s': %m", + id); } static int context_ld_session_removed(sysview_context *c, sd_bus_message *signal) { @@ -1196,11 +1205,8 @@ static int context_ld_session_removed(sysview_context *c, sd_bus_message *signal int r; r = sd_bus_message_read(signal, "so", &id, &path); - if (r < 0) { - log_debug("sysview: cannot parse SessionRemoved from logind: %s", - strerror(-r)); - return r; - } + if (r < 0) + return log_debug_errno(r, "sysview: cannot parse SessionRemoved from logind: %m"); session = sysview_find_session(c, id); if (!session) @@ -1268,7 +1274,8 @@ static int context_ld_list_seats_fn(sd_bus *bus, log_debug("sysview: ListSeats on logind failed: %s: %s", error->name, error->message); - return -sd_bus_error_get_errno(error); + r = -sd_bus_error_get_errno(error); + goto settle; } r = sd_bus_message_enter_container(reply, 'a', "(so)"); @@ -1294,13 +1301,15 @@ static int context_ld_list_seats_fn(sd_bus *bus, r = sd_bus_message_exit_container(reply); if (r < 0) - return r; + goto error; - return 0; + r = 0; + goto settle; error: - log_debug("sysview: erroneous ListSeats response from logind: %s", - strerror(-r)); + log_debug_errno(r, "sysview: erroneous ListSeats response from logind: %m"); +settle: + context_settle(c); return r; } @@ -1318,7 +1327,8 @@ static int context_ld_list_sessions_fn(sd_bus *bus, log_debug("sysview: ListSessions on logind failed: %s: %s", error->name, error->message); - return -sd_bus_error_get_errno(error); + r = -sd_bus_error_get_errno(error); + goto settle; } r = sd_bus_message_enter_container(reply, 'a', "(susso)"); @@ -1344,8 +1354,8 @@ static int context_ld_list_sessions_fn(sd_bus *bus, if (seat) { r = context_raise_session_filter(c, id, seatid, username, uid); if (r < 0) - log_debug("sysview: callback failed while filtering session '%s': %s", - id, strerror(-r)); + log_debug_errno(r, "sysview: callback failed while filtering session '%s': %m", + id); else if (r > 0) context_add_session(c, seat, id); } @@ -1360,13 +1370,15 @@ static int context_ld_list_sessions_fn(sd_bus *bus, r = sd_bus_message_exit_container(reply); if (r < 0) - return r; + goto error; - return 0; + r = 0; + goto settle; error: - log_debug("sysview: erroneous ListSessions response from logind: %s", - strerror(-r)); + log_debug_errno(r, "sysview: erroneous ListSessions response from logind: %m"); +settle: + context_settle(c); return r; } @@ -1397,6 +1409,9 @@ static int context_ld_scan(sysview_context *c) { if (r < 0) return r; + if (!c->settled) + ++c->n_probe; + /* request session list */ m = sd_bus_message_unref(m); @@ -1418,6 +1433,9 @@ static int context_ld_scan(sysview_context *c) { if (r < 0) return r; + if (!c->settled) + ++c->n_probe; + return 0; } @@ -1482,6 +1500,8 @@ void sysview_context_stop(sysview_context *c) { c->running = false; c->scanned = false; + c->settled = false; + c->n_probe = 0; c->event_fn = NULL; c->userdata = NULL; c->scan_src = sd_event_source_unref(c->scan_src); @@ -1495,27 +1515,26 @@ static int context_scan_fn(sd_event_source *s, void *userdata) { Iterator i; int r; + c->rescan = false; + if (!c->scanned) { r = context_ld_scan(c); - if (r < 0) { - log_debug("sysview: logind scan failed: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_debug_errno(r, "sysview: logind scan failed: %m"); } /* skip device scans if no sessions are available */ if (hashmap_size(c->session_map) > 0) { r = context_ud_scan(c); - if (r < 0) { - log_debug("sysview: udev scan failed: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_debug_errno(r, "sysview: udev scan failed: %m"); HASHMAP_FOREACH(seat, c->seat_map, i) seat->scanned = true; } c->scanned = true; + context_settle(c); return 0; } @@ -1526,6 +1545,12 @@ int sysview_context_rescan(sysview_context *c) { if (!c->running) return 0; + if (!c->rescan) { + c->rescan = true; + if (!c->settled) + ++c->n_probe; + } + if (c->scan_src) return sd_event_source_set_enabled(c->scan_src, SD_EVENT_ONESHOT); else