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

Enrico Zini enrico at enricozini.org
Wed Jul 6 15:20:43 UTC 2011


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

    Cleaned up wait/restart loop

diff --git a/dm.c b/dm.c
index f23ed6c..57639ce 100644
--- a/dm.c
+++ b/dm.c
@@ -28,6 +28,7 @@
 #include <sys/wait.h>
 #include <errno.h>
 #include <stdio.h>
+#include <unistd.h>
 
 
 void nodm_display_manager_init(struct nodm_display_manager* dm)
@@ -35,12 +36,15 @@ void nodm_display_manager_init(struct nodm_display_manager* dm)
     nodm_xserver_init(&dm->srv);
     nodm_xsession_init(&dm->session);
     nodm_vt_init(&dm->vt);
+    dm->conf_minimum_session_time = atoi(getenv_with_default("NODM_MIN_SESSION_TIME", "60"));
     dm->_srv_split_args = NULL;
     dm->_srv_split_argv = NULL;
 }
 
 void nodm_display_manager_cleanup(struct nodm_display_manager* dm)
 {
+    nodm_vt_stop(&dm->vt);
+
     // Deallocate parsed arguments, if used
     if (dm->_srv_split_args)
     {
@@ -73,7 +77,17 @@ int nodm_display_manager_start(struct nodm_display_manager* dm)
         *s = NULL;
     }
 
-    res = nodm_xserver_start(&dm->srv);
+    dm->last_session_start = time(NULL);
+
+    res = nodm_display_manager_restart(dm);
+    if (res != E_SUCCESS) return res;
+
+    return E_SUCCESS;
+}
+
+int nodm_display_manager_restart(struct nodm_display_manager* dm)
+{
+    int res = nodm_xserver_start(&dm->srv);
     if (res != E_SUCCESS) return res;
 
     res = nodm_xsession_start(&dm->session, &dm->srv);
@@ -90,8 +104,6 @@ int nodm_display_manager_stop(struct nodm_display_manager* dm)
     res = nodm_xserver_stop(&dm->srv);
     if (res != E_SUCCESS) return res;
 
-    nodm_vt_stop(&dm->vt);
-
     return E_SUCCESS;
 }
 
@@ -214,3 +226,50 @@ void nodm_display_manager_dump_status(struct nodm_display_manager* dm)
     nodm_xserver_dump_status(&dm->srv);
     nodm_xsession_dump_status(&dm->session);
 }
+
+int nodm_display_manager_wait_restart_loop(struct nodm_display_manager* dm)
+{
+    static int retry_times[] = { 0, 0, 30, 30, 60, 60, -1 };
+    int restart_count = 0;
+    int res;
+
+    while (1)
+    {
+        int sstatus;
+        res = nodm_display_manager_wait(dm, &sstatus);
+        time_t end = time(NULL);
+        nodm_display_manager_stop(dm);
+
+        switch (res)
+        {
+            case E_X_SERVER_DIED:
+                break;
+            case E_SESSION_DIED:
+                log_info("X session quit with status %d", sstatus);
+                break;
+            default:
+                return res;
+        }
+
+        /* Check if the session was too short */
+        if (end - dm->last_session_start < dm->conf_minimum_session_time)
+        {
+            if (retry_times[restart_count+1] != -1)
+                ++restart_count;
+        }
+        else
+            restart_count = 0;
+
+        /* Sleep a bit if the session was too short */
+        if (retry_times[restart_count] > 0)
+        {
+            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]);
+        }
+
+        log_info("restarting session");
+        res = nodm_display_manager_restart(dm);
+        if (res != E_SUCCESS) return res;
+    }
+}
diff --git a/dm.h b/dm.h
index e10d504..051965e 100644
--- a/dm.h
+++ b/dm.h
@@ -24,6 +24,7 @@
 #include "xserver.h"
 #include "xsession.h"
 #include "vt.h"
