diff options
author | crees <crees@FreeBSD.org> | 2011-08-31 19:40:26 +0800 |
---|---|---|
committer | crees <crees@FreeBSD.org> | 2011-08-31 19:40:26 +0800 |
commit | 4a05f930f7f9289ca94ce0226f13777872513daf (patch) | |
tree | 8bbedbeeac1b72a07a8c65ee48647e233f05f636 /sysutils | |
parent | 83a59665a10d29a002d34f053756f9c44213d754 (diff) | |
download | freebsd-ports-gnome-4a05f930f7f9289ca94ce0226f13777872513daf.tar.gz freebsd-ports-gnome-4a05f930f7f9289ca94ce0226f13777872513daf.tar.zst freebsd-ports-gnome-4a05f930f7f9289ca94ce0226f13777872513daf.zip |
- Some bugfixes:
* Calculate delays in microseconds, so that delays of less than
one second between reads (needed to implement rates exceeding
64KB/sec) do not get rounded down to zero.
* Fix a reinitialization problem when handling SIGHUP.
* Additional debug messages (only with -d).
* Comment and manpage improvememts
- Pass maintainership to submitter
PR: ports/115853 ports/143566
Submitted by: perryh@pluto.rain.com
Diffstat (limited to 'sysutils')
-rw-r--r-- | sysutils/diskcheckd/Makefile | 18 | ||||
-rw-r--r-- | sysutils/diskcheckd/files/diskcheckd.8 | 39 | ||||
-rw-r--r-- | sysutils/diskcheckd/files/diskcheckd.c | 110 | ||||
-rw-r--r-- | sysutils/diskcheckd/files/diskcheckd.in | 10 | ||||
-rw-r--r-- | sysutils/diskcheckd/pkg-plist | 2 |
5 files changed, 129 insertions, 50 deletions
diff --git a/sysutils/diskcheckd/Makefile b/sysutils/diskcheckd/Makefile index 76868e01a4f1..05816f2b572b 100644 --- a/sysutils/diskcheckd/Makefile +++ b/sysutils/diskcheckd/Makefile @@ -1,5 +1,4 @@ -# ex:ts=8 -# Ports collection makefile for: diskcheckd +# Ports collection Makefile for: diskcheckd # Date created: Thu Aug 23, 2001 # Whom: David W. Chapman Jr. (dwcjr@FreeBSD.org) # @@ -7,19 +6,15 @@ # PORTNAME= diskcheckd -PORTVERSION= 20010823 -PORTREVISION= 5 +PORTVERSION= 20110729 CATEGORIES= sysutils MASTER_SITES= # part of port DISTFILES= # part of port EXTRACT_ONLY= # part of port -MAINTAINER= ports@FreeBSD.org +MAINTAINER= perryh@pluto.rain.com COMMENT= Daemon to check for disk read errors -DEPRECATED= Unmaintained, broken (ports/143566) -EXPIRATION_DATE=2011-10-17 - MAN8= diskcheckd.8 MLINKS= diskcheckd.8 diskcheckd.conf.5 @@ -40,6 +35,11 @@ do-patch: do-install: ${INSTALL_PROGRAM} ${WRKSRC}/diskcheckd ${PREFIX}/sbin ${INSTALL_DATA} ${FILESDIR}/diskcheckd.conf ${PREFIX}/etc/diskcheckd.conf.sample - ${INSTALL_MAN} ${WRKSRC}/diskcheckd.8 ${PREFIX}/man/man8 + ${INSTALL_MAN} ${WRKSRC}/diskcheckd.8 ${MAN8PREFIX}/man/man8 + +post-install: + @[ -f ${PREFIX}/etc/diskcheckd.conf ] \ + || ${CP} -p ${PREFIX}/etc/diskcheckd.conf.sample \ + ${PREFIX}/etc/diskcheckd.conf .include <bsd.port.mk> diff --git a/sysutils/diskcheckd/files/diskcheckd.8 b/sysutils/diskcheckd/files/diskcheckd.8 index 6462aef84032..2fb72e7b994c 100644 --- a/sysutils/diskcheckd/files/diskcheckd.8 +++ b/sysutils/diskcheckd/files/diskcheckd.8 @@ -58,15 +58,16 @@ should not be included in expansion of wildcards (see below). The second format consists of four white space separated fields, which are the full pathname of the disk device, -the size of that disk, -the frequency in days at which to check that disk, +the size of this disk, +the frequency in days at which to check this disk, and the rate in kilobytes per second at which to check this disk. -Naturally, -it would be contradictory to specify both the frequency and the rate, -so only one of these should be specified. -Additionally, -the size of the disk should not be specified if the rate is specified, -as this information is unnecessary. +.Pp +Either the frequency or the rate should be specified, not both, +since a specified frequency will be internally converted to whatever +rate will result in the disk being scanned at (approximately) that +frequency. +The size of the disk should not be specified if the rate is specified, +since the size is used only to convert a specified frequency into a rate. .Pp If the disk is specified as .Dq * , @@ -89,7 +90,7 @@ character. Note that .Nm always reads data from the disk in 64KB blocks, -so the rate your specify may not be the exact rate at which the disk is +so the rate you specify may not be the exact rate at which the disk is actually checked. Similarly, if you specify the third field (days for complete scan) it is unlikely @@ -132,8 +133,14 @@ accepts the following command line options: If this flag is specified, .Nm will not fork into the background and detach from its controlling terminal -to become a daemon. -This flag is primarily used for debugging. +to become a daemon, +and it will duplicate its system log messages on its standard error output. +.Pp +This flag is primarily used for debugging, +and may be specified more than once. +Additional instances will result in additional +debugging messages on standard error; +these added messages will not be written to the system log. .It Fl f Specify the configuration file to use, instead of the default @@ -143,6 +150,13 @@ Specify the file to save disk offsets to, instead of the default .Pa /var/db/diskcheckd.offsets . .El +.Sh PROGRESS REPORTING +After every 5 minutes or so of sleep time between reads +(not including time spent waiting for the reads themselves to complete), +.Nm +will update its command parameter space to show its progress +in scanning each disk. This report can be viewed using +.Xr ps 1 . .Sh FILES .Bl -tag -width /var/db/diskcheckd.offsets -compact .It Pa /usr/local/etc/diskcheckd.conf @@ -188,3 +202,6 @@ with input from .Sh BUGS .Nm assumes all disks have 512 byte sectors. +.Pp +The code that attempts to identify and report which slice and partition +contain a detected error does not understand GPT partitions. diff --git a/sysutils/diskcheckd/files/diskcheckd.c b/sysutils/diskcheckd/files/diskcheckd.c index 76c8846f2395..6177eb38bdf7 100644 --- a/sysutils/diskcheckd/files/diskcheckd.c +++ b/sysutils/diskcheckd/files/diskcheckd.c @@ -63,10 +63,12 @@ struct disk { char *device; off_t size; int secsize; - int days, rate, errors, interval, next; + int days, rate, errors; + long long interval, next; }; volatile sig_atomic_t got_sighup = 0, got_sigterm = 0; +volatile int debug = 0; char **getdisknames(char **, int); off_t dseek(struct disk *, off_t, int); @@ -85,9 +87,11 @@ int main(int argc, char *argv[]) { char *buf; struct disk *disks, *dp; - int ch, ok, minwait, nextwait; + int ch, ok; + long long minwait, nextwait; struct sigaction sa; - int counter, debug; + long long counter; + int initial_debug; const char *conf_file, *save_file; conf_file = _PATH_CONF; @@ -97,7 +101,10 @@ main(int argc, char *argv[]) { while ((ch = getopt(argc, argv, "df:o:")) != -1) switch (ch) { case 'd': - debug = 1; + if (debug) + debug *= 2; + else + debug = 1; break; case 'f': conf_file = optarg; @@ -116,7 +123,9 @@ main(int argc, char *argv[]) { if (argc != 0) usage(); - openlog("diskcheckd", LOG_CONS|LOG_PID, LOG_DAEMON); + initial_debug = debug; + + openlog("diskcheckd", LOG_CONS|LOG_PID|(debug?LOG_PERROR:0), LOG_DAEMON); if (!debug && daemon(0, 0) < 0) { syslog(LOG_NOTICE, "daemon failure: %m"); @@ -150,20 +159,24 @@ main(int argc, char *argv[]) { * each disk's 'next' field, and when that reaches zero, * that disk is read again. */ - counter = 0; - minwait = 0; + counter = 0LL; + minwait = 0LL; while (!got_sigterm) { ok = 0; - nextwait = INT_MAX; + nextwait = LLONG_MAX; for (dp = disks; dp->device != NULL; dp++) if (dp->fd != -1) { + if (debug > 1) + fprintf(stderr, + "%s: next(%qd) -= %qd\n", + dp->device, dp->next, minwait); if ((dp->next -= minwait) == 0) { ok = 1; readchunk(dp, buf); } /* XXX debugging */ - if (dp->next < 0) { + if (dp->next < 0LL) { syslog(LOG_NOTICE, "dp->next < 0 for %s", dp->device); abort(); @@ -178,14 +191,33 @@ main(int argc, char *argv[]) { exit(EXIT_FAILURE); } - if (counter >= 300) { + /* 300 seconds => 5 minutes */ + if (counter >= 300000000LL) { + if (debug) + fprintf(stderr, "counter rollover %qd => 0\n", + counter); updateproctitle(disks); writeoffsets(disks, save_file); - counter = 0; + counter = 0LL; } minwait = nextwait; - sleep(minwait); + if (debug > 1) { + --debug; + fprintf(stderr, "sleep %qd, counter %qd\n", + minwait, counter); + } + + /* + * Handle whole seconds and usec separately to avoid overflow + * when calling usleep -- useconds_t is only 32 bits on at + * least some architectures, and minwait (being long long) + * may exceed INT_MAX. + */ + if (minwait > 1000000LL) + sleep((unsigned int)(minwait / 1000000)); + if ((minwait % 1000000) > 0) + usleep((useconds_t)(minwait % 1000000)); counter += minwait; if (got_sighup) { @@ -194,6 +226,11 @@ main(int argc, char *argv[]) { * memory used for the disk structures, and then * re-read the config file and the disk offsets. */ + if (debug) { + fprintf(stderr, "got SIGHUP, counter == %qd\n", + counter); + debug = initial_debug; + } writeoffsets(disks, save_file); for (dp = disks; dp->device != NULL; dp++) { free(dp->device); @@ -202,10 +239,14 @@ main(int argc, char *argv[]) { free(disks); disks = readconf(conf_file); readoffsets(disks, save_file); + minwait = 0LL; got_sighup = 0; } } + if (debug) + fprintf(stderr, "got %s, counter == %qd\n", + got_sigterm==SIGTERM?"SIGTERM":"SIGINT", counter); writeoffsets(disks, save_file); return (EXIT_SUCCESS); } @@ -384,6 +425,9 @@ readoffsets(struct disk *disks, const char *save_file) { char *space, buf[1024]; if ((fp = fopen(save_file, "r")) == NULL) { + if (debug > 1 && errno == ENOENT) + fprintf(stderr, "open %s failed: %s [continuing]\n", + save_file, strerror(errno)); if (errno != ENOENT) syslog(LOG_NOTICE, "open %s failed: %m", save_file); return; @@ -398,10 +442,15 @@ readoffsets(struct disk *disks, const char *save_file) { dp->device != NULL && strcmp(dp->device, buf) != 0; dp++) ; /* nothing */ - if (dp->device != NULL) + if (dp->device != NULL) { + if (debug) + fprintf(stderr, "%s: seek %s", buf, space + 1); dseek(dp, (off_t)strtoq(space + 1, NULL, 0), SEEK_SET); + } } fclose(fp); + if (debug) + fprintf(stderr, "readoffsets: done\n"); } /* @@ -418,10 +467,21 @@ writeoffsets(struct disk *disks, const char *save_file) { return; } + if (debug) + fprintf(stderr, + "#\tposition/size\tdays\trate\terrors\tintvl\tnext\n"); for (dp = disks; dp->device != NULL; dp++) - if (strcmp(dp->device, "*") != 0) + if (strcmp(dp->device, "*") != 0) { fprintf(fp, "%s %qd\n", dp->device, (quad_t)dseek(dp, 0, SEEK_CUR)); + if (debug) { + fprintf(stderr, "%s %qd\n", dp->device, + (quad_t)dseek(dp, 0, SEEK_CUR)); + fprintf(stderr, "#\t%qd\t%d\t%d\t%d\t%qd\t%qd\n", + (quad_t)dp->size, dp->days, dp->rate, + dp->errors, dp->interval, dp->next); + } + } fclose(fp); } @@ -577,8 +637,8 @@ readconf(const char *conf_file) { dp->fd = -1; dp->rate = -1; dp->size = -1; - dp->interval = -1; - dp->next = 0; + dp->interval = -1LL; + dp->next = 0LL; break; case 1: /* size */ @@ -688,7 +748,7 @@ readconf(const char *conf_file) { disks[numdisks].size = dp->size; disks[numdisks].days = dp->days; disks[numdisks].interval = dp->interval; - disks[numdisks].next = 0; + disks[numdisks].next = 0LL; disks[numdisks].device = *np; numdisks++; } @@ -727,13 +787,20 @@ readconf(const char *conf_file) { if (dp->size < 0) getdisksize(dp); if (dp->rate < 0) - dp->rate = dp->size / (dp->days * 86400); + dp->rate = (dp->size + dp->days * 43200) + / (dp->days * 86400); + /* * 1000000 => convert seconds to usec */ if (dp->rate == 0) /* paranoia, should never really happen */ - dp->interval = READ_SIZE; + dp->interval = (long long)READ_SIZE * 1000000; else - dp->interval = READ_SIZE / dp->rate; + dp->interval = ((long long)READ_SIZE * 1000000) + / dp->rate; + + if (debug > 1) + fprintf(stderr, "%s: rate %d intvl %qd next %qd\n", + dp->device, dp->rate, dp->interval, dp->next); } if (numdisks == 0) { @@ -873,8 +940,7 @@ sighup(int sig) { void sigterm(int sig) { - sig = sig; - got_sigterm = 1; + got_sigterm = sig; } void diff --git a/sysutils/diskcheckd/files/diskcheckd.in b/sysutils/diskcheckd/files/diskcheckd.in index 2140d618c7cd..a5f719bbd608 100644 --- a/sysutils/diskcheckd/files/diskcheckd.in +++ b/sysutils/diskcheckd/files/diskcheckd.in @@ -2,20 +2,16 @@ # # $FreeBSD$ # - # PROVIDE: diskcheckd # REQUIRE: DAEMON # KEYWORD: shutdown # -# Define these diskcheckd_* variables in one of these files: -# /etc/rc.conf -# /etc/rc.conf.local -# /etc/rc.conf.d/diskcheckd +# Add the following line to /etc/rc.conf to enable diskcheckd: # -# DO NOT CHANGE THE DEFAULT VALUES HERE +# diskcheckd_enable="YES" -diskcheckd_enable=${diskcheckd_enable:-"no"} +: ${diskcheckd_enable="NO"} . /etc/rc.subr diff --git a/sysutils/diskcheckd/pkg-plist b/sysutils/diskcheckd/pkg-plist index a7ac39d8e931..e3ec1ff2e996 100644 --- a/sysutils/diskcheckd/pkg-plist +++ b/sysutils/diskcheckd/pkg-plist @@ -1,4 +1,4 @@ sbin/diskcheckd @unexec if cmp -s %D/etc/diskcheckd.conf.sample %D/etc/diskcheckd.conf; then rm -f %D/etc/diskcheckd.conf; fi etc/diskcheckd.conf.sample -@exec if [ ! -f %D/etc/diskcheckd.conf ]; then cp %D/etc/diskcheckd.conf.sample %D/etc/diskcheckd.conf; fi +@exec if [ ! -f %D/etc/diskcheckd.conf ]; then cp %D/%F %B/diskcheckd.conf; fi |