[patch] making dump(8) work with cron(8)
Gunther Schadow
gunther at aurora.regenstrief.org
Thu Dec 13 23:33:31 PST 2007
Hi, please take note of the attached patch and consider
applying it for good. It addresses a long known bug
described in man dump(8):
BUGS
[...] Since dumps are often done in an unattended fashion using
cron(8) jobs asking for Operator intervention would result in the dump
dying. However, there is nothing wrong with a dump tape written when
this sort of read error occurs, and there is no reason to terminate the
dump.
the attached patch fixes it: adding 2 options [-Y | -N]
-Y Do not require a tty, do not ask any questions but answer all
questions with "yes".
-N Do not require a tty, do not ask any questions but answer all
questions with "no".
In order to use dump with cron(8), the -Y or -N options can be used to
tell dump not to require a tty for getting questions answered, but
instead to assume "yes" ( -Y ) or "no" ( -N ) respectively.
I considered an alternative making dump use stdio rather than
forging fopen a /dev/tty. This would allow someone to use some
expect like remote control logic or one could have piped it with
yes(1) or no(1). But I went with the simpler option for now.
regards,
-Gunther
--
Gunther Schadow, M.D., Ph.D. gschadow at regenstrief.org
Associate Professor Indiana University School of Informatics
Regenstrief Institute, Inc. Indiana University School of Medicine
tel:1(317)423-5521 http://aurora.regenstrief.org
-------------- next part --------------
*** dump.h~ Thu Dec 2 08:56:53 2004
--- dump.h Fri Dec 14 01:19:49 2007
***************
*** 87,92 ****
--- 87,93 ----
long dev_bsize; /* block size of underlying disk device */
int dev_bshift; /* log2(dev_bsize) */
int tp_bshift; /* log2(TP_BSIZE) */
+ int dontask; /* don't use interactive terminal, answer all questions with yes (1) or no (-1) */
/* operator interface functions */
void broadcast(const char *message);
*** main.c~ Mon Oct 16 07:52:00 2006
--- main.c Fri Dec 14 01:13:29 2007
***************
*** 121,129 ****
if (argc < 2)
usage();
obsolete(&argc, &argv);
while ((ch = getopt(argc, argv,
! "0123456789aB:b:C:cD:d:f:h:LnP:Ss:T:uWw")) != -1)
switch (ch) {
/* dump level */
case '0': case '1': case '2': case '3': case '4':
--- 121,131 ----
if (argc < 2)
usage();
+ dontask = 0;
+
obsolete(&argc, &argv);
while ((ch = getopt(argc, argv,
! "0123456789aB:b:C:cD:d:f:h:LnP:Ss:T:uWwYN")) != -1)
switch (ch) {
/* dump level */
case '0': case '1': case '2': case '3': case '4':
***************
*** 217,222 ****
--- 219,232 ----
lastdump(ch);
exit(X_FINOK); /* do nothing else */
+ case 'Y':
+ dontask = 1;
+ break;
+
+ case 'N':
+ dontask = -1;
+ break;
+
default:
usage();
}
***************
*** 588,594 ****
usage(void)
{
fprintf(stderr,
! "usage: dump [-0123456789acLnSu] [-B records] [-b blocksize] [-C cachesize]\n"
" [-D dumpdates] [-d density] [-f file | -P pipecommand] [-h level]\n"
" [-s feet] [-T date] filesystem\n"
" dump -W | -w\n");
--- 598,604 ----
usage(void)
{
fprintf(stderr,
! "usage: dump [-0123456789acLnSu] [-Y|-N] [-B records] [-b blocksize] [-C cachesize]\n"
" [-D dumpdates] [-d density] [-f file | -P pipecommand] [-h level]\n"
" [-s feet] [-T date] filesystem\n"
" dump -W | -w\n");
*** optr.c~ Wed Feb 16 01:48:35 2005
--- optr.c Fri Dec 14 01:19:24 2007
***************
*** 78,116 ****
{
char replybuffer[64];
int back, errcount;
! FILE *mytty;
! if ((mytty = fopen(_PATH_TTY, "r")) == NULL)
! quit("fopen on %s fails: %s\n", _PATH_TTY, strerror(errno));
! attnmessage = question;
! timeout = 0;
! alarmcatch(0);
! back = -1;
! errcount = 0;
! do {
! if (fgets(replybuffer, 63, mytty) == NULL) {
! clearerr(mytty);
! if (++errcount > 30) /* XXX ugly */
! quit("excessive operator query failures\n");
! } else if (replybuffer[0] == 'y' || replybuffer[0] == 'Y') {
! back = 1;
! } else if (replybuffer[0] == 'n' || replybuffer[0] == 'N') {
! back = 0;
! } else {
! (void) fprintf(stderr,
! " DUMP: \"Yes\" or \"No\"?\n");
! (void) fprintf(stderr,
! " DUMP: %s: (\"yes\" or \"no\") ", question);
! }
! } while (back < 0);
! /*
! * Turn off the alarm, and reset the signal to trap out..
! */
! (void) alarm(0);
! if (signal(SIGALRM, sig) == SIG_IGN)
! signal(SIGALRM, SIG_IGN);
! (void) fclose(mytty);
return(back);
}
--- 78,124 ----
{
char replybuffer[64];
int back, errcount;
! FILE *mytty = NULL;
! if(!dontask) {
! if ((mytty = fopen(_PATH_TTY, "r")) == NULL)
! quit("fopen on %s fails: %s\n", _PATH_TTY, strerror(errno));
! attnmessage = question;
! timeout = 0;
! alarmcatch(0);
! back = -1;
! errcount = 0;
! do {
! if (fgets(replybuffer, 63, mytty) == NULL) {
! clearerr(mytty);
! if (++errcount > 30) /* XXX ugly */
! quit("excessive operator query failures\n");
! } else if (replybuffer[0] == 'y' || replybuffer[0] == 'Y') {
! back = 1;
! } else if (replybuffer[0] == 'n' || replybuffer[0] == 'N') {
! back = 0;
! } else {
! (void) fprintf(stderr,
! " DUMP: \"Yes\" or \"No\"?\n");
! (void) fprintf(stderr,
! " DUMP: %s: (\"yes\" or \"no\") ", question);
! }
! } while (back < 0);
!
! /*
! * Turn off the alarm, and reset the signal to trap out..
! */
! (void) alarm(0);
! if (signal(SIGALRM, sig) == SIG_IGN)
! signal(SIGALRM, SIG_IGN);
! (void) fclose(mytty);
!
! } else if(dontask == 1)
! back = 1;
! else if(dontask == -1)
! back = 0;
!
return(back);
}
*** dump.8~ Wed Aug 23 08:42:22 2006
--- dump.8 Fri Dec 14 01:43:25 2007
***************
*** 39,44 ****
--- 39,45 ----
.Sh SYNOPSIS
.Nm
.Op Fl 0123456789acLnSu
+ .Op Fl Y | Fl N
.Op Fl B Ar records
.Op Fl b Ar blocksize
.Op Fl C Ar cachesize
***************
*** 258,263 ****
--- 259,270 ----
.Dq operator
by means similar to a
.Xr wall 1 .
+ .It Fl Y
+ Do not require a tty, do not ask any questions but
+ answer all questions with "yes".
+ .It Fl N
+ Do not require a tty, do not ask any questions but
+ answer all questions with "no".
.It Fl S
Display an estimate of the backup size and the number of
tapes required, and exit without actually performing the dump.
***************
*** 403,408 ****
--- 410,430 ----
is busy,
and will be for some time.
.Pp
+ In order to use dump with
+ .Xr cron 8 ,
+ the
+ .Fl Y
+ or
+ .Fl N
+ options can be used to tell
+ .Nm
+ not to require a tty for getting questions answered, but instead
+ to assume "yes" (
+ .Fl Y
+ ) or "no" (
+ .Fl N
+ ) respectively.
+ .Pp
In the event of a catastrophic disk event, the time required
to restore all the necessary backup tapes or files to disk
can be kept to a minimum by staggering the incremental dumps.
***************
*** 493,506 ****
on mounted partitions if the file system is being modified while the
.Nm
is running.
- Since dumps are often done in an unattended fashion using
- .Xr cron 8
- jobs asking for Operator intervention would result in the
- .Nm
- dying.
- However, there is nothing wrong with a dump tape written when this sort
- of read error occurs, and there is no reason to terminate the
- .Nm .
.Pp
Each reel requires a new process, so parent processes for
reels already written just hang around until the entire tape
--- 515,520 ----
More information about the freebsd-bugs
mailing list