(Illustration by Gaich Muramatsu)
Although, BTW, there must be a printf() in there with an old typecast still. 19:22:31 Transferred -636288144 bytes though it is all bark and no bite; the dumps are still churning away just fine. Regards, Sean scaron_at_umich.edu On 9/6/06, Sean Caron <caron.sean_at_gmail.com> wrote: > > Jan -- you are splendid! The patch seems to be doing the trick so far. I > haven't > gotten a full dump off yet -- it'll take a while to pull it all in -- but > it has gotten much > further than before; I think it should be all set. > > Thanks again, > > Sean > scaron_at_umich.edu > > On 9/5/06, Jan Harkes < jaharkes_at_cs.cmu.edu> wrote: > > > On Tue, Sep 05, 2006 at 02:24:19PM -0400, Sean Caron wrote: > > > I'll take a look at backup.cc when I get back home today and see if I > > can > > > get it to cooperate > > > with what you've told me here; otherwise I suppose that I will just > > have to > > > bite the bullet, move > > > my tape drive to a client machine, and give this amanda program a > > shot. > > > > Actually, I did the same looking around backup.cc today while I was > > trying to come up with a fix. My initial idea involved opening a pipe > > inside of backup.cc to simulate the voldump | gzip sequence. > > > > Here is a preliminary patch, > > > > Jan > > > > Break the 4GB limit for backup dumps. > > > > By passing an open filedescriptor and not allowing sftp to seek, we > > should be able to dump volumes that are larger than 4GB. > > > > diff --git a/coda-src/volutil/backup.cc b/coda-src/volutil/backup.cc > > index b94f79a..140ed4e 100644 > > --- a/coda-src/volutil/backup.cc > > +++ b/coda-src/volutil/backup.cc > > @@ -87,27 +87,28 @@ static int Debug = 0; /* Global > > debu > > static int Naptime = 30; /* Sleep period for PollLWP */ > > > > struct hostinfo { > > - bit32 address; /* Assume host IP addresses are 32 > > bits */ > > + bit32 address; /* Assume host IP addresses are 32 bits */ > > RPC2_Handle rpcid; /* should be -1 if connection is dead. */ > > char name[36]; > > -} Hosts[N_SERVERIDS]; > > +} Hosts[N_SERVERIDS]; > > > > #define BADCONNECTION (RPC2_Handle) -1 > > > > bit32 HostAddress[N_SERVERIDS]; /* Need these for macros > > in vrdb.c */ > > char *ThisHost; /* This machine's hostname */ > > -int ThisServerId = -1; /* this server id, as found in > > ../db/servers */ > > +int ThisServerId = -1; /* this server id, as found in > > ../db/servers */ > > > > /* Rock info for communicating with the DumpLWP. */ > > #define ROCKTAG 12345 > > struct rockInfo { > > - char dumpfile[MAXPATHLEN]; > > - VolumeId volid; /* Volume being dumped. */ > > - unsigned long numbytes; /* Number of bytes already written to the > > file. */ > > + int dumpfd; /* Open filedescriptor for WriteDump > > */ > > + VolumeId volid; /* Volume being dumped. */ > > + unsigned int numbytes; /* Number of bytes already written to the > > file. > > + (has to wrap around the same way as > > 'offset') */ > > } Rock; > > > > -struct hgram DataRate; /* Statistics on rate of data > > transfer */ > > -struct hgram DataTransferred; /* and size of dumpfiles. */ > > +struct hgram DataRate; /* Statistics on rate of data transfer > > */ > > +struct hgram DataTransferred; /* and size of dumpfiles. */ > > > > /* Per replica info. */ > > #define LOCKED 0x1 > > @@ -588,47 +589,48 @@ int dumpVolume(volinfo_t *vol) > > long rc; > > RPC2_Unsigned dumplevel = (vol->flags & DUMPLVL_MASK) >> > > DUMPLVL_SHFT; > > int ndumped = 0; > > - > > + > > for (int i = 0; i < vol->nReplicas; i++) { > > if ((Hosts[reps[i].serverNum].rpcid == BADCONNECTION) || > > !ISCLONED(reps[i].flags)) > > - continue; > > - > > + continue; > > + > > if (ISDUMPED(reps[i].flags)) { > > ndumped++; /* Count it, but don't need to redo it. */ > > continue; > > } > > - > > + > > CODA_ASSERT(reps[i].backupId > 0); > > - > > + > > /* get the name of the dumpfile. */ > > struct DiskPartition *part = NULL; > > char buf[MAXPATHLEN]; > > > > part = findBestPartition(); > > - if (vol->flags & REPLICATED) > > + if (vol->flags & REPLICATED) > > sprintf(buf, "%s/%s-%08x.%08x", part->name, > > Hosts[reps[i].serverNum].name, volId, > > reps[i].repvolId); > > - else > > + else > > sprintf(buf, "%s/%s-%08x", part->name, > > Hosts[reps[i].serverNum].name, volId); > > - > > > > /* Remove the file if it already exists. Since we made the > > * dump dir it can only exist if we are retrying the > > * replicated dump even though it succeeded for this replica > > * last time around. Don't care if it fails. */ > > unlink(buf); > > - > > + > > /* Setup the write thread to handle this operation. */ > > - CODA_ASSERT(strlen(buf) < sizeof(Rock.dumpfile)); > > - strcpy(Rock.dumpfile, buf); > > + Rock.dumpfd = open(buf, O_CREAT | O_WRONLY | O_TRUNC, 0644); > > Rock.volid = reps[i].backupId; > > Rock.numbytes = 0; > > - > > + > > VLog(0, "Dumping %x.%x to %s ...", volId, reps[i].repvolId, > > buf); > > > > rc = VolNewDump(Hosts[reps[i].serverNum].rpcid, > > reps[i].backupId, > > &dumplevel); > > + > > + close(Rock.dumpfd); > > + > > if (rc != RPC2_SUCCESS) { > > LogMsg(0,0,stdout, "VolDump (%x) failed on %x with %s\n", > > Hosts[reps[i].serverNum].rpcid, /* For debugging. */ > > @@ -639,26 +641,26 @@ int dumpVolume(volinfo_t *vol) > > continue; > > } > > > > - /* Incremental can be forced to be full. */ > > + /* Incremental can be forced to be full. */ > > if (dumplevel == 0) { > > vol->flags &= ~(INCREMENTAL | DUMPLVL_MASK); > > } > > - > > + > > /* Setup a pointer from the dump subtree to the actual dumpfile > > * if a different partition was used for storage. > > */ > > - > > + > > char link[66]; > > if (vol->flags & REPLICATED) > > > > sprintf(link,"%s/%08x.%08x",Hosts[reps[i].serverNum].name, > > volId, reps[i].repvolId); > > else > > sprintf(link, "%s/%08x", Hosts[reps[i].serverNum].name, > > volId); > > - > > + > > /* Remove the link if it exists. See comment by previous > > unlink. */ > > unlink(link); > > - > > + > > if (symlink(buf, link) == -1) { > > if (errno == EEXIST) { /* Retrying dump. */ > > if (unlink(link) != -1) > > @@ -666,7 +668,7 @@ int dumpVolume(volinfo_t *vol) > > break; > > } > > perror("symlink"); > > - unlink(buf); /* Delete the dump file. */ > > + unlink(buf); /* Delete the dump file. */ > > return -1; > > } > > > > @@ -1291,7 +1293,7 @@ long S_WriteDump(RPC2_Handle rpcid, RPC2 > > struct rockInfo *rockinfo; > > SE_Descriptor sed; > > char *rock; > > - > > + > > CODA_ASSERT(LWP_GetRock(ROCKTAG, &rock) == LWP_SUCCESS); > > rockinfo = (struct rockInfo *)rock; > > > > @@ -1309,13 +1311,11 @@ long S_WriteDump(RPC2_Handle rpcid, RPC2 > > sed.Tag = SMARTFTP; > > sed.Value.SmartFTPD.TransmissionDirection = CLIENTTOSERVER; > > sed.Value.SmartFTPD.ByteQuota = -1; > > - sed.Value.SmartFTPD.SeekOffset = offset; > > + sed.Value.SmartFTPD.SeekOffset = -1; /* setting this to 'offset' > > wreaks > > + havoc with dumps > 4GB */ > > sed.Value.SmartFTPD.hashmark = 0; > > - sed.Value.SmartFTPD.Tag = FILEBYNAME; > > - sed.Value.SmartFTPD.FileInfo.ByName.ProtectionBits = 0755; > > - CODA_ASSERT(strlen(rockinfo->dumpfile) < > > - sizeof( sed.Value.SmartFTPD.FileInfo.ByName.LocalFileName)); > > - strcpy(sed.Value.SmartFTPD.FileInfo.ByName.LocalFileName, > > rockinfo->dumpfile); > > + sed.Value.SmartFTPD.Tag = FILEBYFD; > > + sed.Value.SmartFTPD.FileInfo.ByFD.fd = rockinfo->dumpfd; > > > > struct timeval before, after; > > gettimeofday(&before, 0); > > diff --git a/coda-src/volutil/volclient.cc > > b/coda-src/volutil/volclient.cc > > index 0a8fd78..2dc6ccc 100644 > > --- a/coda-src/volutil/volclient.cc > > +++ b/coda-src/volutil/volclient.cc > > @@ -127,9 +127,10 @@ static void pokexmem(void); > > > > #define ROCKTAG 12345 > > struct rockInfo { > > - int fd; /* Open filedescriptor for ReadDump. */ > > + int fd; /* Open filedescriptor for > > ReadDump/WriteDump. */ > > VolumeId volid; /* Volume being dumped. */ > > - unsigned long numbytes; /* Number of bytes already written to the > > file. */ > > + unsigned int numbytes; /* Number of bytes already written to the > > file. > > + (has to wrap around the same way as > > 'offset') */ > > }; > > > > static void V_InitRPC(int timeout); > > @@ -580,18 +581,18 @@ static void dump(void) > > rock->fd = fileno(outf); > > rock->volid = volid; > > rock->numbytes = 0; > > - > > + > > PROCESS dumpPid; > > LWP_CreateProcess(VolDumpLWP, 16 * 1024, LWP_NORMAL_PRIORITY, > > (void *)rock, "VolDumpLWP", &dumpPid); > > - > > + > > rc = VolNewDump(rpcid, volid, &Incremental); > > if (rc != RPC2_SUCCESS) { > > fprintf(stderr, "\nVolDump failed with %s\n", > > RPC2_ErrorMsg((int)rc)); > > exit(-1); > > } > > > > - fprintf(stderr, "\n%sVolDump completed, %lu bytes dumped\n", > > + fprintf(stderr, "\n%sVolDump completed, %u bytes dumped\n", > > Incremental ? "Incremental " : "", rock->numbytes); > > exit(0); > > } > > @@ -673,7 +674,7 @@ long S_WriteDump(RPC2_Handle rpcid, RPC2 > > struct rockInfo *rockinfo; > > SE_Descriptor sed; > > char *rock; > > - > > + > > CODA_ASSERT(LWP_GetRock(ROCKTAG, &rock) == LWP_SUCCESS); > > rockinfo = (struct rockInfo *)rock; > > > > @@ -684,23 +685,24 @@ long S_WriteDump(RPC2_Handle rpcid, RPC2 > > } > > > > if (rockinfo->numbytes != offset) { > > - fprintf(stderr, "Offset %d != rockInfo->numbytes %ld\n", > > + fprintf(stderr, "Offset %d != rockInfo->numbytes %d\n", > > offset, rockinfo->numbytes); > > } > > - > > + > > /* fetch the file with volume data */ > > memset(&sed, 0, sizeof(SE_Descriptor)); > > sed.Tag = SMARTFTP; > > sed.Value.SmartFTPD.TransmissionDirection = CLIENTTOSERVER; > > sed.Value.SmartFTPD.ByteQuota = -1; > > - sed.Value.SmartFTPD.SeekOffset = offset; > > + sed.Value.SmartFTPD.SeekOffset = -1; /* setting this to 'offset' > > wreaks > > + havoc with dumps > 4GB */ > > sed.Value.SmartFTPD.hashmark = 0; > > sed.Value.SmartFTPD.Tag = FILEBYFD; > > sed.Value.SmartFTPD.FileInfo.ByFD.fd = rockinfo->fd; > > > > if ((rc = RPC2_InitSideEffect(rpcid, &sed)) <= RPC2_ELIMIT){ > > fprintf(stderr, "WriteDump: Error %s in InitSideEffect\n", > > RPC2_ErrorMsg((int)rc)); > > - } else if ((rc = RPC2_CheckSideEffect(rpcid, &sed, > > SE_AWAITLOCALSTATUS)) > > + } else if ((rc = RPC2_CheckSideEffect(rpcid, &sed, > > SE_AWAITLOCALSTATUS)) > > <= RPC2_ELIMIT) { > > fprintf(stderr, "WriteDump: Error %s in CheckSideEffect\n", > > RPC2_ErrorMsg((int)rc)); > > } > > @@ -803,7 +805,6 @@ long S_ReadDump(RPC2_Handle rpcid, RPC2_ > > long rc = 0; > > struct rockInfo *rockinfo; > > SE_Descriptor sed; > > - char *buf; > > char *rock; > > > > CODA_ASSERT(LWP_GetRock(ROCKTAG, &rock) == LWP_SUCCESS); > > @@ -818,41 +819,17 @@ long S_ReadDump(RPC2_Handle rpcid, RPC2_ > > exit(-1); > > } > > > > - /* Set up a buffer and read in the data from the dump file. */ > > - buf = (char *)malloc((unsigned int)*nbytes); > > - if (!buf) { > > - perror("ReadDump: Can't malloc buffer!"); > > - exit(-1); > > - } > > - > > CODA_ASSERT(rockinfo->fd != 0); /* Better have been opened by > > restore() */ > > > > - if (lseek(rockinfo->fd, offset, L_SET) == -1) { > > - perror("ReadDump: lseek"); > > - *nbytes = 0; > > - free(buf); > > - return 0; > > - } > > - > > - *nbytes = read(rockinfo->fd, buf, (int)*nbytes); > > - if (*nbytes == -1) { > > - perror("ReadDump: read"); > > - *nbytes = 0; > > - free(buf); > > - return 0; > > - } > > - > > /* fetch the file with volume data */ > > memset(&sed, 0, sizeof(SE_Descriptor)); > > sed.Tag = SMARTFTP; > > sed.Value.SmartFTPD.TransmissionDirection = SERVERTOCLIENT; > > - sed.Value.SmartFTPD.ByteQuota = -1; > > - sed.Value.SmartFTPD.SeekOffset = 0; > > + sed.Value.SmartFTPD.ByteQuota = *nbytes; > > + sed.Value.SmartFTPD.SeekOffset = -1; > > sed.Value.SmartFTPD.hashmark = 0; > > - sed.Value.SmartFTPD.Tag = FILEINVM; > > - sed.Value.SmartFTPD.FileInfo.ByAddr.vmfile.SeqBody = > > (RPC2_ByteSeq)buf; > > - sed.Value.SmartFTPD.FileInfo.ByAddr.vmfile.MaxSeqLen = > > - sed.Value.SmartFTPD.FileInfo.ByAddr.vmfile.SeqLen = *nbytes; > > + sed.Value.SmartFTPD.Tag = FILEBYFD; > > + sed.Value.SmartFTPD.FileInfo.ByFD.fd = rockinfo->fd; > > > > if ((rc = RPC2_InitSideEffect(rpcid, &sed)) <= RPC2_ELIMIT){ > > fprintf(stderr, "ReadDump: Error %s in InitSideEffect\n", > > RPC2_ErrorMsg((int)rc)); > > @@ -867,7 +844,6 @@ #else > > fprintf(stderr, "."); > > #endif > > rockinfo->numbytes += sed.Value.SmartFTPD.BytesTransferred; > > - free(buf); > > return rc; > > } > > > > >Received on 2006-09-06 20:56:23