From da8abcdd09904ce09109737d55347c1a85c77af3 Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Wed, 17 Dec 2008 14:27:46 +0000 Subject: [PATCH] ebl Add patch that use address instead of file:block git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@8177 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/patches/testing/bsr_addr.patch | 494 ++++++++++++++++++++++++++ 1 file changed, 494 insertions(+) create mode 100644 bacula/patches/testing/bsr_addr.patch diff --git a/bacula/patches/testing/bsr_addr.patch b/bacula/patches/testing/bsr_addr.patch new file mode 100644 index 0000000000..1d0142ba7c --- /dev/null +++ b/bacula/patches/testing/bsr_addr.patch @@ -0,0 +1,494 @@ +Index: src/dird/bsr.c +=================================================================== +--- src/dird/bsr.c (révision 8163) ++++ src/dird/bsr.c (copie de travail) +@@ -325,6 +325,7 @@ + */ + static uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, FILE *fd) + { ++ char ed1[50], ed2[50]; + uint32_t count = 0; + uint32_t total_count = 0; + uint32_t LastIndex = 0; +@@ -374,6 +375,8 @@ + fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock, + bsr->VolParams[i].EndBlock); + } ++ fprintf(fd, "VolAddr=%s-%s\n", edit_uint64(bsr->VolParams[i].StartAddr, ed1), ++ edit_uint64(bsr->VolParams[i].EndAddr, ed2)); + // Dmsg2(100, "bsr VolParam FI=%u LI=%u\n", + // bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex); + +@@ -440,6 +443,8 @@ + fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock, + bsr->VolParams[i].EndBlock); + } ++ fprintf(fd, "VolAddr=%s-%s\n", edit_uint64(bsr->VolParams[i].StartAddr, ed1), ++ edit_uint64(bsr->VolParams[i].EndAddr, ed2)); + // Dmsg2(100, "bsr VolParam FI=%u LI=%u\n", + // bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex); + +Index: src/cats/cats.h +=================================================================== +--- src/cats/cats.h (révision 8163) ++++ src/cats/cats.h (copie de travail) +@@ -844,6 +844,8 @@ + uint32_t StartBlock; /* start block on tape */ + uint32_t EndBlock; /* last block */ + int32_t Slot; /* Slot */ ++ uint64_t StartAddr; /* Start address */ ++ uint64_t EndAddr; /* End address */ + // uint32_t Copy; /* identical copy */ + // uint32_t Stripe; /* RAIT strip number */ + }; +Index: src/cats/sql_get.c +=================================================================== +--- src/cats/sql_get.c (révision 8163) ++++ src/cats/sql_get.c (copie de travail) +@@ -463,6 +463,8 @@ + Vols[i].EndFile = str_to_uint64(row[5]); + Vols[i].StartBlock = str_to_uint64(row[6]); + Vols[i].EndBlock = str_to_uint64(row[7]); ++ Vols[i].StartAddr = (((uint64_t)Vols[i].StartFile)<<32) | Vols[i].StartBlock; ++ Vols[i].EndAddr = (((uint64_t)Vols[i].EndFile)<<32) | Vols[i].EndBlock; + // Vols[i].Copy = str_to_uint64(row[8]); + Vols[i].Slot = str_to_uint64(row[9]); + StorageId = str_to_uint64(row[10]); +Index: src/stored/match_bsr.c +=================================================================== +--- src/stored/match_bsr.c (révision 8174) ++++ src/stored/match_bsr.c (copie de travail) +@@ -36,15 +36,6 @@ + + /* + * ***FIXME*** +- * find_smallest_volfile needs to be fixed to only look at items that +- * are not marked as done. Otherwise, it can find a bsr +- * that has already been consumed, and this will cause the +- * bsr to be used, thus we may seek back and re-read the +- * same records, causing an error. This deficiency must +- * be fixed. For the moment, it has been kludged in +- * read_record.c to avoid seeking back if find_next_bsr +- * returns a bsr pointing to a smaller address (file/block). +- * + * Also for efficiency, once a bsr is done, it really should be + * delinked from the bsr chain. This will avoid the above + * problem and make traversal of the bsr chain more efficient. +@@ -73,7 +64,7 @@ + static int match_jobid(BSR *bsr, BSR_JOBID *jobid, SESSION_LABEL *sessrec, bool done); + static int match_findex(BSR *bsr, BSR_FINDEX *findex, DEV_RECORD *rec, bool done); + static int match_volfile(BSR *bsr, BSR_VOLFILE *volfile, DEV_RECORD *rec, bool done); +-static int match_volblock(BSR *bsr, BSR_VOLBLOCK *volblock, DEV_RECORD *rec, bool done); ++static int match_voladdr(BSR *bsr, BSR_VOLADDR *voladdr, DEV_RECORD *rec, bool done); + static int match_stream(BSR *bsr, BSR_STREAM *stream, DEV_RECORD *rec, bool done); + static int match_all(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sessrec, bool done, JCR *jcr); + static int match_block_sesstime(BSR *bsr, BSR_SESSTIME *sesstime, DEV_BLOCK *block); +@@ -255,68 +246,123 @@ + } + + /* +- * ***FIXME*** +- * This routine needs to be fixed to only look at items that +- * are not marked as done. Otherwise, it can find a bsr +- * that has already been consumed, and this will cause the +- * bsr to be used, thus we may seek back and re-read the +- * same records, causing an error. This deficiency must +- * be fixed. For the moment, it has been kludged in +- * read_record.c to avoid seeking back if find_next_bsr +- * returns a bsr pointing to a smaller address (file/block). ++ * Get the smallest address from this voladdr part ++ * Don't use "done" elements + */ ++static bool get_smallest_voladdr(BSR_VOLADDR *va, uint64_t *ret) ++{ ++ bool ok=false; ++ uint64_t min_val=0; ++ ++ for (; va ; va = va->next) { ++ if (!va->done) { ++ if (ok) { ++ min_val = MIN(min_val, va->saddr); ++ } else { ++ min_val = va->saddr; ++ ok=true; ++ } ++ } ++ } ++ *ret = min_val; ++ return ok; ++} ++ ++/* ++ * Get the smallest file number from this volfile part ++ * Don't use "done" elements ++ */ ++static bool get_smallest_volfile(BSR_VOLFILE *vf, uint32_t *ret) ++{ ++ bool ok=false; ++ uint32_t min_val=0; ++ ++ for (; vf ; vf = vf->next) { ++ if (!vf->done) { ++ if (ok) { ++ min_val = MIN(min_val, vf->sfile); ++ } else { ++ min_val = vf->sfile; ++ ok=true; ++ } ++ } ++ } ++ *ret = min_val; ++ return ok; ++} ++ ++/* ++ * Get the smallest block number from this volblock part ++ * Don't use "done" elements ++ */ ++static bool get_smallest_volblock(BSR_VOLBLOCK *vb, uint32_t *ret) ++{ ++ bool ok=false; ++ uint32_t min_val=0; ++ ++ for (; vb ; vb = vb->next) { ++ if (!vb->done) { ++ if (ok) { ++ min_val = MIN(min_val, vb->sblock); ++ } else { ++ min_val = vb->sblock; ++ ok=true; ++ } ++ } ++ } ++ *ret = min_val; ++ return ok; ++} ++ ++/* ++ * ++ */ + static BSR *find_smallest_volfile(BSR *found_bsr, BSR *bsr) + { + BSR *return_bsr = found_bsr; +- BSR_VOLFILE *vf; +- BSR_VOLBLOCK *vb; +- uint32_t found_bsr_sfile, bsr_sfile; +- uint32_t found_bsr_sblock, bsr_sblock; ++ uint32_t found_bsr_sfile=0, bsr_sfile=0; ++ uint32_t found_bsr_sblock=0, bsr_sblock=0; ++ uint64_t found_bsr_saddr=0, bsr_saddr=0; + +- /* Find the smallest file in the found_bsr */ +- vf = found_bsr->volfile; +- found_bsr_sfile = vf->sfile; +- while ( (vf=vf->next) ) { +- if (vf->sfile < found_bsr_sfile) { +- found_bsr_sfile = vf->sfile; ++ /* if we have VolAddr, use it, else try with File and Block */ ++ if (get_smallest_voladdr(found_bsr->voladdr, &found_bsr_saddr)) { ++ if (get_smallest_voladdr(bsr->voladdr, &bsr_saddr)) { ++ if (found_bsr_saddr > bsr_saddr) { ++ return bsr; ++ } else { ++ return found_bsr; ++ } + } + } + +- /* Find the smallest file in the bsr */ +- vf = bsr->volfile; +- bsr_sfile = vf->sfile; +- while ( (vf=vf->next) ) { +- if (vf->sfile < bsr_sfile) { +- bsr_sfile = vf->sfile; +- } ++ if (!get_smallest_volfile(found_bsr->volfile, &found_bsr_sfile)) { ++ return bsr; /* found_bsr seems to be done...*/ + } ++ ++ if (!get_smallest_volfile(bsr->volfile, &bsr_sfile)) { ++ return found_bsr; /* bsr seems to be done... */ ++ } + + /* if the bsr file is less than the found_bsr file, return bsr */ + if (found_bsr_sfile > bsr_sfile) { + return_bsr = bsr; + } else if (found_bsr_sfile == bsr_sfile) { +- /* Files are equal */ +- /* find smallest block in found_bsr */ +- vb = found_bsr->volblock; +- found_bsr_sblock = vb->sblock; +- while ( (vb=vb->next) ) { +- if (vb->sblock < found_bsr_sblock) { +- found_bsr_sblock = vb->sblock; +- } ++ /* Files are equal, use block to find the smallest */ ++ if (!get_smallest_volblock(found_bsr->volblock, &found_bsr_sblock)) { ++ return bsr; /* Should not be there */ + } +- /* Find smallest block in bsr */ +- vb = bsr->volblock; +- bsr_sblock = vb->sblock; +- while ( (vb=vb->next) ) { +- if (vb->sblock < bsr_sblock) { +- bsr_sblock = vb->sblock; +- } ++ ++ if (!get_smallest_volblock(bsr->volblock, &bsr_sblock)) { ++ return found_bsr; /* Should not be there */ + } ++ + /* Compare and return the smallest */ + if (found_bsr_sblock > bsr_sblock) { + return_bsr = bsr; + } + } ++ Dmsg5(dbglevel, "find_smallest_volfile bsr=0x%p %i > %i | %i > %i\n", ++ return_bsr, found_bsr_sfile, bsr_sfile, found_bsr_sblock, bsr_sblock); + return return_bsr; + } + +@@ -381,13 +427,11 @@ + Dmsg3(dbglevel, "OK bsr file=%u. bsr=%u,%u\n", + rec->File, bsr->volfile->sfile, bsr->volfile->efile); + +- if (!match_volblock(bsr, bsr->volblock, rec, 1)) { +- Dmsg3(dbglevel, "Fail on Block=%u. bsr=%u,%u\n", +- rec->Block, bsr->volblock->sblock, bsr->volblock->eblock); ++ if (!match_voladdr(bsr, bsr->voladdr, rec, 1)) { ++ Dmsg3(dbglevel, "Fail on Addr=%lld. bsr=%lld,%lld\n", ++ rec->Addr, bsr->voladdr->saddr, bsr->voladdr->eaddr); + goto no_match; + } +- Dmsg3(dbglevel, "OK bsr Block=%u. bsr=%u,%u\n", +- rec->Block, bsr->volblock->sblock, bsr->volblock->eblock); + + if (!match_sesstime(bsr, bsr->sesstime, rec, 1)) { + Dmsg2(dbglevel, "Fail on sesstime. bsr=%u rec=%u\n", +@@ -605,42 +649,34 @@ + return 0; + } + +-static int match_volblock(BSR *bsr, BSR_VOLBLOCK *volblock, DEV_RECORD *rec, bool done) ++static int match_voladdr(BSR *bsr, BSR_VOLADDR *voladdr, DEV_RECORD *rec, bool done) + { +- /* +- * Currently block matching does not work correctly for disk +- * files in all cases, so it is "turned off" by the following +- * return statement. +- */ +- return 1; +- +- +- if (!volblock) { ++ if (!voladdr) { + return 1; /* no specification matches all */ + } + /* For the moment, these tests work only with disk. */ + if (rec->state & REC_ISTAPE) { + return 1; /* All File records OK for this match */ + } +-// Dmsg3(dbglevel, "match_volblock: sblock=%u eblock=%u recblock=%u\n", +-// volblock->sblock, volblock->eblock, rec->Block); +- if (volblock->sblock <= rec->Block && volblock->eblock >= rec->Block) { ++// Dmsg3(dbglevel, "match_voladdr: saddr=%q eaddr=%q recaddr=%q\n", ++// volblock->saddr, volblock->eaddr, rec->Addr); ++ if (voladdr->saddr <= rec->Addr && voladdr->eaddr >= rec->Addr) { + return 1; + } + /* Once we get past last eblock, we are done */ +- if (rec->Block > volblock->eblock) { +- volblock->done = true; /* set local done */ ++ if (rec->Addr > voladdr->eaddr) { ++ voladdr->done = true; /* set local done */ + } +- if (volblock->next) { +- return match_volblock(bsr, volblock->next, rec, volblock->done && done); ++ if (voladdr->next) { ++ return match_voladdr(bsr, voladdr->next, rec, voladdr->done && done); + } + + /* If we are done and all prior matches are done, this bsr is finished */ +- if (volblock->done && done) { ++ if (voladdr->done && done) { + bsr->done = true; + bsr->root->reposition = true; +- Dmsg2(dbglevel, "bsr done from volblock rec=%u voleblock=%u\n", +- rec->Block, volblock->eblock); ++ Dmsg2(dbglevel, "bsr done from voladdr rec=%q voleaddr=%q\n", ++ rec->Addr, voladdr->eaddr); + } + return 0; + } +Index: src/stored/parse_bsr.c +=================================================================== +--- src/stored/parse_bsr.c (révision 8163) ++++ src/stored/parse_bsr.c (copie de travail) +@@ -52,6 +52,7 @@ + static BSR *store_sessid(LEX *lc, BSR *bsr); + static BSR *store_volfile(LEX *lc, BSR *bsr); + static BSR *store_volblock(LEX *lc, BSR *bsr); ++static BSR *store_voladdr(LEX *lc, BSR *bsr); + static BSR *store_sesstime(LEX *lc, BSR *bsr); + static BSR *store_include(LEX *lc, BSR *bsr); + static BSR *store_exclude(LEX *lc, BSR *bsr); +@@ -85,6 +86,7 @@ + {"exclude", store_exclude}, + {"volfile", store_volfile}, + {"volblock", store_volblock}, ++ {"voladdr", store_voladdr}, + {"stream", store_stream}, + {"slot", store_slot}, + {"device", store_device}, +@@ -212,17 +214,17 @@ + { + /* + * Every bsr should have a volfile entry and a volblock entry ++ * or a VolAddr + * if we are going to use positioning + */ + for ( ; bsr; bsr=bsr->next) { +- if (!bsr->volfile || !bsr->volblock) { ++ if (!((bsr->volfile && bsr->volblock) || bsr->voladdr)) { + return false; + } + } + return true; + } + +- + static BSR *store_vol(LEX *lc, BSR *bsr) + { + int token; +@@ -563,7 +565,41 @@ + return bsr; + } + ++/* ++ * Routine to handle Volume start/end address ++ */ ++static BSR *store_voladdr(LEX *lc, BSR *bsr) ++{ ++ int token; ++ BSR_VOLADDR *voladdr; + ++ for (;;) { ++ token = lex_get_token(lc, T_PINT64_RANGE); ++ if (token == T_ERROR) { ++ return NULL; ++ } ++ voladdr = (BSR_VOLADDR *)malloc(sizeof(BSR_VOLADDR)); ++ memset(voladdr, 0, sizeof(BSR_VOLADDR)); ++ voladdr->saddr = lc->pint64_val; ++ voladdr->eaddr = lc->pint64_val2; ++ /* Add it to the end of the chain */ ++ if (!bsr->voladdr) { ++ bsr->voladdr = voladdr; ++ } else { ++ /* Add to end of chain */ ++ BSR_VOLADDR *bs = bsr->voladdr; ++ for ( ;bs->next; bs=bs->next) ++ { } ++ bs->next = voladdr; ++ } ++ token = lex_get_token(lc, T_ALL); ++ if (token != T_COMMA) { ++ break; ++ } ++ } ++ return bsr; ++} ++ + static BSR *store_sessid(LEX *lc, BSR *bsr) + { + int token; +@@ -705,6 +741,13 @@ + } + } + ++void dump_voladdr(BSR_VOLADDR *voladdr) ++{ ++ if (voladdr) { ++ Pmsg2(-1, _("VolAddr : %lld-%lld\n"), voladdr->saddr, voladdr->eaddr); ++ dump_voladdr(voladdr->next); ++ } ++} + + void dump_findex(BSR_FINDEX *FileIndex) + { +@@ -795,6 +838,7 @@ + dump_sesstime(bsr->sesstime); + dump_volfile(bsr->volfile); + dump_volblock(bsr->volblock); ++ dump_voladdr(bsr->voladdr); + dump_client(bsr->client); + dump_jobid(bsr->JobId); + dump_job(bsr->job); +@@ -840,6 +884,7 @@ + free_bsr_item((BSR *)bsr->sesstime); + free_bsr_item((BSR *)bsr->volfile); + free_bsr_item((BSR *)bsr->volblock); ++ free_bsr_item((BSR *)bsr->voladdr); + free_bsr_item((BSR *)bsr->JobId); + free_bsr_item((BSR *)bsr->job); + free_bsr_item((BSR *)bsr->FileIndex); +Index: src/stored/record.c +=================================================================== +--- src/stored/record.c (révision 8163) ++++ src/stored/record.c (copie de travail) +@@ -210,7 +210,7 @@ + + void empty_record(DEV_RECORD *rec) + { +- rec->File = rec->Block = 0; ++ rec->Addr = rec->File = rec->Block = 0; + rec->VolSessionId = rec->VolSessionTime = 0; + rec->FileIndex = rec->Stream = 0; + rec->data_len = rec->remainder = 0; +@@ -455,8 +455,8 @@ + rec->Block = ((DEVICE *)block->dev)->EndBlock; + rec->File = ((DEVICE *)block->dev)->EndFile; + } ++ rec->Addr = ((boffset_t)rec->File)<<32 | rec->Block; + +- + /* + * Get the header. There is always a full header, + * otherwise we find it in the next block. +Index: src/stored/record.h +=================================================================== +--- src/stored/record.h (révision 8163) ++++ src/stored/record.h (copie de travail) +@@ -97,6 +97,7 @@ + */ + uint32_t File; /* File number */ + uint32_t Block; /* Block number */ ++ uint64_t Addr; /* Block address */ + uint32_t VolSessionId; /* sequential id within this session */ + uint32_t VolSessionTime; /* session start time */ + int32_t FileIndex; /* sequential file number */ +Index: src/stored/bsr.h +=================================================================== +--- src/stored/bsr.h (révision 8163) ++++ src/stored/bsr.h (copie de travail) +@@ -106,6 +106,12 @@ + bool done; /* local done */ + }; + ++struct BSR_VOLADDR { ++ BSR_VOLADDR *next; ++ uint64_t saddr; /* start address */ ++ uint64_t eaddr; /* end address */ ++ bool done; /* local done */ ++}; + + struct BSR_FINDEX { + BSR_FINDEX *next; +@@ -157,6 +163,7 @@ + uint32_t found; /* count of restored files this bsr */ + BSR_VOLFILE *volfile; + BSR_VOLBLOCK *volblock; ++ BSR_VOLADDR *voladdr; + BSR_SESSTIME *sesstime; + BSR_SESSID *sessid; + BSR_JOBID *JobId; -- 2.39.5