lists.arthurdejong.org
RSS feed

Re: [nss-pam-ldapd] proposed patch for mutexing the daemon

[Date Prev][Date Next] [Thread Prev][Thread Next]

Re: [nss-pam-ldapd] proposed patch for mutexing the daemon



Followup on a private email conversation with Arthur about daemon mutex:

>> - use the same to implement a --check option

Attached is a patch that kinda implements a --check option to be used by
the user or from shell scripts.

The --check (-c) option makes nslcd check if it COULD aquire a lock and
thus tests if a daemon is already running (has the lock).

The exit code is 0 (shell TRUE) if the locking fails, 1 (shell FALSE) if
it succeeds (which is exactly the opposite logic of what it needs to do
when checking for mutex - of course).

The code attempts to
- not break too much of your style habbits
- not duplicate existing code

For this purposes I needed to introduce a boolean variable that is set
by the commandline argument parser and conditionally used by main(). The
test_lock() function needs to be boolean and must not exit() the
program. If you see a better way without mixing up the way main()
currently works, feel free.

Along with other main() changes, this code maybe could be beautified in
future.

I also changed man/nslcd.8.xml, though I didn't test it.

Regards,
TheBonsai
--- nss-pam-ldapd/nslcd/nslcd.c	2010-01-23 14:33:40.000000000 +0100
+++ nss-pam-ldapd.new/nslcd/nslcd.c	2010-01-25 20:41:11.000000000 +0100
@@ -72,6 +72,9 @@
 /* flag to indictate if we are in debugging mode */
 static int nslcd_debugging=0;
 
+/* flag to indicate user requested the --check option */
+static int nslcd_checkonly=0;
+
 /* the exit flag to indicate that a signal was received */
 static volatile int nslcd_exitsignal=0;
 
@@ -112,6 +115,7 @@
 {
   fprintf(fp,"Usage: %s [OPTION]...\n",program_name);
   fprintf(fp,"Name Service LDAP connection daemon.\n");
+  fprintf(fp,"  -c, --check        check if the daemon already is running\n");
   fprintf(fp,"  -d, --debug        don't fork and print debugging to stderr\n");
   fprintf(fp,"      --help         display this help and exit\n");
   fprintf(fp,"      --version      output version information and exit\n");
@@ -122,12 +126,13 @@
 /* the definition of options for getopt(). see getopt(2) */
 static struct option const nslcd_options[] =
 {
+  { "check",       no_argument,       NULL, 'c' },
   { "debug",       no_argument,       NULL, 'd' },
   { "help",        no_argument,       NULL, 'h' },
   { "version",     no_argument,       NULL, 'V' },
   { NULL, 0, NULL, 0 }
 };
-#define NSLCD_OPTIONSTRING "dhV"
+#define NSLCD_OPTIONSTRING "cdhV"
 
 /* parse command line options and save settings in struct  */
 static void parse_cmdline(int argc,char *argv[])
@@ -137,6 +142,9 @@
   {
     switch (optc)
     {
+    case 'c': /* -c, --check        check if the daemon already is running */
+      nslcd_checkonly=1;
+      break;
     case 'd': /* -d, --debug        don't fork and print debugging to stderr */
       nslcd_debugging++;
       log_setdefaultloglevel(LOG_DEBUG);
@@ -468,7 +476,7 @@
 }
 
 /* test to see if we can lock the specified file */
-static void test_lock(const char* filename)
+static int test_lock(const char* filename)
 {
   int fd;
   if (filename!=NULL)
@@ -477,17 +485,21 @@
     if ((fd=open(filename,O_RDWR,0644))<0)
     {
       if (errno==ENOENT)
-        return; /* if file doesn't exist it cannot be locked */
-      log_log(LOG_ERR,"cannot open lock file (%s): %s",filename,strerror(errno));
-      exit(EXIT_FAILURE);
+        return 1; /* if file doesn't exist it cannot be locked, continue */
+      if (nslcd_checkonly==0) /* only make noise when --check wasn't given! */
+        log_log(LOG_ERR,"cannot open lock file (%s): %s",filename,strerror(errno));
+      return 0; /* false */
     }
     if (lockf(fd,F_TEST,0)<0)
     {
-      log_log(LOG_ERR,"daemon may already be active, cannot acquire lock (%s): %s",filename,strerror(errno));
-      exit(EXIT_FAILURE);
+      if (nslcd_checkonly==0)
+        log_log(LOG_ERR,"daemon may already be active, cannot acquire lock (%s): %s",filename,strerror(errno));
+      close(fd);
+      return 0; /* false */
     }
     close(fd);
   }
+  return 1; /* true */
 }
 
 /* write the current process id to the specified file */
@@ -593,8 +605,18 @@
   cfg_init(NSLCD_CONF_PATH);
   /* set default mode for pidfile and socket */
   (void)umask((mode_t)0022);
-  /* see if someone already locked the pidfile */
-  test_lock(NSLCD_PIDFILE);
+  /* see if someone already locked the pidfile
+     if --check option was given:
+       exit TRUE if daemon runs (lock failed), FALSE otherwise */
+  if (test_lock(NSLCD_PIDFILE)) {
+    if (nslcd_checkonly)
+      exit(EXIT_FAILURE);
+  } else {
+    if (nslcd_checkonly)
+      exit(EXIT_SUCCESS);
+    else
+      exit(EXIT_FAILURE);
+  }
   /* daemonize */
   if ((!nslcd_debugging)&&(daemon(0,0)<0))
   {
--- nss-pam-ldapd/man/nslcd.8.xml	2009-12-28 22:23:49.000000000 +0100
+++ nss-pam-ldapd.new/man/nslcd.8.xml	2010-01-25 21:01:46.000000000 +0100
@@ -78,6 +78,14 @@
   <variablelist remap="TP">
    <varlistentry>
     <term>
+     <option>-c, --check</option>
+    </term>
+    <listitem>
+     <para>Check if the daemon is running, exit 0 if yes, 1 if not.</para>
+    </listitem>
+    </varlistentry>
+    <varlistentry>
+    <term>
      <option>-d, --debug</option>
     </term>
     <listitem>
--
To unsubscribe send an email to
nss-pam-ldapd-users-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/nss-pam-ldapd-users