Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Try to prevent running more than one active cleaner on a fil...



details:   https://anonhg.NetBSD.org/src/rev/787662af1562
branches:  trunk
changeset: 499172:787662af1562
user:      perseant <perseant%NetBSD.org@localhost>
date:      Mon Nov 13 22:12:49 2000 +0000

description:
Try to prevent running more than one active cleaner on a filesystem at a time.

Let lfs_cleanerd record its pid in /var/run like other daemons.  Make
mount_lfs not start another cleaner when updating the mount, unless it is
being upgraded from read-only to read-write; when downgrading to read-only,
kill the cleaner using the recorded pids.

diffstat:

 libexec/lfs_cleanerd/Makefile   |   4 +-
 libexec/lfs_cleanerd/cleanerd.c |  32 ++++++++++++++-
 sbin/mount_lfs/mount_lfs.c      |  83 ++++++++++++++++++++++++++++++++++++++--
 3 files changed, 110 insertions(+), 9 deletions(-)

diffs (239 lines):

diff -r 61651b51417c -r 787662af1562 libexec/lfs_cleanerd/Makefile
--- a/libexec/lfs_cleanerd/Makefile     Mon Nov 13 22:05:52 2000 +0000
+++ b/libexec/lfs_cleanerd/Makefile     Mon Nov 13 22:12:49 2000 +0000
@@ -1,10 +1,12 @@
-#      $NetBSD: Makefile,v 1.6 1997/10/22 05:51:29 lukem Exp $
+#      $NetBSD: Makefile,v 1.7 2000/11/13 22:12:50 perseant Exp $
 #      from: @(#)Makefile      8.1 (Berkeley) 6/5/93
 
 PROG=  lfs_cleanerd
 CPPFLAGS+=-I${.CURDIR} -DDIAGNOSTIC
 MAN=   lfs_cleanerd.8
 SRCS=  cleanerd.c lfs_cksum.c library.c misc.c print.c
+LDADD+=-lutil
+DPADD+=${LIBUTIL}
 
 .PATH: ${.CURDIR}/../../sys/ufs/lfs
 
diff -r 61651b51417c -r 787662af1562 libexec/lfs_cleanerd/cleanerd.c
--- a/libexec/lfs_cleanerd/cleanerd.c   Mon Nov 13 22:05:52 2000 +0000
+++ b/libexec/lfs_cleanerd/cleanerd.c   Mon Nov 13 22:12:49 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cleanerd.c,v 1.24 2000/11/11 22:40:13 perseant Exp $   */
+/*     $NetBSD: cleanerd.c,v 1.25 2000/11/13 22:12:50 perseant Exp $   */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -40,7 +40,7 @@
 #if 0
 static char sccsid[] = "@(#)cleanerd.c 8.5 (Berkeley) 6/10/95";
 #else
-__RCSID("$NetBSD: cleanerd.c,v 1.24 2000/11/11 22:40:13 perseant Exp $");
+__RCSID("$NetBSD: cleanerd.c,v 1.25 2000/11/13 22:12:50 perseant Exp $");
 #endif
 #endif /* not lint */
 
@@ -60,6 +60,7 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#include <util.h>
 
 #include <syslog.h>
 
@@ -122,6 +123,7 @@
 unsigned long   cost_benefit __P((FS_INFO *, SEGUSE *));
 int     cost_compare __P((const void *, const void *));
 void    sig_report __P((int));
+void    just_exit __P((int));
 int     main __P((int, char *[]));
 
 /*
@@ -191,6 +193,8 @@
        char *fs_name;                  /* name of filesystem to clean */
        time_t now, lasttime;
        int loopcount;
+       char *pidname;                  /* Name of pid file base */
+       char *cp;
 
        cmd_err = debug = do_quit = 0;
        clean_opts = 0;
@@ -259,7 +263,22 @@
                                fs_name);
                        exit(1);
                }
