Article View: gnu.utils.bug
Article #1058more on tar-1.11.1 incremental dumps
From: James Ganong
Date: Mon, 09 Nov 1992 02:01
Date: Mon, 09 Nov 1992 02:01
236 lines
5558 bytes
5558 bytes
i sent in a patch for tar-1.11.1/gnu.c which i have repeated below.
one of the effects of the bug was to backup more directories
than strictly necessary, which was a good thing because it
mooted another bug that cause some dirs that should be backed up to get
skipped.
so if you use my first fix you probably want to use something
like the second fix i am sending you in this note also.
here is my first patch:
------- gnu.c -------
162,172c162,170
< strp=buf;
< dev=atol(strp);
< while(isdigit(*strp))
< strp++;
< ino=atol(strp);
< while(isspace(*strp))
< strp++;
< while(isdigit(*strp))
< strp++;
< strp++;
< add_dir(un_quote_string(strp),dev,ino,(char *)0);
---
> {
> unsigned long t,u;
> char scratch[1000];
>
> sscanf(buf, "%lu %lu %s", &t, &u, scratch);
> dev=t;
> ino=u;
> add_dir(un_quote_string(scratch),dev,ino,(char *)0);
> }
with just this patch in place the following test
winds up with the file d/e/hi not being restored.
# set up the test data
rm -r d
mkdir d
mkdir d/d
mkdir d/e
echo hi > d/d/hi
# do a level 0 backup
rm date0
tar -cvf tar0 -g date0 d
sleep 2
mv d/d/hi d/e
# do a level 1 backup
cp date0 date1
tar -cvf tar1 -g date1 d
# now simulate loosing it all
rm -r d
# do the restore
tar -xvf tar0 -G
tar -xvf tar1 -G
#end of test case
after this test case is run d/e/hi does not exist
and wish i did.
i think the problem is that tar is not backup up the contents
of the dir d/e when it is doing the level 1 backup:
tar -cvf tar1 -g date1 d
+ tar -cvf tar1 -g date1 d
d/
d/d/
d/e/
tar-1.11.1 DOES backup the contents
of the dir d/e, but i think for the wrong reasons, because
it backs up the contents of ALL the directories.
tar -cvf tar1 -g date1 d
tar: directory d/d has been renamed.
tar: directory d/e has been renamed.
d/
d/d/
d/e/
d/e/hi
you can see the problem with the following test case with tar-1.11.1
# set up the test data
rm -r d
mkdir d
mkdir d/d
mkdir d/e
mkdir d/f
echo hi > d/d/hi
echo goodbye > d/f/bye
# do a level 0 backup
rm date0
tar -cvf tar0 -g date0 d
sleep 2
mv d/d/hi d/e
# do a level 1 backup
cp date0 date1
tar -cvf tar1 -g date1 d
# now simulate loosing it all
rm -r d
# do the restore
tar -xvf tar0 -G
tar -xvf tar1 -G
# end of test case
the problem is that dir d/f gets backed up in the level 1 backup even though
nothing about it has changed:
tar -cvf tar1 -g date1 d
tar: directory d/d has been renamed.
tar: directory d/e has been renamed.
tar: directory d/f has been renamed.
d/
d/d/
d/e/
d/f/
d/e/hi
d/f/bye
i noticed that when tar is deciding to incrementally dump a dir (or not
it only looks at the inode number and device, not at the date.
here is my patch to address this. (along with my first patch,
apply it to tar-1.11.1/gnu.c) note that i don't really know what
is going on here, so please look at it carefully before using it.
*** gnu.c.orig Sun Nov 8 17:53:14 1992
--- gnu.c Sun Nov 8 17:53:27 1992
***************
*** 159,176 ****
strp= &buf[strlen(buf)];
if(strp[-1]=='\n')
strp[-1]='\0';
! strp=buf;
! dev=atol(strp);
! while(isdigit(*strp))
! strp++;
! ino=atol(strp);
! while(isspace(*strp))
! strp++;
! while(isdigit(*strp))
! strp++;
! strp++;
! add_dir(un_quote_string(strp),dev,ino,(char *)0);
! }
fclose(fp);
}
--- 159,174 ----
strp= &buf[strlen(buf)];
if(strp[-1]=='\n')
strp[-1]='\0';
! {
! unsigned long t,u;
! char scratch[1000];
!
! sscanf(buf, "%lu %lu %s", &t, &u, scratch);
! dev=t;
! ino=u;
! add_dir(un_quote_string(scratch),dev,ino,(char *)0);
! }
! }
fclose(fp);
}
***************
*** 377,391 ****
if( dp->dev!=hs.st_dev
|| dp->ino!=hs.st_ino) {
if(f_verbose)
! msg("directory %s has been renamed.",namebuf);
dp->allnew=1;
dp->dev=hs.st_dev;
dp->ino=hs.st_ino;
}
dp->dir_text="";
} else {
if(f_verbose)
! msg("Directory %s is new",namebuf);
add_dir(namebuf,hs.st_dev,hs.st_ino,"");
dp=get_dir(namebuf);
dp->allnew=1;
--- 375,398 ----
if( dp->dev!=hs.st_dev
|| dp->ino!=hs.st_ino) {
if(f_verbose)
! msg("%s is a new dir reusing an old dir name.",namebuf);
dp->allnew=1;
dp->dev=hs.st_dev;
dp->ino=hs.st_ino;
+
+ } else if (f_new_files &&
+ new_time>hs.st_mtime &&
+ new_time>hs.st_mtime &&
+ (f_new_files>1 || new_time>hs.st_ctime)) {
+ if (f_verbose) {
+ msg("dir %s has been changed since previous .",namebuf);
+ }
+ dp->allnew=1;
}
dp->dir_text="";
} else {
if(f_verbose)
! msg("%s is a new dir name",namebuf);
add_dir(namebuf,hs.st_dev,hs.st_ino,"");
dp=get_dir(namebuf);
dp->allnew=1;
Technical Details
Message-ID:
<9211090201.AA16987@ced.berkeley.edu>Path:
arc1-ca.pugleaf.net!sparky!uunet!think.com!rpi!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ced.berkeley.edu!jegShow Full Headers
Complete Article Headers
Newsgroups: gnu.utils.bug Path: arc1-ca.pugleaf.net!sparky!uunet!think.com!rpi!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ced.berkeley.edu!jeg From: jeg@ced.berkeley.edu (James Ganong) Subject: more on tar-1.11.1 incremental dumps Message-ID: <9211090201.AA16987@ced.berkeley.edu> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Mon, 9 Nov 1992 02:01:08 GMT Approved: bug-gnu-utils@prep.ai.mit.edu Lines: 237