From: Kern Sibbald Date: Thu, 5 Dec 2002 21:06:36 +0000 (+0000) Subject: list clients + restore fixes X-Git-Tag: Release-1.28~34 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=4aeeeea666501b9177aed84bce1d1971b56ada92;p=bacula%2Fbacula list clients + restore fixes git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@232 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kernstodo b/bacula/kernstodo index 7f2acd5f5a..36180a4071 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -14,6 +14,13 @@ Testing to do: (painful) For 1.28 release: +- Add count output to restore. +- Need a verbose mode in restore, perhaps to bsr. +- Should we dump a SOS when starting a new tape? +- bscan without -v is too quiet -- perhaps show jobs. +- Get rid of bscan.c:534 error message (one time only). +- Print some statistics when get EOF on device in bscan -- feedback + to let user know it is working. - Add code to put VolFile in bsr for restore command. - Add code to reject whole blocks if not wanted on restore. - Add watchdog timeout for child processes start_child_timer() @@ -614,4 +621,3 @@ Done: (see kernsdone for more) - Make BSR accept count (total files to be restored). - Add code to fast seek to proper place on tape/file when doing Restore. - Replace popen() and pclose() -- fail safe and timeout, no SIG dep. - diff --git a/bacula/src/cats/bdb_get.c b/bacula/src/cats/bdb_get.c index 635f1e8526..0b96eb5e12 100644 --- a/bacula/src/cats/bdb_get.c +++ b/bacula/src/cats/bdb_get.c @@ -494,6 +494,8 @@ int db_get_fileset_record(B_DB *mdb, FILESET_DBR *fsr) int db_get_file_attributes_record(B_DB *mdb, char *fname, FILE_DBR *fdbr) { return 0; } +int db_get_job_volume_parameters(B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams) +{ return 0; } #endif /* HAVE_BACULA_DB */ diff --git a/bacula/src/cats/bdb_list.c b/bacula/src/cats/bdb_list.c index 06d92923e0..4b5f1f452a 100644 --- a/bacula/src/cats/bdb_list.c +++ b/bacula/src/cats/bdb_list.c @@ -267,6 +267,11 @@ void db_list_job_totals(B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, void *c -void db_list_files_for_job(B_DB *mdb, uint32_t jobid, DB_LIST_HANDLER *sendit, void *ctx) {} +void db_list_files_for_job(B_DB *mdb, uint32_t jobid, DB_LIST_HANDLER *sendit, void *ctx) +{ } + +void db_list_client_records(B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx) +{ } + #endif /* HAVE_BACULA_DB */ diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h index e14b808182..81bb4bf9de 100644 --- a/bacula/src/cats/cats.h +++ b/bacula/src/cats/cats.h @@ -315,6 +315,15 @@ typedef struct { uint32_t EndBlock; /* last block */ } JOBMEDIA_DBR; +/* Volume Parameter structure */ +typedef struct { + char VolumeName[MAX_NAME_LENGTH]; /* Volume name */ + uint32_t StartFile; /* File for start of data */ + uint32_t EndFile; /* End file on Volume */ + uint32_t StartBlock; /* start block on tape */ + uint32_t EndBlock; /* last block */ +} VOL_PARAMS; + /* Attributes record -- NOT same as in database because * in general, this "record" creates multiple database diff --git a/bacula/src/cats/protos.h b/bacula/src/cats/protos.h index e841c229ac..a6a19b3828 100644 --- a/bacula/src/cats/protos.h +++ b/bacula/src/cats/protos.h @@ -74,6 +74,7 @@ int db_get_num_media_records(B_DB *mdb); int db_get_num_pool_records(B_DB *mdb); int db_get_pool_ids(B_DB *mdb, int *num_ids, uint32_t **ids); int db_get_media_ids(B_DB *mdb, int *num_ids, uint32_t **ids); +int db_get_job_volume_parameters(B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams); /* list.c */ @@ -84,6 +85,7 @@ void db_list_files_for_job(B_DB *db, uint32_t jobid, DB_LIST_HANDLER sendit, voi void db_list_media_records(B_DB *mdb, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx); void db_list_jobmedia_records(B_DB *mdb, uint32_t JobId, DB_LIST_HANDLER *sendit, void *ctx); int db_list_sql_query(B_DB *mdb, char *query, DB_LIST_HANDLER *sendit, void *ctx, int verbose); +void db_list_client_records(B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx); /* update.c */ int db_update_job_start_record(B_DB *db, JOB_DBR *jr); diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index 1f56e4023a..2bd972912a 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -410,6 +410,61 @@ AND JobMedia.MediaId=Media.MediaId", JobId); return stat; } +/* + * Find Volume parameters for a give JobId + * Returns: 0 on error or no Volumes found + * number of volumes on success + * List of Volumes and start/end file/blocks (malloced structure!) + * + * Returns: number of volumes on success + */ +int db_get_job_volume_parameters(B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams) +{ + SQL_ROW row; + int stat = 0; + int i; + VOL_PARAMS *Vols = NULL; + + db_lock(mdb); + Mmsg(&mdb->cmd, +"SELECT VolumeName,StartFile,EndFile,StartBlock,EndBlock" +" FROM JobMedia,Media WHERE JobMedia.JobId=%u" +" AND JobMedia.MediaId=Media.MediaId", JobId); + + Dmsg1(130, "VolNam=%s\n", mdb->cmd); + if (QUERY_DB(mdb, mdb->cmd)) { + mdb->num_rows = sql_num_rows(mdb); + Dmsg1(130, "Num rows=%d\n", mdb->num_rows); + if (mdb->num_rows <= 0) { + Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId); + stat = 0; + } else { + stat = mdb->num_rows; + if (stat > 0) { + *VolParams = Vols = (VOL_PARAMS *)malloc(stat * sizeof(VOL_PARAMS)); + } + for (i=0; i < stat; i++) { + if ((row = sql_fetch_row(mdb)) == NULL) { + Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); + stat = 0; + break; + } else { + bstrncpy(Vols[i].VolumeName, row[0], MAX_NAME_LENGTH); + Vols[i].StartFile = atoi(row[1]); + Vols[i].EndFile = atoi(row[2]); + Vols[i].StartBlock = atoi(row[3]); + Vols[i].EndBlock = atoi(row[4]); + } + } + } + sql_free_result(mdb); + } + db_unlock(mdb); + return stat; +} + + /* * Get the number of pool records diff --git a/bacula/src/cats/sql_list.c b/bacula/src/cats/sql_list.c index 48fa727697..48b475871a 100644 --- a/bacula/src/cats/sql_list.c +++ b/bacula/src/cats/sql_list.c @@ -92,6 +92,25 @@ db_list_pool_records(B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx) db_unlock(mdb); } +void +db_list_client_records(B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx) +{ + Mmsg(&mdb->cmd, "SELECT ClientId,Name,FileRetention,JobRetention " +"FROM Client ORDER BY ClientId"); + + db_lock(mdb); + if (!QUERY_DB(mdb, mdb->cmd)) { + db_unlock(mdb); + return; + } + + list_result(mdb, sendit, ctx); + + sql_free_result(mdb); + db_unlock(mdb); +} + + void db_list_media_records(B_DB *mdb, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx) { diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 91dc6deff1..975970e357 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -186,6 +186,7 @@ int showcmd(UAContext *ua, char *cmd) * list pools - list pool records * list jobtotals - list totals for all jobs * list media - list media for given pool + * list clients - list clients * */ int listcmd(UAContext *ua, char *cmd) @@ -284,6 +285,10 @@ int listcmd(UAContext *ua, char *cmd) } else if (strcasecmp(ua->argk[i], _("pools")) == 0) { db_list_pool_records(ua->db, prtit, ua); + } else if (strcasecmp(ua->argk[i], _("clients")) == 0) { + db_list_client_records(ua->db, prtit, ua); + + /* List MEDIA or VOLUMES */ } else if (strcasecmp(ua->argk[i], _("media")) == 0 || strcasecmp(ua->argk[i], _("volumes")) == 0) { diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index 6266ab4ea0..c85a4aa2ce 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -80,6 +80,10 @@ typedef struct s_rbsr { uint32_t JobId; /* JobId this bsr */ uint32_t VolSessionId; uint32_t VolSessionTime; + uint32_t StartFile; + uint32_t EndFile; + uint32_t StartBlock; + uint32_t EndBlock; char *VolumeName; /* Volume name */ RBSR_FINDEX *fi; /* File indexes this JobId */ } RBSR; @@ -654,10 +658,10 @@ static void free_bsr(RBSR *bsr) static int complete_bsr(UAContext *ua, RBSR *bsr) { JOB_DBR jr; - POOLMEM *VolumeNames; + VOL_PARAMS *VolParams; + int count = 0; if (bsr) { - VolumeNames = get_pool_memory(PM_MESSAGE); memset(&jr, 0, sizeof(jr)); jr.JobId = bsr->JobId; if (!db_get_job_record(ua->db, &jr)) { @@ -666,13 +670,17 @@ static int complete_bsr(UAContext *ua, RBSR *bsr) } bsr->VolSessionId = jr.VolSessionId; bsr->VolSessionTime = jr.VolSessionTime; - if (!db_get_job_volume_names(ua->db, bsr->JobId, &VolumeNames)) { - bsendmsg(ua, _("Unable to get Job Volumes. ERR=%s\n"), db_strerror(ua->db)); - free_pool_memory(VolumeNames); + if ((count=db_get_job_volume_parameters(ua->db, bsr->JobId, &VolParams)) == 0) { + bsendmsg(ua, _("Unable to get Job Volume Parameters. ERR=%s\n"), db_strerror(ua->db)); + free((char *)VolParams); return 0; } - bsr->VolumeName = bstrdup(VolumeNames); - free_pool_memory(VolumeNames); + bsr->VolumeName = bstrdup(VolParams[0].VolumeName); + bsr->StartFile = VolParams[0].StartFile; + bsr->EndFile = VolParams[0].EndFile; + bsr->StartBlock = VolParams[0].StartBlock; + bsr->EndBlock = VolParams[0].EndBlock; + free((char *)VolParams); return complete_bsr(ua, bsr->next); } return 1; @@ -719,6 +727,7 @@ static void write_bsr(UAContext *ua, RBSR *bsr, FILE *fd) } fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId); fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime); + fprintf(fd, "VolFile=%u-%u\n", bsr->StartFile, bsr->EndFile); write_findex(ua, bsr->fi, fd); write_bsr(ua, bsr->next, fd); } diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 9dd7f3a5d3..a96519ad22 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -56,6 +56,10 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) /* Find next Volume, if any */ vol = jcr->VolList; + if (!vol) { + Jmsg(jcr, M_FATAL, 0, _("No volumes specified. Job cancelled.\n")); + goto get_out; + } jcr->CurVolume++; for (int i=1; iCurVolume; i++) { vol = vol->next; diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index 459c8258b1..075505db5a 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -326,7 +326,6 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) Pmsg1(000, "VOL_LABEL: OK for Volume: %s\n", mr.VolumeName); break; case SOS_LABEL: - mr.VolJobs++; unser_session_label(&label, rec); memset(&jr, 0, sizeof(jr)); @@ -402,11 +401,10 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) create_fileset_record(db, &fsr); jr.FileSetId = fsr.FileSetId; - mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { Pmsg2(000, _("Could not find SessId=%d SessTime=%d for EOS record.\n"), - rec->VolSessionId, rec->VolSessionTime); + rec->VolSessionId, rec->VolSessionTime); break; } @@ -504,16 +502,16 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) ; } strcat(lname, lp); /* "save" link name */ - - if (verbose > 1) { decode_stat(ap, &statp); print_ls_output(fname, lname, type, &statp); } mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { - Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Attributes record.\n"), - rec->VolSessionId, rec->VolSessionTime); + if (mr.VolJobs > 0) { + Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Attributes record.\n"), + rec->VolSessionId, rec->VolSessionTime); + } return; } fr.JobId = mjcr->JobId; @@ -531,8 +529,10 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) } else if (rec->Stream == STREAM_FILE_DATA) { mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { - Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Attributes record.\n"), - rec->VolSessionId, rec->VolSessionTime); + if (mr.VolJobs > 0) { + Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for File Data record.\n"), + rec->VolSessionId, rec->VolSessionTime); + } return; } mjcr->JobBytes += rec->data_len; @@ -541,8 +541,10 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) } else if (rec->Stream == STREAM_SPARSE_DATA) { mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { - Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Attributes record.\n"), - rec->VolSessionId, rec->VolSessionTime); + if (mr.VolJobs > 0) { + Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Sparse Data record.\n"), + rec->VolSessionId, rec->VolSessionTime); + } return; } mjcr->JobBytes += rec->data_len - sizeof(uint64_t); @@ -551,8 +553,10 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) } else if (rec->Stream == STREAM_GZIP_DATA) { mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { - Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Attributes record.\n"), - rec->VolSessionId, rec->VolSessionTime); + if (mr.VolJobs > 0) { + Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for GZIP Data record.\n"), + rec->VolSessionId, rec->VolSessionTime); + } return; } mjcr->JobBytes += rec->data_len; /* No correct, we should expand it */ @@ -561,8 +565,10 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) } else if (rec->Stream == STREAM_SPARSE_GZIP_DATA) { mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { - Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Attributes record.\n"), - rec->VolSessionId, rec->VolSessionTime); + if (mr.VolJobs > 0) { + Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Sparse GZIP Data record.\n"), + rec->VolSessionId, rec->VolSessionTime); + } return; } mjcr->JobBytes += rec->data_len - sizeof(uint64_t); /* No correct, we should expand it */ @@ -835,10 +841,8 @@ static JCR *create_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *label, Pmsg1(0, _("Could not update job start record. ERR=%s\n"), db_strerror(db)); return mjcr; } - if (verbose) { - Pmsg2(000, _("Created new JobId=%u record for original JobId=%u\n"), jr->JobId, + Pmsg2(000, _("Created new JobId=%u record for original JobId=%u\n"), jr->JobId, label->JobId); - } mjcr->JobId = jr->JobId; /* set new JobId */ return mjcr; } @@ -998,8 +1002,10 @@ static int update_MD5_record(B_DB *db, char *MD5buf, DEV_RECORD *rec) mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { - Pmsg2(000, _("Could not find SessId=%d SessTime=%d for EOS record.\n"), - rec->VolSessionId, rec->VolSessionTime); + if (mr.VolJobs > 0) { + Pmsg2(000, _("Could not find SessId=%d SessTime=%d for MD5 record.\n"), + rec->VolSessionId, rec->VolSessionTime); + } return 0; } diff --git a/bacula/src/stored/match_bsr.c b/bacula/src/stored/match_bsr.c index 41aa8daa87..aa564d0c34 100755 --- a/bacula/src/stored/match_bsr.c +++ b/bacula/src/stored/match_bsr.c @@ -85,9 +85,10 @@ static int match_all(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, if (!match_volume(bsr, bsr->volume, volrec, 1)) { goto no_match; } - if (!match_volfile(bsr, bsr->volfile, rec, 1)) { - goto no_match; - } + /* Not yet working */ +// if (!match_volfile(bsr, bsr->volfile, rec, 1)) { +// goto no_match; +// } if (!match_sesstime(bsr, bsr->sesstime, rec, 1)) { goto no_match; }