Hi!
I have a Fedora 17 system with two nvidia videocards, two screens, two
keyboards and two mouses. I've tried to setup multi-seat on it following
this article:
http://code.lexarcana.com/blog/2012/06/17/simple-multiseat-setup-on-fedora-17/.
But without success.
The article propose to create a new seat by attaching a framebuffer device to
the it:
Unfortunally, there are no any devices whose path end with /drm/card1 or
/graphics/fb1 in my system ('loginctl seat-status seat0' does not show any).
These paths arrive only after loading the open-source driver (nouveau), but not
with Nvidia proprietary driver.
Furthermore, the right way of loading graphic driver is after starting
X-server, not before it. So logind should inform gdm about new seats before gdm
starts X-servers that loads nvidia driver.
My idea is
1. make static configuration of videocards and monitors in xorg.conf
2. dynamically add inputdevices according to the site udev rules
3. learn Xorg to select proper ServerLayout section according the -seat
parameter
I created two patches (one for systemd-44-21) and another for
xorg-x11-server-1.12.3-2) that implemented this idea.
The first patch - systemd-logind-site-without-graphics - introduces the new
systemd-logind.conf option: SeatWithoutGraphics with default value "no". But
the value "yes" allows logind to create a new seat by attaching any device for
it, not only graphics.
The second patch - xserver-1.12.3-xorg-seat-layout - introduces the
new ServerLayout option - "Seat". If Xorg runs with only "-seat" command line
parameter, without "-layout" (gdm starts it in this manner), it tries to find a
layout with the value of "Seat" is equal to the value of "-seat" parameter
After applying these patches seems everything works.
The way to setup:
1. install the pached packages systemd and xorg-x11-server-Xorg
2. create xorg.conf with several ServerLayout sections and "Seat" options
specifying what seat it belongs. It is not necessary to add InputDevices to the
layouts.
3. Add "SeatWithoutGraphics=yes" to /etc/systemd/systemd-logind.conf
4. Restart service systemd-logind.service
5. Attach any devices (for example, USB hubs) to your seats seat1, seat2 and so
on. All the seats will be created by logind
6. Restart gdm (init 3 && init 5)
7. All displays will shows the gdm user-selection screen.
I've created a bugs at https://bugzilla.redhat.com/show_bug.cgi?id=878605. It
also resolves
I'd like if my patch will be resolved upstream.
Oleg.
From: Oleg Samarin <[email protected]>
Subject: [PATCH] logind: creating a site without graphics
Added capability of creating a new site without graphic card
diff -Naur systemd-44.old/src/login/logind.c systemd-44/src/login/logind.c
--- systemd-44.old/src/login/logind.c 2012-11-15 22:31:51.000000000 +0400
+++ systemd-44/src/login/logind.c 2012-11-15 22:36:58.343888212 +0400
@@ -321,7 +321,11 @@
if (!device)
return 0;
- seat_add_to_gc_queue(device->seat);
+ LIST_REMOVE(Device, devices, device->seat->devices, device);
+
+ if (! m->seat_without_graphics || ! device->seat->devices) {
+ seat_add_to_gc_queue(device->seat);
+ }
device_free(device);
} else {
@@ -372,9 +376,11 @@
goto finish;
}
- r = udev_enumerate_add_match_subsystem(e, "graphics");
- if (r < 0)
- goto finish;
+ if (! m->seat_without_graphics) {
+ r = udev_enumerate_add_match_subsystem(e, "graphics");
+ if (r < 0)
+ goto finish;
+ }
r = udev_enumerate_add_match_tag(e, "seat");
if (r < 0)
@@ -1128,9 +1134,11 @@
if (r < 0)
return r;
- r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_seat_monitor, "graphics", NULL);
- if (r < 0)
- return r;
+ if (! m->seat_without_graphics) {
+ r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_seat_monitor, "graphics", NULL);
+ if (r < 0)
+ return r;
+ }
r = udev_monitor_enable_receiving(m->udev_seat_monitor);
if (r < 0)
diff -Naur systemd-44.old/src/login/logind-gperf.gperf systemd-44/src/login/logind-gperf.gperf
--- systemd-44.old/src/login/logind-gperf.gperf 2012-11-15 22:31:43.000000000 +0400
+++ systemd-44/src/login/logind-gperf.gperf 2012-11-15 22:36:58.344888199 +0400
@@ -21,3 +21,4 @@
Login.Controllers, config_parse_strv, 0, offsetof(Manager, controllers)
Login.ResetControllers, config_parse_strv, 0, offsetof(Manager, reset_controllers)
Login.InhibitDelayMaxSec,config_parse_usec, 0, offsetof(Manager, inhibit_delay_max)
+Login.SeatWithoutGraphics,config_parse_bool, 0, offsetof(Manager, seat_without_graphics)
diff -Naur systemd-44.old/src/login/logind.h systemd-44/src/login/logind.h
--- systemd-44.old/src/login/logind.h 2012-11-15 22:31:49.000000000 +0400
+++ systemd-44/src/login/logind.h 2012-11-15 22:36:58.344888199 +0400
@@ -77,6 +77,8 @@
unsigned long session_counter;
unsigned long inhibit_counter;
+
+ bool seat_without_graphics;
Hashmap *session_cgroups;
Hashmap *user_cgroups;
diff -Naur systemd-44.old/src/login/multi-seat-x.c systemd-44/src/login/multi-seat-x.c
--- systemd-44.old/src/login/multi-seat-x.c 2012-11-15 22:31:49.000000000 +0400
+++ systemd-44/src/login/multi-seat-x.c 2012-11-14 23:14:03.000000000 +0400
@@ -35,6 +35,7 @@
int i;
const char *seat = NULL;
char **new_argv;
+ int new_argc;
char *path = NULL, *device_node = NULL;
int r;
FILE *f = NULL;
@@ -108,64 +109,71 @@
break;
}
+ /*
if (!device_node) {
log_error("Failed to find device node for seat %s.", seat);
goto fail;
}
+ */
+
+ if (device_node) {
+ r = mkdir_safe_label("/run/systemd/multi-session-x", 0755, 0, 0);
+ if (r < 0) {
+ log_error("Failed to create directory: %s", strerror(-r));
+ goto fail;
+ }
+
+ path = strappend("/run/systemd/multi-session-x/", seat);
+ if (!path) {
+ log_error("Out of memory");
+ goto fail;
+ }
+
+ f = fopen(path, "we");
+ if (!f) {
+ log_error("Failed to write configuration file: %m");
+ goto fail;
+ }
+
+ fprintf(f,
+ "Section \"Device\"\n"
+ " Identifier \"udev\"\n"
+ " Driver \"fbdev\"\n"
+ " Option \"fbdev\" \"%s\"\n"
+ "EndSection\n"
+ "Section \"ServerFlags\"\n"
+ " Option \"AutoAddDevices\" \"True\"\n"
+ " Option \"AllowEmptyInput\" \"True\"\n"
+ " Option \"DontVTSwitch\" \"True\"\n"
+ "EndSection\n"
+ "Section \"InputClass\"\n"
+ " Identifier \"Force Input Devices to Seat\"\n"
+ " Option \"GrabDevice\" \"True\"\n"
+ "EndSection\n",
+ device_node);
+
+ fflush(f);
+
+ if (ferror(f)) {
+ log_error("Failed to write configuration file: %m");
+ goto fail;
+ }
- r = mkdir_safe_label("/run/systemd/multi-session-x", 0755, 0, 0);
- if (r < 0) {
- log_error("Failed to create directory: %s", strerror(-r));
- goto fail;
- }
-
- path = strappend("/run/systemd/multi-session-x/", seat);
- if (!path) {
- log_error("Out of memory");
- goto fail;
- }
-
- f = fopen(path, "we");
- if (!f) {
- log_error("Failed to write configuration file: %m");
- goto fail;
+ fclose(f);
+ f = NULL;
}
- fprintf(f,
- "Section \"Device\"\n"
- " Identifier \"udev\"\n"
- " Driver \"fbdev\"\n"
- " Option \"fbdev\" \"%s\"\n"
- "EndSection\n"
- "Section \"ServerFlags\"\n"
- " Option \"AutoAddDevices\" \"True\"\n"
- " Option \"AllowEmptyInput\" \"True\"\n"
- " Option \"DontVTSwitch\" \"True\"\n"
- "EndSection\n"
- "Section \"InputClass\"\n"
- " Identifier \"Force Input Devices to Seat\"\n"
- " Option \"GrabDevice\" \"True\"\n"
- "EndSection\n",
- device_node);
-
- fflush(f);
-
- if (ferror(f)) {
- log_error("Failed to write configuration file: %m");
- goto fail;
- }
-
- fclose(f);
- f = NULL;
-
new_argv = alloca(sizeof(char*) * (argc + 3 + 1));
memcpy(new_argv, argv, sizeof(char*) * (argc + 2 + 1));
+ new_argc = argc;
new_argv[0] = (char*) X_SERVER;
- new_argv[argc+0] = (char*) "-config";
- new_argv[argc+1] = path;
- new_argv[argc+2] = (char*) "-sharevts";
- new_argv[argc+3] = NULL;
+ if (device_node) {
+ new_argv[new_argc ++] = (char*) "-config";
+ new_argv[new_argc ++] = path;
+ }
+ new_argv[new_argc ++] = (char*) "-sharevts";
+ new_argv[new_argc] = NULL;
udev_enumerate_unref(enumerator);
enumerator = NULL;
@@ -173,8 +181,10 @@
udev_unref(udev);
udev = NULL;
- free(device_node);
- device_node = NULL;
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
execv(X_SERVER, new_argv);
log_error("Failed to execute real X server: %m");
diff -Naur systemd-44.old/src/login/systemd-logind.conf systemd-44/src/login/systemd-logind.conf
--- systemd-44.old/src/login/systemd-logind.conf 2012-11-15 22:31:43.000000000 +0400
+++ systemd-44/src/login/systemd-logind.conf 2012-11-15 22:36:58.344888199 +0400
@@ -15,3 +15,4 @@
#Controllers=
#ResetControllers=cpu
#InhibitDelayMaxSec=5
+#SeatWithoutGraphics=no
From: Oleg Samarin <[email protected]>
Subject: [PATCH] logind: creating a site without graphics
Added capability of specifying "Seat" option in the ServerLayout section for using the layout in the seat
diff -uNr xorg-server-1.12.3.old/hw/xfree86/common/xf86Config.c xorg-server-1.12.3/hw/xfree86/common/xf86Config.c
--- xorg-server-1.12.3.old/hw/xfree86/common/xf86Config.c 2012-07-09 04:39:02.000000000 +0400
+++ xorg-server-1.12.3/hw/xfree86/common/xf86Config.c 2012-11-12 21:47:18.000000000 +0400
@@ -1475,6 +1475,7 @@
* which layout section is the active one?
*
* If there is a -layout command line option, use that one, otherwise
+ * try to find a layout with the "Seat" option equal SeatId. If could not find
* pick the first one.
*/
from = X_DEFAULT;
@@ -1491,6 +1492,11 @@
return FALSE;
}
conf_layout = l;
+ } else if (SeatId != NULL) {
+ // try to find by seat
+ if ((l = xf86findLayoutByOption("Seat", SeatId, conf_layout)) != NULL) {
+ conf_layout = l;
+ }
}
xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
adjp = conf_layout->lay_adjacency_lst;
diff -uNr xorg-server-1.12.3.old/hw/xfree86/parser/Layout.c xorg-server-1.12.3/hw/xfree86/parser/Layout.c
--- xorg-server-1.12.3.old/hw/xfree86/parser/Layout.c 2012-07-06 09:17:19.000000000 +0400
+++ xorg-server-1.12.3/hw/xfree86/parser/Layout.c 2012-11-12 21:48:00.000000000 +0400
@@ -532,3 +532,17 @@
}
return NULL;
}
+
+XF86ConfLayoutPtr
+xf86findLayoutByOption(const char *optionName, const char *optionValue, XF86ConfLayoutPtr list)
+{
+ char *value;
+
+ while (list) {
+ value = xf86findOptionValue(list->lay_option_lst, optionName);
+ if (value != NULL && xf86nameCompare(value, optionValue) == 0)
+ return list;
+ list = list->list.next;
+ }
+ return NULL;
+}
diff -uNr xorg-server-1.12.3.old/hw/xfree86/parser/xf86Parser.h xorg-server-1.12.3/hw/xfree86/parser/xf86Parser.h
--- xorg-server-1.12.3.old/hw/xfree86/parser/xf86Parser.h 2012-06-26 08:12:50.000000000 +0400
+++ xorg-server-1.12.3/hw/xfree86/parser/xf86Parser.h 2012-11-12 21:42:18.000000000 +0400
@@ -437,6 +437,12 @@
XF86ConfDevicePtr p);
extern _X_EXPORT XF86ConfLayoutPtr xf86findLayout(const char *name,
XF86ConfLayoutPtr list);
+extern _X_EXPORT XF86ConfLayoutPtr xf86findLayoutByOption(
+ const char *optionName,
+ const char *optionValue,
+ XF86ConfLayoutPtr list
+);
+
extern _X_EXPORT XF86ConfMonitorPtr xf86findMonitor(const char *ident,
XF86ConfMonitorPtr p);
extern _X_EXPORT XF86ConfModesPtr xf86findModes(const char *ident,
_______________________________________________
systemd-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/systemd-devel