+#include <time.h>
 
 struct nodm_display_manager
 {
@@ -36,6 +37,15 @@ struct nodm_display_manager
     /// VT allocation
     struct nodm_vt vt;
 
+    /** 
+     * The minimum time (in seconds) that a session should last to be
+     * considered successful
+     */
+    int conf_minimum_session_time;
+
+    /// Time the last session started
+    time_t last_session_start;
+
     /// Storage for split server arguments used by nodm_x_cmdline_split
     char** _srv_split_argv;
     void* _srv_split_args;
@@ -53,15 +63,26 @@ void nodm_display_manager_cleanup(struct nodm_display_manager* dm);
 /// Start X and the X session
 int nodm_display_manager_start(struct nodm_display_manager* dm);
 
+/// Restart X and the X session after they died
+int nodm_display_manager_restart(struct nodm_display_manager* dm);
+
 /// Wait for X or the X session to end
 int nodm_display_manager_wait(struct nodm_display_manager* dm, int* session_status);
 
-// TODO: int nodm_display_manager_restart(struct nodm_display_manager* dm);
-
 /// Stop X and the X session
 int nodm_display_manager_stop(struct nodm_display_manager* dm);
 
 /**
+ * nodm wait/restart loop.
+ *
+ * Wait for the X server or session to terminate and restart them.
+ *
+ * If the session was very short-lived, it wants for an incremental amount of
+ * time before restarting it.
+ */
+int nodm_display_manager_wait_restart_loop(struct nodm_display_manager* dm);
+
+/**
  * Split xcmdline using wordexp shell-like expansion and set dm->srv.argv.
  *
  * If the first token starts with '/' or '.', it is used as the X server, else
diff --git a/nodm.c b/nodm.c
index 9b95a3e..8f4a930 100644
--- a/nodm.c
+++ b/nodm.c
@@ -40,96 +40,7 @@
 #include <time.h>
 #include <unistd.h>
 
-
-#define _(...) (__VA_ARGS__)
-
-/* Program name used in error messages */
-static const char *Prog;
-
-/*
- * Run the X session
- *
- * @param xsession
- *   The path to the X session
- * @param xoptions
- *   X options (can be NULL if no options are to be passed)
- * @param mst
- *   The minimum time (in seconds) that a session should last to be considered
- *   successful
- */
-void run_and_restart(const char* xsession, const char* xoptions, int mst)
-{
-	static int retry_times[] = { 0, 0, 30, 30, 60, 60, -1 };
-	int restart_count = 0;
-    /*
-	char command[BUFSIZ];
-	const char* args[4];
-
-	if (xoptions != NULL)
-		snprintf(command, BUFSIZ, "exec %s %s -- %s", xinit, xsession, xoptions);
-	else
-		snprintf(command, BUFSIZ, "exec %s %s", xinit, xsession);
-	command[BUFSIZ-1] = 0;
-
-	args[0] = "/bin/sh";
-	args[1] = "-c";
-	args[2] = command;
-	args[3] = 0;
-    */
-
-	while (1)
-	{
-        struct nodm_display_manager dm;
-        nodm_display_manager_init(&dm);
-
-        int status = nodm_display_manager_parse_xcmdline(&dm, xoptions);
-        if (status != E_SUCCESS)
-            exit(status);
-
-		/* Run the X server */
-		time_t begin = time(NULL);
-		time_t end;
-        // TODO status = nodm_x_with_session(&s);
-        log_info("X session exited with status %d", status);
-        end = time(NULL);
-        nodm_display_manager_cleanup(&dm);
-
-		/* Check if the session was too short */
-		if (end - begin < mst)
-		{
-            log_warn("session was shorter than %d seconds: possible problems", mst);
-			if (retry_times[restart_count+1] != -1)
-				++restart_count;
-		}
-		else
-			restart_count = 0;
-
-		/* Sleep a bit if the session was too short */
-		sleep(retry_times[restart_count]);
-        log_info("restarting session");
-	}
-}
-
-/*
- * Copy from the environment the value of $name into dest.
- *
- * If $name is not in the environment, use def.
- *
- * @param destination buffer, should be at least BUFSIZ long
- * @param name name of the environment variable to look up
- * @param def default value to use if $name is not found
- */
-static void string_from_env(char* dest, const char* name, const char* def)
-{
-	char* cp = getenv(name);
-	if (cp != NULL)
-		strncpy(dest, cp, BUFSIZ-1);
-	else
-		strncpy(dest, def, BUFSIZ-1);
-	dest[BUFSIZ-1] = 0;
-}
-
-static void monitor_cmdline_help(int argc, char** argv, FILE* out)
+static void do_help(int argc, char** argv, FILE* out)
 {
 	fprintf(out, "Usage: %s [options]\n\n", argv[0]);
 	fprintf(out, "Options:\n");
@@ -139,73 +50,6 @@ static void monitor_cmdline_help(int argc, char** argv, FILE* out)
 	fprintf(out, "                (use for testing)\n");
 }
 
-/*
- * Start the monitor, that will continue to rerun xinit with appropriate delays
- */
-static int nodm_monitor(int argc, char **argv)
-{
-	static int opt_help = 0;
-	static int opt_version = 0;
-	static struct option options[] =
-	{
-		/* These options set a flag. */
-		{"help",    no_argument,       &opt_help, 1},
-		{"version", no_argument,       &opt_version, 1},
-		{"session", required_argument, 0, 's'},
-		{0, 0, 0, 0}
-	};
-	const char* opt_session = NODM_SESSION;
-	char xoptions[BUFSIZ];
-	char* cp;
-	int mst;
-
-	/* Parse command line options */
-	while (1)
-	{
-		int option_index = 0;
-		int c = getopt_long(argc, argv, "s:", options, &option_index);
-		if (c == -1) break;
-		switch (c)
-		{
-			case 0: break;
-			case 's': opt_session = optarg; break;
-			default:
-				  fprintf(stderr, "Invalid command line option\n");
-				  monitor_cmdline_help(argc, argv, stderr);
-				  return 1;
-		}
-	}
-	if (opt_help)
-	{
-		monitor_cmdline_help(argc, argv, stdout);
-		return 0;
-	}
-	if (opt_version)
-	{
-		printf("%s version %s\n", NAME, VERSION);
-		return 0;
-	}
-
-	/* We only run if we are root */
-	if (getuid() != 0)
-	{
-		fprintf (stderr, _("%s: can only be run by root\n"), Prog);
-		return E_NOPERM;
-	}
-
-	log_info("starting nodm monitor");
-
-	/* Read the configuration from the environment */
-	cp = getenv("NODM_MIN_SESSION_TIME");
-	mst = cp ? atoi(cp) : 60;
-	string_from_env(xoptions, "NODM_X_OPTIONS", "");
-
-	setenv("NODM_RUN_SESSION", "1", 1);
-	run_and_restart(opt_session, xoptions, mst);
-
-	return 0;
-}
-
 
 /*
  * nodm - start X with autologin to a given user
@@ -217,28 +61,76 @@ static int nodm_monitor(int argc, char **argv)
  */
 int main (int argc, char **argv)
 {
-	/*
-	 * Get the program name. The program name is used as a prefix to
-	 * most error messages.
-	 */
-	Prog = basename(argv[0]);
-
-    // TODO: move these after command line parsing, so we can implement
-    // --verbose --no-syslog --no-stderr and the like
+    static int opt_help = 0;
+    static int opt_version = 0;
+    static struct option options[] =
+    {
+        /* These options set a flag. */
+        {"help",    no_argument,       &opt_help, 1},
+        {"version", no_argument,       &opt_version, 1},
+        {0, 0, 0, 0}
+    };
+
+    // Parse command line options
+    while (1)
+    {
+        int option_index = 0;
+        int c = getopt_long(argc, argv, ":", options, &option_index);
+        if (c == -1) break;
+        switch (c)
+        {
+            case 0: break;
+            default:
+                fprintf(stderr, "Invalid command line option\n");
+                do_help(argc, argv, stderr);
+                return E_USAGE;
+        }
+    }
+    if (opt_help)
+    {
+        do_help(argc, argv, stdout);
+        return E_SUCCESS;
+    }
+    if (opt_version)
+    {
+        printf("%s version %s\n", NAME, VERSION);
+        return E_SUCCESS;
+    }
+
+    // We only run if we are root
+    if (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
     struct log_config cfg = {
-        .program_name = Prog,
+        .program_name = basename(argv[0]),
         .log_to_syslog = true,
-        .log_to_stderr = true,
+        .log_to_stderr = false,
         .info_to_stderr = false,
+        .verbose = false
     };
     log_start(&cfg);
 
-    /*
-     * Process the command line arguments. 
-     */
+    log_info("starting nodm");
+
+    // Run 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", ""));
+    if (res != E_SUCCESS) goto cleanup;
+
+    res = nodm_display_manager_start(&dm);
+    if (res != E_SUCCESS) goto cleanup;
 
-    int ret = nodm_monitor(argc, argv);
+    res = nodm_display_manager_wait_restart_loop(&dm);
+    if (res != E_SUCCESS) goto cleanup;
 
+cleanup:
+    nodm_display_manager_cleanup(&dm);
     log_end();
-    return ret;
+    return res;
 }
diff --git a/xsession-child.c b/xsession-child.c
index 18a6e23..a483d36 100644
--- a/xsession-child.c
+++ b/xsession-child.c
@@ -327,7 +327,6 @@ int nodm_xsession_child_common_env(struct nodm_xsession_child* s)
     unsetenv("NODM_XSESSION");
     unsetenv("NODM_X_OPTIONS");
     unsetenv("NODM_MIN_SESSION_TIME");
-    unsetenv("NODM_RUN_SESSION");
 
     // Move to home directory
     if (chdir(s->pwent.pw_dir) == 0)

-- 
Automatic Display Manager



More information about the pkg-fso-commits mailing list