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

Reply via email to