terminal: add system view interface
We're going to need multiple binaries that provide session-services via logind device management. To avoid re-writing the seat/session/device scan/monitor interface for each of them, this commit adds a generic helper to libsystemd-terminal: The sysview interface scans and tracks seats, sessions and devices on a system. It basically mirrors the state of logind on the application side. Now, each session-service can listen for matching sessions and attach to them. On each session, managed device access is provided. This way, it is pretty simple to write session-services that attach to multiple sessions (even split across seats).
This commit is contained in:
parent
aae2b488d0
commit
7ed3a638b2
|
@ -2971,6 +2971,9 @@ libsystemd_terminal_la_CFLAGS = \
|
|||
$(AM_CFLAGS)
|
||||
|
||||
libsystemd_terminal_la_SOURCES = \
|
||||
src/libsystemd-terminal/sysview.h \
|
||||
src/libsystemd-terminal/sysview-internal.h \
|
||||
src/libsystemd-terminal/sysview.c \
|
||||
src/libsystemd-terminal/term-internal.h \
|
||||
src/libsystemd-terminal/term-charset.c \
|
||||
src/libsystemd-terminal/term-page.c \
|
||||
|
@ -2981,6 +2984,7 @@ libsystemd_terminal_la_SOURCES = \
|
|||
src/libsystemd-terminal/unifont.c
|
||||
|
||||
libsystemd_terminal_la_LIBADD = \
|
||||
libudev-internal.la \
|
||||
libsystemd-internal.la \
|
||||
libsystemd-shared.la
|
||||
|
||||
|
|
140
src/libsystemd-terminal/sysview-internal.h
Normal file
140
src/libsystemd-terminal/sysview-internal.h
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <libudev.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <systemd/sd-bus.h>
|
||||
#include <systemd/sd-event.h>
|
||||
#include "hashmap.h"
|
||||
#include "list.h"
|
||||
#include "macro.h"
|
||||
#include "sysview.h"
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
* Devices
|
||||
*/
|
||||
|
||||
struct sysview_device {
|
||||
sysview_seat *seat;
|
||||
const char *name;
|
||||
unsigned int type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
struct udev_device *ud;
|
||||
} evdev, drm;
|
||||
};
|
||||
};
|
||||
|
||||
sysview_device *sysview_find_device(sysview_context *c, const char *name);
|
||||
|
||||
int sysview_device_new(sysview_device **out, sysview_seat *seat, const char *name);
|
||||
sysview_device *sysview_device_free(sysview_device *device);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(sysview_device*, sysview_device_free);
|
||||
|
||||
/*
|
||||
* Sessions
|
||||
*/
|
||||
|
||||
struct sysview_session {
|
||||
sysview_seat *seat;
|
||||
char *name;
|
||||
char *path;
|
||||
|
||||
sd_bus_slot *slot_take_control;
|
||||
|
||||
bool custom : 1;
|
||||
bool public : 1;
|
||||
bool wants_control : 1;
|
||||
bool has_control : 1;
|
||||
};
|
||||
|
||||
sysview_session *sysview_find_session(sysview_context *c, const char *name);
|
||||
|
||||
int sysview_session_new(sysview_session **out, sysview_seat *seat, const char *name);
|
||||
sysview_session *sysview_session_free(sysview_session *session);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(sysview_session*, sysview_session_free);
|
||||
|
||||
/*
|
||||
* Seats
|
||||
*/
|
||||
|
||||
struct sysview_seat {
|
||||
sysview_context *context;
|
||||
char *name;
|
||||
|
||||
Hashmap *session_map;
|
||||
Hashmap *device_map;
|
||||
|
||||
bool scanned : 1;
|
||||
bool public : 1;
|
||||
};
|
||||
|
||||
sysview_seat *sysview_find_seat(sysview_context *c, const char *name);
|
||||
|
||||
int sysview_seat_new(sysview_seat **out, sysview_context *c, const char *name);
|
||||
sysview_seat *sysview_seat_free(sysview_seat *seat);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(sysview_seat*, sysview_seat_free);
|
||||
|
||||
/*
|
||||
* Contexts
|
||||
*/
|
||||
|
||||
struct sysview_context {
|
||||
sd_event *event;
|
||||
sd_bus *sysbus;
|
||||
struct udev *ud;
|
||||
uint64_t custom_sid;
|
||||
|
||||
Hashmap *seat_map;
|
||||
Hashmap *session_map;
|
||||
Hashmap *device_map;
|
||||
|
||||
sd_event_source *scan_src;
|
||||
sysview_event_fn event_fn;
|
||||
void *userdata;
|
||||
|
||||
/* udev scanner */
|
||||
struct udev_monitor *ud_monitor;
|
||||
sd_event_source *ud_monitor_src;
|
||||
|
||||
/* logind scanner */
|
||||
sd_bus_slot *ld_slot_manager_signal;
|
||||
sd_bus_slot *ld_slot_list_seats;
|
||||
sd_bus_slot *ld_slot_list_sessions;
|
||||
|
||||
bool scan_logind : 1;
|
||||
bool scan_evdev : 1;
|
||||
bool scan_drm : 1;
|
||||
bool running : 1;
|
||||
bool scanned : 1;
|
||||
bool rescan : 1;
|
||||
};
|
||||
|
||||
int sysview_context_rescan(sysview_context *c);
|
1471
src/libsystemd-terminal/sysview.c
Normal file
1471
src/libsystemd-terminal/sysview.c
Normal file
File diff suppressed because it is too large
Load diff
151
src/libsystemd-terminal/sysview.h
Normal file
151
src/libsystemd-terminal/sysview.h
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
/*
|
||||
* System View
|
||||
* The sysview interface scans and monitors the system for seats, sessions and
|
||||
* devices. It basically mirrors the state of logind on the application side.
|
||||
* It's meant as base for session services that require managed device access.
|
||||
* The logind controller API is employed to allow unprivileged access to all
|
||||
* devices of a user.
|
||||
* Furthermore, the sysview interface can be used for system services that run
|
||||
* in situations where logind is not available, but session-like services are
|
||||
* needed. For instance, the initrd does not run logind but might require
|
||||
* graphics access. It cannot run session services, though. The sysview
|
||||
* interface pretends that a session is available and provides the same
|
||||
* interface as to normal session services.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <libudev.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <systemd/sd-bus.h>
|
||||
#include <systemd/sd-event.h>
|
||||
#include "util.h"
|
||||
|
||||
typedef struct sysview_event sysview_event;
|
||||
typedef struct sysview_device sysview_device;
|
||||
typedef struct sysview_session sysview_session;
|
||||
typedef struct sysview_seat sysview_seat;
|
||||
typedef struct sysview_context sysview_context;
|
||||
|
||||
/*
|
||||
* Events
|
||||
*/
|
||||
|
||||
enum {
|
||||
SYSVIEW_EVENT_SEAT_ADD,
|
||||
SYSVIEW_EVENT_SEAT_REMOVE,
|
||||
|
||||
SYSVIEW_EVENT_SESSION_FILTER,
|
||||
SYSVIEW_EVENT_SESSION_ADD,
|
||||
SYSVIEW_EVENT_SESSION_REMOVE,
|
||||
SYSVIEW_EVENT_SESSION_ATTACH,
|
||||
SYSVIEW_EVENT_SESSION_DETACH,
|
||||
SYSVIEW_EVENT_SESSION_CONTROL,
|
||||
};
|
||||
|
||||
struct sysview_event {
|
||||
unsigned int type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
sysview_seat *seat;
|
||||
} seat_add, seat_remove;
|
||||
|
||||
struct {
|
||||
const char *id;
|
||||
const char *seatid;
|
||||
const char *username;
|
||||
unsigned int uid;
|
||||
} session_filter;
|
||||
|
||||
struct {
|
||||
sysview_session *session;
|
||||
} session_add, session_remove;
|
||||
|
||||
struct {
|
||||
sysview_session *session;
|
||||
sysview_device *device;
|
||||
} session_attach, session_detach;
|
||||
|
||||
struct {
|
||||
sysview_session *session;
|
||||
int error;
|
||||
} session_control;
|
||||
};
|
||||
};
|
||||
|
||||
typedef int (*sysview_event_fn) (sysview_context *c, void *userdata, sysview_event *e);
|
||||
|
||||
/*
|
||||
* Devices
|
||||
*/
|
||||
|
||||
enum {
|
||||
SYSVIEW_DEVICE_EVDEV,
|
||||
SYSVIEW_DEVICE_DRM,
|
||||
SYSVIEW_DEVICE_CNT
|
||||
};
|
||||
|
||||
unsigned int sysview_device_get_type(sysview_device *device);
|
||||
struct udev_device *sysview_device_get_ud(sysview_device *device);
|
||||
|
||||
/*
|
||||
* Sessions
|
||||
*/
|
||||
|
||||
const char *sysview_session_get_name(sysview_session *session);
|
||||
|
||||
int sysview_session_take_control(sysview_session *session);
|
||||
void sysview_session_release_control(sysview_session *session);
|
||||
|
||||
/*
|
||||
* Seats
|
||||
*/
|
||||
|
||||
const char *sysview_seat_get_name(sysview_seat *seat);
|
||||
|
||||
/*
|
||||
* Contexts
|
||||
*/
|
||||
|
||||
enum {
|
||||
SYSVIEW_CONTEXT_SCAN_LOGIND = (1 << 0),
|
||||
SYSVIEW_CONTEXT_SCAN_EVDEV = (1 << 1),
|
||||
SYSVIEW_CONTEXT_SCAN_DRM = (1 << 2),
|
||||
};
|
||||
|
||||
int sysview_context_new(sysview_context **out,
|
||||
unsigned int flags,
|
||||
sd_event *event,
|
||||
sd_bus *sysbus,
|
||||
struct udev *ud);
|
||||
sysview_context *sysview_context_free(sysview_context *c);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(sysview_context*, sysview_context_free);
|
||||
|
||||
bool sysview_context_is_running(sysview_context *c);
|
||||
int sysview_context_start(sysview_context *c, sysview_event_fn event_fn, void *userdata);
|
||||
void sysview_context_stop(sysview_context *c);
|
Loading…
Reference in a new issue