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 <[email protected]>
Reviewed-by: Peter Hutterer <[email protected]> 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 > > _______________________________________________ > [email protected]: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: http://lists.x.org/mailman/listinfo/xorg-devel > _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
