Source-Changes-HG archive

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

[src/trunk]: src/libexec/lfs_cleanerd Various minor LFS improvements:



details:   https://anonhg.NetBSD.org/src/rev/5a527cc0ec0e
branches:  trunk
changeset: 574262:5a527cc0ec0e
user:      perseant <perseant%NetBSD.org@localhost>
date:      Sat Feb 26 05:43:04 2005 +0000

description:
Various minor LFS improvements:

* Adapt lfs_cleanerd to use the fcntl call to get the Ifile filehandle,
  so it need not be in the namespace.
* Make lfs_cleanerd be more careful when there are very few available
  segments.
* Remove the Ifile from the filesystem namespace.  The cleaner now uses
  a fcntl call on the root inode to find the Ifile filehandle.
* Make lfs_cleanerd less verbose when the filesystem is unmounted.

diffstat:

 libexec/lfs_cleanerd/clean.h    |    3 +-
 libexec/lfs_cleanerd/cleanerd.c |   81 ++++++++++++++-----------
 libexec/lfs_cleanerd/library.c  |  123 ++++++++++++++++++---------------------
 3 files changed, 105 insertions(+), 102 deletions(-)

diffs (truncated from 414 to 300 lines):

diff -r ac03fa3eca05 -r 5a527cc0ec0e libexec/lfs_cleanerd/clean.h
--- a/libexec/lfs_cleanerd/clean.h      Sat Feb 26 05:40:42 2005 +0000
+++ b/libexec/lfs_cleanerd/clean.h      Sat Feb 26 05:43:04 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: clean.h,v 1.19 2004/04/21 01:05:32 christos Exp $      */
+/*     $NetBSD: clean.h,v 1.20 2005/02/26 05:43:04 perseant Exp $      */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -158,6 +158,7 @@
 void            reread_fs_info(FS_INFO *, int);
 void            toss (void *, int *, size_t,
                     int (*)(const void *, const void *, const void *), void *);
+void            log_exit(int, int, char *, ...);
 
 void            dump_super(struct lfs *);
 void            dump_cleaner_info(void *);
diff -r ac03fa3eca05 -r 5a527cc0ec0e libexec/lfs_cleanerd/cleanerd.c
--- a/libexec/lfs_cleanerd/cleanerd.c   Sat Feb 26 05:40:42 2005 +0000
+++ b/libexec/lfs_cleanerd/cleanerd.c   Sat Feb 26 05:43:04 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cleanerd.c,v 1.51 2004/04/21 01:05:32 christos Exp $   */
+/*     $NetBSD: cleanerd.c,v 1.52 2005/02/26 05:43:04 perseant Exp $   */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -36,7 +36,7 @@
 #if 0
 static char sccsid[] = "@(#)cleanerd.c 8.5 (Berkeley) 6/10/95";
 #else
-__RCSID("$NetBSD: cleanerd.c,v 1.51 2004/04/21 01:05:32 christos Exp $");
+__RCSID("$NetBSD: cleanerd.c,v 1.52 2005/02/26 05:43:04 perseant Exp $");
 #endif
 #endif /* not lint */
 
@@ -291,18 +291,14 @@
                lasttime=0;
                loopcount=0;
            loop:
-               if ((childpid=fork()) < 0) {
-                       syslog(LOG_ERR,"%s: couldn't fork, exiting: %m",
-                               fs_name);
-                       exit(1);
-               }
+               if ((childpid=fork()) < 0)
+                       log_exit(0, LOG_ERR,"%s: couldn't fork, exiting: %m",
+                                fs_name);
                if(childpid == 0) {
                        /* Record child's pid */
                        asprintf(&pidname, "lfs_cleanerd:s:%s", fs_name);
-                       if (!pidname) {
-                               syslog(LOG_WARNING,"malloc failed: %m");
-                               exit(1);
-                       }
+                       if (!pidname)
+                               log_exit(0, LOG_WARNING,"malloc failed: %m");
                        while((cp = strchr(pidname, '/')) != NULL)
                                *cp = '|';
                        pidfile(pidname);
@@ -313,10 +309,8 @@
                } else {
                        /* Record parent's pid */
                        asprintf(&pidname, "lfs_cleanerd:m:%s", fs_name);
-                       if (!pidname) {
-                               syslog(LOG_WARNING,"malloc failed: %m");
-                               exit(1);
-                       }
+                       if (!pidname)
+                               log_exit(0, LOG_WARNING,"malloc failed: %m");
                        while((cp = strchr(pidname, '/')) != NULL)
                                *cp = '|';
                        pidfile(pidname);
@@ -329,16 +323,15 @@
                                loopcount=0;
                        }
                        lasttime = now;
