Samba 2.2.4 & daemontools

Michael Handler handler-list-samba-technical at grendel.net
Mon May 13 22:12:02 GMT 2002


I'm trying to run smbd and nmbd under Dan Bernstein's supervise &
svscan process control programs from his daemontools package
(http://cr.yp.to/daemontools.html). Jos Backus has raised this issue
in the past, re: the -i "interactive" flag and making smbd and nmbd
create their own process groups, but unfortunately the -i flag isn't
sufficient to make smbd run correctly under daemontools, as it makes
smbd only answer the first connection comes in. Additionally, the
-i flag forces smbd and nmbd to log to stdout, which may not be
desireable in all situations.

Attached please find a set of patches against Samba 2.2.4 to make
the following changes:

* smbd, nmbd, and winbindd now all have -S and -F options. The -S flag
  means log to stdout. The -F flag makes the daemons run in the
  foreground properly for use under daemontools, e.g. all operations
  are normal, setsid(2) is called for process group creation, but the
  fork(2)/exit pair and the closing of fd's 0, 1, and 2 (for rsh) are
  skipped.

* when setup_logging() selects stdout to write all logs to, it sets
  that filedescriptor to "unbuffered" to ensure that logs are written out
  promptly, especially under multilog (from daemontools).

Samba team members, if this code and changes are acceptable to you,
I would appreciate being told what work I need to do in order to
ensure that this functionality is rolled forward into Samba 3.0 and
forward, and what documentation patches I should submit for both
2.0 and 3.0.

If this code or changes are unacceptable for any reason, please don't
hesitate to let me know so we can begin a dialogue about the proper way
to implement this functionality into Samba.

Thank you all very much for your excellent work on Samba over the years.

--michael

-- 
handler at grendel.net (michael handler)                           washington, dc
-------------- next part --------------
diff -x configure -x *.in -ur /home/handler/src/samba-2.2.4/source/include/proto.h work/samba-2.2.4/source/include/proto.h
--- /home/handler/src/samba-2.2.4/source/include/proto.h	Thu May  2 21:03:05 2002
+++ work/samba-2.2.4/source/include/proto.h	Mon May 13 20:51:26 2002
@@ -1125,7 +1125,7 @@
 						ssize_t (*write_fn)(int, const void *, size_t));
 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n);
 void msleep(unsigned int t);
-void become_daemon(void);
+void become_daemon(BOOL fork);
 BOOL yesno(char *p);
 void *Realloc(void *p,size_t size);
 void safe_free(void *p);
