Skip site navigation (1)Skip section navigation (2)
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>