From: Alain Spineux Date: Tue, 4 May 2021 09:43:45 +0000 (+0200) Subject: Fix org#2500 .bvfs_get_jobids jobid=X must return X in the list part2 X-Git-Tag: Release-11.3.2~548 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77d4c509828d95975e53d73f98cea76671076eb3;p=thirdparty%2Fbacula.git Fix org#2500 .bvfs_get_jobids jobid=X must return X in the list part2 - restrict this feature to the ".bvfs_get_jobids" command only - else any call with a jcr->JobId != 0 force the function to use it this is not what we want. - notice the following change in the behaviour of the .bvfs_get_jobids command when a job has been migrated : | JobId | Name | StartTime | Type | Level | JobFiles +-------+------------------+---------------------+------+-------+--------- | 1 | MigrationJobSave | 2021-05-04 11:16:26 | M | F | 3131 | 5 | MigrationJobSave | 2021-05-04 11:16:26 | B | F | 3131 *.bvfs_get_jobids jobid=1 5 <== before the change *.bvfs_get_jobids jobid=1 <== after the change --- diff --git a/bacula/src/cats/bdb.h b/bacula/src/cats/bdb.h index 1dfd03b9e..5cc4b0bd3 100644 --- a/bacula/src/cats/bdb.h +++ b/bacula/src/cats/bdb.h @@ -244,7 +244,7 @@ public: int opts, DB_RESULT_HANDLER *result_handler, void *ctx); bool bdb_get_base_jobid(JCR *jcr, JOB_DBR *jr, JobId_t *jobid); - bool bdb_get_accurate_jobids(JCR *jcr, JOB_DBR *jr, db_list_ctx *jobids); + bool bdb_get_accurate_jobids(JCR *jcr, JOB_DBR *jr, uint32_t from_jobid, db_list_ctx *jobids); bool bdb_get_used_base_jobids(JCR *jcr, POOLMEM *jobids, db_list_ctx *result); bool bdb_get_restoreobject_record(JCR *jcr, ROBJECT_DBR *rr); bool bdb_get_plugin_object_record(JCR *jcr, OBJECT_DBR *obj_r); diff --git a/bacula/src/cats/bvfs.c b/bacula/src/cats/bvfs.c index 0ccd54389..21bca79f5 100644 --- a/bacula/src/cats/bvfs.c +++ b/bacula/src/cats/bvfs.c @@ -994,7 +994,7 @@ bool Bvfs::get_delta(FileId_t fileid) jr.StartTime = jr2.StartTime; /* Get accurate jobid list */ - if (!db->bdb_get_accurate_jobids(jcr, &jr, &lst)) { + if (!db->bdb_get_accurate_jobids(jcr, &jr, jid, &lst)) { Dmsg1(0, "Unable to get Accurate list for jobid %d\n", jid); goto bail_out; } @@ -1778,7 +1778,7 @@ void Bvfs::insert_missing_delta(char *output_table, int64_t *res) jr.StartTime = jr2.StartTime; /* Get accurate jobid list */ - db->bdb_get_accurate_jobids(jcr, &jr, &lst); + db->bdb_get_accurate_jobids(jcr, &jr, jr.JobId, &lst); Dmsg2(dbglevel_sql, "JobId list for %lld is %s\n", res[0], lst.list); diff --git a/bacula/src/cats/protos.h b/bacula/src/cats/protos.h index 505fc30c5..74f9e3dab 100644 --- a/bacula/src/cats/protos.h +++ b/bacula/src/cats/protos.h @@ -240,7 +240,9 @@ void bdb_free_restoreobject_record(JCR *jcr, ROBJECT_DBR *rr); #define db_get_base_jobid(jcr, mdb, jr, jobid) \ mdb->bdb_get_base_jobid(jcr, jr, jobid) #define db_get_accurate_jobids(jcr, mdb, jr, jobids) \ - mdb->bdb_get_accurate_jobids(jcr, jr, jobids) + mdb->bdb_get_accurate_jobids(jcr, jr, 0, jobids) +#define db_get_accurate_jobids_from_jobid(jcr, mdb, jr, jobid_hint, jobids) \ + mdb->bdb_get_accurate_jobids(jcr, jr, jobid_hint, jobids) #define db_get_used_base_jobids(jcr, mdb, jobids, result) \ mdb->bdb_get_used_base_jobids(jcr, jobids, result) #define db_get_restoreobject_record(jcr, mdb, rr) \ diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index 2ea05947e..5a8d126a2 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -1535,10 +1535,19 @@ static uint32_t btemp_cur = 1; * If you specify jr->StartTime, it will be used to limit the search * in the time. (usually now) * + * In some case multiple job can satisfy the requirement (two jobs ran exactly + * at the same time or mutiple copy jobs), and the function take the first one. + * But when specified, like in the command ".bvfs_get_jobids jobid=XXX" we must + * verify that XXX match the requirement and return it if it exists, not any + * other "interchangeable jobs". That's what the from_jobid is for. If not sure, + * set 0 + * * TODO: look and merge from ua_restore.c */ bool BDB::bdb_get_accurate_jobids(JCR *jcr, - JOB_DBR *jr, db_list_ctx *jobids) + JOB_DBR *jr, + uint32_t from_jobid, + db_list_ctx *jobids) { bool ret=false; char clientid[50], jobid[50], filesetid[50]; @@ -1552,15 +1561,15 @@ bool BDB::bdb_get_accurate_jobids(JCR *jcr, bstrutime(date, sizeof(date), StartTime + 1); jobids->reset(); - /* If we are comming from bconsole, we must ensure that we + /* If we are coming from bconsole, we must ensure that we * have a unique name. */ - if (jcr->JobId == 0) { + if (from_jobid == 0) { P(btemp_mutex); bsnprintf(jobid, sizeof(jobid), "0%u", btemp_cur++); V(btemp_mutex); } else { - edit_uint64(jcr->JobId, jobid); + edit_uint64(from_jobid, jobid); Mmsg(aux, " AND JobId = %s ", jobid); } diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index a8f819383..411c03e15 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -1394,6 +1394,7 @@ bail_out: static bool dot_bvfs_get_jobids(UAContext *ua, const char *cmd) { JOB_DBR jr; + uint32_t jobid_hint = 0; /* if specified with a jobid=XXX */ memset(&jr, 0, sizeof(JOB_DBR)); db_list_ctx jobids, tempids; @@ -1419,7 +1420,7 @@ static bool dot_bvfs_get_jobids(UAContext *ua, const char *cmd) if ((pos = find_arg_with_value(ua, "jobid")) >= 0) { jr.JobId = str_to_int64(ua->argv[pos]); - + jobid_hint = jr.JobId; /* Guess JobId from Job name, take the last successful jobid */ } else if ((pos = find_arg_with_value(ua, "job")) >= 0) { JOB *job; @@ -1516,7 +1517,7 @@ static bool dot_bvfs_get_jobids(UAContext *ua, const char *cmd) /* Foreach different FileSet, we build a restore jobid list */ for (int i=0; i < ids.num_ids; i++) { jr.FileSetId = ids.DBId[i]; - if (!db_get_accurate_jobids(ua->jcr, ua->db, &jr, &tempids)) { + if (!db_get_accurate_jobids_from_jobid(ua->jcr, ua->db, &jr, jobid_hint, &tempids)) { return true; } jobids.add(tempids);