[kde-workspace] fix some multiseat issues in kdm (XDG_SEAT, plymouth)

Martin Briza mbriza at fedoraproject.org
Thu Jul 11 11:50:16 UTC 2013


commit f7b192c0fc78065490919f020386f010fba3a985
Author: Martin Briza <mbriza at redhat.com>
Date:   Thu Jul 11 10:56:49 2013 +0200

    fix some multiseat issues in kdm (XDG_SEAT, plymouth)

 kde-workspace-4.10.90-kdm-logind-multiseat.patch |   67 +++++++++-
 kde-workspace.spec                               |    6 +-
 kdebase-workspace-4.4.92-kdm_plymouth081.patch   |  168 +++++++++++++++++-----
 3 files changed, 200 insertions(+), 41 deletions(-)
---
diff --git a/kde-workspace-4.10.90-kdm-logind-multiseat.patch b/kde-workspace-4.10.90-kdm-logind-multiseat.patch
index 2a81e7d..fe65ac8 100644
--- a/kde-workspace-4.10.90-kdm-logind-multiseat.patch
+++ b/kde-workspace-4.10.90-kdm-logind-multiseat.patch
@@ -230,7 +230,7 @@ diff -up kde-workspace-4.10.90/kdm/backend/dm.c.kdm_logind kde-workspace-4.10.90
 +            if (!link->systemd_seat)
 +                continue;
 +            /* see if the can_graphical property didn't change */