-                       if(loopcount > LOOP_THRESHOLD) {
-                               syslog(LOG_ERR,"%s: cleanerd looping, exiting",
-                                       fs_name);
-                               exit(1);
-                       }
-                       if (fs_getmntinfo(&lstatvfsp, fs_name, MOUNT_LFS) == 0) {
-                               /* fs has been unmounted(?); exit quietly */
-                               syslog(LOG_ERR,"lfs_cleanerd: fs %s unmounted, exiting", fs_name);
-                               exit(0);
-                       }
+                       if (loopcount > LOOP_THRESHOLD)
+                               log_exit(0, LOG_ERR,
+                                        "%s: cleanerd looping, exiting",
+                                        fs_name);
+                       /* Check for unmounted fs */
+                       if (fs_getmntinfo(&lstatvfsp, fs_name, MOUNT_LFS) == 0)
+                               log_exit(0, LOG_NOTICE,
+                                       "lfs_cleanerd: %s unmounted, exiting",
+                                       fs_name);
                        goto loop;
                }
        } else
@@ -379,8 +372,11 @@
                fsid = lstatvfsp->f_fsidx;
                if(debug > 1)
                        syslog(LOG_DEBUG,"Cleaner going to sleep.");
-               if (lfs_segwait_emul(ifile_fd, &timeout) < 0)
+               if (lfs_segwait_emul(ifile_fd, &timeout) < 0) {
+                       if (errno == ESHUTDOWN) /* FS unmounted */
+                               exit(0);
                        syslog(LOG_WARNING,"LFCNSEGWAIT: %m");
+               }
                if(debug > 1)
                        syslog(LOG_DEBUG,"Cleaner waking up.");
        }
@@ -402,7 +398,8 @@
         * number of free blocks.
         */
        fsb_per_seg = segtod(lfsp, 1);
-       max_free_segs = fsp->fi_cip->bfree / fsb_per_seg + lfsp->lfs_minfreeseg;
+       max_free_segs = MAX(fsp->fi_cip->bfree, 0) / fsb_per_seg +
+                       lfsp->lfs_minfreeseg;
        
        /* 
         * We will clean if there are not enough free blocks or total clean
@@ -411,7 +408,7 @@
        now = time((time_t *)NULL);
 
        if(debug > 1) {
-               syslog(LOG_DEBUG, "fsb_per_seg = %lu bfree = %u avail = %d",
+               syslog(LOG_DEBUG, "fsb_per_seg = %lu bfree = %d avail = %d",
                       fsb_per_seg, fsp->fi_cip->bfree, fsp->fi_cip->avail);
                syslog(LOG_DEBUG, "clean segs = %d, max_free_segs = %ld",
                       fsp->fi_cip->clean, max_free_segs);
@@ -427,7 +424,7 @@
                if(debug)
                        syslog(LOG_DEBUG, "Cleaner Running  at %s"
                               " (%d of %lu segments available, avail = %d,"
-                              " bfree = %u)",
+                              " bfree = %d)",
                               ctime(&now), fsp->fi_cip->clean, max_free_segs,
                               fsp->fi_cip->avail, fsp->fi_cip->bfree);
                clean_fs(fsp, cost_benefit, nsegs, options);
@@ -558,8 +555,8 @@
                nsegs = MAX(nsegs, fsp->fi_lfs.lfs_minfreeseg);
 #endif
        /* But back down if we haven't got that many free to clean into */
