Date: Tue, 02 Jul 1996 16:40:04 +1000 From: Luke Mewburn <lukem@telstra.com.au> To: bugs@freebsd.org Subject: restore(8) problems with dumps that have same dumpdate Message-ID: <199607020640.QAA15180@balrog.supp.cpr.itg.telecom.com.au>
next in thread | raw e-mail | index | archive | help
[ Note: I'm not on the FreeBSD lists, nor do I run FreeBSD (I'm a NetBSD/{i386,pmax,sun3} user infact), but this problem is present in 4.2BSD thru to 4.4BSD-lite2, and I thought that the FreeBSD crowd may be interested... Note: I'm not on this list, so please Cc any comments to me as well. These problems are also documented in the NetBSD PR database as <bin/2544> and <bin/2557> - Luke. ] I have two patches. The comments for the first: restore(8) creates temporary files which contain details about permissions to restore to directories when finished. These temporary names are based upon the "dump date" of the backup. So, if you have multiple tape drives that you're restoring from that had backups started at the same time (rather easy to do with automatic backup systems), or you have a dump archive in a file and you're extracting in one session and "tvf"-ing in another, then you lose. I'm sure that this bug has been present since 4.2BSD days, and has even migrated to Solaris 2 (ufsrestore) amongst others. The comments for the second patch: Due to an oversight in the first patch, this broke the 'r' and 'R' (mainly the latter) into being useless. Also, I missed a place where the tempfilename needed to have the unique string applied. So, here's the two patches. You may have to extract and apply them separately The second requires the first to be applied. The man page is also updated warning users that 'r' and 'R' still share the same temp files. ---- PATCH 1 ---- diff -c /ftp/pub/NetBSD/NetBSD-current/src/sbin/restore/dirs.c ./dirs.c *** /ftp/pub/NetBSD/NetBSD-current/src/sbin/restore/dirs.c Sat Oct 14 11:13:00 1995 --- ./dirs.c Thu Jun 13 15:14:17 1996 *************** *** 111,119 **** static long seekpt; static FILE *df, *mf; static RST_DIR *dirp; ! static char dirfile[32] = "#"; /* No file */ ! static char modefile[32] = "#"; /* No file */ ! static char dot[2] = "."; /* So it can be modified */ /* * Format of old style directories. --- 111,119 ---- static long seekpt; static FILE *df, *mf; static RST_DIR *dirp; ! static char dirfile[MAXPATHLEN] = "#"; /* No file */ ! static char modefile[MAXPATHLEN] = "#"; /* No file */ ! static char dot[2] = "."; /* So it can be modified */ /* * Format of old style directories. *************** *** 151,157 **** struct direct nulldir; vprintf(stdout, "Extract directories from tape\n"); ! (void) sprintf(dirfile, "%s/rstdir%d", _PATH_TMP, dumpdate); df = fopen(dirfile, "w"); if (df == NULL) { fprintf(stderr, --- 151,163 ---- struct direct nulldir; vprintf(stdout, "Extract directories from tape\n"); ! (void) sprintf(dirfile, "%s/rstdir%d-XXXXXX", _PATH_TMP, dumpdate); ! if (mktemp(dirfile) == NULL) { ! fprintf(stderr, ! "restore: %s - cannot generate directory temporary\n", ! dirfile); ! exit(1); ! } df = fopen(dirfile, "w"); if (df == NULL) { fprintf(stderr, *************** *** 161,167 **** exit(1); } if (genmode != 0) { ! (void) sprintf(modefile, "%s/rstmode%d", _PATH_TMP, dumpdate); mf = fopen(modefile, "w"); if (mf == NULL) { fprintf(stderr, --- 167,180 ---- exit(1); } if (genmode != 0) { ! (void) sprintf(modefile, "%s/rstmode%d-XXXXXX", _PATH_TMP, ! dumpdate); ! if (mktemp(modefile) == NULL) { ! fprintf(stderr, ! "restore: %s - cannot generate modefile\n", ! modefile); ! exit(1); ! } mf = fopen(modefile, "w"); if (mf == NULL) { fprintf(stderr, Only in .: obj.i386 ---- END PATCH 1 ---- ---- PATCH 2 ---- Index: dirs.c =================================================================== RCS file: /support/cvsroot/util/bsddump/restore/dirs.c,v retrieving revision 1.2 diff -c -r1.2 dirs.c *** dirs.c 1996/06/13 05:24:09 1.2 --- dirs.c 1996/06/17 07:16:38 *************** *** 163,174 **** struct direct nulldir; vprintf(stdout, "Extract directories from tape\n"); ! (void) sprintf(dirfile, "%s/rstdir%d-XXXXXX", _PATH_TMP, dumpdate); ! if (mktemp(dirfile) == NULL) { ! fprintf(stderr, ! "restore: %s - cannot generate directory temporary\n", ! dirfile); ! exit(1); } df = fopen(dirfile, "w"); if (df == NULL) { --- 163,177 ---- struct direct nulldir; vprintf(stdout, "Extract directories from tape\n"); ! (void) sprintf(dirfile, "%s/rstdir%d", _PATH_TMP, dumpdate); ! if (command != 'r' && command != 'R') { ! (void *) strcat(dirfile, "-XXXXXX"); ! if (mktemp(dirfile) == NULL) { ! fprintf(stderr, ! "restore: %s - cannot mktemp directory temporary\n", ! dirfile); ! exit(1); ! } } df = fopen(dirfile, "w"); if (df == NULL) { *************** *** 179,191 **** exit(1); } if (genmode != 0) { ! (void) sprintf(modefile, "%s/rstmode%d-XXXXXX", _PATH_TMP, ! dumpdate); ! if (mktemp(modefile) == NULL) { ! fprintf(stderr, ! "restore: %s - cannot generate modefile\n", ! modefile); ! exit(1); } mf = fopen(modefile, "w"); if (mf == NULL) { --- 182,196 ---- exit(1); } if (genmode != 0) { ! (void) sprintf(modefile, "%s/rstmode%d", _PATH_TMP, dumpdate); ! if (command != 'r' && command != 'R') { ! (void *) strcat(modefile, "-XXXXXX"); ! if (mktemp(modefile) == NULL) { ! fprintf(stderr, ! "restore: %s - cannot mktemp modefile\n", ! modefile); ! exit(1); ! } } mf = fopen(modefile, "w"); if (mf == NULL) { *************** *** 622,628 **** char *cp; vprintf(stdout, "Set directory mode, owner, and times.\n"); ! (void) sprintf(modefile, "%s/rstmode%d", _PATH_TMP, dumpdate); mf = fopen(modefile, "r"); if (mf == NULL) { fprintf(stderr, "fopen: %s\n", strerror(errno)); --- 627,639 ---- char *cp; vprintf(stdout, "Set directory mode, owner, and times.\n"); ! if (command == 'r' || command == 'R') ! (void) sprintf(modefile, "%s/rstmode%d", _PATH_TMP, dumpdate); ! if (modefile[0] == '#') { ! panic("modefile not defined\n"); ! fprintf(stderr, "directory mode, owner, and times not set\n"); ! return; ! } mf = fopen(modefile, "r"); if (mf == NULL) { fprintf(stderr, "fopen: %s\n", strerror(errno)); Index: restore.8 =================================================================== RCS file: /support/cvsroot/util/bsddump/restore/restore.8,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 restore.8 *** restore.8 1996/06/07 05:58:21 1.1.1.1 --- restore.8 1996/06/17 07:33:59 *************** *** 423,428 **** --- 423,450 ---- thus a full dump must be done to get a new set of directories reflecting the new inode numbering, even though the contents of the files is unchanged. + .Pp + The temporary files + .Pa /tmp/rstdir* + and + .Pa /tmp/rstmode* + are generated with a unique name based on the date of the dump + and the process ID (see + .Xr mktemp 3 ), + except for when + .Fl r + or + .Fl R + is used. + Because + .Fl R + allows you to restart a + .Fl r + operation that may have been interrupted, the temporary files should + be the same across different processes. + In all other cases, the files are unique because it is possible to + have two different dumps started at the same time, and separate + operations shouldn't conflict with each other. .Sh HISTORY The .Nm restore ---- END PATCH 2 ---- -- Luke Mewburn UNIX Technical Support <lukem@telstra.com.au> CPR Project, ITG, Telstra. Phone: +61 3 9634 2112
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199607020640.QAA15180>