-               if(childpid != 0) {
+               if(childpid == 0) {
+                       /* Record child's pid */
+                       pidname = malloc(strlen(fs_name) + 16);
+                       sprintf(pidname, "lfs_cleanerd:s:%s", fs_name);
+                       while((cp = strchr(pidname, '/')) != NULL)
+                               *cp = '|';
+                       pidfile(pidname);
+               } else {
+                       /* Record parent's pid */
+                       pidname = malloc(strlen(fs_name) + 16);
+                       sprintf(pidname, "lfs_cleanerd:m:%s", fs_name);
+                       while((cp = strchr(pidname, '/')) != NULL)
+                               *cp = '|';
+                       pidfile(pidname);
+                       signal(SIGINT, just_exit);
+
                        wait(NULL);
                        /* If the child is looping, give up */
                        ++loopcount;
@@ -932,3 +951,10 @@
        if (sig == SIGINT)
                exit(0);
 }
+
+void
+just_exit(sig)
+       int sig;
+{
+       exit(0);
+}
diff -r 61651b51417c -r 787662af1562 sbin/mount_lfs/mount_lfs.c
--- a/sbin/mount_lfs/mount_lfs.c        Mon Nov 13 22:05:52 2000 +0000
+++ b/sbin/mount_lfs/mount_lfs.c        Mon Nov 13 22:12:49 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mount_lfs.c,v 1.11 2000/10/30 20:56:59 jdolecek Exp $  */
+/*     $NetBSD: mount_lfs.c,v 1.12 2000/11/13 22:12:49 perseant Exp $  */
 
 /*-
  * Copyright (c) 1993, 1994
@@ -43,7 +43,7 @@
 #if 0
 static char sccsid[] = "@(#)mount_lfs.c        8.4 (Berkeley) 4/26/95";
 #else
-__RCSID("$NetBSD: mount_lfs.c,v 1.11 2000/10/30 20:56:59 jdolecek Exp $");
+__RCSID("$NetBSD: mount_lfs.c,v 1.12 2000/11/13 22:12:49 perseant Exp $");
 #endif
 #endif /* not lint */
 
@@ -58,6 +58,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <paths.h>
+
+#include <signal.h>
 
 #include "mntopts.h"
 #include "pathnames.h"
@@ -68,10 +71,12 @@
        { NULL }
 };
 
-int    main __P((int, char *[]));
-int    mount_lfs __P((int argc, char **argv));
+int            main __P((int, char *[]));
+int            mount_lfs __P((int, char *[]));
 static void    invoke_cleaner __P((char *));
 static void    usage __P((void));
+static void    kill_daemon __P((char *));
+static void    kill_cleaner __P((char *));
 
 static int short_rds, cleaner_debug, cleaner_bytes;
 static char *nsegs;
@@ -92,9 +97,11 @@
        char *argv[];
 {
        struct ufs_args args;
-       int ch, mntflags, noclean;
+       int ch, mntflags, noclean, mntsize, oldflags, i;
        char *fs_name, *options;
+
        const char *errcause;
+       struct statfs *mntbuf;
 
        options = NULL;
        nsegs = "4";
@@ -141,6 +148,23 @@
        } else
                args.export.ex_flags = 0;
 
+       /*
+        * Record the previous status of this filesystem (if any) before
+        * performing the mount, so we can know whether to start or
+        * kill the cleaner process below.
+        */
+       oldflags = MNT_RDONLY; /* If not mounted, pretend r/o */
+       if (mntflags & MNT_UPDATE) {
+               if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0)
+                       err(1, "getmntinfo");
+               for (i = 0; i < mntsize; i++) {
+                       if (strcmp(mntbuf[i].f_mntfromname, args.fspec) == 0) {
+                               oldflags = mntbuf[i].f_flags;
+                               break;
+                       }
+               }
+       }
+
        if (mount(MOUNT_LFS, fs_name, mntflags, &args)) {
                switch (errno) {
                case EMFILE:
@@ -160,14 +184,63 @@
                errx(1, "%s on %s: %s", args.fspec, fs_name, errcause);
        }
 
+       /* Not mounting fresh or upgrading to r/w; don't start the cleaner */
+       if (!(oldflags & MNT_RDONLY) || (mntflags & MNT_RDONLY))
+               noclean = 1;
        if (!noclean)
                invoke_cleaner(fs_name);
                /* NOTREACHED */
 
+       /* Downgrade to r/o; kill the cleaner */
+       if ((mntflags & MNT_RDONLY) && !(oldflags & MNT_RDONLY))
+               kill_cleaner(fs_name);
+
        exit(0);
 }
 
 static void
+kill_daemon(pidname)
+       char *pidname;
+{
+       FILE *fp;
+       char s[80];
+       pid_t pid;
+
+       fp = fopen(pidname, "r");
+       if (fp) {
+               fgets(s, 80, fp);
+               pid = atoi(s);
+               if (pid)
+                       kill(pid, SIGINT);
+               fclose(fp);
+       }
+}
+
+static void
+kill_cleaner(name)
+       char *name;
+{
+       char *pidname;
+       char *cp;
+       int off;
+
+       /* Parent first */
+       pidname = malloc(strlen(name) + 20 + strlen(_PATH_VARRUN));
+       sprintf(pidname, "%slfs_cleanerd:m:%s.pid", _PATH_VARRUN, name);
+       off = strlen(_PATH_VARRUN);
+       while((cp = strchr(pidname + off, '/')) != NULL)
+               *cp = '|';
+       kill_daemon(pidname);
+
+       /* Then child */
+       sprintf(pidname, "%slfs_cleanerd:s:%s.pid", _PATH_VARRUN, name);
+       off = strlen(_PATH_VARRUN);
+       while((cp = strchr(pidname + off, '/')) != NULL)
+               *cp = '|';
+       kill_daemon(pidname);
+}
+
+static void
 invoke_cleaner(name)
        char *name;
 {



Home | Main Index | Thread Index | Old Index