-       if(fsp->fi_cip->clean < nsegs)
-               nsegs = fsp->fi_cip->clean;
+       if (nsegs > fsp->fi_cip->clean / 2)
+               nsegs = MAX(1, fsp->fi_cip->clean / 2);
 
        if (debug > 1)
                syslog(LOG_DEBUG, "clean_fs: found %ld segments to clean in %s",
@@ -571,10 +568,20 @@
 
                /* Check which cleaning algorithm to use. */
                if (options & CLEAN_BYTES) {
-                       /* Count bytes */
+                       /*
+                        * Count bytes.  Be careful here not to run us out
+                        * of segments to write into.  We try to stay below
+                        * our given number of segments minus 1/4 segment,
+                        * unless we can't clean anything without going over
+                        * the limit (e.g. nsegs == 1 and the preferred
+                        * segment to clean is 80% full).
+                        */
                        cleaned_bytes = 0;
-                       to_clean = nsegs * fsp->fi_lfs.lfs_ssize;
-                       for (; i && cleaned_bytes < to_clean; i--, ++sp) {
+                       to_clean = nsegs * fsp->fi_lfs.lfs_ssize -
+                                  fsp->fi_lfs.lfs_ssize / 4;
+                       for (; i && (cleaned_bytes == 0 ||
+                                    cleaned_bytes + sp->sl_bytes <= to_clean);
+                              i--, ++sp) {
                                if (add_segment(fsp, sp, sbp) < 0) {
                                        syslog(LOG_WARNING,"add_segment failed"
                                               " segment %ld: %m", sp->sl_id);
@@ -763,7 +770,8 @@
 
        /* get the current disk address of blocks contained by the segment */
        if ((error = lfs_bmapv_emul(ifile_fd, tba, num_blocks)) < 0) {
-               syslog(LOG_WARNING, "add_segment: LFCNBMAPV failed");
+               if (errno != ESHUTDOWN)
+                       syslog(LOG_WARNING, "add_segment: LFCNBMAPV failed");
                goto out;
        }
 
@@ -973,7 +981,8 @@
        for (bp = sbp->ba; sbp->nb > 0; bp += clean_blocks) {
                clean_blocks = maxblocks < sbp->nb ? maxblocks : sbp->nb;
                if ((error = lfs_markv_emul(ifile_fd, bp, clean_blocks)) < 0) {
-                       syslog(LOG_WARNING,"clean_segment: LFCNMARKV failed: %m");
+                       if (errno != ESHUTDOWN)
+                               syslog(LOG_WARNING,"clean_segment: LFCNMARKV failed: %m");
                        ++cleaner_stats.segs_error;
                        if (errno == ENOENT) break;
                }
diff -r ac03fa3eca05 -r 5a527cc0ec0e libexec/lfs_cleanerd/library.c
--- a/libexec/lfs_cleanerd/library.c    Sat Feb 26 05:40:42 2005 +0000
+++ b/libexec/lfs_cleanerd/library.c    Sat Feb 26 05:43:04 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: library.c,v 1.40 2004/04/21 01:05:32 christos Exp $    */
+/*     $NetBSD: library.c,v 1.41 2005/02/26 05:43:04 perseant Exp $    */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)library.c  8.3 (Berkeley) 5/24/95";
 #else
-__RCSID("$NetBSD: library.c,v 1.40 2004/04/21 01:05:32 christos Exp $");
+__RCSID("$NetBSD: library.c,v 1.41 2005/02/26 05:43:04 perseant Exp $");
 #endif
 #endif /* not lint */
 
@@ -43,15 +43,19 @@
 #include <sys/stat.h>
 #include <sys/mount.h>
 #include <sys/types.h>
+#include <sys/fstypes.h>
 #include <sys/mman.h>
 
 #include <ufs/ufs/dinode.h>
 #include <ufs/lfs/lfs.h>
 
+#include <dirent.h>
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <unistd.h>
 #include <syslog.h>
@@ -121,8 +125,7 @@
 
        fsp->fi_statvfsp = lstatvfsp;
        if (get_superblock(fsp, &fsp->fi_lfs)) {
-               syslog(LOG_ERR, "get_fs_info: get_superblock failed (%m)");
-                exit(1);
+               log_exit(0, LOG_ERR, "get_fs_info: get_superblock failed (%m)");
         }
        get_ifile(fsp, use_mmap);
        return (fsp);
@@ -137,14 +140,12 @@
 reread_fs_info(FS_INFO *fsp, int use_mmap)
 {
        if (ifile_fd != -1) {
-               if (fstatvfs(ifile_fd, fsp->fi_statvfsp) == -1) {
-                       syslog(LOG_ERR, "reread_fs_info: fstatvfs failed (%m)");
-                       exit(1);
-               }
+               if (fstatvfs(ifile_fd, fsp->fi_statvfsp) == -1)
+                       log_exit(EBADF, LOG_ERR, "reread_fs_info: fstatvfs failed (%m)");
        } else if (statvfs(fsp->fi_statvfsp->f_mntonname, fsp->fi_statvfsp)) {
-               syslog(LOG_ERR, "reread_fs_info: statvfs `%s' failed (%m)",
-                   fsp->fi_statvfsp->f_mntonname);
-                exit(1);
+               log_exit(EBADF, LOG_ERR, "reread_fs_info: "
+                        "fstatvfs `%s' failed (%m)",
+                        fsp->fi_statvfsp->f_mntonname);
         }
        get_ifile(fsp, use_mmap);
 }
@@ -159,10 +160,8 @@
 
        (void)snprintf(rdev, sizeof(rdev), "/dev/r%s",
            fsp->fi_statvfsp->f_mntfromname + 5);
-       if ((dev_fd = open(rdev, O_RDONLY)) == -1) {
-               syslog(LOG_ERR, "Cannot open `%s' (%m)", rdev);
-               exit(1);
-       }
+       if ((dev_fd = open(rdev, O_RDONLY)) == -1)
+               log_exit(0, LOG_ERR, "Cannot open `%s' (%m)", rdev);
        return dev_fd;
 }
 
@@ -265,45 +264,33 @@
 void
 get_ifile(FS_INFO *fsp, int use_mmap)
 {
+       struct fhandle fh;
        struct stat file_stat;
-       struct statvfs statvfsbuf;
        caddr_t ifp;
        char *ifile_name;
        int count;
+       int rfd; /* Root file descriptor */
 
        ifp = NULL;
-       asprintf(&ifile_name, "%s/%s", fsp->fi_statvfsp->f_mntonname,
-           IFILE_NAME);
-       if (!ifile_name) {
-               syslog(LOG_ERR, "get_ifile: malloc failed: %m");
-               exit(1);
-       }
-
        if(ifile_fd == -1) {
-               /* XXX KS - Do we ever *write* to the ifile? */
-               if ((ifile_fd = open(ifile_name, O_RDONLY)) == -1) {
-                       syslog(LOG_ERR, "get_ifile: cannot open `%s': %m",
-                           ifile_name);



Home | Main Index | Thread Index | Old Index