chiark / gitweb /
terminal: forward evdev RESYNC events to linked devices
[elogind.git] / src / libsystemd-terminal / idev-evdev.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <fcntl.h>
23 #include <inttypes.h>
24 #include <libevdev/libevdev.h>
25 #include <libudev.h>
26 #include <stdbool.h>
27 #include <stdlib.h>
28 #include <systemd/sd-bus.h>
29 #include <systemd/sd-event.h>
30 #include <unistd.h>
31 #include "bus-util.h"
32 #include "hashmap.h"
33 #include "idev.h"
34 #include "idev-internal.h"
35 #include "macro.h"
36 #include "udev-util.h"
37 #include "util.h"
38
39 typedef struct idev_evdev idev_evdev;
40 typedef struct unmanaged_evdev unmanaged_evdev;
41 typedef struct managed_evdev managed_evdev;
42
43 struct idev_evdev {
44         idev_element element;
45         struct libevdev *evdev;
46         int fd;
47         sd_event_source *fd_src;
48         sd_event_source *idle_src;
49
50         bool unsync : 1;                /* not in-sync with kernel */
51         bool resync : 1;                /* re-syncing with kernel */
52         bool running : 1;
53 };
54
55 struct unmanaged_evdev {
56         idev_evdev evdev;
57         char *devnode;
58 };
59
60 struct managed_evdev {
61         idev_evdev evdev;
62         dev_t devnum;
63
64         sd_bus_slot *slot_pause_device;
65         sd_bus_slot *slot_resume_device;
66         sd_bus_slot *slot_take_device;
67
68         bool requested : 1;             /* TakeDevice() was sent */
69         bool acquired : 1;              /* TakeDevice() was successful */
70 };
71
72 #define idev_evdev_from_element(_e) container_of((_e), idev_evdev, element)
73 #define unmanaged_evdev_from_element(_e) \
74         container_of(idev_evdev_from_element(_e), unmanaged_evdev, evdev)
75 #define managed_evdev_from_element(_e) \
76         container_of(idev_evdev_from_element(_e), managed_evdev, evdev)
77
78 #define IDEV_EVDEV_INIT(_vtable, _session) ((idev_evdev){ \
79                 .element = IDEV_ELEMENT_INIT((_vtable), (_session)), \
80                 .fd = -1, \
81         })
82
83 #define IDEV_EVDEV_NAME_MAX (8 + DECIMAL_STR_MAX(unsigned) * 2)
84
85 static const idev_element_vtable unmanaged_evdev_vtable;
86 static const idev_element_vtable managed_evdev_vtable;
87
88 static int idev_evdev_resume(idev_evdev *evdev, int dev_fd);
89 static void idev_evdev_pause(idev_evdev *evdev, bool release);
90
91 /*
92  * Virtual Evdev Element
93  * The virtual evdev element is the base class of all other evdev elements. It
94  * uses libevdev to access the kernel evdev API. It supports asynchronous
95  * access revocation, re-syncing if events got dropped and more.
96  * This element cannot be used by itself. There must be a wrapper around it
97  * which opens a file-descriptor and passes it to the virtual evdev element.
98  */
99
100 static void idev_evdev_name(char *out, dev_t devnum) {
101         /* @out must be at least of size IDEV_EVDEV_NAME_MAX */
102         sprintf(out, "evdev/%u:%u", major(devnum), minor(devnum));
103 }
104
105 static int idev_evdev_feed_resync(idev_evdev *evdev) {
106         idev_data data = {
107                 .type = IDEV_DATA_RESYNC,
108                 .resync = evdev->resync,
109         };
110
111         return idev_element_feed(&evdev->element, &data);
112 }
113
114 static int idev_evdev_feed_evdev(idev_evdev *evdev, struct input_event *event) {
115         idev_data data = {
116                 .type = IDEV_DATA_EVDEV,
117                 .resync = evdev->resync,
118                 .evdev = {
119                         .event = *event,
120                 },
121         };
122
123         return idev_element_feed(&evdev->element, &data);
124 }
125
126 static void idev_evdev_hup(idev_evdev *evdev) {
127         /*
128          * On HUP, we close the current fd via idev_evdev_pause(). This drops
129          * the event-sources from the main-loop and effectively puts the
130          * element asleep. If the HUP is part of a hotplug-event, a following
131          * udev-notification will destroy the element. Otherwise, the HUP is
132          * either result of access-revokation or a serious error.
133          * For unmanaged devices, we should never receive HUP (except for
134          * unplug-events). But if we do, something went seriously wrong and we
135          * shouldn't try to be clever.
136          * Instead, we simply stay asleep and wait for the device to be
137          * disabled and then re-enabled (or closed and re-opened). This will
138          * re-open the device node and restart the device.
139          * For managed devices, a HUP usually means our device-access was
140          * revoked. In that case, we simply put the device asleep and wait for
141          * logind to notify us once the device is alive again. logind also
142          * passes us a new fd. Hence, we don't have to re-enable the device.
143          *
144          * Long story short: The only thing we have to do here, is close() the
145          * file-descriptor and remove it from the main-loop. Everything else is
146          * handled via additional events we receive.
147          */
148
149         idev_evdev_pause(evdev, true);
150 }
151
152 static int idev_evdev_io(idev_evdev *evdev) {
153         idev_element *e = &evdev->element;
154         struct input_event ev;
155         unsigned int flags;
156         int r, error = 0;
157
158         /*
159          * Read input-events via libevdev until the input-queue is drained. In
160          * case we're disabled, don't do anything. The input-queue might
161          * overflow, but we don't care as we have to resync after wake-up,
162          * anyway.
163          * TODO: libevdev should give us a hint how many events to read. We
164          * really want to avoid starvation, so we shouldn't read forever in
165          * case we cannot keep up with the kernel.
166          * TODO: Make sure libevdev always reports SYN_DROPPED to us, regardless
167          * whether any event was synced afterwards.
168          */
169
170         flags = LIBEVDEV_READ_FLAG_NORMAL;
171         while (e->enabled) {
172                 if (evdev->unsync) {
173                         /* immediately resync, even if in sync right now */
174                         evdev->unsync = false;
175                         evdev->resync = false;
176                         flags = LIBEVDEV_READ_FLAG_NORMAL;
177                         r = libevdev_next_event(evdev->evdev, flags | LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
178                         if (r < 0 && r != -EAGAIN) {
179                                 r = 0;
180                                 goto error;
181                         } else if (r != LIBEVDEV_READ_STATUS_SYNC) {
182                                 log_debug("idev-evdev: %s/%s: cannot force resync: %d",
183                                           e->session->name, e->name, r);
184                         }
185                 } else {
186                         r = libevdev_next_event(evdev->evdev, flags, &ev);
187                 }
188
189                 if (evdev->resync && r == -EAGAIN) {
190                         /* end of re-sync */
191                         evdev->resync = false;
192                         flags = LIBEVDEV_READ_FLAG_NORMAL;
193                 } else if (r == -EAGAIN) {
194                         /* no data available */
195                         break;
196                 } else if (r < 0) {
197                         /* read error */
198                         goto error;
199                 } else if (r == LIBEVDEV_READ_STATUS_SYNC) {
200                         if (evdev->resync) {
201                                 /* sync-event */
202                                 r = idev_evdev_feed_evdev(evdev, &ev);
203                                 if (r != 0) {
204                                         error = r;
205                                         break;
206                                 }
207                         } else {
208                                 /* start of sync */
209                                 evdev->resync = true;
210                                 flags = LIBEVDEV_READ_FLAG_SYNC;
211                                 r = idev_evdev_feed_resync(evdev);
212                                 if (r != 0) {
213                                         error = r;
214                                         break;
215                                 }
216                         }
217                 } else {
218                         /* normal event */
219                         r = idev_evdev_feed_evdev(evdev, &ev);
220                         if (r != 0) {
221                                 error = r;
222                                 break;
223                         }
224                 }
225         }
226
227         if (error < 0)
228                 log_debug("idev-evdev: %s/%s: error on data event: %s",
229                           e->session->name, e->name, strerror(-error));
230         return error;
231
232 error:
233         idev_evdev_hup(evdev);
234         return 0; /* idev_evdev_hup() handles the error so discard it */
235 }
236
237 static int idev_evdev_event_fn(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
238         idev_evdev *evdev = userdata;
239
240         /* fetch data as long as EPOLLIN is signalled */
241         if (revents & EPOLLIN)
242                 return idev_evdev_io(evdev);
243
244         if (revents & (EPOLLHUP | EPOLLERR))
245                 idev_evdev_hup(evdev);
246
247         return 0;
248 }
249
250 static int idev_evdev_idle_fn(sd_event_source *s, void *userdata) {
251         idev_evdev *evdev = userdata;
252
253         /*
254          * The idle-event is raised whenever we have to re-sync the libevdev
255          * state from the kernel. We simply call into idev_evdev_io() which
256          * flushes the state and re-syncs it if @unsync is set.
257          * State has to be synced whenever our view of the kernel device is
258          * out of date. This is the case when we open the device, if the
259          * kernel's receive buffer overflows, or on other exceptional
260          * situations. Events during re-syncs must be forwarded to the upper
261          * layers so they can update their view of the device. However, such
262          * events must only be handled passively, as they might be out-of-order
263          * and/or re-ordered. Therefore, we mark them as 'sync' events.
264          */
265
266         if (!evdev->unsync)
267                 return 0;
268
269         return idev_evdev_io(evdev);
270 }
271
272 static void idev_evdev_destroy(idev_evdev *evdev) {
273         assert(evdev);
274         assert(evdev->fd < 0);
275
276         libevdev_free(evdev->evdev);
277         evdev->evdev = NULL;
278 }
279
280 static void idev_evdev_enable(idev_evdev *evdev) {
281         assert(evdev);
282         assert(evdev->fd_src);
283         assert(evdev->idle_src);
284
285         if (evdev->running)
286                 return;
287         if (evdev->fd < 0 || evdev->element.n_open < 1 || !evdev->element.enabled)
288                 return;
289
290         evdev->running = true;
291         sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_ON);
292         sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_ONESHOT);
293 }
294
295 static void idev_evdev_disable(idev_evdev *evdev) {
296         assert(evdev);
297         assert(evdev->fd_src);
298         assert(evdev->idle_src);
299
300         if (!evdev->running)
301                 return;
302
303         evdev->running = false;
304         idev_evdev_feed_resync(evdev);
305         sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_OFF);
306         sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_OFF);
307 }
308
309 static int idev_evdev_resume(idev_evdev *evdev, int dev_fd) {
310         idev_element *e = &evdev->element;
311         _cleanup_close_ int fd = dev_fd;
312         int r, flags;
313
314         if (fd < 0 || evdev->fd == fd) {
315                 fd = -1;
316                 idev_evdev_enable(evdev);
317                 return 0;
318         }
319
320         idev_evdev_pause(evdev, true);
321         log_debug("idev-evdev: %s/%s: resume", e->session->name, e->name);
322
323         r = fd_nonblock(fd, true);
324         if (r < 0)
325                 return r;
326
327         r = fd_cloexec(fd, true);
328         if (r < 0)
329                 return r;
330
331         flags = fcntl(fd, F_GETFL, 0);
332         if (flags < 0)
333                 return -errno;
334
335         flags &= O_ACCMODE;
336         if (flags == O_WRONLY)
337                 return -EACCES;
338
339         evdev->element.readable = true;
340         evdev->element.writable = !(flags & O_RDONLY);
341
342         /*
343          * TODO: We *MUST* re-sync the device so we get a delta of the changed
344          * state while we didn't read events from the device. This works just
345          * fine with libevdev_change_fd(), however, libevdev_new_from_fd() (or
346          * libevdev_set_fd()) don't pass us events for the initial device
347          * state. So even if we force a re-sync, we will not get the delta for
348          * the initial device state.
349          * We really need to fix libevdev to support that!
350          */
351         if (evdev->evdev)
352                 r = libevdev_change_fd(evdev->evdev, fd);
353         else
354                 r = libevdev_new_from_fd(fd, &evdev->evdev);
355
356         if (r < 0)
357                 return r;
358
359         r = sd_event_add_io(e->session->context->event,
360                             &evdev->fd_src,
361                             fd,
362                             EPOLLHUP | EPOLLERR | EPOLLIN,
363                             idev_evdev_event_fn,
364                             evdev);
365         if (r < 0)
366                 return r;
367
368         r = sd_event_add_defer(e->session->context->event,
369                                &evdev->idle_src,
370                                idev_evdev_idle_fn,
371                                evdev);
372         if (r < 0) {
373                 evdev->fd_src = sd_event_source_unref(evdev->fd_src);
374                 return r;
375         }
376
377         sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_OFF);
378         sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_OFF);
379
380         evdev->unsync = true;
381         evdev->fd = fd;
382         fd = -1;
383
384         idev_evdev_enable(evdev);
385         return 0;
386 }
387
388 static void idev_evdev_pause(idev_evdev *evdev, bool release) {
389         idev_element *e = &evdev->element;
390
391         if (evdev->fd < 0)
392                 return;
393
394         log_debug("idev-evdev: %s/%s: pause", e->session->name, e->name);
395
396         idev_evdev_disable(evdev);
397         if (release) {
398                 evdev->idle_src = sd_event_source_unref(evdev->idle_src);
399                 evdev->fd_src = sd_event_source_unref(evdev->fd_src);
400                 evdev->fd = safe_close(evdev->fd);
401         }
402 }
403
404 /*
405  * Unmanaged Evdev Element
406  * The unmanaged evdev element opens the evdev node for a given input device
407  * directly (/dev/input/eventX) and thus needs sufficient privileges. It opens
408  * the device only if we really require it and releases it as soon as we're
409  * disabled or closed.
410  * The unmanaged element can be used in all situations where you have direct
411  * access to input device nodes. Unlike managed evdev elements, it can be used
412  * outside of user sessions and in emergency situations where logind is not
413  * available.
414  */
415
416 static void unmanaged_evdev_resume(idev_element *e) {
417         unmanaged_evdev *eu = unmanaged_evdev_from_element(e);
418         int r, fd;
419
420         /*
421          * Unmanaged devices can be acquired on-demand. Therefore, don't
422          * acquire it unless someone opened the device *and* we're enabled.
423          */
424         if (e->n_open < 1 || !e->enabled)
425                 return;
426
427         fd = eu->evdev.fd;
428         if (fd < 0) {
429                 fd = open(eu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
430                 if (fd < 0) {
431                         if (errno != EACCES && errno != EPERM) {
432                                 log_debug("idev-evdev: %s/%s: cannot open node %s: %m",
433                                           e->session->name, e->name, eu->devnode);
434                                 return;
435                         }
436
437                         fd = open(eu->devnode, O_RDONLY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
438                         if (fd < 0) {
439                                 log_debug("idev-evdev: %s/%s: cannot open node %s: %m",
440                                           e->session->name, e->name, eu->devnode);
441                                 return;
442                         }
443
444                         e->readable = true;
445                         e->writable = false;
446                 } else {
447                         e->readable = true;
448                         e->writable = true;
449                 }
450         }
451
452         r = idev_evdev_resume(&eu->evdev, fd);
453         if (r < 0)
454                 log_debug("idev-evdev: %s/%s: cannot resume: %s",
455                           e->session->name, e->name, strerror(-r));
456 }
457
458 static void unmanaged_evdev_pause(idev_element *e) {
459         unmanaged_evdev *eu = unmanaged_evdev_from_element(e);
460
461         /*
462          * Release the device if the device is disabled or there is no-one who
463          * opened it. This guarantees we stay only available if we're opened
464          * *and* enabled.
465          */
466
467         idev_evdev_pause(&eu->evdev, true);
468 }
469
470 static int unmanaged_evdev_new(idev_element **out, idev_session *s, struct udev_device *ud) {
471         _cleanup_(idev_element_freep) idev_element *e = NULL;
472         char name[IDEV_EVDEV_NAME_MAX];
473         unmanaged_evdev *eu;
474         const char *devnode;
475         dev_t devnum;
476         int r;
477
478         assert_return(s, -EINVAL);
479         assert_return(ud, -EINVAL);
480
481         devnode = udev_device_get_devnode(ud);
482         devnum = udev_device_get_devnum(ud);
483         if (!devnode || devnum == 0)
484                 return -ENODEV;
485
486         idev_evdev_name(name, devnum);
487
488         eu = new0(unmanaged_evdev, 1);
489         if (!eu)
490                 return -ENOMEM;
491
492         e = &eu->evdev.element;
493         eu->evdev = IDEV_EVDEV_INIT(&unmanaged_evdev_vtable, s);
494
495         eu->devnode = strdup(devnode);
496         if (!eu->devnode)
497                 return -ENOMEM;
498
499         r = idev_element_add(e, name);
500         if (r < 0)
501                 return r;
502
503         if (out)
504                 *out = e;
505         e = NULL;
506         return 0;
507 }
508
509 static void unmanaged_evdev_free(idev_element *e) {
510         unmanaged_evdev *eu = unmanaged_evdev_from_element(e);
511
512         idev_evdev_destroy(&eu->evdev);
513         free(eu->devnode);
514         free(eu);
515 }
516
517 static const idev_element_vtable unmanaged_evdev_vtable = {
518         .free                   = unmanaged_evdev_free,
519         .enable                 = unmanaged_evdev_resume,
520         .disable                = unmanaged_evdev_pause,
521         .open                   = unmanaged_evdev_resume,
522         .close                  = unmanaged_evdev_pause,
523 };
524
525 /*
526  * Managed Evdev Element
527  * The managed evdev element uses systemd-logind to acquire evdev devices. This
528  * means, we do not open the device node /dev/input/eventX directly. Instead,
529  * logind passes us a file-descriptor whenever our session is activated. Thus,
530  * we don't need access to the device node directly.
531  * Furthermore, whenever the session is put asleep, logind revokes the
532  * file-descriptor so we loose access to the device.
533  * Managed evdev elements should be preferred over unmanaged elements whenever
534  * you run inside a user session with exclusive device access.
535  */
536
537 static int managed_evdev_take_device_fn(sd_bus *bus,
538                                         sd_bus_message *reply,
539                                         void *userdata,
540                                         sd_bus_error *ret_error) {
541         managed_evdev *em = userdata;
542         idev_element *e = &em->evdev.element;
543         idev_session *s = e->session;
544         int r, paused, fd;
545
546         em->slot_take_device = sd_bus_slot_unref(em->slot_take_device);
547
548         if (sd_bus_message_is_method_error(reply, NULL)) {
549                 const sd_bus_error *error = sd_bus_message_get_error(reply);
550
551                 log_debug("idev-evdev: %s/%s: TakeDevice failed: %s: %s",
552                           s->name, e->name, error->name, error->message);
553                 return 0;
554         }
555
556         em->acquired = true;
557
558         r = sd_bus_message_read(reply, "hb", &fd, &paused);
559         if (r < 0) {
560                 log_debug("idev-evdev: %s/%s: erroneous TakeDevice reply", s->name, e->name);
561                 return 0;
562         }
563
564         /* If the device is paused, ignore it; we will get the next fd via
565          * ResumeDevice signals. */
566         if (paused)
567                 return 0;
568
569         fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
570         if (fd < 0) {
571                 log_debug("idev-evdev: %s/%s: cannot duplicate evdev fd: %m", s->name, e->name);
572                 return 0;
573         }
574
575         r = idev_evdev_resume(&em->evdev, fd);
576         if (r < 0)
577                 log_debug("idev-evdev: %s/%s: cannot resume: %s",
578                           s->name, e->name, strerror(-r));
579
580         return 0;
581 }
582
583 static void managed_evdev_resume(idev_element *e) {
584         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
585         managed_evdev *em = managed_evdev_from_element(e);
586         idev_session *s = e->session;
587         idev_context *c = s->context;
588         int r;
589
590         /*
591          * Acquiring managed devices is heavy, so do it only once we're
592          * enabled *and* opened by someone.
593          */
594         if (e->n_open < 1 || !e->enabled)
595                 return;
596
597         /* bail out if already pending */
598         if (em->requested)
599                 return;
600
601         r = sd_bus_message_new_method_call(c->sysbus,
602                                            &m,
603                                            "org.freedesktop.login1",
604                                            s->path,
605                                            "org.freedesktop.login1.Session",
606                                            "TakeDevice");
607         if (r < 0)
608                 goto error;
609
610         r = sd_bus_message_append(m, "uu", major(em->devnum), minor(em->devnum));
611         if (r < 0)
612                 goto error;
613
614         r = sd_bus_call_async(c->sysbus,
615                               &em->slot_take_device,
616                               m,
617                               managed_evdev_take_device_fn,
618                               em,
619                               0);
620         if (r < 0)
621                 goto error;
622
623         em->requested = true;
624         return;
625
626 error:
627         log_debug("idev-evdev: %s/%s: cannot send TakeDevice request: %s",
628                   s->name, e->name, strerror(-r));
629 }
630
631 static void managed_evdev_pause(idev_element *e) {
632         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
633         managed_evdev *em = managed_evdev_from_element(e);
634         idev_session *s = e->session;
635         idev_context *c = s->context;
636         int r;
637
638         /*
639          * Releasing managed devices is heavy. Once acquired, we get
640          * notifications for sleep/wake-up events, so there's no reason to
641          * release it if disabled but opened. However, if a device is closed,
642          * we release it immediately as we don't care for sleep/wake-up events
643          * then (even if we're actually enabled).
644          */
645
646         idev_evdev_pause(&em->evdev, false);
647
648         if (e->n_open > 0 || !em->requested)
649                 return;
650
651         /*
652          * If TakeDevice() is pending or was successful, make sure to
653          * release the device again. We don't care for return-values,
654          * so send it without waiting or callbacks.
655          * If a failed TakeDevice() is pending, but someone else took
656          * the device on the same bus-connection, we might incorrectly
657          * release their device. This is an unlikely race, though.
658          * Furthermore, you really shouldn't have two users of the
659          * controller-API on the same session, on the same devices, *AND* on
660          * the same bus-connection. So we don't care for that race..
661          */
662
663         idev_evdev_pause(&em->evdev, true);
664         em->requested = false;
665
666         if (!em->acquired && !em->slot_take_device)
667                 return;
668
669         em->slot_take_device = sd_bus_slot_unref(em->slot_take_device);
670         em->acquired = false;
671
672         r = sd_bus_message_new_method_call(c->sysbus,
673                                            &m,
674                                            "org.freedesktop.login1",
675                                            s->path,
676                                            "org.freedesktop.login1.Session",
677                                            "ReleaseDevice");
678         if (r >= 0) {
679                 r = sd_bus_message_append(m, "uu", major(em->devnum), minor(em->devnum));
680                 if (r >= 0)
681                         r = sd_bus_send(c->sysbus, m, NULL);
682         }
683
684         if (r < 0 && r != -ENOTCONN)
685                 log_debug("idev-evdev: %s/%s: cannot send ReleaseDevice: %s",
686                           s->name, e->name, strerror(-r));
687 }
688
689 static int managed_evdev_pause_device_fn(sd_bus *bus,
690                                          sd_bus_message *signal,
691                                          void *userdata,
692                                          sd_bus_error *ret_error) {
693         managed_evdev *em = userdata;
694         idev_element *e = &em->evdev.element;
695         idev_session *s = e->session;
696         idev_context *c = s->context;
697         uint32_t major, minor;
698         const char *mode;
699         int r;
700
701         /*
702          * We get PauseDevice() signals from logind whenever a device we
703          * requested was, or is about to be, paused. Arguments are major/minor
704          * number of the device and the mode of the operation.
705          * In case the event is not about our device, we ignore it. Otherwise,
706          * we treat it as asynchronous access-revocation (as if we got HUP on
707          * the device fd). Note that we might have already treated the HUP
708          * event via EPOLLHUP, whichever comes first.
709          *
710          * @mode can be one of the following:
711          *   "pause": The device is about to be paused. We must react
712          *            immediately and respond with PauseDeviceComplete(). Once
713          *            we replied, logind will pause the device. Note that
714          *            logind might apply any kind of timeout and force pause
715          *            the device if we don't respond in a timely manner. In
716          *            this case, we will receive a second PauseDevice event
717          *            with @mode set to "force" (or similar).
718          *   "force": The device was disabled forecfully by logind. Access is
719          *            already revoked. This is just an asynchronous
720          *            notification so we can put the device asleep (in case
721          *            we didn't already notice the access revocation).
722          *    "gone": This is like "force" but is sent if the device was
723          *            paused due to a device-removal event.
724          *
725          * We always handle PauseDevice signals as "force" as we properly
726          * support asynchronous access revocation, anyway. But in case logind
727          * sent mode "pause", we also call PauseDeviceComplete() to immediately
728          * acknowledge the request.
729          */
730
731         r = sd_bus_message_read(signal, "uus", &major, &minor, &mode);
732         if (r < 0) {
733                 log_debug("idev-evdev: %s/%s: erroneous PauseDevice signal",
734                           s->name, e->name);
735                 return 0;
736         }
737
738         /* not our device? */
739         if (makedev(major, minor) != em->devnum)
740                 return 0;
741
742         idev_evdev_pause(&em->evdev, true);
743
744         if (streq(mode, "pause")) {
745                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
746
747                 /*
748                  * Sending PauseDeviceComplete() is racy if logind triggers the
749                  * timeout. That is, if we take too long and logind pauses the
750                  * device by sending a forced PauseDevice, our
751                  * PauseDeviceComplete call will be stray. That's fine, though.
752                  * logind ignores such stray calls. Only if logind also sent a
753                  * further PauseDevice() signal, it might match our call
754                  * incorrectly to the newer PauseDevice(). That's fine, too, as
755                  * we handle that event asynchronously, anyway. Therefore,
756                  * whatever happens, we're fine. Yay!
757                  */
758
759                 r = sd_bus_message_new_method_call(c->sysbus,
760                                                    &m,
761                                                    "org.freedesktop.login1",
762                                                    s->path,
763                                                    "org.freedesktop.login1.Session",
764                                                    "PauseDeviceComplete");
765                 if (r >= 0) {
766                         r = sd_bus_message_append(m, "uu", major, minor);
767                         if (r >= 0)
768                                 r = sd_bus_send(c->sysbus, m, NULL);
769                 }
770
771                 if (r < 0)
772                         log_debug("idev-evdev: %s/%s: cannot send PauseDeviceComplete: %s",
773                                   s->name, e->name, strerror(-r));
774         }
775
776         return 0;
777 }
778
779 static int managed_evdev_resume_device_fn(sd_bus *bus,
780                                           sd_bus_message *signal,
781                                           void *userdata,
782                                           sd_bus_error *ret_error) {
783         managed_evdev *em = userdata;
784         idev_element *e = &em->evdev.element;
785         idev_session *s = e->session;
786         uint32_t major, minor;
787         int r, fd;
788
789         /*
790          * We get ResumeDevice signals whenever logind resumed a previously
791          * paused device. The arguments contain the major/minor number of the
792          * related device and a new file-descriptor for the freshly opened
793          * device-node.
794          * If the signal is not about our device, we simply ignore it.
795          * Otherwise, we take the file-descriptor and immediately resume the
796          * device.
797          */
798
799         r = sd_bus_message_read(signal, "uuh", &major, &minor, &fd);
800         if (r < 0) {
801                 log_debug("idev-evdev: %s/%s: erroneous ResumeDevice signal",
802                           s->name, e->name);
803                 return 0;
804         }
805
806         /* not our device? */
807         if (makedev(major, minor) != em->devnum)
808                 return 0;
809
810         fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
811         if (fd < 0) {
812                 log_debug("idev-evdev: %s/%s: cannot duplicate evdev fd: %m",
813                           s->name, e->name);
814                 return 0;
815         }
816
817         r = idev_evdev_resume(&em->evdev, fd);
818         if (r < 0)
819                 log_debug("idev-evdev: %s/%s: cannot resume: %s",
820                           s->name, e->name, strerror(-r));
821
822         return 0;
823 }
824
825 static int managed_evdev_setup_bus(managed_evdev *em) {
826         idev_element *e = &em->evdev.element;
827         idev_session *s = e->session;
828         idev_context *c = s->context;
829         _cleanup_free_ char *match = NULL;
830         int r;
831
832         match = strjoin("type='signal',"
833                         "sender='org.freedesktop.login1',"
834                         "interface='org.freedesktop.login1.Session',"
835                         "member='PauseDevice',"
836                         "path='", s->path, "'",
837                         NULL);
838         if (!match)
839                 return -ENOMEM;
840
841         r = sd_bus_add_match(c->sysbus,
842                              &em->slot_pause_device,
843                              match,
844                              managed_evdev_pause_device_fn,
845                              em);
846         if (r < 0)
847                 return r;
848
849         free(match);
850         match = strjoin("type='signal',"
851                         "sender='org.freedesktop.login1',"
852                         "interface='org.freedesktop.login1.Session',"
853                         "member='ResumeDevice',"
854                         "path='", s->path, "'",
855                         NULL);
856         if (!match)
857                 return -ENOMEM;
858
859         r = sd_bus_add_match(c->sysbus,
860                              &em->slot_resume_device,
861                              match,
862                              managed_evdev_resume_device_fn,
863                              em);
864         if (r < 0)
865                 return r;
866
867         return 0;
868 }
869
870 static int managed_evdev_new(idev_element **out, idev_session *s, struct udev_device *ud) {
871         _cleanup_(idev_element_freep) idev_element *e = NULL;
872         char name[IDEV_EVDEV_NAME_MAX];
873         managed_evdev *em;
874         dev_t devnum;
875         int r;
876
877         assert_return(s, -EINVAL);
878         assert_return(s->managed, -EINVAL);
879         assert_return(s->context->sysbus, -EINVAL);
880         assert_return(ud, -EINVAL);
881
882         devnum = udev_device_get_devnum(ud);
883         if (devnum == 0)
884                 return -ENODEV;
885
886         idev_evdev_name(name, devnum);
887
888         em = new0(managed_evdev, 1);
889         if (!em)
890                 return -ENOMEM;
891
892         e = &em->evdev.element;
893         em->evdev = IDEV_EVDEV_INIT(&managed_evdev_vtable, s);
894         em->devnum = devnum;
895
896         r = managed_evdev_setup_bus(em);
897         if (r < 0)
898                 return r;
899
900         r = idev_element_add(e, name);
901         if (r < 0)
902                 return r;
903
904         if (out)
905                 *out = e;
906         e = NULL;
907         return 0;
908 }
909
910 static void managed_evdev_free(idev_element *e) {
911         managed_evdev *em = managed_evdev_from_element(e);
912
913         em->slot_resume_device = sd_bus_slot_unref(em->slot_resume_device);
914         em->slot_pause_device = sd_bus_slot_unref(em->slot_pause_device);
915         idev_evdev_destroy(&em->evdev);
916         free(em);
917 }
918
919 static const idev_element_vtable managed_evdev_vtable = {
920         .free                   = managed_evdev_free,
921         .enable                 = managed_evdev_resume,
922         .disable                = managed_evdev_pause,
923         .open                   = managed_evdev_resume,
924         .close                  = managed_evdev_pause,
925 };
926
927 /*
928  * Generic Constructor
929  * Instead of relying on the caller to choose between managed and unmanaged
930  * evdev devices, the idev_evdev_new() constructor does that for you (by
931  * looking at s->managed).
932  */
933
934 bool idev_is_evdev(idev_element *e) {
935         return e && (e->vtable == &unmanaged_evdev_vtable ||
936                      e->vtable == &managed_evdev_vtable);
937 }
938
939 idev_element *idev_find_evdev(idev_session *s, dev_t devnum) {
940         char name[IDEV_EVDEV_NAME_MAX];
941
942         assert_return(s, NULL);
943         assert_return(devnum != 0, NULL);
944
945         idev_evdev_name(name, devnum);
946         return idev_find_element(s, name);
947 }
948
949 int idev_evdev_new(idev_element **out, idev_session *s, struct udev_device *ud) {
950         assert_return(s, -EINVAL);
951         assert_return(ud, -EINVAL);
952
953         return s->managed ? managed_evdev_new(out, s, ud) : unmanaged_evdev_new(out, s, ud);
954 }