#include <systemd/sd-event.h>
#include <systemd/sd-login.h>
#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"
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;
}
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);
}
/*
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,
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;
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);
}
}
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);
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);
}
}
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;
}
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);
}
}
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) {
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)
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;
}
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) {
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);
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);
}
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;
}
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;
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)
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
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) {
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)
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)");
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;
}
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)");
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);
}
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;
}
if (r < 0)
return r;
+ if (!c->settled)
+ ++c->n_probe;
+
/* request session list */
m = sd_bus_message_unref(m);
if (r < 0)
return r;
+ if (!c->settled)
+ ++c->n_probe;
+
return 0;
}
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);
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;
}
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