X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=bacula%2Fsrc%2Fstored%2Fparse_bsr.c;h=f4c631b39827bb89693f11c438c6f0bff066f216;hb=2499795e233e43bd4eb4d99e0473b67e6c6b60d8;hp=f5076ee584c9d769c6fbca360068802a54255648;hpb=043dfdbe5bb4cec577c9000959f051b83c270b08;p=bacula%2Fbacula diff --git a/bacula/src/stored/parse_bsr.c b/bacula/src/stored/parse_bsr.c old mode 100755 new mode 100644 index f5076ee584..f4c631b398 --- a/bacula/src/stored/parse_bsr.c +++ b/bacula/src/stored/parse_bsr.c @@ -1,3 +1,30 @@ +/* + Bacula® - The Network Backup Solution + + Copyright (C) 2002-2009 Free Software Foundation Europe e.V. + + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version two of the GNU General Public + License as published by the Free Software Foundation and included + in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + Bacula® is a registered trademark of Kern Sibbald. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +*/ /* * Parse a Bootstrap Records (used for restores) * @@ -6,21 +33,6 @@ * Version $Id$ */ -/* - Copyright (C) 2002-2005 Kern Sibbald - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as amended with additional clauses defined in the - file LICENSE in the main source directory. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - the file LICENSE for additional details. - - */ - #include "bacula.h" #include "stored.h" @@ -29,6 +41,7 @@ typedef BSR * (ITEM_HANDLER)(LEX *lc, BSR *bsr); static BSR *store_vol(LEX *lc, BSR *bsr); static BSR *store_mediatype(LEX *lc, BSR *bsr); +static BSR *store_device(LEX *lc, BSR *bsr); static BSR *store_client(LEX *lc, BSR *bsr); static BSR *store_job(LEX *lc, BSR *bsr); static BSR *store_jobid(LEX *lc, BSR *bsr); @@ -39,11 +52,14 @@ static BSR *store_findex(LEX *lc, BSR *bsr); 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); static BSR *store_stream(LEX *lc, BSR *bsr); static BSR *store_slot(LEX *lc, BSR *bsr); +static BSR *store_fileregex(LEX *lc, BSR *bsr); +static BSR *store_nothing(LEX *lc, BSR *bsr); static bool is_fast_rejection_ok(BSR *bsr); static bool is_positioning_ok(BSR *bsr); @@ -71,10 +87,13 @@ struct kw_items items[] = { {"exclude", store_exclude}, {"volfile", store_volfile}, {"volblock", store_volblock}, - {"stream", store_stream}, - {"slot", store_slot}, + {"voladdr", store_voladdr}, + {"stream", store_stream}, + {"slot", store_slot}, + {"device", store_device}, + {"fileregex", store_fileregex}, + {"storage", store_nothing}, {NULL, NULL} - }; /* @@ -124,28 +143,28 @@ BSR *parse_bsr(JCR *jcr, char *fname) BSR *root_bsr = new_bsr(); BSR *bsr = root_bsr; - Dmsg1(200, "Enter parse_bsf %s\n", fname); + Dmsg1(300, "Enter parse_bsf %s\n", fname); if ((lc = lex_open_file(lc, fname, s_err)) == NULL) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Cannot open bootstrap file %s: %s\n"), - fname, be.strerror()); + fname, be.bstrerror()); } lc->caller_ctx = (void *)jcr; while ((token=lex_get_token(lc, T_ALL)) != T_EOF) { - Dmsg1(200, "parse got token=%s\n", lex_tok_to_str(token)); + Dmsg1(300, "parse got token=%s\n", lex_tok_to_str(token)); if (token == T_EOL) { continue; } for (i=0; items[i].name; i++) { if (strcasecmp(items[i].name, lc->str) == 0) { token = lex_get_token(lc, T_ALL); - Dmsg1 (200, "in T_IDENT got token=%s\n", lex_tok_to_str(token)); + Dmsg1 (300, "in T_IDENT got token=%s\n", lex_tok_to_str(token)); if (token != T_EQUALS) { scan_err1(lc, "expected an equals, got: %s", lc->str); bsr = NULL; break; } - Dmsg1(200, "calling handler for %s\n", items[i].name); + Dmsg1(300, "calling handler for %s\n", items[i].name); /* Call item handler */ bsr = items[i].handler(lc, bsr); i = -1; @@ -153,7 +172,7 @@ BSR *parse_bsr(JCR *jcr, char *fname) } } if (i >= 0) { - Dmsg1(200, "Keyword = %s\n", lc->str); + Dmsg1(300, "Keyword = %s\n", lc->str); scan_err1(lc, "Keyword %s not found", lc->str); bsr = NULL; break; @@ -163,7 +182,7 @@ BSR *parse_bsr(JCR *jcr, char *fname) } } lc = lex_close_file(lc); - Dmsg0(200, "Leave parse_bsf()\n"); + Dmsg0(300, "Leave parse_bsf()\n"); if (!bsr) { free_bsr(root_bsr); root_bsr = NULL; @@ -197,17 +216,17 @@ static bool is_positioning_ok(BSR *bsr) { /* * 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; @@ -220,6 +239,7 @@ static BSR *store_vol(LEX *lc, BSR *bsr) } if (bsr->volume) { bsr->next = new_bsr(); + bsr->next->prev = bsr; bsr = bsr->next; } /* This may actually be more than one volume separated by a | @@ -268,6 +288,39 @@ static BSR *store_mediatype(LEX *lc, BSR *bsr) return bsr; } +static BSR *store_nothing(LEX *lc, BSR *bsr) +{ + int token; + + token = lex_get_token(lc, T_STRING); + if (token == T_ERROR) { + return NULL; + } + return bsr; +} + +/* Shove the Device name in each Volume in the current bsr */ +static BSR *store_device(LEX *lc, BSR *bsr) +{ + int token; + + token = lex_get_token(lc, T_STRING); + if (token == T_ERROR) { + return NULL; + } + if (!bsr->volume) { + Emsg1(M_ERROR,0, _("Device \"%s\" in bsr at inappropriate place.\n"), + lc->str); + return bsr; + } + BSR_VOLUME *bv; + for (bv=bsr->volume; bv; bv=bv->next) { + bstrncpy(bv->device, lc->str, sizeof(bv->device)); + } + return bsr; +} + + static BSR *store_client(LEX *lc, BSR *bsr) { @@ -409,6 +462,32 @@ static BSR *store_count(LEX *lc, BSR *bsr) return bsr; } +static BSR *store_fileregex(LEX *lc, BSR *bsr) +{ + int token; + int rc; + + token = lex_get_token(lc, T_STRING); + if (token == T_ERROR) { + return NULL; + } + + if (bsr->fileregex) free(bsr->fileregex); + bsr->fileregex = bstrdup(lc->str); + + if (bsr->fileregex_re == NULL) + bsr->fileregex_re = (regex_t *)bmalloc(sizeof(regex_t)); + + rc = regcomp(bsr->fileregex_re, bsr->fileregex, REG_EXTENDED|REG_NOSUB); + if (rc != 0) { + char prbuf[500]; + regerror(rc, bsr->fileregex_re, prbuf, sizeof(prbuf)); + Emsg2(M_ERROR, 0, _("REGEX '%s' compile error. ERR=%s\n"), + bsr->fileregex, prbuf); + return NULL; + } + return bsr; +} static BSR *store_jobtype(LEX *lc, BSR *bsr) { @@ -499,6 +578,40 @@ static BSR *store_volblock(LEX *lc, BSR *bsr) 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) { @@ -603,7 +716,12 @@ static BSR *store_slot(LEX *lc, BSR *bsr) if (token == T_ERROR) { return NULL; } - bsr->Slot = lc->pint32_val; + if (!bsr->volume) { + Emsg1(M_ERROR,0, _("Slot %d in bsr at inappropriate place.\n"), + lc->pint32_val); + return bsr; + } + bsr->volume->Slot = lc->pint32_val; scan_to_eol(lc); return bsr; } @@ -636,6 +754,13 @@ void dump_volblock(BSR_VOLBLOCK *volblock) } } +void dump_voladdr(BSR_VOLADDR *voladdr) +{ + if (voladdr) { + Pmsg2(-1, _("VolAddr : %llu-%llu\n"), voladdr->saddr, voladdr->eaddr); + dump_voladdr(voladdr->next); + } +} void dump_findex(BSR_FINDEX *FileIndex) { @@ -677,6 +802,9 @@ void dump_volume(BSR_VOLUME *volume) { if (volume) { Pmsg1(-1, _("VolumeName : %s\n"), volume->VolumeName); + Pmsg1(-1, _(" MediaType : %s\n"), volume->MediaType); + Pmsg1(-1, _(" Device : %s\n"), volume->device); + Pmsg1(-1, _(" Slot : %d\n"), volume->Slot); dump_volume(volume->next); } } @@ -707,9 +835,6 @@ void dump_sesstime(BSR_SESSTIME *sesstime) } - - - void dump_bsr(BSR *bsr, bool recurse) { int save_debug = debug_level; @@ -726,13 +851,11 @@ void dump_bsr(BSR *bsr, bool recurse) 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); dump_findex(bsr->FileIndex); - if (bsr->Slot) { - Pmsg1(-1, _("Slot : %u\n"), bsr->Slot); - } if (bsr->count) { Pmsg1(-1, _("count : %u\n"), bsr->count); Pmsg1(-1, _("found : %u\n"), bsr->found); @@ -763,30 +886,63 @@ static void free_bsr_item(BSR *bsr) } } -void free_bsr(BSR *bsr) +/* + * Remove a single item from the bsr tree + */ +void remove_bsr(BSR *bsr) { - if (!bsr) { - return; - } free_bsr_item((BSR *)bsr->volume); free_bsr_item((BSR *)bsr->client); free_bsr_item((BSR *)bsr->sessid); 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); free_bsr_item((BSR *)bsr->JobType); free_bsr_item((BSR *)bsr->JobLevel); - free_bsr(bsr->next); + if (bsr->fileregex) { + bfree(bsr->fileregex); + } + if (bsr->fileregex_re) { + regfree(bsr->fileregex_re); + free(bsr->fileregex_re); + } + if (bsr->attr) { + free_attr(bsr->attr); + } + if (bsr->next) { + bsr->next->prev = bsr->prev; + } + if (bsr->prev) { + bsr->prev->next = bsr->next; + } free(bsr); } +/* + * Free all bsrs in chain + */ +void free_bsr(BSR *bsr) +{ + BSR *next_bsr; + + if (!bsr) { + return; + } + next_bsr = bsr->next; + /* Remove (free) current bsr */ + remove_bsr(bsr); + /* Now get the next one */ + free_bsr(next_bsr); +} + /***************************************************************** * Routines for handling volumes */ -VOL_LIST *new_restore_volume() +static VOL_LIST *new_restore_volume() { VOL_LIST *vol; vol = (VOL_LIST *)malloc(sizeof(VOL_LIST)); @@ -801,41 +957,48 @@ VOL_LIST *new_restore_volume() * returns: 1 if volume added * 0 if volume already in list */ -int add_restore_volume(JCR *jcr, VOL_LIST *vol) +static bool add_restore_volume(JCR *jcr, VOL_LIST *vol) { VOL_LIST *next = jcr->VolList; + /* Add volume to volume manager's read list */ + add_read_volume(jcr, vol->VolumeName); + if (!next) { /* list empty ? */ jcr->VolList = vol; /* yes, add volume */ } else { + /* Loop through all but last */ for ( ; next->next; next=next->next) { if (strcmp(vol->VolumeName, next->VolumeName) == 0) { + /* Save smallest start file */ if (vol->start_file < next->start_file) { next->start_file = vol->start_file; } - return 0; /* already in list */ + return false; /* already in list */ } } + /* Check last volume in list */ if (strcmp(vol->VolumeName, next->VolumeName) == 0) { if (vol->start_file < next->start_file) { next->start_file = vol->start_file; } - return 0; /* already in list */ + return false; /* already in list */ } next->next = vol; /* add volume */ } - return 1; + return true; } void free_restore_volume_list(JCR *jcr) { - VOL_LIST *next = jcr->VolList; + VOL_LIST *vol = jcr->VolList; VOL_LIST *tmp; - for ( ; next; ) { - tmp = next->next; - free(next); - next = tmp; + for ( ; vol; ) { + tmp = vol->next; + remove_read_volume(jcr, vol->VolumeName); + free(vol); + vol = tmp; } jcr->VolList = NULL; } @@ -852,8 +1015,8 @@ void create_restore_volume_list(JCR *jcr) /* * Build a list of volumes to be processed */ - jcr->NumVolumes = 0; - jcr->CurVolume = 0; + jcr->NumReadVolumes = 0; + jcr->CurReadVolume = 0; if (jcr->bsr) { BSR *bsr = jcr->bsr; if (!bsr->volume || !bsr->volume->VolumeName) { @@ -875,9 +1038,11 @@ void create_restore_volume_list(JCR *jcr) vol = new_restore_volume(); bstrncpy(vol->VolumeName, bsrvol->VolumeName, sizeof(vol->VolumeName)); bstrncpy(vol->MediaType, bsrvol->MediaType, sizeof(vol->MediaType)); + bstrncpy(vol->device, bsrvol->device, sizeof(vol->device)); + vol->Slot = bsrvol->Slot; vol->start_file = sfile; if (add_restore_volume(jcr, vol)) { - jcr->NumVolumes++; + jcr->NumReadVolumes++; Dmsg2(400, "Added volume=%s mediatype=%s\n", vol->VolumeName, vol->MediaType); } else { @@ -898,7 +1063,7 @@ void create_restore_volume_list(JCR *jcr) bstrncpy(vol->VolumeName, p, sizeof(vol->VolumeName)); bstrncpy(vol->MediaType, jcr->dcr->media_type, sizeof(vol->MediaType)); if (add_restore_volume(jcr, vol)) { - jcr->NumVolumes++; + jcr->NumReadVolumes++; } else { free((char *)vol); }