int db_delete_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr);
/* sql_find.c */
-bool db_find_last_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime, int JobLevel);
-bool db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime);
+bool db_find_last_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime, char *job, int JobLevel);
+bool db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime, char *job);
bool db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr);
int db_find_next_volume(JCR *jcr, B_DB *mdb, int index, bool InChanger, MEDIA_DBR *mr);
bool db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel);
* find last Job start time Incremental and Differential saves.
*
* StartTime is returned in stime
+ * Job name is returned in job (MAX_NAME_LENGTH)
*
* Returns: 0 on failure
- * 1 on success, jr is unchanged, but stime is set
+ * 1 on success, jr is unchanged, but stime and job are set
*/
bool
-db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime)
+db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime, char *job)
{
SQL_ROW row;
char ed1[50], ed2[50];
db_lock(mdb);
mdb->db_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name));
pm_strcpy(stime, "0000-00-00 00:00:00"); /* default */
+ job[0] = 0;
+
/* If no Id given, we must find corresponding job */
if (jr->JobId == 0) {
/* Differential is since last Full backup */
Mmsg(mdb->cmd,
-"SELECT StartTime FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND "
+"SELECT StartTime, Job FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND "
"Level='%c' AND Name='%s' AND ClientId=%s AND FileSetId=%s "
"ORDER BY StartTime DESC LIMIT 1",
jr->JobType, L_FULL, esc_name,
sql_free_result(mdb);
/* Now edit SQL command for Incremental Job */
Mmsg(mdb->cmd,
-"SELECT StartTime FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND "
+"SELECT StartTime, Job FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND "
"Level IN ('%c','%c','%c') AND Name='%s' AND ClientId=%s "
"AND FileSetId=%s ORDER BY StartTime DESC LIMIT 1",
jr->JobType, L_INCREMENTAL, L_DIFFERENTIAL, L_FULL, esc_name,
}
} else {
Dmsg1(100, "Submitting: %s\n", mdb->cmd);
- Mmsg(mdb->cmd, "SELECT StartTime FROM Job WHERE Job.JobId=%s",
+ Mmsg(mdb->cmd, "SELECT StartTime, Job FROM Job WHERE Job.JobId=%s",
edit_int64(jr->JobId, ed1));
}
sql_free_result(mdb);
goto bail_out;
}
- Dmsg1(100, "Got start time: %s\n", row[0]);
+ Dmsg2(100, "Got start time: %s, job: %s\n", row[0], row[1]);
pm_strcpy(stime, row[0]);
+ bstrncpy(job, row[1], MAX_NAME_LENGTH);
sql_free_result(mdb);
* Find the last job start time for the specified JobLevel
*
* StartTime is returned in stime
+ * Job name is returned in job (MAX_NAME_LENGTH)
*
* Returns: false on failure
- * true on success, jr is unchanged, but stime is set
+ * true on success, jr is unchanged, but stime and job are set
*/
bool
-db_find_last_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime, int JobLevel)
+db_find_last_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr,
+ POOLMEM **stime, char *job, int JobLevel)
{
SQL_ROW row;
char ed1[50], ed2[50];
db_lock(mdb);
mdb->db_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name));
pm_strcpy(stime, "0000-00-00 00:00:00"); /* default */
+ job[0] = 0;
Mmsg(mdb->cmd,
-"SELECT StartTime FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND "
+"SELECT StartTime, Job FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND "
"Level='%c' AND Name='%s' AND ClientId=%s AND FileSetId=%s "
"ORDER BY StartTime DESC LIMIT 1",
jr->JobType, JobLevel, esc_name,
}
Dmsg1(100, "Got start time: %s\n", row[0]);
pm_strcpy(stime, row[0]);
+ bstrncpy(job, row[1], MAX_NAME_LENGTH);
+
sql_free_result(mdb);
db_unlock(mdb);
return true;
static char filesetcmd[] = "fileset%s\n"; /* set full fileset */
static char jobcmd[] = "JobId=%s Job=%s SDid=%u SDtime=%u Authorization=%s\n";
/* Note, mtime_only is not used here -- implemented as file option */
-static char levelcmd[] = "level = %s%s%s mtime_only=%d\n";
+static char levelcmd[] = "level = %s%s%s mtime_only=%d %s%s\n";
static char runscript[] = "Run OnSuccess=%u OnFailure=%u AbortOnError=%u When=%u Command=%s\n";
static char runbeforenow[]= "RunBeforeNow\n";
utime_t now;
utime_t last_full_time = 0;
utime_t last_diff_time;
+ char prev_job[MAX_NAME_LENGTH];
since[0] = 0;
/* If job cloned and a since time already given, use it */
if (!jcr->stime) {
jcr->stime = get_pool_memory(PM_MESSAGE);
}
- jcr->stime[0] = 0;
+ jcr->PrevJob[0] = jcr->stime[0] = 0;
/*
* Lookup the last FULL backup job to get the time/date for a
* differential or incremental save.
* This is probably redundant, but some of the code below
* uses jcr->stime, so don't remove unless you are sure.
*/
- if (!db_find_job_start_time(jcr, jcr->db, &jcr->jr, &jcr->stime)) {
+ if (!db_find_job_start_time(jcr,jcr->db, &jcr->jr, &jcr->stime, jcr->PrevJob)) {
do_full = true;
}
- have_full = db_find_last_job_start_time(jcr, jcr->db, &jcr->jr, &stime, L_FULL);
+ have_full = db_find_last_job_start_time(jcr, jcr->db, &jcr->jr,
+ &stime, prev_job, L_FULL);
if (have_full) {
last_full_time = str_to_utime(stime);
} else {
/* Make sure the last diff is recent enough */
if (have_full && jcr->getJobLevel() == L_INCREMENTAL && jcr->job->MaxDiffInterval > 0) {
/* Lookup last diff job */
- if (db_find_last_job_start_time(jcr, jcr->db, &jcr->jr, &stime, L_DIFFERENTIAL)) {
+ if (db_find_last_job_start_time(jcr, jcr->db, &jcr->jr,
+ &stime, prev_job, L_DIFFERENTIAL)) {
last_diff_time = str_to_utime(stime);
/* If no Diff since Full, use Full time */
if (last_diff_time < last_full_time) {
jcr->setJobLevel(jcr->jr.JobLevel = L_DIFFERENTIAL);
} else {
if (jcr->job->rerun_failed_levels) {
- if (db_find_failed_job_since(jcr, jcr->db, &jcr->jr, jcr->stime, JobLevel)) {
+ if (db_find_failed_job_since(jcr, jcr->db, &jcr->jr,
+ jcr->stime, JobLevel)) {
Jmsg(jcr, M_INFO, 0, _("Prior failed job found in catalog. Upgrading to %s.\n"),
level_to_str(JobLevel));
bsnprintf(since, since_len, _(" (upgraded from %s)"),
jcr->jr.JobId = jcr->JobId;
break;
}
- Dmsg2(100, "Level=%c last start time=%s\n", jcr->getJobLevel(), jcr->stime);
+ Dmsg3(100, "Level=%c last start time=%s job=%s\n",
+ jcr->getJobLevel(), jcr->stime, jcr->PrevJob);
}
static void send_since_time(JCR *jcr)
char ed1[50];
stime = str_to_utime(jcr->stime);
- fd->fsend(levelcmd, "", NT_("since_utime "), edit_uint64(stime, ed1), 0);
+ fd->fsend(levelcmd, "", NT_("since_utime "), edit_uint64(stime, ed1), 0,
+ NT_("prev_job="), jcr->PrevJob);
while (bget_dirmsg(fd) >= 0) { /* allow him to poll us to sync clocks */
Jmsg(jcr, M_INFO, 0, "%s\n", fd->msg);
}
*/
switch (jcr->getJobLevel()) {
case L_BASE:
- fd->fsend(levelcmd, not_accurate, "base", rerunning, 0);
+ fd->fsend(levelcmd, not_accurate, "base", rerunning, 0, "", "");
break;
/* L_NONE is the console, sending something off to the FD */
case L_NONE:
case L_FULL:
- fd->fsend(levelcmd, not_accurate, "full", rerunning, 0);
+ fd->fsend(levelcmd, not_accurate, "full", rerunning, 0, "", "");
break;
case L_DIFFERENTIAL:
- fd->fsend(levelcmd, accurate, "differential", rerunning, 0);
+ fd->fsend(levelcmd, accurate, "differential", rerunning, 0, "", "");
send_since_time(jcr);
break;
case L_INCREMENTAL:
- fd->fsend(levelcmd, accurate, "incremental", rerunning, 0);
+ fd->fsend(levelcmd, accurate, "incremental", rerunning, 0, "", "");
send_since_time(jcr);
break;
case L_SINCE:
*((char **)value) = jcr->Job;
Dmsg1(dbglvl, "Bacula: return Job name=%s\n", jcr->Job);
break;
+ case bVarPrevJobName:
+ *((char **)value) = jcr->PrevJob;
+ Dmsg1(dbglvl, "Bacula: return Previous Job name=%s\n", jcr->PrevJob);
+ break;
case bVarJobStatus:
*((int *)value) = jcr->JobStatus;
Dmsg1(dbglvl, "Bacula: return bVarJobStatus=%d\n", jcr->JobStatus);
bVarExePath = 16,
bVarVersion = 17,
bVarDistName = 18,
- bVarBEEF = 19
+ bVarBEEF = 19,
+ bVarPrevJobName = 20
} bVariable;
/* Events that are passed to plugin */
if (jcr->getJobLevel() == L_NONE) {
jcr->setJobLevel(L_SINCE); /* if no other job level set, do it now */
}
- if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d",
- buf, &mtime_only) != 2) {
- goto bail_out;
+ if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d prev_job=%127s",
+ buf, &mtime_only, jcr->PrevJob) != 3) {
+ if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d",
+ buf, &mtime_only) != 2) {
+ goto bail_out;
+ }
}
since_time = str_to_uint64(buf); /* this is the since time */
- Dmsg1(100, "since_time=%lld\n", since_time);
+ Dmsg2(100, "since_time=%lld prev_job=%s\n", since_time, jcr->PrevJob);
char ed1[50], ed2[50];
/*
* Sync clocks by polling him for the time. We take
JCR *mig_jcr; /* JCR for migration/copy job */
char FSCreateTime[MAX_TIME_LENGTH]; /* FileSet CreateTime as returned from DB */
char since[MAX_TIME_LENGTH]; /* since time */
+ char PrevJob[MAX_NAME_LENGTH]; /* Previous job name assiciated with since time */
union {
JobId_t RestoreJobId; /* Id specified by UA */
JobId_t MigrateJobId;
int32_t buf_size; /* length of buffer */
FF_PKT *ff; /* Find Files packet */
char stored_addr[MAX_NAME_LENGTH]; /* storage daemon address */
+ char PrevJob[MAX_NAME_LENGTH]; /* Previous job name assiciated with since time */
uint32_t StartFile;
uint32_t EndFile;
uint32_t StartBlock;