From owner-freebsd-bugs@FreeBSD.ORG Fri Dec 14 07:33:31 2007 Return-Path: Delivered-To: freebsd-bugs@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D9D6116A419 for ; Fri, 14 Dec 2007 07:33:31 +0000 (UTC) (envelope-from gunther@aurora.regenstrief.org) Received: from aurora.regenstrief.org (aurora.regenstrief.org [134.68.31.122]) by mx1.freebsd.org (Postfix) with ESMTP id A808913C468 for ; Fri, 14 Dec 2007 07:33:31 +0000 (UTC) (envelope-from gunther@aurora.regenstrief.org) Received: from [192.168.16.252] (adsl-68-77-90-206.dsl.ipltin.ameritech.net [68.77.90.206]) by aurora.regenstrief.org (8.13.8/8.13.6) with ESMTP id lBE777qQ044331; Fri, 14 Dec 2007 07:07:07 GMT (envelope-from gunther@aurora.regenstrief.org) Message-ID: <47622C05.2000907@aurora.regenstrief.org> Date: Fri, 14 Dec 2007 02:08:53 -0500 From: Gunther Schadow User-Agent: Mozilla Thunderbird 1.0.2 (Windows/20050317) X-Accept-Language: en-us, en MIME-Version: 1.0 To: freebsd-bugs@freebsd.org Content-Type: multipart/mixed; boundary="------------020603040606090708080804" Cc: Mirkasim Ali Subject: [patch] making dump(8) work with cron(8) X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Dec 2007 07:33:31 -0000 This is a multi-part message in MIME format. --------------020603040606090708080804 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit 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@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 --------------020603040606090708080804 Content-Type: text/plain; name="dontask.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dontask.patch" *** 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 ---- --------------020603040606090708080804--