[PATCH v2 11/14] systemd-logind: Hookup systemd-logind integration
Peter Hutterer
peter.hutterer at who-t.net
Tue Feb 11 06:56:14 CET 2014
On Tue, Feb 04, 2014 at 12:49:17PM +0100, Hans de Goede wrote:
> This commits makes the changes necessary outside of the systemd-logind core
> to make the server use systemd-logind managed fds for input devices and drm
> nodes.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
Cheers,
Peter
> ---
> config/config.c | 13 ++++++++++
> config/udev.c | 39 +++++++++++++++++++++++++++---
> hw/xfree86/common/xf86Events.c | 15 +++++++++---
> hw/xfree86/common/xf86Xinput.c | 18 ++++++++++++++
> hw/xfree86/os-support/linux/lnx_platform.c | 32 +++++++++++++++++++++---
> 5 files changed, 107 insertions(+), 10 deletions(-)
>
> diff --git a/config/config.c b/config/config.c
> index 5833992..ebfe6a1 100644
> --- a/config/config.c
> +++ b/config/config.c
> @@ -27,10 +27,12 @@
> #include <dix-config.h>
> #endif
>
> +#include <unistd.h>
> #include "os.h"
> #include "inputstr.h"
> #include "hotplug.h"
> #include "config-backends.h"
> +#include "systemd-logind.h"
>
> void
> config_pre_init(void)
> @@ -231,10 +233,21 @@ void
> config_odev_free_attributes(struct OdevAttributes *attribs)
> {
> struct OdevAttribute *iter, *safe;
> + int major = 0, minor = 0, fd = -1;
>
> xorg_list_for_each_entry_safe(iter, safe, &attribs->list, member) {
> + switch (iter->attrib_id) {
> + case ODEV_ATTRIB_MAJOR: major = iter->attrib_value; break;
> + case ODEV_ATTRIB_MINOR: minor = iter->attrib_value; break;
> + case ODEV_ATTRIB_FD: fd = iter->attrib_value; break;
> + }
> xorg_list_del(&iter->member);
> free(iter->attrib_name);
> free(iter);
> }
> +
> + if (fd != -1) {
> + systemd_logind_release_fd(major, minor);
> + close(fd);
> + }
> }
> diff --git a/config/udev.c b/config/udev.c
> index 436b8f0..e888ab1 100644
> --- a/config/udev.c
> +++ b/config/udev.c
> @@ -29,6 +29,7 @@
>
> #include <libudev.h>
> #include <ctype.h>
> +#include <unistd.h>
>
> #include "input.h"
> #include "inputstr.h"
> @@ -36,6 +37,7 @@
> #include "config-backends.h"
> #include "os.h"
> #include "globals.h"
> +#include "systemd-logind.h"
>
> #define UDEV_XKB_PROP_KEY "xkb"
>
> @@ -55,9 +57,18 @@ static struct udev_monitor *udev_monitor;
> #ifdef CONFIG_UDEV_KMS
> static Bool
> config_udev_odev_setup_attribs(const char *path, const char *syspath,
> + int major, int minor,
> config_odev_probe_proc_ptr probe_callback);
> #endif
>
> +static char itoa_buf[16];
> +
> +static const char *itoa(int i)
> +{
> + snprintf(itoa_buf, sizeof(itoa_buf), "%d", i);
> + return itoa_buf;
> +}
> +
> static void
> device_added(struct udev_device *udev_device)
> {
> @@ -73,6 +84,7 @@ device_added(struct udev_device *udev_device)
> struct udev_device *parent;
> int rc;
> const char *dev_seat;
> + dev_t devnum;
>
> path = udev_device_get_devnode(udev_device);
>
> @@ -91,6 +103,8 @@ device_added(struct udev_device *udev_device)
> if (!SeatId && strcmp(dev_seat, "seat0"))
> return;
>
> + devnum = udev_device_get_devnum(udev_device);
> +
> #ifdef CONFIG_UDEV_KMS
> if (!strcmp(udev_device_get_subsystem(udev_device), "drm")) {
> const char *sysname = udev_device_get_sysname(udev_device);
> @@ -100,7 +114,8 @@ device_added(struct udev_device *udev_device)
>
> LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);
>
> - config_udev_odev_setup_attribs(path, syspath, NewGPUDeviceRequest);
> + config_udev_odev_setup_attribs(path, syspath, major(devnum),
> + minor(devnum), NewGPUDeviceRequest);
> return;
> }
> #endif
> @@ -153,6 +168,8 @@ device_added(struct udev_device *udev_device)
> input_options = input_option_new(input_options, "name", name);
> input_options = input_option_new(input_options, "path", path);
> input_options = input_option_new(input_options, "device", path);
> + input_options = input_option_new(input_options, "major", itoa(major(devnum)));
> + input_options = input_option_new(input_options, "minor", itoa(minor(devnum)));
> if (path)
> attrs.device = strdup(path);
>
> @@ -270,6 +287,7 @@ device_removed(struct udev_device *device)
> if (!strcmp(udev_device_get_subsystem(device), "drm")) {
> const char *sysname = udev_device_get_sysname(device);
> const char *path = udev_device_get_devnode(device);
> + dev_t devnum = udev_device_get_devnum(device);
>
> if (strncmp(sysname,"card", 4) != 0)
> return;
> @@ -277,7 +295,10 @@ device_removed(struct udev_device *device)
> if (!path)
> return;
>
> - config_udev_odev_setup_attribs(path, syspath, DeleteGPUDeviceRequest);
> + config_udev_odev_setup_attribs(path, syspath, major(devnum),
> + minor(devnum), DeleteGPUDeviceRequest);
> + /* Retry vtenter after a drm node removal */
> + systemd_logind_vtenter();
> return;
> }
> #endif
> @@ -427,6 +448,7 @@ config_udev_fini(void)
>
> static Bool
> config_udev_odev_setup_attribs(const char *path, const char *syspath,
> + int major, int minor,
> config_odev_probe_proc_ptr probe_callback)
> {
> struct OdevAttributes *attribs = config_odev_allocate_attribute_list();
> @@ -443,6 +465,14 @@ config_udev_odev_setup_attribs(const char *path, const char *syspath,
> if (ret == FALSE)
> goto fail;
>
> + ret = config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MAJOR, major);
> + if (ret == FALSE)
> + goto fail;
> +
> + ret = config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MINOR, minor);
> + if (ret == FALSE)
> + goto fail;
> +
> /* ownership of attribs is passed to probe layer */
> probe_callback(attribs);
> return TRUE;
> @@ -477,6 +507,7 @@ config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback)
> struct udev_device *udev_device = udev_device_new_from_syspath(udev, syspath);
> const char *path = udev_device_get_devnode(udev_device);
> const char *sysname = udev_device_get_sysname(udev_device);
> + dev_t devnum = udev_device_get_devnum(udev_device);
>
> if (!path || !syspath)
> goto no_probe;
> @@ -485,8 +516,8 @@ config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback)
> else if (strncmp(sysname, "card", 4) != 0)
> goto no_probe;
>
> - config_udev_odev_setup_attribs(path, syspath, probe_callback);
> -
> + config_udev_odev_setup_attribs(path, syspath, major(devnum),
> + minor(devnum), probe_callback);
> no_probe:
> udev_device_unref(udev_device);
> }
> diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
> index 7b53949..06af739 100644
> --- a/hw/xfree86/common/xf86Events.c
> +++ b/hw/xfree86/common/xf86Events.c
> @@ -85,6 +85,8 @@
> #endif
>
> #include "xf86platformBus.h"
> +#include "systemd-logind.h"
> +
> /*
> * This is a toggling variable:
> * FALSE = No VT switching keys have been pressed last time around
> @@ -556,8 +558,11 @@ xf86VTEnter(void)
> /* Turn screen saver off when switching back */
> dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
>
> - for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
> - xf86EnableInputDeviceForVTSwitch(pInfo);
> + /* If we use systemd-logind it will enable input devices for us */
> + if (!systemd_logind_controls_session())
> + for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
> + xf86EnableInputDeviceForVTSwitch(pInfo);
> +
> for (ih = InputHandlers; ih; ih = ih->next) {
> if (ih->is_input)
> xf86EnableInputHandler(ih);
> @@ -589,10 +594,14 @@ xf86VTSwitch(void)
> /*
> * Since all screens are currently all in the same state it is sufficient
> * check the first. This might change in future.
> + *
> + * VTLeave is always handled here (VT_PROCESS guarantees this is safe),
> + * if we use systemd_logind xf86VTEnter() gets called by systemd-logind.c
> + * once it has resumed all drm nodes.
> */
> if (xf86VTOwner())
> xf86VTLeave();
> - else
> + else if (!systemd_logind_controls_session())
> xf86VTEnter();
> }
>
> diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
> index 6404ef5..9ad07ca 100644
> --- a/hw/xfree86/common/xf86Xinput.c
> +++ b/hw/xfree86/common/xf86Xinput.c
> @@ -63,6 +63,7 @@
> #include "mipointer.h"
> #include "extinit.h"
> #include "loaderProcs.h"
> +#include "systemd-logind.h"
>
> #include "exevents.h" /* AddInputDevice */
> #include "exglobals.h"
> @@ -80,6 +81,7 @@
>
> #include <stdarg.h>
> #include <stdint.h> /* for int64_t */
> +#include <unistd.h>
>
> #include "mi.h"
>
> @@ -773,6 +775,11 @@ xf86DeleteInput(InputInfoPtr pInp, int flags)
> /* Else the entry wasn't in the xf86InputDevs list (ignore this). */
> }
>
> + if (pInp->flags & XI86_SERVER_FD) {
> + systemd_logind_release_fd(pInp->major, pInp->minor);
> + close(pInp->fd);
> + }
> +
> free((void *) pInp->driver);
> free((void *) pInp->name);
> xf86optionListFree(pInp->options);
> @@ -816,6 +823,7 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
> {
> InputDriverPtr drv = NULL;
> DeviceIntPtr dev = NULL;
> + Bool paused;
> int rval;
>
> /* Memory leak for every attached device if we don't
> @@ -830,6 +838,16 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
> goto unwind;
> }
>
> + if (drv->capabilities & XI86_DRV_CAP_SERVER_FD) {
> + pInfo->fd = systemd_logind_take_fd(pInfo->major, pInfo->minor,
> + pInfo->attrs->device, &paused);
> + if (pInfo->fd != -1) {
> + /* FIXME handle paused */
> + pInfo->flags |= XI86_SERVER_FD;
> + pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd);
> + }
> + }
> +
> xf86Msg(X_INFO, "Using input driver '%s' for '%s'\n", drv->driverName,
> pInfo->name);
>
> diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c
> index f4c4d12..109a9a7 100644
> --- a/hw/xfree86/os-support/linux/lnx_platform.c
> +++ b/hw/xfree86/os-support/linux/lnx_platform.c
> @@ -18,16 +18,38 @@
> #include "xf86Bus.h"
>
> #include "hotplug.h"
> +#include "systemd-logind.h"
>
> static Bool
> get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
> {
> drmSetVersion sv;
> char *buf;
> - int fd;
> + int major, minor, fd;
> int err = 0;
> + Bool paused, server_fd = FALSE;
> +
> + major = config_odev_get_int_attribute(attribs, ODEV_ATTRIB_MAJOR, 0);
> + minor = config_odev_get_int_attribute(attribs, ODEV_ATTRIB_MINOR, 0);
> +
> + fd = systemd_logind_take_fd(major, minor, path, &paused);
> + if (fd != -1) {
> + if (paused) {
> + LogMessage(X_ERROR,
> + "Error systemd-logind returned paused fd for drm node\n");
> + systemd_logind_release_fd(major, minor);
> + return FALSE;
> + }
> + if (!config_odev_add_int_attribute(attribs, ODEV_ATTRIB_FD, fd)) {
> + systemd_logind_release_fd(major, minor);
> + return FALSE;
> + }
> + server_fd = TRUE;
> + }
> +
> + if (fd == -1)
> + fd = open(path, O_RDWR, O_CLOEXEC);
>
> - fd = open(path, O_RDWR, O_CLOEXEC);
> if (fd == -1)
> return FALSE;
>
> @@ -48,12 +70,16 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
> delayed_index = xf86_num_platform_devices - 1;
> }
>
> + if (server_fd)
> + xf86_platform_devices[delayed_index].flags |= XF86_PDEV_SERVER_FD;
> +
> buf = drmGetBusid(fd);
> xf86_add_platform_device_attrib(delayed_index,
> ODEV_ATTRIB_BUSID, buf);
> drmFreeBusid(buf);
> out:
> - close(fd);
> + if (!server_fd)
> + close(fd);
> return (err == 0);
> }
>
> --
> 1.8.5.3
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
>
More information about the xorg-devel
mailing list