rpms/anacron/devel anacron-2.3-lock-files.patch,NONE,1.1

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Fri Apr 14 00:49:41 UTC 2006


Author: jvdias

Update of /cvs/dist/rpms/anacron/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv7873

Added Files:
	anacron-2.3-lock-files.patch 
Log Message:
fix bug 188403: add lock and pid file management to anacron process

anacron-2.3-lock-files.patch:
 global.h |    8 +++
 main.c   |  168 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 151 insertions(+), 25 deletions(-)

--- NEW FILE anacron-2.3-lock-files.patch ---
--- anacron-2.3/main.c.lock-files	2000-06-22 20:00:14.000000000 -0400
+++ anacron-2.3/main.c	2006-04-13 20:38:13.000000000 -0400
@@ -21,39 +21,42 @@
     `COPYING' that comes with the Anacron source distribution.
 */
 
-
-#include <time.h>
-#include <stdio.h>
+#include <sys/types.h>
 #include <unistd.h>
+#include <time.h>
 #include <signal.h>
 #include <fcntl.h>
-#include <sys/types.h>
+#include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
 #include "global.h"
 #include "gregor.h"
 
-pid_t primary_pid;
-int day_now;
-int year, month, day_of_month;                 /* date anacron started */
-
-char *program_name;
-char *anacrontab;
-int serialize, force, update_only, now,
-    no_daemon, quiet;                            /* command-line options */
-char **args;                       /* vector of "job" command-line arguments */
-int nargs;                                     /* number of these */
+pid_t primary_pid=-1;
+int day_now=0;
+int year=0, month=0, day_of_month=0;                 /* date anacron started */
+
+char *program_name=0;
+char *anacrontab=0;
+int serialize=0, force=0, update_only=0, now=0,
+    no_daemon=0, quiet=0;                            /* command-line options */
+char **args=0;                       /* vector of "job" command-line arguments */
+int nargs=0;                                     /* number of these */
 char *defarg = "*";
-int in_background;                             /* are we in the background? */
-int old_umask;                                 /* umask when started */
-sigset_t old_sigmask;                          /* signal mask when started */
-
-job_rec *first_job_rec;
-env_rec *first_env_rec;
-
-static time_t start_sec;                       /* time anacron started */
-static volatile int got_sigalrm, got_sigchld, got_sigusr1;
-int running_jobs, running_mailers;              /* , number of */
+int in_background=0;                             /* are we in the background? */
+int old_umask=0;                                 /* umask when started */
+sigset_t old_sigmask={0};                          /* signal mask when started */
+
+job_rec *first_job_rec=0;
+env_rec *first_env_rec=0;
+
+static time_t start_sec=0;                       /* time anacron started */
+static volatile int got_sigalrm=0, got_sigchld=0, got_sigusr1=0;
+int running_jobs=0, running_mailers=0;              /* , number of */
 
 static void
 print_version()
@@ -183,6 +186,8 @@
     if (close(fd)) die_e("Can't close file descriptor %d", fd);
 }
 
+static int anacron_already_running();
+
 static void
 go_background()
 /* Become a daemon. The foreground process exits successfully. */
@@ -206,9 +211,16 @@
     else
     {
 	/* child */
+	xcloselog();
 	primary_pid = getpid();
 	if (setsid() == -1) die_e("setsid() error");
 	in_background = 1;
+	chdir(SPOOLDIR);
+	if( anacron_already_running() )
+	{
+	    errno=EDEADLK;
+	    die_e("Cannot run in daemon mode - anacron already running.");	    
+	}
     }
 }
 
@@ -265,6 +277,16 @@
     sa.sa_mask = ss;
     sa.sa_flags = 0;
     if (sigaction(SIGUSR1, &sa, NULL)) die_e("sigaction error");
+    /* setup SIGQUIT handler */
+    sa.sa_handler = handle_sigusr1;
+    sa.sa_mask = ss;
+    sa.sa_flags = 0;
+    if (sigaction(SIGQUIT, &sa, NULL)) die_e("sigaction error");
+    /* setup SIGTERM handler */
+    sa.sa_handler = handle_sigusr1;
+    sa.sa_mask = ss;
+    sa.sa_flags = 0;
+    if (sigaction(SIGTERM, &sa, NULL)) die_e("sigaction error");
 }
 
 static void
@@ -409,6 +431,94 @@
 	explain("Jobs will be executed sequentially");
 }
 
+static void remove_lock_and_pid_files(void)
+{
+    unlink(PID_FILE);
+    unlink(LOCK_FILE);
+}
+
+static int anacron_already_running()
+{
+    char buf[PATH_MAX], buf2[PATH_MAX], buf3[32];
+    FILE *fp=0;
+    pid_t pid=-1;
+    mode_t mode;
+    int len, fd;
+
+    if ( access( PID_FILE, F_OK ) == 0 )
+    {
+	if ( ( fp = fopen( PID_FILE, "r" ) ) == 0L )
+	{
+	    complain("%s exists but is not readable",PID_FILE);
+	    return 1;
+	}
+
+	if ( fscanf(fp,"%u",&pid) != 1 )
+	{
+	    explain("%s does not contain a valid pid",PID_FILE);
+	    return 1;
+	}
+
+	fclose(fp);
+
+	snprintf(buf, PATH_MAX, "/proc/%u", pid);
+
+	if( access(buf, F_OK) == 0 )
+	{
+	
+	    snprintf(buf3, 32, "/proc/%u/exe", pid);
+	    if( (len = readlink(buf3, buf2, PATH_MAX)) <= 0 )
+		len = 0;
+
+	    buf2[len] = '\0';
+
+	    snprintf(buf3, 32, "/proc/%u/exe", getpid());
+	    if( (len = readlink(buf3,  buf, PATH_MAX)) <= 0 )
+		len = 0;
+	    buf[len] = '\0';
+	
+	    if( strcmp( buf, buf2 ) == 0 )
+		return 1;
+	}
+    }
+    /* main process removes lock files once it 
+     * has determined no other anacron is running:
+     */
+    remove_lock_and_pid_files();
+
+    if( no_daemon || in_background )
+    {
+	/* daemon process, or main process in no_daemon mode,
+         * creates the lock and pid files:
+	 */
+	if( ( fd = open(LOCK_FILE, O_CREAT | O_WRONLY | O_EXCL, 0600) ) == -1 )
+	{
+	    complain("Cannot exclusively create %s: %s",PID_FILE,strerror(errno));
+	    return 1;
+	}
+	close(fd);
+
+	mode = umask(0077);
+	if( ( fp = fopen(PID_FILE, "w") ) == 0L )
+	{
+	    complain("Cannot create %s",PID_FILE);
+	    umask(mode);
+	    return 1;
+	}
+	umask(mode);
+
+	/* lock and pid files removed automatically at normal exit
+         * by creator process:
+         */
+	atexit( remove_lock_and_pid_files );
+
+	fprintf(fp,"%u",getpid());
+	fflush(fp);
+	fclose(fp);
+    }
+    return 0;
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -423,6 +533,12 @@
 
     parse_opts(argc, argv);
 
+    if ( anacron_already_running() )
+    {
+	errno=EDEADLK;
+	die_e("Cannot run - another anacron process is already running.");
+    }
+
     if (anacrontab == NULL)
 	anacrontab = strdup(ANACRONTAB);
 
@@ -433,7 +549,9 @@
     old_umask = umask(0);
 
     if (sigprocmask(0, NULL, &old_sigmask)) die_e("sigset error");
-
+    
+    if( !no_daemon )
+	ioctl(0,TIOCNOTTY,0);
     if (fclose(stdin)) die_e("Can't close stdin");
     xopen(0, "/dev/null", O_RDONLY);
 
--- anacron-2.3/global.h.lock-files	2000-06-22 20:00:14.000000000 -0400
+++ anacron-2.3/global.h	2006-04-13 20:25:42.000000000 -0400
@@ -34,6 +34,14 @@
 /* Mail interface.  (All MTAs should supply this command) */
 #define SENDMAIL "/usr/sbin/sendmail"
 
+#ifndef PID_FILE
+#define PID_FILE "/var/run/anacron.pid"
+#endif
+
+#ifndef LOCK_FILE
+#define LOCK_FILE "/var/lock/subsys/anacron"
+#endif
+
 /* End of user-configurable section */
 
 




More information about the fedora-cvs-commits mailing list