[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