vbackup: add -i flag to avoid score prefetching (David Swasey)

This commit is contained in:
Russ Cox 2007-11-27 15:49:09 -05:00
parent 89d6e06cb1
commit a4b5da0be7
2 changed files with 68 additions and 39 deletions

View file

@ -5,7 +5,7 @@ back up Unix file systems to Venti
.SH SYNOPSIS .SH SYNOPSIS
.B vbackup .B vbackup
[ [
.B -DVnv .B -DVinv
] ]
[ [
.B -M .B -M
@ -154,6 +154,10 @@ The default is the name returned by
.B -n .B -n
No-op mode: do not write any blocks to the server No-op mode: do not write any blocks to the server
.TP .TP
.B -i
Read scores incrementally from the previous backup as needed,
rather than prefetching them.
.TP
.B -v .B -v
Print verbose output. Print verbose output.
.TP .TP

View file

@ -6,6 +6,7 @@
* *
* -D print debugging * -D print debugging
* -f 'fast' writes - skip write if block exists on server * -f 'fast' writes - skip write if block exists on server
* -i read old scores incrementally
* -m set mount name * -m set mount name
* -M set mount place * -M set mount place
* -n nop -- don't actually write blocks * -n nop -- don't actually write blocks
@ -63,6 +64,7 @@ int errors; /* are we exiting with an error status? */
int fastwrites; /* do not write blocks already on server */ int fastwrites; /* do not write blocks already on server */
int fsscanblock; /* last block scanned */ int fsscanblock; /* last block scanned */
Fsys* fsys; /* file system being backed up */ Fsys* fsys; /* file system being backed up */
int incremental; /* use vscores rather than bscores */
int nchange; /* number of changed blocks */ int nchange; /* number of changed blocks */
int nop; /* don't actually send blocks to venti */ int nop; /* don't actually send blocks to venti */
int nskip; /* number of blocks skipped (already on server) */ int nskip; /* number of blocks skipped (already on server) */
@ -72,6 +74,7 @@ Queue* qventi; /* queue cmp->venti */
int statustime; /* print status every _ seconds */ int statustime; /* print status every _ seconds */
int verbose; /* print extra stuff */ int verbose; /* print extra stuff */
VtFile* vfile; /* venti file being written */ VtFile* vfile; /* venti file being written */
VtFile* vscores; /* venti file with block scores */
Channel* writechan; /* chan(WriteReq) */ Channel* writechan; /* chan(WriteReq) */
VtConn* z; /* connection to venti */ VtConn* z; /* connection to venti */
VtCache* zcache; /* cache of venti blocks */ VtCache* zcache; /* cache of venti blocks */
@ -127,6 +130,9 @@ threadmain(int argc, char **argv)
case 'f': case 'f':
fastwrites = 1; fastwrites = 1;
break; break;
case 'i':
incremental = 1;
break;
case 'm': case 'm':
mountname = EARGF(usage()); mountname = EARGF(usage());
break; break;
@ -233,41 +239,49 @@ threadmain(int argc, char **argv)
sysfatal("file system block counts don't match %lld %lld", e.size, fsys->nblock*bsize); sysfatal("file system block counts don't match %lld %lld", e.size, fsys->nblock*bsize);
} }
/* if(incremental){
* write scores of blocks into temporary file if(vtfilegetentry(vfile, &e) < 0)
*/ sysfatal("vtfilegetentry: %r");
if((tmp = getenv("TMP")) != nil){ if((vscores = vtfileopenroot(c, &e)) == nil)
/* okay, good */ sysfatal("vtfileopenroot: %r");
}else if(access("/var/tmp", 0) >= 0) vtfileunlock(vfile);
tmp = "/var/tmp"; }else{
else /*
tmp = "/tmp"; * write scores of blocks into temporary file
tmpnam = smprint("%s/vbackup.XXXXXX", tmp); */
if(tmpnam == nil) if((tmp = getenv("TMP")) != nil){
sysfatal("smprint: %r"); /* okay, good */
}else if(access("/var/tmp", 0) >= 0)
if((fd = opentemp(tmpnam)) < 0) tmp = "/var/tmp";
sysfatal("opentemp %s: %r", tmpnam); else
if(statustime) tmp = "/tmp";
print("# %T reading scores into %s\n", tmpnam); tmpnam = smprint("%s/vbackup.XXXXXX", tmp);
if(verbose) if(tmpnam == nil)
fprint(2, "read scores into %s...\n", tmpnam); sysfatal("smprint: %r");
Binit(&bscores, fd, OWRITE); if((fd = opentemp(tmpnam)) < 0)
for(i=0; i<fsys->nblock; i++){ sysfatal("opentemp %s: %r", tmpnam);
if(vtfileblockscore(vfile, i, score) < 0) if(statustime)
sysfatal("vtfileblockhash %d: %r", i); print("# %T reading scores into %s\n", tmpnam);
if(Bwrite(&bscores, score, VtScoreSize) != VtScoreSize) if(verbose)
sysfatal("Bwrite: %r"); fprint(2, "read scores into %s...\n", tmpnam);
Binit(&bscores, fd, OWRITE);
for(i=0; i<fsys->nblock; i++){
if(vtfileblockscore(vfile, i, score) < 0)
sysfatal("vtfileblockhash %d: %r", i);
if(Bwrite(&bscores, score, VtScoreSize) != VtScoreSize)
sysfatal("Bwrite: %r");
}
Bterm(&bscores);
vtfileunlock(vfile);
/*
* prep scores for rereading
*/
seek(fd, 0, 0);
Binit(&bscores, fd, OREAD);
} }
Bterm(&bscores);
vtfileunlock(vfile);
/*
* prep scores for rereading
*/
seek(fd, 0, 0);
Binit(&bscores, fd, OREAD);
/* /*
* start the main processes * start the main processes
@ -305,6 +319,8 @@ threadmain(int argc, char **argv)
/* /*
* prepare root block * prepare root block
*/ */
if(incremental)
vtfileclose(vscores);
vtfilelock(vfile, -1); vtfilelock(vfile, -1);
if(vtfileflush(vfile) < 0) if(vtfileflush(vfile) < 0)
sysfatal("vtfileflush: %r"); sysfatal("vtfileflush: %r");
@ -408,14 +424,21 @@ cmpproc(void *dummy)
USED(dummy); USED(dummy);
if(incremental)
vtfilelock(vscores, VtOREAD);
bsize = fsys->blocksize; bsize = fsys->blocksize;
while((db = qread(qcmp, &bno)) != nil){ while((db = qread(qcmp, &bno)) != nil){
data = db->data; data = db->data;
sha1(data, vtzerotruncate(VtDataType, data, bsize), score, nil); sha1(data, vtzerotruncate(VtDataType, data, bsize), score, nil);
if(Bseek(&bscores, (vlong)bno*VtScoreSize, 0) < 0) if(incremental){
sysfatal("cmpproc Bseek: %r"); if(vtfileblockscore(vscores, bno, score1) < 0)
if(Bread(&bscores, score1, VtScoreSize) != VtScoreSize) sysfatal("cmpproc vtfileblockscore %d: %r", bno);
sysfatal("cmpproc Bread: %r"); }else{
if(Bseek(&bscores, (vlong)bno*VtScoreSize, 0) < 0)
sysfatal("cmpproc Bseek: %r");
if(Bread(&bscores, score1, VtScoreSize) != VtScoreSize)
sysfatal("cmpproc Bread: %r");
}
if(memcmp(score, score1, VtScoreSize) != 0){ if(memcmp(score, score1, VtScoreSize) != 0){
nchange++; nchange++;
if(verbose) if(verbose)
@ -425,6 +448,8 @@ cmpproc(void *dummy)
blockput(db); blockput(db);
} }
qclose(qventi); qclose(qventi);
if(incremental)
vtfileunlock(vscores);
if(statustime) if(statustime)
print("# %T cmp proc exiting\n"); print("# %T cmp proc exiting\n");
runlock(&endlk); runlock(&endlk);