diff -x configure -x *.in -ur /home/handler/src/samba-2.2.4/source/lib/debug.c work/samba-2.2.4/source/lib/debug.c
--- /home/handler/src/samba-2.2.4/source/lib/debug.c	Thu May  2 21:03:07 2002
+++ work/samba-2.2.4/source/lib/debug.c	Mon May 13 22:36:00 2002
@@ -291,6 +291,7 @@
 	if (interactive) {
 		stdout_logging = True;
 		dbf = stdout;
+		setbuf(stdout, NULL);
 	}
 #ifdef WITH_SYSLOG
 	else {
diff -x configure -x *.in -ur /home/handler/src/samba-2.2.4/source/lib/util.c work/samba-2.2.4/source/lib/util.c
--- /home/handler/src/samba-2.2.4/source/lib/util.c	Thu May  2 21:03:11 2002
+++ work/samba-2.2.4/source/lib/util.c	Mon May 13 20:49:52 2002
@@ -607,10 +607,12 @@
  Become a daemon, discarding the controlling terminal.
 ****************************************************************************/
 
-void become_daemon(void)
+void become_daemon(BOOL fork)
 {
-	if (sys_fork()) {
-		_exit(0);
+	if (fork) {
+		if (sys_fork()) {
+			_exit(0);
+		}
 	}
 
   /* detach from the terminal */
@@ -626,8 +628,10 @@
 	}
 #endif /* HAVE_SETSID */
 
-	/* Close fd's 0,1,2. Needed if started by rsh */
-	close_low_fds();
+	if (fork) {
+		/* Close fd's 0,1,2. Needed if started by rsh */
+		close_low_fds();
+	}
 }
 
 /****************************************************************************
diff -x configure -x *.in -ur /home/handler/src/samba-2.2.4/source/nmbd/nmbd.c work/samba-2.2.4/source/nmbd/nmbd.c
--- /home/handler/src/samba-2.2.4/source/nmbd/nmbd.c	Thu May  2 21:03:17 2002
+++ work/samba-2.2.4/source/nmbd/nmbd.c	Mon May 13 23:09:47 2002
@@ -643,9 +643,11 @@
 static void usage(char *pname)
 {
 
-  printf( "Usage: %s [-DaiohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
+  printf( "Usage: %s [-DFSaiohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
   printf( "       [-n name] [-p port] [-s configuration file]\n" );
   printf( "\t-D                    Become a daemon (default)\n" );
+  printf( "\t-F                    Run daemon in foreground (for daemontools, etc)\n" );
+  printf( "\t-S                    Log to stdout\n" );
   printf( "\t-a                    Append to log file (default)\n" );
   printf( "\t-i                    Run interactive (not a daemon)\n" );
   printf( "\t-o                    Overwrite log file, don't append\n" );
@@ -673,6 +675,8 @@
   extern BOOL  append_log;
   extern BOOL AllowDebugChange;
   BOOL opt_interactive = False;
+  BOOL fork = True;
+  BOOL log_stdout = False;
   pstring logfile;
 
   append_log = True;  /* Default, override with '-o' option. */
@@ -725,10 +729,16 @@
 #endif
 
   while( EOF != 
-         (opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dip:hSH:G:f:" )) )
+         (opt = getopt( argc, argv, "FSVaos:T:I:C:bAB:N:Rn:l:d:Dip:hH:G:f:" )) )
     {
       switch (opt)
         {
+        case 'F':
+          fork = False;
+          break;
+        case 'S':
+          log_stdout = True;
+          break;
         case 's':
           pstrcpy(servicesf,optarg);
           break;          
@@ -758,6 +768,8 @@
           break;
         case 'i':
           opt_interactive = True;
+          log_stdout = True;
+          fork = False; /* for stdout logging check below */
           break;
         case 'D':
           is_daemon = True;
@@ -788,7 +800,13 @@
         }
     }
 
-  setup_logging( argv[0], opt_interactive );
+  if (log_stdout && fork) {
+    printf("Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n");
+    usage(argv[0]);
+    exit(1);
+  }
+
+  setup_logging( argv[0], log_stdout );
   reopen_logs();
 
   DEBUG( 0, ( "Netbios nameserver version %s started.\n", VERSION ) );
@@ -830,7 +848,7 @@
   if (is_daemon && !opt_interactive)
   {
     DEBUG( 2, ( "Becoming a daemon.\n" ) );
-    become_daemon();
+    become_daemon(fork);
   }
 
 #if HAVE_SETPGID
diff -x configure -x *.in -ur /home/handler/src/samba-2.2.4/source/nsswitch/winbindd.c work/samba-2.2.4/source/nsswitch/winbindd.c
--- /home/handler/src/samba-2.2.4/source/nsswitch/winbindd.c	Thu May  2 21:03:20 2002
+++ work/samba-2.2.4/source/nsswitch/winbindd.c	Mon May 13 23:04:07 2002
@@ -666,6 +666,8 @@
 static void usage(void)
 {
 	printf("Usage: winbindd [options]\n");
+	printf("\t-F                daemon in foreground mode\n");
+	printf("\t-S                log to stdout\n");
 	printf("\t-i                interactive mode\n");
 	printf("\t-n                disable cacheing\n");
 	printf("\t-d level          set debug level\n");
@@ -682,6 +684,8 @@
 	pstring logfile;
 	int accept_sock;
 	BOOL interactive = False;
+	BOOL fork = True;
+	BOOL log_stdout = False;
 	int opt;
 
 	/* glibc (?) likes to print "User defined signal 1" and exit if a
@@ -707,12 +711,20 @@
 
 	/* Initialise samba/rpc client stuff */
 
-	while ((opt = getopt(argc, argv, "id:s:nh")) != EOF) {
+	while ((opt = getopt(argc, argv, "FSid:s:nh")) != EOF) {
 		switch (opt) {
 
+		case 'F':
+			fork = False;
+			break;
+		case 'S':
+			log_stdout = True;
+			break;
 			/* Don't become a daemon */
 		case 'i':
 			interactive = True;
+			log_stdout = True;
+			fork = False; /* for stdout logging check below */
 			break;
 
 			/* disable cacheing */
@@ -741,6 +753,13 @@
 		}
 	}
 
+        if (log_stdout && fork) {
+                printf("Can't log to stdout (-S) unless daemon is in foreground
+(-F) or interactive (-i)\n");
+                usage();
+                exit(1);
+        }
+
 	/* Append to log file by default as we are a single process daemon
 	   program. */
 
@@ -749,7 +768,7 @@
 	snprintf(logfile, sizeof(logfile), "%s/log.winbindd", LOGFILEBASE);
 	lp_set_logfile(logfile);
 
-	setup_logging("winbindd", interactive);
+	setup_logging("winbindd", log_stdout);
 	reopen_logs();
 
 	DEBUG(1, ("winbindd version %s started.\n", VERSION ) );
@@ -778,7 +797,7 @@
         fstrcpy(global_myworkgroup, lp_workgroup());
 
 	if (!interactive)
-		become_daemon();
+		become_daemon(fork);
 
 #if HAVE_SETPGID
 	/*
diff -x configure -x *.in -ur /home/handler/src/samba-2.2.4/source/smbd/server.c work/samba-2.2.4/source/smbd/server.c
--- /home/handler/src/samba-2.2.4/source/smbd/server.c	Thu May  2 21:03:49 2002
+++ work/samba-2.2.4/source/smbd/server.c	Mon May 13 22:53:38 2002
@@ -536,9 +536,11 @@
 static void usage(char *pname)
 {
 
-	printf("Usage: %s [-DaioPh?V] [-d debuglevel] [-l log basename] [-p port]\n", pname);
+	printf("Usage: %s [-DFSaioPh?V] [-d debuglevel] [-l log basename] [-p port]\n", pname);
 	printf("       [-O socket options] [-s services file]\n");
 	printf("\t-D                    Become a daemon (default)\n");
+	printf("\t-F                    Run daemon in foreground (for daemontools, etc)\n");
+	printf("\t-S                    Log to stdout\n");
 	printf("\t-a                    Append to log file (default)\n");
 	printf("\t-i                    Run interactive (not a daemon)\n");
 	printf("\t-o                    Overwrite log file, don't append\n");
@@ -563,6 +565,8 @@
 	extern BOOL AllowDebugChange;
 	/* shall I run as a daemon */
 	BOOL is_daemon = False;
+	BOOL fork = True;
+	BOOL log_stdout = False;
 	BOOL interactive = False;
 	BOOL specified_logfile = False;
 	int port = SMB_PORT;
@@ -580,7 +584,7 @@
 		argc--;
 	}
 
-	while ( EOF != (opt = getopt(argc, argv, "O:l:s:d:Dip:h?Vaof:")) )
+	while ( EOF != (opt = getopt(argc, argv, "O:l:s:d:DFSip:h?Vaof:")) )
 		switch (opt)  {
 		case 'O':
 			pstrcpy(user_socket_options,optarg);
@@ -608,8 +612,18 @@
 			is_daemon = True;
 			break;
 
+		case 'F':
+			fork = False;
+			break;
+
+		case 'S':
+			log_stdout = True;
+			break;
+
 		case 'i':
 			interactive = True;
+			log_stdout = True;
+			fork = False; /* for stdout logging check below */
 			break;
 
 		case 'd':
@@ -640,6 +654,12 @@
 			exit(1);
 		}
 
+	if (log_stdout && fork) {
+		printf("Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n");
+		usage(argv[0]);
+		exit(1);
+	}
+
 #ifdef HAVE_SETLUID
 	/* needed for SecureWare on SCO */
 	setluid(0);
@@ -658,7 +678,7 @@
 
 	pstrcpy(remote_machine, "smbd");
 
-	setup_logging(argv[0],interactive);
+	setup_logging(argv[0],log_stdout);
 
 	charset_initialise();
 
@@ -760,7 +780,7 @@
 
 	if (is_daemon && !interactive) {
 		DEBUG( 3, ( "Becoming a daemon.\n" ) );
-		become_daemon();
+		become_daemon(fork);
 	}
 
 #if HAVE_SETPGID
diff -x configure -x *.in -ur /home/handler/src/samba-2.2.4/source/web/startstop.c work/samba-2.2.4/source/web/startstop.c
--- /home/handler/src/samba-2.2.4/source/web/startstop.c	Mon Dec 13 08:27:57 1999
+++ work/samba-2.2.4/source/web/startstop.c	Mon May 13 22:58:15 2002
@@ -39,7 +39,7 @@
 
 	slprintf(binfile, sizeof(pstring) - 1, "%s/smbd", SBINDIR);
 
-	become_daemon();
+	become_daemon(True);
 
 	execl(binfile, binfile, "-D", NULL);
 
@@ -60,7 +60,7 @@
 
 	slprintf(binfile, sizeof(pstring) - 1, "%s/nmbd", SBINDIR);
 	
-	become_daemon();
+	become_daemon(True);
 
 	execl(binfile, binfile, "-D", NULL);
 


More information about the samba-technical mailing list