From 22e73357ff5dacb6ec594b95ffe2c426df74a6e8 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 29 Oct 2012 18:09:35 +0100 Subject: [PATCH] uterm: monitor: put systemd-layer into separate file This moves all systemd code into uterm_systemd.[ch]. This removes all the ugly #ifdef's. Furthermore, this fixes some hidden bugs in the previous implementation and makes use of sd_booted() to see whether runtime systemd is really available. Signed-off-by: David Herrmann --- Makefile.am | 2 + configure.ac | 2 +- src/uterm_monitor.c | 98 +++++++++++++------------------- src/uterm_systemd.c | 132 ++++++++++++++++++++++++++++++++++++++++++++ src/uterm_systemd.h | 75 +++++++++++++++++++++++++ 5 files changed, 248 insertions(+), 61 deletions(-) create mode 100644 src/uterm_systemd.c create mode 100644 src/uterm_systemd.h diff --git a/Makefile.am b/Makefile.am index 3da9dd7..d06e6aa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -179,6 +179,7 @@ libuterm_la_SOURCES = \ src/uterm_input.h \ src/uterm_video.h \ src/uterm_pci.h \ + src/uterm_systemd.h \ src/uterm_video.c \ src/uterm_monitor.c \ src/uterm_vt.c \ @@ -197,6 +198,7 @@ libuterm_la_LDFLAGS = \ -version-info 1:0:0 if BUILD_ENABLE_MULTI_SEAT +libuterm_la_SOURCES += src/uterm_systemd.c libuterm_la_CPPFLAGS += $(SYSTEMD_CFLAGS) libuterm_la_LIBADD += $(SYSTEMD_LIBS) endif diff --git a/configure.ac b/configure.ac index ab16640..b7abdbf 100644 --- a/configure.ac +++ b/configure.ac @@ -53,7 +53,7 @@ PKG_CHECK_MODULES([WAYLAND], [wayland-client wayland-server wayland-cursor], AC_SUBST(WAYLAND_CFLAGS) AC_SUBST(WAYLAND_LIBS) -PKG_CHECK_MODULES([SYSTEMD], [libsystemd-login], +PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon libsystemd-login], [have_systemd=yes], [have_systemd=no]) AC_SUBST(SYSTEMD_CFLAGS) AC_SUBST(SYSTEMD_LIBS) diff --git a/src/uterm_monitor.c b/src/uterm_monitor.c index 3a1df8b..c29fc30 100644 --- a/src/uterm_monitor.c +++ b/src/uterm_monitor.c @@ -44,12 +44,9 @@ #include "shl_dlist.h" #include "uterm.h" #include "uterm_pci.h" +#include "uterm_systemd.h" #include "uterm_video.h" -#ifdef BUILD_ENABLE_MULTI_SEAT - #include -#endif - #define LOG_SUBSYSTEM "monitor" struct uterm_monitor_dev { @@ -75,10 +72,8 @@ struct uterm_monitor { uterm_monitor_cb cb; void *data; -#ifdef BUILD_ENABLE_MULTI_SEAT - sd_login_monitor *sd_mon; + struct uterm_sd *sd; struct ev_fd *sd_mon_fd; -#endif char *pci_primary_id; @@ -92,8 +87,6 @@ struct uterm_monitor { static void monitor_new_seat(struct uterm_monitor *mon, const char *name); static void monitor_free_seat(struct uterm_monitor_seat *seat); -#ifdef BUILD_ENABLE_MULTI_SEAT - static void monitor_refresh_seats(struct uterm_monitor *mon) { char **seats; @@ -101,7 +94,14 @@ static void monitor_refresh_seats(struct uterm_monitor *mon) struct shl_dlist *iter, *tmp; struct uterm_monitor_seat *seat; - num = sd_get_seats(&seats); + /* Use only seat0 if multi-seat support is not available */ + if (!mon->sd) { + if (shl_dlist_empty(&mon->seats)) + monitor_new_seat(mon, "seat0"); + return; + } + + num = uterm_sd_get_seats(mon->sd, &seats); if (num < 0) { log_warn("cannot read seat information from systemd: %d", num); return; @@ -116,25 +116,28 @@ static void monitor_refresh_seats(struct uterm_monitor *mon) break; } - if (i < num) + if (i < num) { + free(seats[i]); seats[i] = NULL; - else + } else { monitor_free_seat(seat); + } } /* Add all new seats */ for (i = 0; i < num; ++i) { - if (seats[i]) + if (seats[i]) { monitor_new_seat(mon, seats[i]); - free(seats[i]); + free(seats[i]); + } } free(seats); } static void monitor_sd_event(struct ev_fd *fd, - int mask, - void *data) + int mask, + void *data) { struct uterm_monitor *mon = data; @@ -143,8 +146,10 @@ static void monitor_sd_event(struct ev_fd *fd, return; } - sd_login_monitor_flush(mon->sd_mon); - ev_eloop_flush_fd(mon->eloop, mon->sd_mon_fd); + if (mon->sd) { + uterm_sd_flush(mon->sd); + ev_eloop_flush_fd(mon->eloop, mon->sd_mon_fd); + } monitor_refresh_seats(mon); } @@ -157,14 +162,13 @@ static int monitor_sd_init(struct uterm_monitor *mon) { int ret, sfd; - ret = sd_login_monitor_new("seat", &mon->sd_mon); - if (ret) { - errno = -ret; - log_err("cannot create systemd login monitor (%d): %m", ret); - return -EFAULT; - } + ret = uterm_sd_new(&mon->sd); + if (ret == -EOPNOTSUPP) + return 0; + else if (ret) + return ret; - sfd = sd_login_monitor_get_fd(mon->sd_mon); + sfd = uterm_sd_get_fd(mon->sd); if (sfd < 0) { log_err("cannot get systemd login monitor fd"); ret = -EFAULT; @@ -172,46 +176,26 @@ static int monitor_sd_init(struct uterm_monitor *mon) } ret = ev_eloop_new_fd(mon->eloop, &mon->sd_mon_fd, sfd, EV_READABLE, - monitor_sd_event, mon); + monitor_sd_event, mon); if (ret) goto err_sd; return 0; err_sd: - sd_login_monitor_unref(mon->sd_mon); + uterm_sd_free(mon->sd); return ret; } static void monitor_sd_deinit(struct uterm_monitor *mon) { + if (!mon->sd) + return; + ev_eloop_rm_fd(mon->sd_mon_fd); - sd_login_monitor_unref(mon->sd_mon); + uterm_sd_free(mon->sd); } -#else /* !BUILD_ENABLE_MULTI_SEAT */ - -static void monitor_refresh_seats(struct uterm_monitor *mon) -{ - if (shl_dlist_empty(&mon->seats)) - monitor_new_seat(mon, "seat0"); -} - -static void monitor_sd_poll(struct uterm_monitor *mon) -{ -} - -static int monitor_sd_init(struct uterm_monitor *mon) -{ - return 0; -} - -static void monitor_sd_deinit(struct uterm_monitor *mon) -{ -} - -#endif /* BUILD_ENABLE_MULTI_SEAT */ - static void seat_new_dev(struct uterm_monitor_seat *seat, unsigned int type, unsigned int flags, @@ -567,12 +551,10 @@ static void monitor_udev_add(struct uterm_monitor *mon, } if (!strcmp(subs, "drm")) { -#ifdef BUILD_ENABLE_MULTI_SEAT - if (udev_device_has_tag(dev, "seat") != 1) { + if (mon->sd && udev_device_has_tag(dev, "seat") != 1) { log_debug("adding non-seat'ed device %s", name); return; } -#endif id = get_card_id(dev); if (id < 0) { log_debug("adding drm sub-device %s", name); @@ -582,12 +564,10 @@ static void monitor_udev_add(struct uterm_monitor *mon, type = UTERM_MONITOR_DRM; flags = get_drm_flags(mon, node); } else if (!strcmp(subs, "graphics")) { -#ifdef BUILD_ENABLE_MULTI_SEAT - if (udev_device_has_tag(dev, "seat") != 1) { + if (mon->sd && udev_device_has_tag(dev, "seat") != 1) { log_debug("adding non-seat'ed device %s", name); return; } -#endif id = get_fb_id(dev); if (id < 0) { log_debug("adding fbdev sub-device %s", name); @@ -608,12 +588,10 @@ static void monitor_udev_add(struct uterm_monitor *mon, log_debug("adding device without parent %s", name); return; } -#ifdef BUILD_ENABLE_MULTI_SEAT - if (udev_device_has_tag(p, "seat") != 1) { + if (mon->sd && udev_device_has_tag(p, "seat") != 1) { log_debug("adding non-seat'ed device %s", name); return; } -#endif sname = udev_device_get_property_value(p, "ID_SEAT"); type = UTERM_MONITOR_INPUT; flags = 0; diff --git a/src/uterm_systemd.c b/src/uterm_systemd.c new file mode 100644 index 0000000..057247c --- /dev/null +++ b/src/uterm_systemd.c @@ -0,0 +1,132 @@ +/* + * uterm - Linux User-Space Terminal + * + * Copyright (c) 2012 David Herrmann + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Systemd integration + * Systemd provides multi-seat support and other helpers that we can use in + * uterm. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "log.h" +#include "uterm.h" +#include "uterm_systemd.h" + +#define LOG_SUBSYSTEM "systemd" + +struct uterm_sd { + sd_login_monitor *mon; +}; + +int uterm_sd_new(struct uterm_sd **out) +{ + int ret; + struct uterm_sd *sd; + + if (!out) + return -EINVAL; + + ret = sd_booted(); + if (ret < 0) { + log_warning("cannot determine whether system booted with systemd (%d): %s", + ret, strerror(-ret)); + return -EOPNOTSUPP; + } else if (!ret) { + log_info("system not booted with systemd, disabling multi-seat support"); + return -EOPNOTSUPP; + } + + log_info("system booted with systemd, enabling multi-seat support"); + + sd = malloc(sizeof(*sd)); + if (!sd) + return -ENOMEM; + memset(sd, 0, sizeof(*sd)); + + ret = sd_login_monitor_new("seat", &sd->mon); + if (ret) { + log_err("cannot create systemd login monitor (%d): %s", + ret, strerror(-ret)); + ret = -EFAULT; + goto err_free; + } + + *out = sd; + return 0; + +err_free: + free(sd); + return ret; +} + +void uterm_sd_free(struct uterm_sd *sd) +{ + if (!sd) + return; + + sd_login_monitor_unref(sd->mon); + free(sd); +} + +int uterm_sd_get_fd(struct uterm_sd *sd) +{ + if (!sd) + return -EINVAL; + + return sd_login_monitor_get_fd(sd->mon); +} + +void uterm_sd_flush(struct uterm_sd *sd) +{ + if (!sd) + return; + + sd_login_monitor_flush(sd->mon); +} + +int uterm_sd_get_seats(struct uterm_sd *sd, char ***seats) +{ + int ret; + char **s; + + if (!sd || !seats) + return -EINVAL; + + ret = sd_get_seats(&s); + if (ret < 0) { + log_warning("cannot read seat information from systemd: %d", + ret); + return -EFAULT; + } + + *seats = s; + return ret; +} diff --git a/src/uterm_systemd.h b/src/uterm_systemd.h new file mode 100644 index 0000000..1eef08a --- /dev/null +++ b/src/uterm_systemd.h @@ -0,0 +1,75 @@ +/* + * uterm - Linux User-Space Terminal + * + * Copyright (c) 2012 David Herrmann + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Systemd integration + * Systemd provides multi-seat support and other helpers that we can use in + * uterm. + */ + +#ifndef UTERM_SYSTEMD_H +#define UTERM_SYSTEMD_H + +#include +#include "uterm.h" + +struct uterm_sd; + +#ifdef BUILD_ENABLE_MULTI_SEAT + +int uterm_sd_new(struct uterm_sd **out); +void uterm_sd_free(struct uterm_sd *sd); +int uterm_sd_get_fd(struct uterm_sd *sd); +void uterm_sd_flush(struct uterm_sd *sd); +int uterm_sd_get_seats(struct uterm_sd *sd, char ***seats); + +#else + +static inline int uterm_sd_new(struct uterm_sd **out) +{ + return -EOPNOTSUPP; +} + +static inline void uterm_sd_free(struct uterm_sd *sd) +{ +} + +static inline int uterm_sd_get_fd(struct uterm_sd *sd) +{ + return -1; +} + +static inline void uterm_sd_flush(struct uterm_sd *sd) +{ +} + +static inline int uterm_sd_get_seats(struct uterm_sd *sd, char ***seats) +{ + return -EINVAL; +} + +#endif + +#endif /* UTERM_SYSTEMD_H */