From 0eab712b22255cdd2cfdb9afb9156ed117fcf4c8 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 4 Sep 2005 15:47:12 +0000 Subject: [PATCH] Fix out of order volumes during restore. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2375 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kes-1.37 | 4 + bacula/src/dird/bsr.c | 187 +++-- bacula/src/dird/bsr.h | 17 +- bacula/src/dird/protos.h | 45 +- bacula/src/dird/ua.h | 37 + bacula/src/dird/ua_output.c | 3 +- bacula/src/dird/ua_restore.c | 728 +++++++++--------- bacula/src/dird/verify.c | 21 +- .../gnome2-console/test-gnome-console.conf | 2 +- bacula/src/lib/mem_pool.c | 80 +- bacula/src/version.h | 6 +- 11 files changed, 610 insertions(+), 520 deletions(-) diff --git a/bacula/kes-1.37 b/bacula/kes-1.37 index 872460643a..333f269dc9 100644 --- a/bacula/kes-1.37 +++ b/bacula/kes-1.37 @@ -3,6 +3,10 @@ General: +Changes to 1.37.38: +04Sep05 +- Fix out of order volumes during restore. + Changes to 1.37.37: 30Aug05 - Final tweaks to build Win32. diff --git a/bacula/src/dird/bsr.c b/bacula/src/dird/bsr.c index 36c15553ae..96ff865de5 100644 --- a/bacula/src/dird/bsr.c +++ b/bacula/src/dird/bsr.c @@ -29,7 +29,7 @@ #include "dird.h" /* Forward referenced functions */ -static uint32_t write_bsr(UAContext *ua, RBSR *bsr, FILE *fd); +static uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, FILE *fd); void print_bsr(UAContext *ua, RBSR *bsr); @@ -111,10 +111,10 @@ static void print_findex(UAContext *ua, RBSR_FINDEX *fi) for ( ; fi; fi=fi->next) { if (fi->findex == fi->findex2) { bsendmsg(ua, "FileIndex=%d\n", fi->findex); -// Dmsg1(100, "FileIndex=%d\n", fi->findex); + Dmsg1(1000, "FileIndex=%d\n", fi->findex); } else { bsendmsg(ua, "FileIndex=%d-%d\n", fi->findex, fi->findex2); -// Dmsg2(100, "FileIndex=%d-%d\n", fi->findex, fi->findex2); + Dmsg2(1000, "FileIndex=%d-%d\n", fi->findex, fi->findex2); } } } @@ -187,12 +187,14 @@ void make_unique_restore_filename(UAContext *ua, POOLMEM **fname) /* * Write the bootstrap records to file */ -uint32_t write_bsr_file(UAContext *ua, RBSR *bsr) +uint32_t write_bsr_file(UAContext *ua, RESTORE_CTX &rx) { FILE *fd; POOLMEM *fname = get_pool_memory(PM_MESSAGE); uint32_t count = 0;; bool err; + char *p; + JobId_t JobId; make_unique_restore_filename(ua, &fname); fd = fopen(fname, "w+"); @@ -203,7 +205,7 @@ uint32_t write_bsr_file(UAContext *ua, RBSR *bsr) goto bail_out; } /* Write them to file */ - count = write_bsr(ua, bsr, fd); + count = write_bsr(ua, rx, fd); err = ferror(fd); fclose(fd); if (err) { @@ -220,10 +222,27 @@ uint32_t write_bsr_file(UAContext *ua, RBSR *bsr) bsendmsg(ua, _("The job will require the following Volumes:\n")); /* Create Unique list of Volumes using prompt list */ start_prompt(ua, ""); - for (RBSR *nbsr=bsr; nbsr; nbsr=nbsr->next) { - for (int i=0; i < nbsr->VolCount; i++) { - if (nbsr->VolParams[i].VolumeName[0]) { - add_prompt(ua, nbsr->VolParams[i].VolumeName); + if (*rx.JobIds) { + /* Ensure that the volumes are printed in JobId order */ + for (p=rx.JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { + for (RBSR *nbsr=rx.bsr; nbsr; nbsr=nbsr->next) { + if (JobId != nbsr->JobId) { + continue; + } + for (int i=0; i < nbsr->VolCount; i++) { + if (nbsr->VolParams[i].VolumeName[0]) { + add_prompt(ua, nbsr->VolParams[i].VolumeName); + } + } + } + } + } else { + /* Print Volumes in any order */ + for (RBSR *nbsr=rx.bsr; nbsr; nbsr=nbsr->next) { + for (int i=0; i < nbsr->VolCount; i++) { + if (nbsr->VolParams[i].VolumeName[0]) { + add_prompt(ua, nbsr->VolParams[i].VolumeName); + } } } } @@ -243,57 +262,123 @@ bail_out: return count; } -static uint32_t write_bsr(UAContext *ua, RBSR *bsr, FILE *fd) +/* + * Here we actually write out the details of the bsr file. + * Note, there is one bsr for each JobId, but the bsr may + * have multiple volumes, which have been entered in the + * order they were written. + * The bsrs must be written out in the order the JobIds + * are found in the jobid list. + */ +static uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, FILE *fd) { uint32_t count = 0; uint32_t total_count = 0; uint32_t LastIndex = 0; bool first = true; - for ( ; bsr; bsr=bsr->next) { - /* - * For a given volume, loop over all the JobMedia records. - * VolCount is the number of JobMedia records. - */ - for (int i=0; i < bsr->VolCount; i++) { - if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex, - bsr->VolParams[i].LastIndex)) { - bsr->VolParams[i].VolumeName[0] = 0; /* zap VolumeName */ - continue; - } - fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName); - fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType); - fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId); - fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime); - if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) { - fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile); - } else { - fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile, - bsr->VolParams[i].EndFile); - } - if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) { - fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock); - } else { - fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock, - bsr->VolParams[i].EndBlock); + char *p; + JobId_t JobId; + RBSR *bsr; + if (*rx.JobIds == 0) { + for (bsr=rx.bsr; bsr; bsr=bsr->next) { + /* + * For a given volume, loop over all the JobMedia records. + * VolCount is the number of JobMedia records. + */ + for (int i=0; i < bsr->VolCount; i++) { + if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex, + bsr->VolParams[i].LastIndex)) { + bsr->VolParams[i].VolumeName[0] = 0; /* zap VolumeName */ + continue; + } + fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName); + fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType); + fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId); + fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime); + if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) { + fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile); + } else { + fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile, + bsr->VolParams[i].EndFile); + } + if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) { + fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock); + } else { + fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock, + bsr->VolParams[i].EndBlock); + } + // Dmsg2(100, "bsr VolParam FI=%u LI=%u\n", + // bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex); + + count = write_findex(ua, bsr->fi, bsr->VolParams[i].FirstIndex, + bsr->VolParams[i].LastIndex, fd); + if (count) { + fprintf(fd, "Count=%u\n", count); + } + total_count += count; + /* If the same file is present on two tapes or in two files + * on a tape, it is a continuation, and should not be treated + * twice in the totals. + */ + if (!first && LastIndex == bsr->VolParams[i].FirstIndex) { + total_count--; + } + first = false; + LastIndex = bsr->VolParams[i].LastIndex; } -// Dmsg2(100, "bsr VolParam FI=%u LI=%u\n", -// bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex); - - count = write_findex(ua, bsr->fi, bsr->VolParams[i].FirstIndex, - bsr->VolParams[i].LastIndex, fd); - if (count) { - fprintf(fd, "Count=%u\n", count); + } + return total_count; + } + for (p=rx.JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { + for (bsr=rx.bsr; bsr; bsr=bsr->next) { + if (JobId != bsr->JobId) { + continue; } - total_count += count; - /* If the same file is present on two tapes or in two files - * on a tape, it is a continuation, and should not be treated - * twice in the totals. + /* + * For a given volume, loop over all the JobMedia records. + * VolCount is the number of JobMedia records. */ - if (!first && LastIndex == bsr->VolParams[i].FirstIndex) { - total_count--; + for (int i=0; i < bsr->VolCount; i++) { + if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex, + bsr->VolParams[i].LastIndex)) { + bsr->VolParams[i].VolumeName[0] = 0; /* zap VolumeName */ + continue; + } + fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName); + fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType); + fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId); + fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime); + if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) { + fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile); + } else { + fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile, + bsr->VolParams[i].EndFile); + } + if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) { + fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock); + } else { + fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock, + bsr->VolParams[i].EndBlock); + } + // Dmsg2(100, "bsr VolParam FI=%u LI=%u\n", + // bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex); + + count = write_findex(ua, bsr->fi, bsr->VolParams[i].FirstIndex, + bsr->VolParams[i].LastIndex, fd); + if (count) { + fprintf(fd, "Count=%u\n", count); + } + total_count += count; + /* If the same file is present on two tapes or in two files + * on a tape, it is a continuation, and should not be treated + * twice in the totals. + */ + if (!first && LastIndex == bsr->VolParams[i].FirstIndex) { + total_count--; + } + first = false; + LastIndex = bsr->VolParams[i].LastIndex; } - first = false; - LastIndex = bsr->VolParams[i].LastIndex; } } return total_count; diff --git a/bacula/src/dird/bsr.h b/bacula/src/dird/bsr.h index e89025e5f6..3b299dd3ac 100644 --- a/bacula/src/dird/bsr.h +++ b/bacula/src/dird/bsr.h @@ -14,19 +14,14 @@ 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 as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. + 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 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., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -48,7 +43,7 @@ struct RBSR_FINDEX { */ struct RBSR { RBSR *next; /* next JobId */ - uint32_t JobId; /* JobId this bsr */ + JobId_t JobId; /* JobId this bsr */ uint32_t VolSessionId; uint32_t VolSessionTime; int VolCount; /* Volume parameter count */ diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 085937b64b..8917124961 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -48,7 +48,7 @@ extern void backup_cleanup(JCR *jcr, int TermCode); RBSR *new_bsr(); void free_bsr(RBSR *bsr); bool complete_bsr(UAContext *ua, RBSR *bsr); -uint32_t write_bsr_file(UAContext *ua, RBSR *bsr); +uint32_t write_bsr_file(UAContext *ua, RESTORE_CTX &rx); void add_findex(RBSR *bsr, uint32_t JobId, int32_t findex); void add_findex_all(RBSR *bsr, uint32_t JobId); RBSR_FINDEX *new_findex(); @@ -68,7 +68,7 @@ int variable_expansion(JCR *jcr, char *inp, POOLMEM **exp); /* fd_cmds.c */ extern int connect_to_file_daemon(JCR *jcr, int retry_interval, - int max_retry_time, int verbose); + int max_retry_time, int verbose); extern bool send_include_list(JCR *jcr); extern bool send_exclude_list(JCR *jcr); extern bool send_bootstrap_file(JCR *jcr); @@ -76,7 +76,7 @@ extern bool send_level_command(JCR *jcr); extern int get_attributes_and_put_in_catalog(JCR *jcr); extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId); extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname, - char *link, char *attr, int stream); + char *link, char *attr, int stream); extern void get_level_since_time(JCR *jcr, char *since, int since_len); extern int send_run_before_and_after_commands(JCR *jcr); @@ -110,7 +110,7 @@ extern void mount_request(JCR *jcr, BSOCK *bs, char *buf); /* msgchan.c */ extern bool connect_to_storage_daemon(JCR *jcr, int retry_interval, - int max_retry_time, int verbose); + int max_retry_time, int verbose); extern int start_storage_daemon_job(JCR *jcr, alist *store, int append); extern int start_storage_daemon_message_thread(JCR *jcr); extern int bget_dirmsg(BSOCK *bs); @@ -165,6 +165,9 @@ void prtit(void *ctx, const char *msg); int complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool); RUN *find_next_run(RUN *run, JOB *job, time_t &runtime); +/* ua_restore.c */ +int get_next_jobid_from_list(char **p, JobId_t *JobId); + /* ua_server.c */ void bsendmsg(void *sock, const char *fmt, ...); UAContext *new_ua_context(JCR *jcr); @@ -172,29 +175,29 @@ JCR *new_control_jcr(const char *base_name, int job_type); void free_ua_context(UAContext *ua); /* ua_select.c */ -STORE *select_storage_resource(UAContext *ua); -JOB *select_job_resource(UAContext *ua); -JOB *select_restore_job_resource(UAContext *ua); -CLIENT *select_client_resource(UAContext *ua); +STORE *select_storage_resource(UAContext *ua); +JOB *select_job_resource(UAContext *ua); +JOB *select_restore_job_resource(UAContext *ua); +CLIENT *select_client_resource(UAContext *ua); FILESET *select_fileset_resource(UAContext *ua); -int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr); -int select_media_dbr(UAContext *ua, MEDIA_DBR *mr); -bool select_pool_dbr(UAContext *ua, POOL_DBR *pr); -int select_client_dbr(UAContext *ua, CLIENT_DBR *cr); - -void start_prompt(UAContext *ua, const char *msg); -void add_prompt(UAContext *ua, const char *prompt); -int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt); +int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr); +int select_media_dbr(UAContext *ua, MEDIA_DBR *mr); +bool select_pool_dbr(UAContext *ua, POOL_DBR *pr); +int select_client_dbr(UAContext *ua, CLIENT_DBR *cr); + +void start_prompt(UAContext *ua, const char *msg); +void add_prompt(UAContext *ua, const char *prompt); +int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt); CAT *get_catalog_resource(UAContext *ua); STORE *get_storage_resource(UAContext *ua, bool use_default); -int get_storage_drive(UAContext *ua, STORE *store); -int get_media_type(UAContext *ua, char *MediaType, int max_media); -bool get_pool_dbr(UAContext *ua, POOL_DBR *pr); -int get_client_dbr(UAContext *ua, CLIENT_DBR *cr); +int get_storage_drive(UAContext *ua, STORE *store); +int get_media_type(UAContext *ua, char *MediaType, int max_media); +bool get_pool_dbr(UAContext *ua, POOL_DBR *pr); +int get_client_dbr(UAContext *ua, CLIENT_DBR *cr); POOL *get_pool_resource(UAContext *ua); POOL *select_pool_resource(UAContext *ua); CLIENT *get_client_resource(UAContext *ua); -int get_job_dbr(UAContext *ua, JOB_DBR *jr); +int get_job_dbr(UAContext *ua, JOB_DBR *jr); int find_arg_keyword(UAContext *ua, const char **list); int find_arg(UAContext *ua, const char *keyword); diff --git a/bacula/src/dird/ua.h b/bacula/src/dird/ua.h index 43b79a08e7..4498f05560 100644 --- a/bacula/src/dird/ua.h +++ b/bacula/src/dird/ua.h @@ -68,4 +68,41 @@ struct TREE_CTX { uint32_t DeltaCount; /* trigger for printing */ }; +struct NAME_LIST { + char **name; /* list of names */ + int num_ids; /* ids stored */ + int max_ids; /* size of array */ + int num_del; /* number deleted */ + int tot_ids; /* total to process */ +}; + + +/* Main structure for obtaining JobIds or Files to be restored */ +struct RESTORE_CTX { + utime_t JobTDate; + uint32_t TotalFiles; + JobId_t JobId; + char ClientName[MAX_NAME_LENGTH]; + char last_jobid[20]; + POOLMEM *JobIds; /* User entered string of JobIds */ + STORE *store; + JOB *restore_job; + POOL *pool; + int restore_jobs; + uint32_t selected_files; + char *where; + RBSR *bsr; + POOLMEM *fname; /* filename only */ + POOLMEM *path; /* path only */ + POOLMEM *query; + int fnl; /* filename length */ + int pnl; /* path length */ + bool found; + bool all; /* mark all as default */ + NAME_LIST name_list; +}; + +#define MAX_ID_LIST_LEN 1000000 + + #endif diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 7cbff318a8..2c97d1cb32 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -340,7 +340,8 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist) /* List MEDIA or VOLUMES */ } else if (strcasecmp(ua->argk[i], N_("media")) == 0 || - strncasecmp(ua->argk[i], N_("volume"), 7) == 0) { + strcasecmp(ua->argk[i], N_("volume")) == 0 || + strcasecmp(ua->argk[i], N_("volumes")) == 0) { bool done = false; for (j=i+1; jargc; j++) { if (strcasecmp(ua->argk[j], N_("job")) == 0 && ua->argv[j]) { diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index 75bfa96529..37a8812574 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -1,12 +1,12 @@ /* * * Bacula Director -- User Agent Database restore Command - * Creates a bootstrap file for restoring files and - * starts the restore job. + * Creates a bootstrap file for restoring files and + * starts the restore job. * - * Tree handling routines split into ua_tree.c July MMIII. - * BSR (bootstrap record) handling routines split into - * bsr.c July MMIII + * Tree handling routines split into ua_tree.c July MMIII. + * BSR (bootstrap record) handling routines split into + * bsr.c July MMIII * * Kern Sibbald, July MMII * @@ -36,58 +36,20 @@ extern void print_bsr(UAContext *ua, RBSR *bsr); /* Imported variables */ -extern char *uar_list_jobs, *uar_file, *uar_sel_files; -extern char *uar_del_temp, *uar_del_temp1, *uar_create_temp; -extern char *uar_create_temp1, *uar_last_full, *uar_full; -extern char *uar_inc, *uar_list_temp, *uar_sel_jobid_temp; +extern char *uar_list_jobs, *uar_file, *uar_sel_files; +extern char *uar_del_temp, *uar_del_temp1, *uar_create_temp; +extern char *uar_create_temp1, *uar_last_full, *uar_full; +extern char *uar_inc, *uar_list_temp, *uar_sel_jobid_temp; extern char *uar_sel_all_temp1, *uar_sel_fileset, *uar_mediatype; -extern char *uar_jobid_fileindex, *uar_dif, *uar_sel_all_temp; -extern char *uar_count_files, *uar_jobids_fileindex; +extern char *uar_jobid_fileindex, *uar_dif, *uar_sel_all_temp; +extern char *uar_count_files, *uar_jobids_fileindex; extern char *uar_jobid_fileindex_from_dir; -struct NAME_LIST { - char **name; /* list of names */ - int num_ids; /* ids stored */ - int max_ids; /* size of array */ - int num_del; /* number deleted */ - int tot_ids; /* total to process */ -}; - - -/* Main structure for obtaining JobIds or Files to be restored */ -struct RESTORE_CTX { - utime_t JobTDate; - uint32_t TotalFiles; - uint32_t JobId; - char ClientName[MAX_NAME_LENGTH]; - char last_jobid[20]; - POOLMEM *JobIds; /* User entered string of JobIds */ - STORE *store; - JOB *restore_job; - POOL *pool; - int restore_jobs; - uint32_t selected_files; - char *where; - RBSR *bsr; - POOLMEM *fname; /* filename only */ - POOLMEM *path; /* path only */ - POOLMEM *query; - int fnl; /* filename length */ - int pnl; /* path length */ - bool found; - bool all; /* mark all as default */ - NAME_LIST name_list; -}; - - -#define MAX_ID_LIST_LEN 1000000 - /* Forward referenced functions */ static int last_full_handler(void *ctx, int num_fields, char **row); static int jobid_handler(void *ctx, int num_fields, char **row); -static int get_next_jobid_from_list(char **p, uint32_t *JobId); static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx); static int fileset_handler(void *ctx, int num_fields, char **row); static void print_name_list(UAContext *ua, NAME_LIST *name_list); @@ -100,9 +62,9 @@ static void free_rx(RESTORE_CTX *rx); static void split_path_and_filename(RESTORE_CTX *rx, char *fname); static int jobid_fileindex_handler(void *ctx, int num_fields, char **row); static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file, - char *date); + char *date); static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *dir, - char *date); + char *date); static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, bool dir); static int get_client_name(UAContext *ua, RESTORE_CTX *rx); static int get_date(UAContext *ua, char *date, int date_len); @@ -114,7 +76,7 @@ static int count_handler(void *ctx, int num_fields, char **row); */ int restore_cmd(UAContext *ua, const char *cmd) { - RESTORE_CTX rx; /* restore context */ + RESTORE_CTX rx; /* restore context */ JOB *job; int i; POOLMEM *fname; @@ -139,10 +101,10 @@ int restore_cmd(UAContext *ua, const char *cmd) LockRes(); foreach_res(job, R_JOB) { if (job->JobType == JT_RESTORE) { - if (!rx.restore_job) { - rx.restore_job = job; - } - rx.restore_jobs++; + if (!rx.restore_job) { + rx.restore_job = job; + } + rx.restore_jobs++; } } UnlockRes(); @@ -160,31 +122,31 @@ int restore_cmd(UAContext *ua, const char *cmd) * add_findex() */ switch (user_select_jobids_or_files(ua, &rx)) { - case 0: /* error */ + case 0: /* error */ goto bail_out; - case 1: /* selected by jobid */ + case 1: /* selected by jobid */ if (!build_directory_tree(ua, &rx)) { bsendmsg(ua, _("Restore not done.\n")); - goto bail_out; + goto bail_out; } break; - case 2: /* selected by filename, no tree needed */ + case 2: /* selected by filename, no tree needed */ break; } if (rx.bsr->JobId) { uint32_t selected_files; - if (!complete_bsr(ua, rx.bsr)) { /* find Vol, SessId, SessTime from JobIds */ + if (!complete_bsr(ua, rx.bsr)) { /* find Vol, SessId, SessTime from JobIds */ bsendmsg(ua, _("Unable to construct a valid BSR. Cannot continue.\n")); - goto bail_out; + goto bail_out; } - if (!(selected_files = write_bsr_file(ua, rx.bsr))) { + if (!(selected_files = write_bsr_file(ua, rx))) { bsendmsg(ua, _("No files selected to be restored.\n")); - goto bail_out; + goto bail_out; } /* If no count of files, use bsr generated value (often wrong) */ if (rx.selected_files == 0) { - rx.selected_files = selected_files; + rx.selected_files = selected_files; } if (rx.selected_files==1) { bsendmsg(ua, _("\n1 file selected to be restored.\n\n")); @@ -220,13 +182,13 @@ int restore_cmd(UAContext *ua, const char *cmd) "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\"" " where=\"%s\" files=%d catalog=\"%s\"", job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"", - fname, rx.where, rx.selected_files, ua->catalog->hdr.name); + fname, rx.where, rx.selected_files, ua->catalog->hdr.name); } else { Mmsg(ua->cmd, "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\"" " files=%d catalog=\"%s\"", job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"", - fname, rx.selected_files, ua->catalog->hdr.name); + fname, rx.selected_files, ua->catalog->hdr.name); } free_pool_memory(fname); if (find_arg(ua, N_("yes")) > 0) { @@ -275,12 +237,12 @@ static int get_client_name(UAContext *ua, RESTORE_CTX *rx) /* try command line argument */ int i = find_arg_with_value(ua, N_("client")); if (i >= 0) { - bstrncpy(rx->ClientName, ua->argv[i], sizeof(rx->ClientName)); - return 1; + bstrncpy(rx->ClientName, ua->argv[i], sizeof(rx->ClientName)); + return 1; } memset(&cr, 0, sizeof(cr)); if (!get_client_dbr(ua, &cr)) { - return 0; + return 0; } bstrncpy(rx->ClientName, cr.Name, sizeof(rx->ClientName)); } @@ -293,8 +255,8 @@ static int get_client_name(UAContext *ua, RESTORE_CTX *rx) * select which files are to be restored. * * Returns: 2 if filename list made - * 1 if jobid list made - * 0 on error + * 1 if jobid list made + * 0 on error */ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) { @@ -346,86 +308,86 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) for (i=1; iargc; i++) { /* loop through arguments */ bool found_kw = false; - for (j=0; kw[j]; j++) { /* loop through keywords */ - if (strcasecmp(kw[j], ua->argk[i]) == 0) { - found_kw = true; - break; - } + for (j=0; kw[j]; j++) { /* loop through keywords */ + if (strcasecmp(kw[j], ua->argk[i]) == 0) { + found_kw = true; + break; + } } if (!found_kw) { bsendmsg(ua, _("Unknown keyword: %s\n"), ua->argk[i]); - return 0; + return 0; } /* Found keyword in kw[] list, process it */ switch (j) { - case 0: /* jobid */ - if (*rx->JobIds != 0) { + case 0: /* jobid */ + if (*rx->JobIds != 0) { pm_strcat(rx->JobIds, ","); - } - pm_strcat(rx->JobIds, ua->argv[i]); - done = true; - break; - case 1: /* current */ - bstrutime(date, sizeof(date), time(NULL)); - have_date = true; - break; - case 2: /* before */ - if (str_to_utime(ua->argv[i]) == 0) { + } + pm_strcat(rx->JobIds, ua->argv[i]); + done = true; + break; + case 1: /* current */ + bstrutime(date, sizeof(date), time(NULL)); + have_date = true; + break; + case 2: /* before */ + if (str_to_utime(ua->argv[i]) == 0) { bsendmsg(ua, _("Improper date format: %s\n"), ua->argv[i]); - return 0; - } - bstrncpy(date, ua->argv[i], sizeof(date)); - have_date = true; - break; - case 3: /* file */ - case 4: /* dir */ - if (!have_date) { - bstrutime(date, sizeof(date), time(NULL)); - } - if (!get_client_name(ua, rx)) { - return 0; - } - pm_strcpy(ua->cmd, ua->argv[i]); - insert_one_file_or_dir(ua, rx, date, j==4); - if (rx->name_list.num_ids) { - /* Check MediaType and select storage that corresponds */ - get_storage_from_mediatype(ua, &rx->name_list, rx); - done = true; - } - break; - case 5: /* select */ - if (!have_date) { - bstrutime(date, sizeof(date), time(NULL)); - } - if (!select_backups_before_date(ua, rx, date)) { - return 0; - } - done = true; - break; - case 6: /* pool specified */ - rx->pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]); - if (!rx->pool) { + return 0; + } + bstrncpy(date, ua->argv[i], sizeof(date)); + have_date = true; + break; + case 3: /* file */ + case 4: /* dir */ + if (!have_date) { + bstrutime(date, sizeof(date), time(NULL)); + } + if (!get_client_name(ua, rx)) { + return 0; + } + pm_strcpy(ua->cmd, ua->argv[i]); + insert_one_file_or_dir(ua, rx, date, j==4); + if (rx->name_list.num_ids) { + /* Check MediaType and select storage that corresponds */ + get_storage_from_mediatype(ua, &rx->name_list, rx); + done = true; + } + break; + case 5: /* select */ + if (!have_date) { + bstrutime(date, sizeof(date), time(NULL)); + } + if (!select_backups_before_date(ua, rx, date)) { + return 0; + } + done = true; + break; + case 6: /* pool specified */ + rx->pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]); + if (!rx->pool) { bsendmsg(ua, _("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]); - return 0; - } - if (!acl_access_ok(ua, Pool_ACL, ua->argv[i])) { - rx->pool = NULL; + return 0; + } + if (!acl_access_ok(ua, Pool_ACL, ua->argv[i])) { + rx->pool = NULL; bsendmsg(ua, _("Error: Pool resource \"%s\" access not allowed.\n"), ua->argv[i]); - return 0; - } - break; - case 7: /* all specified */ - rx->all = true; - break; + return 0; + } + break; + case 7: /* all specified */ + rx->all = true; + break; /* * All keywords 7 or greater are ignored or handled by a select prompt */ default: - break; + break; } } if (rx->name_list.num_ids) { - return 2; /* filename list made */ + return 2; /* filename list made */ } if (!done) { @@ -443,176 +405,176 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) start_prompt(ua, _("To select the JobIds, you have the following choices:\n")); for (int i=0; list[i]; i++) { - add_prompt(ua, list[i]); + add_prompt(ua, list[i]); } done = true; switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) { - case -1: /* error */ - return 0; - case 0: /* list last 20 Jobs run */ - gui_save = ua->jcr->gui; - ua->jcr->gui = true; - db_list_sql_query(ua->jcr, ua->db, uar_list_jobs, prtit, ua, 1, HORZ_LIST); - ua->jcr->gui = gui_save; - done = false; - break; - case 1: /* list where a file is saved */ - if (!get_client_name(ua, rx)) { - return 0; - } + case -1: /* error */ + return 0; + case 0: /* list last 20 Jobs run */ + gui_save = ua->jcr->gui; + ua->jcr->gui = true; + db_list_sql_query(ua->jcr, ua->db, uar_list_jobs, prtit, ua, 1, HORZ_LIST); + ua->jcr->gui = gui_save; + done = false; + break; + case 1: /* list where a file is saved */ + if (!get_client_name(ua, rx)) { + return 0; + } if (!get_cmd(ua, _("Enter Filename (no path):"))) { - return 0; - } - len = strlen(ua->cmd); - fname = (char *)malloc(len * 2 + 1); - db_escape_string(fname, ua->cmd, len); - Mmsg(rx->query, uar_file, rx->ClientName, fname); - free(fname); - gui_save = ua->jcr->gui; - ua->jcr->gui = true; - db_list_sql_query(ua->jcr, ua->db, rx->query, prtit, ua, 1, HORZ_LIST); - ua->jcr->gui = gui_save; - done = false; - break; - case 2: /* enter a list of JobIds */ + return 0; + } + len = strlen(ua->cmd); + fname = (char *)malloc(len * 2 + 1); + db_escape_string(fname, ua->cmd, len); + Mmsg(rx->query, uar_file, rx->ClientName, fname); + free(fname); + gui_save = ua->jcr->gui; + ua->jcr->gui = true; + db_list_sql_query(ua->jcr, ua->db, rx->query, prtit, ua, 1, HORZ_LIST); + ua->jcr->gui = gui_save; + done = false; + break; + case 2: /* enter a list of JobIds */ if (!get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) { - return 0; - } - pm_strcpy(rx->JobIds, ua->cmd); - break; - case 3: /* Enter an SQL list command */ + return 0; + } + pm_strcpy(rx->JobIds, ua->cmd); + break; + case 3: /* Enter an SQL list command */ if (!get_cmd(ua, _("Enter SQL list command: "))) { - return 0; - } - gui_save = ua->jcr->gui; - ua->jcr->gui = true; - db_list_sql_query(ua->jcr, ua->db, ua->cmd, prtit, ua, 1, HORZ_LIST); - ua->jcr->gui = gui_save; - done = false; - break; - case 4: /* Select the most recent backups */ - bstrutime(date, sizeof(date), time(NULL)); - if (!select_backups_before_date(ua, rx, date)) { - return 0; - } - break; - case 5: /* select backup at specified time */ - if (!get_date(ua, date, sizeof(date))) { - return 0; - } - if (!select_backups_before_date(ua, rx, date)) { - return 0; - } - break; - case 6: /* Enter files */ - bstrutime(date, sizeof(date), time(NULL)); - if (!get_client_name(ua, rx)) { - return 0; - } + return 0; + } + gui_save = ua->jcr->gui; + ua->jcr->gui = true; + db_list_sql_query(ua->jcr, ua->db, ua->cmd, prtit, ua, 1, HORZ_LIST); + ua->jcr->gui = gui_save; + done = false; + break; + case 4: /* Select the most recent backups */ + bstrutime(date, sizeof(date), time(NULL)); + if (!select_backups_before_date(ua, rx, date)) { + return 0; + } + break; + case 5: /* select backup at specified time */ + if (!get_date(ua, date, sizeof(date))) { + return 0; + } + if (!select_backups_before_date(ua, rx, date)) { + return 0; + } + break; + case 6: /* Enter files */ + bstrutime(date, sizeof(date), time(NULL)); + if (!get_client_name(ua, rx)) { + return 0; + } bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n" "containg a list of file names with paths, and terminate\n" "them with a blank line.\n")); - for ( ;; ) { + for ( ;; ) { if (!get_cmd(ua, _("Enter full filename: "))) { - return 0; - } - len = strlen(ua->cmd); - if (len == 0) { - break; - } - insert_one_file_or_dir(ua, rx, date, false); - } - /* Check MediaType and select storage that corresponds */ - if (rx->name_list.num_ids) { - get_storage_from_mediatype(ua, &rx->name_list, rx); - } - return 2; - case 7: /* enter files backed up before specified time */ - if (!get_date(ua, date, sizeof(date))) { - return 0; - } - if (!get_client_name(ua, rx)) { - return 0; - } + return 0; + } + len = strlen(ua->cmd); + if (len == 0) { + break; + } + insert_one_file_or_dir(ua, rx, date, false); + } + /* Check MediaType and select storage that corresponds */ + if (rx->name_list.num_ids) { + get_storage_from_mediatype(ua, &rx->name_list, rx); + } + return 2; + case 7: /* enter files backed up before specified time */ + if (!get_date(ua, date, sizeof(date))) { + return 0; + } + if (!get_client_name(ua, rx)) { + return 0; + } bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n" "containg a list of file names with paths, and terminate\n" "them with a blank line.\n")); - for ( ;; ) { + for ( ;; ) { if (!get_cmd(ua, _("Enter full filename: "))) { - return 0; - } - len = strlen(ua->cmd); - if (len == 0) { - break; - } - insert_one_file_or_dir(ua, rx, date, false); - } - /* Check MediaType and select storage that corresponds */ - if (rx->name_list.num_ids) { - get_storage_from_mediatype(ua, &rx->name_list, rx); - } - return 2; - - case 8: /* Find JobIds for current backup */ - bstrutime(date, sizeof(date), time(NULL)); - if (!select_backups_before_date(ua, rx, date)) { - return 0; - } - done = false; - break; - - case 9: /* Find JobIds for give date */ - if (!get_date(ua, date, sizeof(date))) { - return 0; - } - if (!select_backups_before_date(ua, rx, date)) { - return 0; - } - done = false; - break; - - case 10: /* Enter directories */ - if (*rx->JobIds != 0) { + return 0; + } + len = strlen(ua->cmd); + if (len == 0) { + break; + } + insert_one_file_or_dir(ua, rx, date, false); + } + /* Check MediaType and select storage that corresponds */ + if (rx->name_list.num_ids) { + get_storage_from_mediatype(ua, &rx->name_list, rx); + } + return 2; + + case 8: /* Find JobIds for current backup */ + bstrutime(date, sizeof(date), time(NULL)); + if (!select_backups_before_date(ua, rx, date)) { + return 0; + } + done = false; + break; + + case 9: /* Find JobIds for give date */ + if (!get_date(ua, date, sizeof(date))) { + return 0; + } + if (!select_backups_before_date(ua, rx, date)) { + return 0; + } + done = false; + break; + + case 10: /* Enter directories */ + if (*rx->JobIds != 0) { bsendmsg(ua, _("You have already seleted the following JobIds: %s\n"), - rx->JobIds); + rx->JobIds); } else if (get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) { - if (*rx->JobIds != 0 && *ua->cmd) { + if (*rx->JobIds != 0 && *ua->cmd) { pm_strcat(rx->JobIds, ","); - } - pm_strcat(rx->JobIds, ua->cmd); - } + } + pm_strcat(rx->JobIds, ua->cmd); + } if (*rx->JobIds == 0 || *rx->JobIds == '.') { - return 0; /* nothing entered, return */ - } - bstrutime(date, sizeof(date), time(NULL)); - if (!get_client_name(ua, rx)) { - return 0; - } + return 0; /* nothing entered, return */ + } + bstrutime(date, sizeof(date), time(NULL)); + if (!get_client_name(ua, rx)) { + return 0; + } bsendmsg(ua, _("Enter full directory names or start the name\n" "with a < to indicate it is a filename containg a list\n" "of directories and terminate them with a blank line.\n")); - for ( ;; ) { + for ( ;; ) { if (!get_cmd(ua, _("Enter directory name: "))) { - return 0; - } - len = strlen(ua->cmd); - if (len == 0) { - break; - } - /* Add trailing slash to end of directory names */ + return 0; + } + len = strlen(ua->cmd); + if (len == 0) { + break; + } + /* Add trailing slash to end of directory names */ if (ua->cmd[0] != '<' && ua->cmd[len-1] != '/') { strcat(ua->cmd, "/"); - } - insert_one_file_or_dir(ua, rx, date, true); - } - /* Check MediaType and select storage that corresponds */ - if (rx->name_list.num_ids) { - get_storage_from_mediatype(ua, &rx->name_list, rx); - } - return 2; - - case 11: /* Cancel or quit */ - return 0; + } + insert_one_file_or_dir(ua, rx, date, true); + } + /* Check MediaType and select storage that corresponds */ + if (rx->name_list.num_ids) { + get_storage_from_mediatype(ua, &rx->name_list, rx); + } + return 2; + + case 11: /* Cancel or quit */ + return 0; } } @@ -634,25 +596,25 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) int stat = get_next_jobid_from_list(&p, &JobId); if (stat < 0) { bsendmsg(ua, _("Invalid JobId in list.\n")); - return 0; + return 0; } if (stat == 0) { - break; + break; } if (jr.JobId == JobId) { - continue; /* duplicate of last JobId */ + continue; /* duplicate of last JobId */ } jr.JobId = JobId; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { - char ed1[50]; + char ed1[50]; bsendmsg(ua, _("Unable to get Job record for JobId=%s: ERR=%s\n"), - edit_int64(JobId, ed1), db_strerror(ua->db)); - return 0; + edit_int64(JobId, ed1), db_strerror(ua->db)); + return 0; } if (!acl_access_ok(ua, Job_ACL, jr.Name)) { bsendmsg(ua, _("No authorization. Job \"%s\" not selected.\n"), - jr.Name); - continue; + jr.Name); + continue; } rx->TotalFiles += jr.JobFiles; } @@ -668,10 +630,10 @@ static int get_date(UAContext *ua, char *date, int date_len) "BEFORE the date you specify below.\n\n")); for ( ;; ) { if (!get_cmd(ua, _("Enter date as YYYY-MM-DD HH:MM:SS :"))) { - return 0; + return 0; } if (str_to_utime(ua->cmd) != 0) { - break; + break; } bsendmsg(ua, _("Improper date format.\n")); } @@ -693,30 +655,30 @@ static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, b case '<': p++; if ((ffd = fopen(p, "r")) == NULL) { - berrno be; + berrno be; bsendmsg(ua, _("Cannot open file %s: ERR=%s\n"), - p, be.strerror()); - break; + p, be.strerror()); + break; } while (fgets(file, sizeof(file), ffd)) { - line++; - if (dir) { - if (!insert_dir_into_findex_list(ua, rx, file, date)) { + line++; + if (dir) { + if (!insert_dir_into_findex_list(ua, rx, file, date)) { bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p); - } - } else { - if (!insert_file_into_findex_list(ua, rx, file, date)) { + } + } else { + if (!insert_file_into_findex_list(ua, rx, file, date)) { bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p); - } - } + } + } } fclose(ffd); break; default: if (dir) { - insert_dir_into_findex_list(ua, rx, ua->cmd, date); + insert_dir_into_findex_list(ua, rx, ua->cmd, date); } else { - insert_file_into_findex_list(ua, rx, ua->cmd, date); + insert_file_into_findex_list(ua, rx, ua->cmd, date); } break; } @@ -728,7 +690,7 @@ static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, b * and FileIndex, then insert them into the findex list. */ static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file, - char *date) + char *date) { char ed1[50]; @@ -736,16 +698,16 @@ static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *f split_path_and_filename(rx, file); if (*rx->JobIds == 0) { Mmsg(rx->query, uar_jobid_fileindex, date, rx->path, rx->fname, - rx->ClientName); + rx->ClientName); } else { Mmsg(rx->query, uar_jobids_fileindex, rx->JobIds, date, - rx->path, rx->fname, rx->ClientName); + rx->path, rx->fname, rx->ClientName); } rx->found = false; /* Find and insert jobid and File Index */ if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) { bsendmsg(ua, _("Query failed: %s. ERR=%s\n"), - rx->query, db_strerror(ua->db)); + rx->query, db_strerror(ua->db)); } if (!rx->found) { bsendmsg(ua, _("No database record found for: %s\n"), file); @@ -767,7 +729,7 @@ static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *f * to get the JobId and FileIndexes of all files in that directory. */ static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *dir, - char *date) + char *date) { char ed1[50]; @@ -777,13 +739,13 @@ static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *di return false; } else { Mmsg(rx->query, uar_jobid_fileindex_from_dir, rx->JobIds, - dir, rx->ClientName); + dir, rx->ClientName); } rx->found = false; /* Find and insert jobid and File Index */ if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) { bsendmsg(ua, _("Query failed: %s. ERR=%s\n"), - rx->query, db_strerror(ua->db)); + rx->query, db_strerror(ua->db)); } if (!rx->found) { bsendmsg(ua, _("No database record found for: %s\n"), dir); @@ -813,12 +775,12 @@ static void split_path_and_filename(RESTORE_CTX *rx, char *name) */ for (p=f=name; *p; p++) { if (*p == '/') { - f = p; /* set pos of last slash */ + f = p; /* set pos of last slash */ } } if (*f == '/') { /* did we find a slash? */ - f++; /* yes, point to filename */ - } else { /* no, whole thing must be path name */ + f++; /* yes, point to filename */ + } else { /* no, whole thing must be path name */ f = p; } @@ -830,7 +792,7 @@ static void split_path_and_filename(RESTORE_CTX *rx, char *name) rx->fnl = p - f; if (rx->fnl > 0) { rx->fname = check_pool_memory_size(rx->fname, rx->fnl+1); - memcpy(rx->fname, f, rx->fnl); /* copy filename */ + memcpy(rx->fname, f, rx->fnl); /* copy filename */ rx->fname[rx->fnl] = 0; } else { rx->fname[0] = 0; @@ -880,20 +842,20 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) bsendmsg(ua, "%s\n", db_strerror(ua->db)); } if (rx->found) { - /* Add about 25% more than this job for over estimate */ - tree.FileEstimate = rx->JobId + (rx->JobId >> 2); - tree.DeltaCount = rx->JobId/50; /* print 50 ticks */ + /* Add about 25% more than this job for over estimate */ + tree.FileEstimate = rx->JobId + (rx->JobId >> 2); + tree.DeltaCount = rx->JobId/50; /* print 50 ticks */ } } for (p=rx->JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { char ed1[50]; if (JobId == last_JobId) { - continue; /* eliminate duplicate JobIds */ + continue; /* eliminate duplicate JobIds */ } last_JobId = JobId; bsendmsg(ua, _("\nBuilding directory tree for JobId %s ... "), - edit_int64(JobId, ed1)); + edit_int64(JobId, ed1)); items++; /* * Find files for this JobId and insert them in the tree @@ -914,46 +876,46 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) bsendmsg(ua, _("\nThere were no files inserted into the tree, so file selection\n" "is not possible.Most likely your retention policy pruned the files\n")); if (!get_yesno(ua, _("\nDo you want to restore all the files? (yes|no): "))) { - OK = false; + OK = false; } else { - last_JobId = 0; - for (p=rx->JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { - if (JobId == last_JobId) { - continue; /* eliminate duplicate JobIds */ - } - add_findex_all(rx->bsr, JobId); - } - OK = true; + last_JobId = 0; + for (p=rx->JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { + if (JobId == last_JobId) { + continue; /* eliminate duplicate JobIds */ + } + add_findex_all(rx->bsr, JobId); + } + OK = true; } } else { char ec1[50]; if (items==1) { - if (tree.all) { + if (tree.all) { bsendmsg(ua, _("\n1 Job, %s files inserted into the tree and marked for extraction.\n"), - edit_uint64_with_commas(tree.FileCount, ec1)); - } - else { + edit_uint64_with_commas(tree.FileCount, ec1)); + } + else { bsendmsg(ua, _("\n1 Job, %s files inserted into the tree.\n"), - edit_uint64_with_commas(tree.FileCount, ec1)); - } + edit_uint64_with_commas(tree.FileCount, ec1)); + } } else { - if (tree.all) { + if (tree.all) { bsendmsg(ua, _("\n%d Jobs, %s files inserted into the tree and marked for extraction.\n"), - items, edit_uint64_with_commas(tree.FileCount, ec1)); - } - else { + items, edit_uint64_with_commas(tree.FileCount, ec1)); + } + else { bsendmsg(ua, _("\n%d Jobs, %s files inserted into the tree.\n"), - items, edit_uint64_with_commas(tree.FileCount, ec1)); - } + items, edit_uint64_with_commas(tree.FileCount, ec1)); + } } /* Check MediaType and select storage that corresponds */ get_storage_from_mediatype(ua, &rx->name_list, rx); if (find_arg(ua, N_("done")) < 0) { - /* Let the user interact in selecting which files to restore */ - OK = user_select_files_from_tree(&tree); + /* Let the user interact in selecting which files to restore */ + OK = user_select_files_from_tree(&tree); } /* @@ -961,20 +923,20 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) * extracted making a bootstrap file. */ if (OK) { - for (TREE_NODE *node=first_tree_node(tree.root); node; node=next_tree_node(node)) { + for (TREE_NODE *node=first_tree_node(tree.root); node; node=next_tree_node(node)) { Dmsg2(400, "FI=%d node=0x%x\n", node->FileIndex, node); - if (node->extract || node->extract_dir) { + if (node->extract || node->extract_dir) { Dmsg2(400, "type=%d FI=%d\n", node->type, node->FileIndex); - add_findex(rx->bsr, node->JobId, node->FileIndex); - if (node->extract && node->type != TN_NEWDIR) { - rx->selected_files++; /* count only saved files */ - } - } - } + add_findex(rx->bsr, node->JobId, node->FileIndex); + if (node->extract && node->type != TN_NEWDIR) { + rx->selected_files++; /* count only saved files */ + } + } + } } } - free_tree(tree.root); /* free the directory tree */ + free_tree(tree.root); /* free the directory tree */ return OK; } @@ -1021,11 +983,11 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat bstrncpy(fsr.FileSet, ua->argv[i], sizeof(fsr.FileSet)); if (!db_get_fileset_record(ua->jcr, ua->db, &fsr)) { bsendmsg(ua, _("Error getting FileSet \"%s\": ERR=%s\n"), fsr.FileSet, - db_strerror(ua->db)); - i = -1; + db_strerror(ua->db)); + i = -1; } } - if (i < 0) { /* fileset not found */ + if (i < 0) { /* fileset not found */ edit_int64(cr.ClientId, ed1); Mmsg(rx->query, uar_sel_fileset, ed1, ed1); start_prompt(ua, _("The defined FileSet resources are:\n")); @@ -1033,8 +995,8 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat bsendmsg(ua, "%s\n", db_strerror(ua->db)); } if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), - fileset_name, sizeof(fileset_name)) < 0) { - goto bail_out; + fileset_name, sizeof(fileset_name)) < 0) { + goto bail_out; } bstrncpy(fsr.FileSet, fileset_name, sizeof(fsr.FileSet)); @@ -1053,7 +1015,7 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat bstrncpy(pr.Name, rx->pool->hdr.name, sizeof(pr.Name)); if (db_get_pool_record(ua->jcr, ua->db, &pr)) { bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%s ", - edit_int64(pr.PoolId, ed1)); + edit_int64(pr.PoolId, ed1)); } else { bsendmsg(ua, _("Pool \"%s\" not found, using any pool.\n"), pr.Name); } @@ -1062,7 +1024,7 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat /* Find JobId of last Full backup for this client, fileset */ edit_int64(cr.ClientId, ed1); Mmsg(rx->query, uar_last_full, ed1, ed1, date, fsr.FileSet, - pool_select); + pool_select); if (!db_sql_query(ua->db, rx->query, NULL, NULL)) { bsendmsg(ua, "%s\n", db_strerror(ua->db)); goto bail_out; @@ -1087,7 +1049,7 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat /* Now find most recent Differental Job after Full save, if any */ Mmsg(rx->query, uar_dif, edit_uint64(rx->JobTDate, ed1), date, - edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select); + edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select); if (!db_sql_query(ua->db, rx->query, NULL, NULL)) { bsendmsg(ua, "%s\n", db_strerror(ua->db)); } @@ -1103,7 +1065,7 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat /* Now find all Incremental Jobs after Full/dif save */ Mmsg(rx->query, uar_inc, edit_uint64(rx->JobTDate, ed1), date, - edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select); + edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select); if (!db_sql_query(ua->db, rx->query, NULL, NULL)) { bsendmsg(ua, "%s\n", db_strerror(ua->db)); } @@ -1131,7 +1093,7 @@ bail_out: /* Return next JobId from comma separated list */ -static int get_next_jobid_from_list(char **p, uint32_t *JobId) +int get_next_jobid_from_list(char **p, JobId_t *JobId) { char jobid[30]; char *q = *p; @@ -1139,10 +1101,10 @@ static int get_next_jobid_from_list(char **p, uint32_t *JobId) jobid[0] = 0; for (int i=0; i<(int)sizeof(jobid); i++) { if (*q == 0) { - break; + break; } else if (*q == ',') { - q++; - break; + q++; + break; } jobid[i] = *q++; jobid[i+1] = 0; @@ -1150,7 +1112,7 @@ static int get_next_jobid_from_list(char **p, uint32_t *JobId) if (jobid[0] == 0) { return 0; } else if (!is_a_number(jobid)) { - return -1; /* error */ + return -1; /* error */ } *p = q; *JobId = str_to_int64(jobid); @@ -1187,7 +1149,7 @@ static int jobid_handler(void *ctx, int num_fields, char **row) RESTORE_CTX *rx = (RESTORE_CTX *)ctx; if (strcmp(rx->last_jobid, row[0]) == 0) { - return 0; /* duplicate id */ + return 0; /* duplicate id */ } bstrncpy(rx->last_jobid, row[0], sizeof(rx->last_jobid)); if (rx->JobIds[0] != 0) { @@ -1236,16 +1198,16 @@ static int unique_name_list_handler(void *ctx, int num_fields, char **row) } if (name->num_ids == name->max_ids) { if (name->max_ids == 0) { - name->max_ids = 1000; - name->name = (char **)bmalloc(sizeof(char *) * name->max_ids); + name->max_ids = 1000; + name->name = (char **)bmalloc(sizeof(char *) * name->max_ids); } else { - name->max_ids = (name->max_ids * 3) / 2; - name->name = (char **)brealloc(name->name, sizeof(char *) * name->max_ids); + name->max_ids = (name->max_ids * 3) / 2; + name->name = (char **)brealloc(name->name, sizeof(char *) * name->max_ids); } } for (int i=0; inum_ids; i++) { if (strcmp(name->name[i], row[0]) == 0) { - return 0; /* already in list, return */ + return 0; /* already in list, return */ } } /* Add new name to list */ @@ -1307,10 +1269,10 @@ static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, REST LockRes(); foreach_res(store, R_STORAGE) { if (strcmp(name_list->name[0], store->media_type) == 0) { - if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) { - rx->store = store; - } - break; + if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) { + rx->store = store; + } + break; } } UnlockRes(); @@ -1320,15 +1282,15 @@ static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, REST store = NULL; int i = find_arg_with_value(ua, "storage"); if (i > 0) { - store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]); - if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) { - store = NULL; - } + store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]); + if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) { + store = NULL; + } } if (store && (store != rx->store)) { bsendmsg(ua, _("Warning default storage overridden by %s on command line.\n"), - store->hdr.name); - rx->store = store; + store->hdr.name); + rx->store = store; } return; } @@ -1340,6 +1302,6 @@ static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, REST bsendmsg(ua, _("\nWarning. Unable to find Storage resource for\n" "MediaType \"%s\", needed by the Jobs you selected.\n" "You will be allowed to select a Storage device later.\n"), - name_list->name[0]); + name_list->name[0]); } } diff --git a/bacula/src/dird/verify.c b/bacula/src/dird/verify.c index 20261083c8..6edbf80cad 100644 --- a/bacula/src/dird/verify.c +++ b/bacula/src/dird/verify.c @@ -125,18 +125,21 @@ bool do_verify_init(JCR *jcr) * File daemon but not used). */ if (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) { - RBSR *bsr = new_bsr(); + RESTORE_CTX rx; UAContext *ua; - bsr->JobId = jcr->target_jr.JobId; + memset(&rx, 0, sizeof(rx)); + rx.bsr = new_bsr(); + rx.JobIds = ""; + rx.bsr->JobId = jcr->target_jr.JobId; ua = new_ua_context(jcr); - complete_bsr(ua, bsr); - bsr->fi = new_findex(); - bsr->fi->findex = 1; - bsr->fi->findex2 = jcr->target_jr.JobFiles; - jcr->ExpectedFiles = write_bsr_file(ua, bsr); + complete_bsr(ua, rx.bsr); + rx.bsr->fi = new_findex(); + rx.bsr->fi->findex = 1; + rx.bsr->fi->findex2 = jcr->target_jr.JobFiles; + jcr->ExpectedFiles = write_bsr_file(ua, rx); if (jcr->ExpectedFiles == 0) { free_ua_context(ua); - free_bsr(bsr); + free_bsr(rx.bsr); return false; } if (jcr->RestoreBootstrap) { @@ -146,7 +149,7 @@ bool do_verify_init(JCR *jcr) make_unique_restore_filename(ua, &fname); jcr->RestoreBootstrap = bstrdup(fname); free_ua_context(ua); - free_bsr(bsr); + free_bsr(rx.bsr); free_pool_memory(fname); jcr->needs_sd = true; diff --git a/bacula/src/gnome2-console/test-gnome-console.conf b/bacula/src/gnome2-console/test-gnome-console.conf index b2725a1f9f..fa5f9bcd4e 100644 --- a/bacula/src/gnome2-console/test-gnome-console.conf +++ b/bacula/src/gnome2-console/test-gnome-console.conf @@ -5,6 +5,6 @@ Director { Name = rufus-dir DIRport = 8101 - address = rufus + address = localhost Password = UA_password } diff --git a/bacula/src/lib/mem_pool.c b/bacula/src/lib/mem_pool.c index 8b0a502dfb..d4d03795bf 100644 --- a/bacula/src/lib/mem_pool.c +++ b/bacula/src/lib/mem_pool.c @@ -15,7 +15,7 @@ * there is enough memory, simply call the check_pool_memory_size() * with the desired size and it will adjust only if necessary. * - * Kern E. Sibbald + * Kern E. Sibbald * * Version $Id$ */ @@ -43,11 +43,11 @@ #include "bacula.h" struct s_pool_ctl { - int32_t size; /* default size */ - int32_t max_allocated; /* max allocated */ - int32_t max_used; /* max buffers used */ - int32_t in_use; /* number in use */ - struct abufhead *free_buf; /* pointer to free buffers */ + int32_t size; /* default size */ + int32_t max_allocated; /* max allocated */ + int32_t max_used; /* max buffers used */ + int32_t in_use; /* number in use */ + struct abufhead *free_buf; /* pointer to free buffers */ }; /* Bacula Name length plus extra */ @@ -59,30 +59,30 @@ struct s_pool_ctl { * Define default Pool buffer sizes */ static struct s_pool_ctl pool_ctl[] = { - { 256, 256, 0, 0, NULL }, /* PM_NOPOOL no pooling */ - { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */ - { 256, 256, 0, 0, NULL }, /* PM_FNAME filename buffers */ - { 512, 512, 0, 0, NULL }, /* PM_MESSAGE message buffer */ - { 1024, 1024, 0, 0, NULL } /* PM_EMSG error message buffer */ + { 256, 256, 0, 0, NULL }, /* PM_NOPOOL no pooling */ + { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */ + { 256, 256, 0, 0, NULL }, /* PM_FNAME filename buffers */ + { 512, 512, 0, 0, NULL }, /* PM_MESSAGE message buffer */ + { 1024, 1024, 0, 0, NULL } /* PM_EMSG error message buffer */ }; #else /* This is used ONLY when stress testing the code */ static struct s_pool_ctl pool_ctl[] = { - { 20, 20, 0, 0, NULL }, /* PM_NOPOOL no pooling */ - { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */ - { 20, 20, 0, 0, NULL }, /* PM_FNAME filename buffers */ - { 20, 20, 0, 0, NULL }, /* PM_MESSAGE message buffer */ - { 20, 20, 0, 0, NULL } /* PM_EMSG error message buffer */ + { 20, 20, 0, 0, NULL }, /* PM_NOPOOL no pooling */ + { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */ + { 20, 20, 0, 0, NULL }, /* PM_FNAME filename buffers */ + { 20, 20, 0, 0, NULL }, /* PM_MESSAGE message buffer */ + { 20, 20, 0, 0, NULL } /* PM_EMSG error message buffer */ }; #endif /* Memory allocation control structures and storage. */ struct abufhead { - int32_t ablen; /* Buffer length in bytes */ - int32_t pool; /* pool */ - struct abufhead *next; /* pointer to next free buffer */ + int32_t ablen; /* Buffer length in bytes */ + int32_t pool; /* pool */ + struct abufhead *next; /* pointer to next free buffer */ }; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; @@ -105,7 +105,7 @@ POOLMEM *sm_get_pool_memory(const char *fname, int lineno, int pool) pool_ctl[pool].free_buf = buf->next; pool_ctl[pool].in_use++; if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) { - pool_ctl[pool].max_used = pool_ctl[pool].in_use; + pool_ctl[pool].max_used = pool_ctl[pool].in_use; } V(mutex); Dmsg3(1800, "sm_get_pool_memory reuse %x to %s:%d\n", buf, fname, lineno); @@ -202,17 +202,17 @@ void sm_free_pool_memory(const char *fname, int lineno, POOLMEM *obuf) pool = buf->pool; pool_ctl[pool].in_use--; if (pool == 0) { - free((char *)buf); /* free nonpooled memory */ - } else { /* otherwise link it to the free pool chain */ + free((char *)buf); /* free nonpooled memory */ + } else { /* otherwise link it to the free pool chain */ #ifdef DEBUG struct abufhead *next; /* Don't let him free the same buffer twice */ for (next=pool_ctl[pool].free_buf; next; next=next->next) { - if (next == buf) { + if (next == buf) { Dmsg4(1800, "bad free_pool_memory %x pool=%d from %s:%d\n", buf, pool, fname, lineno); - V(mutex); /* unblock the pool */ - ASSERT(next != buf); /* attempt to free twice */ - } + V(mutex); /* unblock the pool */ + ASSERT(next != buf); /* attempt to free twice */ + } } #endif buf->next = pool_ctl[pool].free_buf; @@ -225,7 +225,7 @@ void sm_free_pool_memory(const char *fname, int lineno, POOLMEM *obuf) #else -/* ========= NO SMARTALLOC ========================================= */ +/* ========= NO SMARTALLOC ========================================= */ POOLMEM *get_pool_memory(int pool) { @@ -332,16 +332,16 @@ void free_pool_memory(POOLMEM *obuf) pool = buf->pool; pool_ctl[pool].in_use--; if (pool == 0) { - free((char *)buf); /* free nonpooled memory */ - } else { /* otherwise link it to the free pool chain */ + free((char *)buf); /* free nonpooled memory */ + } else { /* otherwise link it to the free pool chain */ #ifdef DEBUG struct abufhead *next; /* Don't let him free the same buffer twice */ for (next=pool_ctl[pool].free_buf; next; next=next->next) { - if (next == buf) { - V(mutex); - ASSERT(next != buf); /* attempt to free twice */ - } + if (next == buf) { + V(mutex); + ASSERT(next != buf); /* attempt to free twice */ + } } #endif buf->next = pool_ctl[pool].free_buf; @@ -368,9 +368,9 @@ void close_memory_pool() for (int i=1; i<=PM_MAX; i++) { buf = pool_ctl[i].free_buf; while (buf) { - next = buf->next; - free((char *)buf); - buf = next; + next = buf->next; + free((char *)buf); + buf = next; } pool_ctl[i].free_buf = NULL; } @@ -398,7 +398,7 @@ void print_memory_pool_stats() Pmsg0(-1, "Pool Maxsize Maxused Inuse\n"); for (int i=0; i<=PM_MAX; i++) Pmsg4(-1, "%5s %7d %7d %5d\n", pool_name(i), pool_ctl[i].max_allocated, - pool_ctl[i].max_used, pool_ctl[i].in_use); + pool_ctl[i].max_used, pool_ctl[i].in_use); Pmsg0(-1, "\n"); } @@ -503,7 +503,7 @@ int32_t POOL_MEM::max_size() char *cp = mem; cp -= HEAD_SIZE; size = ((struct abufhead *)cp)->ablen; - Dmsg1(000, "max_size=%d\n", size); + Dmsg1(900, "max_size=%d\n", size); return size; } @@ -520,7 +520,7 @@ void POOL_MEM::realloc_pm(int32_t size) V(mutex); Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size); } - Dmsg2(000, "Old buf=0x%x new buf=0x%x\n", cp, buf); + Dmsg2(900, "Old buf=0x%x new buf=0x%x\n", cp, buf); ((struct abufhead *)buf)->ablen = size; pool = ((struct abufhead *)buf)->pool; if (size > pool_ctl[pool].max_allocated) { @@ -528,7 +528,7 @@ void POOL_MEM::realloc_pm(int32_t size) } mem = buf+HEAD_SIZE; V(mutex); - Dmsg3(000, "Old buf=0x%x new buf=0x%x mem=0x%x\n", cp, buf, mem); + Dmsg3(900, "Old buf=0x%x new buf=0x%x mem=0x%x\n", cp, buf, mem); } int POOL_MEM::strcat(const char *str) diff --git a/bacula/src/version.h b/bacula/src/version.h index b778264870..13dab19d90 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -3,9 +3,9 @@ */ #undef VERSION -#define VERSION "1.37.37" -#define BDATE "30 August 2005" -#define LSMDATE "30Aug05" +#define VERSION "1.37.38" +#define BDATE "04 September 2005" +#define LSMDATE "04Sep05" /* Debug flags */ #undef DEBUG -- 2.39.5