[pkg-fso-commits] [SCM] Automatic Display Manager branch, bug540201, updated. debian/0.6-1-52-g7a268a7

Enrico Zini enrico at enricozini.org
Wed Jul 6 19:13:32 UTC 2011


The following commit has been merged in the bug540201 branch:
commit 361289e062c2d84183ce4d88d2bcff3848aae4b9
Author: Enrico Zini <enrico at enricozini.org>
Date:   Wed Jul 6 17:46:15 2011 +0200

    Implemented --nested to be a user session manager for nested X servers

diff --git a/README b/README
index 627ee03..85a3c74 100644
--- a/README
+++ b/README
@@ -22,13 +22,17 @@ of least surprise.  This is what is offered:
    setting up the session via PAM, updating lastlog, logging to syslog.
  - nodm performs VT allocation, looking for a free virtual terminal in which to
    run X and keeping it allocated across X restarts.
- - X is started (by default, /usr/bin/X), nodm waits until it is ready to
-   accept connections and then runs a standard X session script (by default,
-   /etc/X11/Xsession).
+ - X is started (by default, /usr/bin/X)
+ - once the X esrver is ready to accept connections, the X session is set up:
+    - the DISPLAY and WINDOWPATH environment variables are set
+    - the session is wrapped in a PAM session, which sets up the user
+      environment
+    - ~/.xsession-error is truncated if it exists
+ - The session script is run (by default, /etc/X11/Xsession) using "sh -l"
  - If the X server or the X session exit, the other is killed and then both are
    restarted.
  - If a session exits too soon, nodm will wait a bit before restarting.  The
-   waiting time go as follow:
+   waiting times go as follow:
     - The first time the session exits too soon, restart immediately
     - The second and third time, wait 30 seconds
     - All remaining times, wait 1 minute.
diff --git a/dm.c b/dm.c
index 57639ce..2b31ea8 100644
--- a/dm.c
+++ b/dm.c
@@ -29,6 +29,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <time.h>
 
 
 void nodm_display_manager_init(struct nodm_display_manager* dm)
@@ -265,7 +266,23 @@ int nodm_display_manager_wait_restart_loop(struct nodm_display_manager* dm)
         {
             log_warn("session lasted less than %d seconds: sleeping %d seconds before restarting it",
                     dm->conf_minimum_session_time, retry_times[restart_count]);
-            sleep(retry_times[restart_count]);
+            struct timespec tosleep = { .tv_sec = retry_times[restart_count], .tv_nsec = 0 };
+            struct timespec remaining;
+            while (true)
+            {
+                int r = nanosleep(&tosleep, &remaining);
+                if (r != -1)
+                    break;
+                else if (errno == EINTR)
+                {
+                    tosleep = remaining;
+                }
+                else
+                {
+                    log_warn("sleep aborted: %m (ignoring error");
+                    break;
+                }
+            }
         }
 
         log_info("restarting session");
diff --git a/nodm.c b/nodm.c
index 8f4a930..d497012 100644
--- a/nodm.c
+++ b/nodm.c
@@ -42,12 +42,14 @@
 
 static void do_help(int argc, char** argv, FILE* out)
 {
-	fprintf(out, "Usage: %s [options]\n\n", argv[0]);
-	fprintf(out, "Options:\n");
-	fprintf(out, " --help         print this help message\n");
-	fprintf(out, " --version      print %s's version number\n", NAME);
-	fprintf(out, " --session=cmd  run cmd instead of %s\n", NODM_SESSION);
-	fprintf(out, "                (use for testing)\n");
+    fprintf(out, "Usage: %s [options]\n\n", argv[0]);
+    fprintf(out, "Options:\n");
+    fprintf(out, " --help      print this help message\n");
+    fprintf(out, " --version   print %s's version number\n", NAME);
+    fprintf(out, " --verbose   verbose outpout or logging\n");
+    fprintf(out, " --nested    run a nested X server, does not require root.");
+    fprintf(out, "             The server defaults to \"/usr/bin/Xnest :1\",");
+    fprintf(out, "             override with NODM_X_OPTIONS\n");
 }
 
 
@@ -63,13 +65,18 @@ int main (int argc, char **argv)
 {
     static int opt_help = 0;
     static int opt_version = 0;
+    static int opt_verbose = 0;
+    static int opt_nested = 0;
     static struct option options[] =
     {
         /* These options set a flag. */
         {"help",    no_argument,       &opt_help, 1},
         {"version", no_argument,       &opt_version, 1},
+        {"verbose", no_argument,       &opt_verbose, 1},
+        {"nested",  no_argument,       &opt_nested, 1},
         {0, 0, 0, 0}
     };
+    // TODO: implement --no-syslog --no-stderr and the like
 
     // Parse command line options
     while (1)
@@ -98,34 +105,58 @@ int main (int argc, char **argv)
     }
 
     // We only run if we are root
-    if (getuid() != 0)
+    if (!opt_nested && getuid() != 0)
     {
         fprintf(stderr, "%s: can only be run by root\n", basename(argv[0]));
         return E_NOPERM;
     }
 
-    // TODO: implement --verbose --no-syslog --no-stderr and the like
+    // Setup logging
     struct log_config cfg = {
         .program_name = basename(argv[0]),
-        .log_to_syslog = true,
-        .log_to_stderr = false,
-        .info_to_stderr = false,
-        .verbose = false
+        .verbose = opt_verbose
     };
+    if (opt_nested)
+    {
+        cfg.log_to_syslog = false;
+        cfg.log_to_stderr = true;
+        cfg.info_to_stderr = opt_verbose;
+    } else {
+        cfg.log_to_syslog = true;
+        cfg.log_to_stderr = false;
+        cfg.info_to_stderr = false;
+    }
     log_start(&cfg);
 
     log_info("starting nodm");
 
-    // Run the display manager
+    // Setup the display manager
     struct nodm_display_manager dm;
     nodm_display_manager_init(&dm);
 
-    int res = nodm_display_manager_parse_xcmdline(&dm, getenv_with_default("NODM_X_OPTIONS", ""));
+    // Choose the default X server
+    const char* default_x_server = opt_nested ? "/usr/bin/Xnest :1" : "";
+
+    // Parse X server command line
+    int res = nodm_display_manager_parse_xcmdline(&dm,
+            getenv_with_default("NODM_X_OPTIONS", default_x_server));
     if (res != E_SUCCESS) goto cleanup;
 
+    if (opt_nested)
+    {
+        // For nested servers, disable PAM, user change, ~/.xsession-error
+        // cleanup and VT allocation
+        dm.session.conf_use_pam = false;
+        dm.session.conf_cleanup_xse = false;
+        dm.session.conf_run_as[0] = 0;
+        dm.vt.conf_initial_vt = -1;
+    }
+
+    // Start the first session
     res = nodm_display_manager_start(&dm);
     if (res != E_SUCCESS) goto cleanup;
 
+    // Enter the wait/restart loop
     res = nodm_display_manager_wait_restart_loop(&dm);
     if (res != E_SUCCESS) goto cleanup;
 

-- 
Automatic Display Manager



More information about the pkg-fso-commits mailing list