diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index 8a71d446ced223be923eb385994069fa6b761359..b918b5d5715955900ae75bbdbff098ea6b792d7f 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.635 2007/10/31 22:08:03 chrfranke Exp $ +$Id: CHANGELOG,v 1.636 2007/11/01 20:53:29 chrfranke Exp $ The most recent version of this file is: http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup @@ -33,6 +33,10 @@ NOTES FOR FUTURE RELEASES: see TODO file. <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE> + [CF] smartd: Added option '-n, --no-fork' so that smartd works + better with modern init methods. Thanks to Enrico Scholz + for the patch from 2005-12-24. + [CF] Windows: Improved ATA/SCSI device type detection and DEVICESCAN. This also fixes a regression in 3ware DEVICESCAN. diff --git a/sm5/smartd.8.in b/sm5/smartd.8.in index 761aa3c950c66c68786b04cf9ff566f9b9b7621a..0b3708993f8149ab1fdd651abdd6eb48d14ce1e1 100644 --- a/sm5/smartd.8.in +++ b/sm5/smartd.8.in @@ -1,7 +1,7 @@ .ig Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net> -$Id: smartd.8.in,v 1.119 2007/10/20 13:02:50 chrfranke Exp $ +$Id: smartd.8.in,v 1.120 2007/11/01 20:53:29 chrfranke Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -251,6 +251,16 @@ messages from the event viewer. Use \'\fBsyslogevt -r smartd\fP\' to register, \'\fBsyslogevt -u smartd\fP\' to unregister and \'\fBsyslogevt\fP\' for more help. +.TP +.B \-n, \-\-no\-fork +Do not fork into background; this is useful when executed from modern +init methods like initng, minit or supervise. + +On Cygwin, this allows running \fBsmartd\fP as service via cygrunsrv, +see NOTES below. + +On Windows, this option is not available, use \'\-\-service\' instead. + .TP .B \-p NAME, \-\-pidfile=NAME Writes pidfile \fINAME\fP containing the \fBsmartd\fP Process ID @@ -347,8 +357,8 @@ equivalent. .B \-\-service Cygwin and Windows only: Enables \fBsmartd\fP to run as a Windows service. -On Cygwin, this option simply prevents forking into background mode to -allow running \fBsmartd\fP as service via cygrunsrv, see NOTES below. +On Cygwin, this option is kept for backward compatibility only. +It has the same effect as \'\-n, \-\-no\-fork\', see above. On Windows, this option enables the buildin service support. The option must be specified in the service command line as the first @@ -1955,4 +1965,4 @@ smartmontools home page at \fBhttp://smartmontools.sourceforge.net/#references\f .SH CVS ID OF THIS PAGE: -$Id: smartd.8.in,v 1.119 2007/10/20 13:02:50 chrfranke Exp $ +$Id: smartd.8.in,v 1.120 2007/11/01 20:53:29 chrfranke Exp $ diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp index dd6179d994c53f3b3c8d4d1140676a9bad690e2c..d7c8dcdd0c44303699a360764fef6c5b3537a3e0 100644 --- a/sm5/smartd.cpp +++ b/sm5/smartd.cpp @@ -119,14 +119,14 @@ extern "C" int getdomainname(char *, int); // no declaration in header files! extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *escalade_c_cvsid, *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid; -static const char *filenameandversion="$Id: smartd.cpp,v 1.393 2007/10/20 13:02:51 chrfranke Exp $"; +static const char *filenameandversion="$Id: smartd.cpp,v 1.394 2007/11/01 20:53:30 chrfranke Exp $"; #ifdef NEED_SOLARIS_ATA_CODE extern const char *os_solaris_ata_s_cvsid; #endif #ifdef _WIN32 extern const char *daemon_win32_c_cvsid, *hostname_win32_c_cvsid, *syslog_win32_c_cvsid; #endif -const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.393 2007/10/20 13:02:51 chrfranke Exp $" +const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.394 2007/11/01 20:53:30 chrfranke Exp $" ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID #ifdef DAEMON_WIN32_H_CVSID DAEMON_WIN32_H_CVSID @@ -174,9 +174,9 @@ static int quit=0; // command-line; this is the default syslog(3) log facility to use. static int facility=LOG_DAEMON; -#ifdef __CYGWIN__ -// command-line: running as service, so don't fork() -static int is_service=0; +#ifndef _WIN32 +// command-line: fork into background? +static bool do_fork=true; #endif // used for control of printing, passing arguments to atacmds.c @@ -1001,30 +1001,32 @@ void DaemonInit(){ // flush all buffered streams. Else we might get two copies of open // streams since both parent and child get copies of the buffers. fflush(NULL); + + if (do_fork) { + if ((pid=fork()) < 0) { + // unable to fork! + PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n"); + EXIT(EXIT_STARTUP); + } + else if (pid) + // we are the parent process -- exit cleanly + EXIT(0); - if ((pid=fork()) < 0) { - // unable to fork! - PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n"); - EXIT(EXIT_STARTUP); - } - else if (pid) - // we are the parent process -- exit cleanly - EXIT(0); - - // from here on, we are the child process. - setsid(); + // from here on, we are the child process. + setsid(); - // Fork one more time to avoid any possibility of having terminals - if ((pid=fork()) < 0) { - // unable to fork! - PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n"); - EXIT(EXIT_STARTUP); - } - else if (pid) - // we are the parent process -- exit cleanly - EXIT(0); + // Fork one more time to avoid any possibility of having terminals + if ((pid=fork()) < 0) { + // unable to fork! + PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n"); + EXIT(EXIT_STARTUP); + } + else if (pid) + // we are the parent process -- exit cleanly + EXIT(0); - // Now we are the child's child... + // Now we are the child's child... + } // close any open file descriptors for (i=getdtablesize();i>=0;--i) @@ -1043,8 +1045,9 @@ void DaemonInit(){ dup(i); umask(0); chdir("/"); - - PrintOut(LOG_INFO, "smartd has fork()ed into background mode. New PID=%d.\n", (int)getpid()); + + if (do_fork) + PrintOut(LOG_INFO, "smartd has fork()ed into background mode. New PID=%d.\n", (int)getpid()); #else // _WIN32 @@ -1186,24 +1189,23 @@ void Usage (void){ #else PrintOut(LOG_INFO," Log to \"./smartd.log\", stdout, stderr [default is event log]\n\n"); #endif +#ifndef _WIN32 + PrintOut(LOG_INFO," -n, --no-fork\n"); + PrintOut(LOG_INFO," Do not fork into background\n\n"); +#endif // _WIN32 PrintOut(LOG_INFO," -p NAME, --pidfile=NAME\n"); PrintOut(LOG_INFO," Write PID file NAME\n\n"); PrintOut(LOG_INFO," -q WHEN, --quit=WHEN\n"); PrintOut(LOG_INFO," Quit on one of: %s\n\n", GetValidArgList('q')); PrintOut(LOG_INFO," -r, --report=TYPE\n"); PrintOut(LOG_INFO," Report transactions for one of: %s\n\n", GetValidArgList('r')); -#if defined(_WIN32) || defined(__CYGWIN__) +#ifdef _WIN32 PrintOut(LOG_INFO," --service\n"); PrintOut(LOG_INFO," Running as windows service (see man page), install with:\n"); -#ifdef _WIN32 PrintOut(LOG_INFO," smartd install [options]\n"); PrintOut(LOG_INFO," Remove service with:\n"); PrintOut(LOG_INFO," smartd remove\n\n"); #else - PrintOut(LOG_INFO," /etc/rc.d/init.d/smartd install [options]\n"); - PrintOut(LOG_INFO," Remove service with:\n"); - PrintOut(LOG_INFO," /etc/rc.d/init.d/smartd remove\n\n"); -#endif #endif // _WIN32 || __CYGWIN__ PrintOut(LOG_INFO," -V, --version, --license, --copyright\n"); PrintOut(LOG_INFO," Print License, Copyright, and version information\n"); @@ -1214,6 +1216,7 @@ void Usage (void){ PrintOut(LOG_INFO," -h Display this help and exit\n"); PrintOut(LOG_INFO," -i N Set interval between disk checks to N seconds, where N >= 10\n"); PrintOut(LOG_INFO," -l local? Use syslog facility local0 - local7, or daemon\n"); + PrintOut(LOG_INFO," -n Do not fork into background\n"); PrintOut(LOG_INFO," -p NAME Write PID file NAME\n"); PrintOut(LOG_INFO," -q WHEN Quit on one of: %s\n", GetValidArgList('q')); PrintOut(LOG_INFO," -r TYPE Report transactions for one of: %s\n", GetValidArgList('r')); @@ -3792,7 +3795,7 @@ void ParseOpts(int argc, char **argv){ char *tailptr; long lchecktime; // Please update GetValidArgList() if you edit shortopts - const char *shortopts = "c:l:q:dDi:p:r:Vh?"; + const char *shortopts = "c:l:q:dDni:p:r:Vh?"; #ifdef HAVE_GETOPT_LONG char *arg; // Please update GetValidArgList() if you edit longopts @@ -3803,10 +3806,13 @@ void ParseOpts(int argc, char **argv){ { "debug", no_argument, 0, 'd' }, { "showdirectives", no_argument, 0, 'D' }, { "interval", required_argument, 0, 'i' }, +#ifndef _WIN32 + { "no-fork", no_argument, 0, 'n' }, +#endif { "pidfile", required_argument, 0, 'p' }, { "report", required_argument, 0, 'r' }, #if defined(_WIN32) || defined(__CYGWIN__) - { "service", no_argument, 0, 'S' }, + { "service", no_argument, 0, 'n' }, #endif { "version", no_argument, 0, 'V' }, { "license", no_argument, 0, 'V' }, @@ -3878,6 +3884,12 @@ void ParseOpts(int argc, char **argv){ // enable debug mode debugmode = TRUE; break; + case 'n': + // don't fork() +#ifndef _WIN32 // On Windows, --service is already handled by daemon_main() + do_fork = false; +#endif + break; case 'D': // print summary of all valid directives debugmode = TRUE; @@ -3942,14 +3954,6 @@ void ParseOpts(int argc, char **argv){ // output file with PID number pid_file=CustomStrDup(optarg, 1, __LINE__,filenameandversion); break; -#if defined(_WIN32) || defined(__CYGWIN__) - case 'S': - // running as service -#ifdef __CYGWIN__ // On Windows, option is already handled by daemon_main(), so ignore it - is_service = 1; -#endif - break; -#endif // _WIN32 || __CYGWIN__ case 'V': // print version and CVS info PrintCopyleft(); @@ -4422,9 +4426,6 @@ static int smartd_main(int argc, char **argv) // fork into background if needed if (firstpass && !debugmode) { -#ifdef __CYGWIN__ - if (!is_service) // don't fork() if running as service via cygrunsrv -#endif DaemonInit(); } diff --git a/sm5/smartd.initd.in b/sm5/smartd.initd.in index d58dc3bae933e80ac934ba891df25e38d31a04b9..9b2ca48533efafe76cc8e67102bedf84593cbf02 100755 --- a/sm5/smartd.initd.in +++ b/sm5/smartd.initd.in @@ -1,8 +1,8 @@ #! /bin/sh # smartmontools init file for smartd -# Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net> -# $Id: smartd.initd.in,v 1.35 2006/10/24 13:29:24 sbrabec Exp $ +# Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net> +# $Id: smartd.initd.in,v 1.36 2007/11/01 20:53:30 chrfranke Exp $ # For RedHat and cousins: # chkconfig: 2345 40 40 @@ -446,7 +446,7 @@ http://smartmontools.sourceforge.net/" fi echo "Installing service ${smartd_svcname}${smartd_opts+ with options '$smartd_opts'}:" cygrunsrv -I "$smartd_svcname" -d "$smartd_svcdisp" -f "$smartd_svcdesc" $dep \ - -e CYGWIN="$CYGWIN" -p $SMARTD_BIN -a "--service -p ${PID_FILE}${smartd_opts+ }$smartd_opts" + -e CYGWIN="$CYGWIN" -p $SMARTD_BIN -a "-n -p ${PID_FILE}${smartd_opts+ }$smartd_opts" RETVAL=$? ;; remove)