[PATCH 09/12] systemd-logind: Hookup systemd-logind integration

Hans de Goede hdegoede at redhat.com
Wed Jan 15 06:32:23 PST 2014


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>
---
 config/config.c                            |  5 ++-
 config/udev.c                              | 60 ++++++++++++++++++++++++++----
 hw/xfree86/common/xf86Events.c             | 15 ++++++--
 hw/xfree86/common/xf86Xinput.c             |  5 ++-
 hw/xfree86/os-support/linux/lnx_platform.c | 13 +++++--
 5 files changed, 81 insertions(+), 17 deletions(-)

diff --git a/config/config.c b/config/config.c
index 07c90eb..8d33388 100644
--- a/config/config.c
+++ b/config/config.c
@@ -32,6 +32,7 @@
 #include "inputstr.h"
 #include "hotplug.h"
 #include "config-backends.h"
+#include "systemd-logind.h"
 
 void
 config_pre_init(void)
@@ -143,8 +144,10 @@ config_odev_allocate_attribute_list(void)
 void
 config_odev_free_attribute_list(struct OdevAttributes *attribs)
 {
-    if (attribs->server_fd)
+    if (attribs->server_fd) {
+        systemd_logind_put_fd(makedev(attribs->major, attribs->minor));
         close(attribs->fd);
+    }
     config_odev_free_attributes(attribs);
     free(attribs);
 }
diff --git a/config/udev.c b/config/udev.c
index 436b8f0..c1a5c91 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,
+                               dev_t devnum,
                                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)
 {
@@ -71,8 +82,10 @@ device_added(struct udev_device *udev_device)
     DeviceIntPtr dev = NULL;
     struct udev_list_entry *set, *entry;
     struct udev_device *parent;
-    int rc;
+    int rc, fd = -1;
     const char *dev_seat;
+    dev_t devnum;
+    Bool paused = FALSE;
 
     path = udev_device_get_devnode(udev_device);
 
@@ -91,6 +104,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 +115,7 @@ 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, 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);
 
@@ -232,11 +249,22 @@ device_added(struct udev_device *udev_device)
     if (ServerIsNotSeat0())
         input_options = input_option_new(input_options, "GrabDevice", "on");
 
-    LogMessage(X_INFO, "config/udev: Adding input device %s (%s)\n",
-               name, path);
+    fd = systemd_logind_get_fd(devnum, path, &paused);
+    if (fd != -1)
+        input_options = input_option_new(input_options, "fd", itoa(fd));
+
+    LogMessage(X_INFO, "config/udev: Adding input device %s (%s:%d)\n",
+               name, path, fd);
+    /* FIXME check paused, if paused put the device on a list for probing
+       later */
     rc = NewInputDeviceRequest(input_options, &attrs, &dev);
-    if (rc != Success)
+    if (rc != Success) {
+        if (fd != -1) {
+            systemd_logind_put_fd(devnum);
+            close(fd);
+        }
         goto unwind;
+    }
 
  unwind:
     free(config_info);
@@ -270,6 +298,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 +306,9 @@ device_removed(struct udev_device *device)
         if (!path)
             return;
 
-        config_udev_odev_setup_attribs(path, syspath, DeleteGPUDeviceRequest);
+        config_udev_odev_setup_attribs(path, syspath, devnum, DeleteGPUDeviceRequest);
+        /* Retry vtenter after a drm node removal */
+        systemd_logind_vtenter();
         return;
     }
 #endif
@@ -427,9 +458,11 @@ config_udev_fini(void)
 
 static Bool
 config_udev_odev_setup_attribs(const char *path, const char *syspath,
+                               dev_t devnum,
                                config_odev_probe_proc_ptr probe_callback)
 {
     struct OdevAttributes *attribs = config_odev_allocate_attribute_list();
+    Bool paused = FALSE;
     int ret;
 
     if (!attribs)
@@ -443,6 +476,17 @@ config_udev_odev_setup_attribs(const char *path, const char *syspath,
     if (ret == FALSE)
         goto fail;
 
+    if (probe_callback != DeleteGPUDeviceRequest) {
+        /* device added, try to get server managed fd */
+        attribs->fd = systemd_logind_get_fd(devnum, path, &paused);
+        if (attribs->fd != -1)
+            attribs->server_fd = TRUE;
+    }
+
+    attribs->major = major(devnum);
+    attribs->minor = minor(devnum);
+    attribs->paused = paused;
+
     /* ownership of attribs is passed to probe layer */
     probe_callback(attribs);
     return TRUE;
@@ -477,6 +521,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 +530,7 @@ 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, 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..5ea79de 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 3a9e8ae..e317810 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"
@@ -774,8 +775,10 @@ xf86DeleteInput(InputInfoPtr pInp, int flags)
         /* Else the entry wasn't in the xf86InputDevs list (ignore this). */
     }
 
-    if (pInp->flags & XI86_SERVER_FD)
+    if (pInp->flags & XI86_SERVER_FD) {
+        systemd_logind_put_fd(makedev(pInp->major, pInp->minor));
         close(pInp->fd);
+    }
 
     free((void *) pInp->driver);
     free((void *) pInp->name);
diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c
index 1865b31..2c0fe2e 100644
--- a/hw/xfree86/os-support/linux/lnx_platform.c
+++ b/hw/xfree86/os-support/linux/lnx_platform.c
@@ -24,10 +24,14 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
 {
     drmSetVersion sv;
     char *buf;
-    int fd;
+    int fd = -1;
     int err = 0;
 
-    fd = open(path, O_RDWR, O_CLOEXEC);
+    if (attribs->fd == -1)
+        fd = open(path, O_RDWR, O_CLOEXEC);
+    else
+        fd = attribs->fd;
+
     if (fd == -1)
         return FALSE;
 
@@ -53,7 +57,8 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
                                     ODEV_ATTRIB_BUSID, buf);
     drmFreeBusid(buf);
 out:
-    close(fd);
+    if (attribs->fd == -1)
+        close(fd);
     return (err == 0);
 }
 
@@ -145,7 +150,7 @@ xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
 
     LogMessage(X_INFO, "xfree86: Adding drm device (%s)\n", path);
 
-    if (!xf86VTOwner()) {
+    if (attribs->paused || !xf86VTOwner()) {
             /* if we don't currently own the VT then don't probe the device,
                just mark it as unowned for later use */
             attribs->unowned = TRUE;
-- 
1.8.4.2



More information about the xorg-devel mailing list