-+            if (strcmp(*iter_name, link->systemd_seat)) {
++            if (strcmp(*iter_name, link->systemd_seat) == 0) {
 +                if (!can_graphical) {
 +                    free(link->systemd_seat);
 +                    link->systemd_seat = NULL;
@@ -318,7 +318,36 @@ diff -up kde-workspace-4.10.90/kdm/backend/dm.h.kdm_logind kde-workspace-4.10.90
 diff -up kde-workspace-4.10.90/kdm/backend/server.c.kdm_logind kde-workspace-4.10.90/kdm/backend/server.c
 --- kde-workspace-4.10.90/kdm/backend/server.c.kdm_logind	2013-06-27 16:27:30.184895241 -0500
 +++ kde-workspace-4.10.90/kdm/backend/server.c	2013-06-27 16:27:30.201895054 -0500
-@@ -70,6 +70,21 @@ prepareServerArgv(struct display *d, con
+@@ -43,6 +43,7 @@ from the copyright holder.
+ #include <stdio.h>
+ #include <signal.h>
+ 
++#define SYSTEMD_X_WRAPPER "/lib/systemd/systemd-multi-seat-x"
+ 
+ struct display *startingServer;
+ time_t serverTimeout = TO_INF;
+@@ -55,9 +56,18 @@ prepareServerArgv(struct display *d, con
+     char vtstr[8];
+ #endif
+ 
+-    if (!(argv = parseArgs(0, d->serverCmd)) ||
+-        !(argv = addStrArr(argv, d->name, -1)))
++#if WITH_SYSTEMD
++    FILE *tmpFile = NULL;
++    if ((tmpFile = fopen(SYSTEMD_X_WRAPPER, "rb")) != NULL && fclose(tmpFile) == 0) {
++        if (!(argv = parseArgs(0, SYSTEMD_X_WRAPPER)) || !(argv = addStrArr(argv, d->name, -1))) {
++            exit(47);
++        }
++    }
++    else
++#endif
++    if (!(argv = parseArgs(0, d->serverCmd)) || !(argv = addStrArr(argv, d->name, -1))) {
+         exit(47);
++    }
+ #ifdef HAVE_VTS
+     if (d->serverVT &&
+         !(argv = addStrArr(argv, vtstr,
+@@ -70,6 +80,25 @@ prepareServerArgv(struct display *d, con
      if (!changeUser(d->serverUID, d->authFile))
          exit(47);
  
@@ -328,6 +357,10 @@ diff -up kde-workspace-4.10.90/kdm/backend/server.c.kdm_logind kde-workspace-4.1
 +            exit(47);
 +        if (!(argv = parseArgs(argv, d->systemd_seat)))
 +            exit(47);
++        if (!(argv = parseArgs(argv, "-layout")))
++            exit(47);
++        if (!(argv = parseArgs(argv, d->systemd_seat)))
++            exit(47);
 +    }
 +    else {
 +        if (!(argv = parseArgs(argv, "-seat")))
@@ -340,3 +373,33 @@ diff -up kde-workspace-4.10.90/kdm/backend/server.c.kdm_logind kde-workspace-4.1
      return argv;
  }
  
+--- kde-workspace-4.10.2/kdm/backend/client.c.kdm_logind
++++ kde-workspace-4.10.2/kdm/backend/client.c
+@@ -1461,6 +1461,14 @@ startClient(volatile int *pid)
+ #endif
+     userEnviron = inheritEnv(env, envvars);
+     env = systemEnv(0, curuser);
++#ifdef WITH_SYSTEMD
++    if (td->systemd_seat) {
++        char *envbuf;
++        ASPrintf(&envbuf, "XDG_SEAT=%s", td->systemd_seat);
++        pam_putenv(pamh, envbuf);
++        env = setEnv(env, "XDG_SEAT", td->systemd_seat);
++    }
++#endif
+     systemEnviron = setEnv(env, "HOME", p->pw_dir);
+     debug("user environment:\n%[|''>'\n's"
+           "system environment:\n%[|''>'\n's"
+--- kde-workspace-4.10.2/kdm/backend/session.c.kdm_logind
++++ kde-workspace-4.10.2/kdm/backend/session.c
+@@ -437,6 +437,10 @@ openGreeter()
+ 
+     grttalk.pipe = &grtproc.pipe;
+     env = systemEnv(dupEnv(), 0);
++#ifdef WITH_SYSTEMD
++    if (td->systemd_seat)
++        env = setEnv(env, "XDG_SEAT", td->systemd_seat);
++#endif
+     if (gOpen(&grtproc, (char **)0, "_greet", env, name,
+               greeterUID, td->greeterAuthFile, &td->gpipe))
+         sessionExit(EX_UNMANAGE_DPY);
diff --git a/kde-workspace.spec b/kde-workspace.spec
index 5291ef2..798e834 100644
--- a/kde-workspace.spec
+++ b/kde-workspace.spec
@@ -17,7 +17,7 @@
 Summary: KDE Workspace
 Name:    kde-workspace
 Version: 4.10.90
-Release: 1%{?dist}
+Release: 2%{?dist}
 
 License: GPLv2
 URL:     https://projects.kde.org/projects/kde/kde-workspace
@@ -1039,6 +1039,10 @@ fi
 
 
 %changelog
+* Thu Jul 11 2013 Martin Briza <mbriza at redhat.com> - 4.10.90-2
+- fix some multiseat issues in kdm, (XDG_SEAT, plymouth cooperation) as per discussion in #975079,
+  thanks go to Stefan BrĂ¼ns and Laercio de Sousa
+
 * Thu Jun 27 2013 Rex Dieter <rdieter at fedoraproject.org> - 4.10.90-1
 - 4.10.90
 
diff --git a/kdebase-workspace-4.4.92-kdm_plymouth081.patch b/kdebase-workspace-4.4.92-kdm_plymouth081.patch
index 2c49ccd..4a69f3c 100644
--- a/kdebase-workspace-4.4.92-kdm_plymouth081.patch
+++ b/kdebase-workspace-4.4.92-kdm_plymouth081.patch
@@ -1,7 +1,7 @@
 diff -up kdebase-workspace-4.4.92/kdm/backend/dm.c.kdm_plymouth kdebase-workspace-4.4.92/kdm/backend/dm.c
 --- kdebase-workspace-4.4.92/kdm/backend/dm.c.kdm_plymouth	2010-07-06 01:54:30.000000000 -0500
 +++ kdebase-workspace-4.4.92/kdm/backend/dm.c	2010-07-07 13:55:48.425171749 -0500
-@@ -1329,6 +1329,81 @@ getBusyVTs(void)
+@@ -1329,52 +1329,184 @@ getBusyVTs(void)
      return activeVTs;
  }
  
@@ -28,7 +28,8 @@ diff -up kdebase-workspace-4.4.92/kdm/backend/dm.c.kdm_plymouth kdebase-workspac
 +plymouth_is_running (void)
 +{
 +        int status;
-+        status = system ("/bin/plymouth --ping");
++        status = system ("/usr/bin/plymouth --ping");
++        logError("plymouth --ping -> %d\n", WEXITSTATUS (status));
 +
 +        return WIFEXITED (status) && WEXITSTATUS (status) == 0;
 +}
@@ -37,7 +38,8 @@ diff -up kdebase-workspace-4.4.92/kdm/backend/dm.c.kdm_plymouth kdebase-workspac
 +plymouth_has_active_vt (void)
 +{
 +        int status;
-+        status = system ("/bin/plymouth --has-active-vt");
++        status = system ("/usr/bin/plymouth --has-active-vt");
++        logError("plymouth --has-active-vt -> %d\n", WEXITSTATUS (status));
 +
 +        return WIFEXITED (status) && WEXITSTATUS (status) == 0;
 +}
@@ -46,7 +48,8 @@ diff -up kdebase-workspace-4.4.92/kdm/backend/dm.c.kdm_plymouth kdebase-workspac
 +plymouth_prepare_for_transition (void)
 +{
 +        int status;
-+        status = system ("/bin/plymouth deactivate");
++        status = system ("/usr/bin/plymouth deactivate");
++        logError("plymouth deactivate -> %d\n", WEXITSTATUS (status));
 +
 +        return WIFEXITED (status) && WEXITSTATUS (status) == 0;
 +}
@@ -55,7 +58,8 @@ diff -up kdebase-workspace-4.4.92/kdm/backend/dm.c.kdm_plymouth kdebase-workspac
 +plymouth_quit_with_transition (void)
 +{
 +        int status;
-+        status = system ("/bin/plymouth quit --retain-splash");
++        status = system ("/usr/bin/plymouth --wait quit --retain-splash");
++        logError("plymouth --wait quit --retain-splash -> %d\n", WEXITSTATUS (status));
 +
 +        return WIFEXITED (status) && WEXITSTATUS (status) == 0;
 +}
@@ -64,7 +68,8 @@ diff -up kdebase-workspace-4.4.92/kdm/backend/dm.c.kdm_plymouth kdebase-workspac
 +plymouth_quit_without_transition (void)
 +{
 +        int status;
-+        status = system ("/bin/plymouth quit");
++        status = system ("/usr/bin/plymouth --wait quit");
++        logError("plymouth --wait quit -> %d\n", WEXITSTATUS (status));
 +
 +        return WIFEXITED (status) && WEXITSTATUS (status) == 0;
 +}
@@ -83,50 +88,136 @@ diff -up kdebase-workspace-4.4.92/kdm/backend/dm.c.kdm_plymouth kdebase-workspac
  static void
  allocateVT(struct display *d)
  {
-@@ -1338,6 +1413,43 @@ allocateVT(struct display *d)
+     struct display *cd;
+-    int i, tvt, volun;
++    int i, tvt;
+ 
      if ((d->displayType & d_location) == dLocal &&
          d->status == notRunning && !d->serverVT && d->reqSrvVT >= 0)
      {
++        /* Try to find the correct VT.
++         * If ServerVT is specified in the config, use it (if the admin used the
++         * same VT for multiple display, it is his/her own fault, no checks done).
++         * Otherwise, walk the list of specified VTs. Positive numbers are used
++         * even if the VT is already in use by a tty. Negative numbers and 
++         * unspecified numbers (up to #15) are used if not already in use.
++         * VTs already in use (cd->serverVT) or requested (cd->reqSrvVT)
++         * by any display are skipped.
++         */
++
++        /* some special handling is needed for Plymouth:
++         * if no VT is requested, use the active VT from plymouth for the first
++         * started display.
++         * If the display takes over the VT from plymouth, deactivate plymouth
++         */
++
++        char allowedVTs[16] = { 0 };
+         if (d->reqSrvVT && d->reqSrvVT < 16) {
+-            d->serverVT = d->reqSrvVT;
++            allowedVTs[d->reqSrvVT] = 1;
+         } else {
+-            for (i = tvt = 0;;) {
+-                if (serverVTs[i]) {
+-                    tvt = atoi(serverVTs[i++]);
+-                    volun = False;
+-                    if (tvt < 0) {
+-                        tvt = -tvt;
+-                        volun = True;
+-                    }
+-                    if (!tvt || tvt >= 16)
+-                        continue;
+-                } else {
+-                    if (++tvt >= 16)
+-                        break;
+-                    volun = True;
++            for (i = 0; serverVTs[i]; i++) {
++                tvt = atoi(serverVTs[i]);
++                if ((tvt >= 0) && (tvt < 16)) {
++                    allowedVTs[tvt] = 1;
++                } else if (tvt > -16) {
++                    allowedVTs[-tvt] = 2;
+                 }
+-                for (cd = displays; cd; cd = cd->next) {
+-                    if (cd->reqSrvVT == tvt && /* protect from lusers */
+-                            (cd->status != zombie || cd->zstatus != DS_REMOVE))
+-                        goto next;
+-                    if (cd->serverVT == tvt) {
+-                        if (cd->status != zombie || cd->zstatus == DS_REMOTE)
+-                            goto next;
+-                        if (!cd->follower) {
+-                            d->serverVT = -1;
+-                            cd->follower = d;
+-                            return;
+-                        }
+-                    }
++            }
++
++            for (tvt = 15; allowedVTs[tvt] == 0; tvt--) {
++              allowedVTs[tvt] = 2;
++            }
++
++            for (cd = displays; cd; cd = cd->next) {
++                if (cd->status != zombie) {
++                    if (cd->reqSrvVT >= 0) allowedVTs[cd->reqSrvVT] = 0;
++                    if (cd->serverVT >= 0) allowedVTs[cd->serverVT] = 0;
++                } else if (cd->zstatus == DS_REMOTE) {
++                    /* dying, but will spawn new server for remote login */
++                    if (cd->serverVT >= 0) allowedVTs[cd->serverVT] = 0;
++                } else if (cd->zstatus != DS_REMOVE) {
++                    /* dying, but will be restarted or reserved */
++                    if (cd->reqSrvVT >= 0) allowedVTs[cd->reqSrvVT] = 0;
+                 }
+-                if (!volun || !((1 << tvt) & getBusyVTs())) {
+-                    d->serverVT = tvt;
++            }
++        }
++
 +        /* check for plymouth using newer methods */
-+        d->plymouth_is_running = plymouth_is_running ();
-+        if (d->plymouth_is_running) {
-+            /* call plymouth deactivate */
++        if (plymouth_is_running ()) {
++            logError("plymouth is running ...\n");
 +            plymouth_prepare_for_transition ();
 +            if (plymouth_has_active_vt ()) {
-+                /* plymouth was displaying a splash screen and has
-+                 * terminated leaving it on screen
-+                 */
-+                int vt;
-+                vt = get_active_vt ();
-+                if (vt > 0) {
-+                    /* start the X server on the active vt */
++                int vt = get_active_vt ();
++                /* tell plymouth to quit when server starts */
++                logError("plymouth should quit when server starts\n");
++                d->plymouth_is_running = 1;
++                if (allowedVTs[vt]) {
++                    logError("plymouth is active on VT %d, reusing for %s\n", vt, d->name);
 +                    d->serverVT = vt;
-+                    return;
-+                }
-+           }
-+           else {
-+                /* plymouth might have been running but did not display
-+                * a splash screen.
-+                */ 
-+               
-+                /* call plymouth quit and start the X server as usual */
-+                d->plymouth_is_running = !plymouth_quit_without_transition ();
+                     return;
+                 }
+-          next: ;
++            } else {
++                plymouth_quit_without_transition ();
 +            }
-+
 +        /* fallback to old/deprecated method */
 +        } else if ( triggered_to_force_display_on_active_vt() >= 0 ) {
-+            int vt;
-+            vt = get_active_vt();
-+            if (vt > 0) {
++            int vt = get_active_vt ();
++            if (allowedVTs[vt]) {
 +                d->serverVT = vt;
 +                return;
 +            }
 +        }
 +
-+      
-         if (d->reqSrvVT && d->reqSrvVT < 16) {
-             d->serverVT = d->reqSrvVT;
-         } else {
++        logError("Active VT: %d, busy mask: 0x%x\n", get_active_vt(), getBusyVTs());
++        for (tvt = 0; tvt < 16; tvt++) {
++            if ((allowedVTs[tvt] == 1) ||
++                ((allowedVTs[tvt] == 2) && !((1 << tvt) & getBusyVTs()))) {
++                d->serverVT = tvt;
++                return;
++            }
++        }
++
++        for (cd = displays; cd; cd = cd->next) {
++            if ((cd->status == zombie) && (cd->zstatus != DS_REMOTE) &&
++                (cd->follower == 0) && (cd->reqSrvVT != cd->serverVT)) {
++            /* removed; or restarted/reserved on any VT */
++                    d->serverVT = -1;
++                    cd->follower = d;
++                    return;
+             }
+         }
+     }
 diff -up kdebase-workspace-4.4.92/kdm/backend/dm.h.kdm_plymouth kdebase-workspace-4.4.92/kdm/backend/dm.h
 --- kdebase-workspace-4.4.92/kdm/backend/dm.h.kdm_plymouth	2010-07-06 01:54:30.000000000 -0500
 +++ kdebase-workspace-4.4.92/kdm/backend/dm.h	2010-07-07 13:48:11.874921158 -0500
@@ -139,7 +230,7 @@ diff -up kdebase-workspace-4.4.92/kdm/backend/dm.h.kdm_plymouth kdebase-workspac
  };
  
  #define d_location   1
-@@ -404,6 +406,8 @@ int anyDisplaysLeft(void);
+@@ -428,6 +430,8 @@ int anyDisplaysLeft(void);
  void forEachDisplay(void (*f)(struct display *));
  #ifdef HAVE_VTS
  void forEachDisplayRev(void (*f)(struct display *));
@@ -156,10 +247,11 @@ diff -up kdebase-workspace-4.4.92/kdm/backend/server.c.kdm_plymouth kdebase-work
      d->serverStatus = ignore;
      serverTimeout = TO_INF;
 +    if (d->plymouth_is_running) {
-+        debug( "Quitting Plymouth with transition\n" );
++        logError( "Quitting Plymouth with transition\n" );
 +        d->plymouth_is_running = !plymouth_quit_with_transition ();
-+        debug ("Is Plymouth still running? %s\n", d->plymouth_is_running ? "yes" : "no");
++        logError ("Is Plymouth still running? %s\n", d->plymouth_is_running ? "yes" : "no");
 +    }
      debug("X server ready, starting session\n");
      startDisplayP2(d);
  }
+ 
\ No newline at end of file


More information about the scm-commits mailing list