/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2012 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.
/*
* Foreach files in currrent list, send "/path/fname\0LStat\0MD5\0Delta" to FD
* row[0]=Path, row[1]=Filename, row[2]=FileIndex
- * row[3]=JobId row[4]=LStat row[5]=MarkId row[6]=MD5
+ * row[3]=JobId row[4]=LStat row[5]=DeltaSeq row[6]=MD5
*/
static int accurate_list_handler(void *ctx, int num_fields, char **row)
{
POOL_MEM buf;
db_list_ctx jobids;
db_list_ctx nb;
- char ed1[50];
- /* For incomplete Jobs, we add our own id */
- if (jcr->incomplete) {
- edit_int64(jcr->JobId, ed1);
- jobids.add(ed1);
- } else {
- if (!jcr->accurate || job_canceled(jcr)) {
- return true;
- }
- /* In base level, no previous job is used */
- if (jcr->is_JobLevel(L_BASE)) {
- return true;
- }
-
- if (jcr->is_JobLevel(L_FULL)) {
- /* On Full mode, if no previous base job, no accurate things */
- if (!get_base_jobids(jcr, &jobids)) {
- return true;
- }
+ /* In base level, no previous job is used and no restart incomplete jobs */
+ if (jcr->is_canceled() || jcr->is_JobLevel(L_BASE)) {
+ return true;
+ }
+ if (!jcr->accurate) {
+ return true;
+ }
+
+ if (jcr->is_JobLevel(L_FULL)) {
+ /* On Full mode, if no previous base job, no accurate things */
+ if (get_base_jobids(jcr, &jobids)) {
jcr->HasBase = true;
Jmsg(jcr, M_INFO, 0, _("Using BaseJobId(s): %s\n"), jobids.list);
-
} else {
- /* For Incr/Diff level, we search for older jobs */
- db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
+ return true;
+ }
+ } else {
+ /* For Incr/Diff level, we search for older jobs */
+ db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
- /* We are in Incr/Diff, but no Full to build the accurate list... */
- if (jobids.count == 0) {
- Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n"));
- return false; /* fail */
- }
+ /* We are in Incr/Diff, but no Full to build the accurate list... */
+ if (jobids.count == 0) {
+ Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n"));
+ return false; /* fail */
}
}
return false;
}
- /* For incomplete Jobs, we add our own id */
- if (jcr->incomplete) {
- edit_int64(jcr->JobId, ed1);
- Mmsg(buf, "SELECT max(FileIndex) FROM File WHERE JobId=%s", ed1);
- if (!db_sql_query(jcr->db, buf.c_str(), db_int64_handler, &job)) {
- Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
- return false;
- }
- jcr->JobFiles = job.value;
- Mmsg(buf, "SELECT VolSessionId FROM Job WHERE JobId=%s", ed1);
- if (!db_sql_query(jcr->db, buf.c_str(), db_int64_handler, &job)) {
- Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
- return false;
- }
- jcr->VolSessionId = job.value;
- Mmsg(buf, "SELECT VolSessionTime FROM Job WHERE JobId=%s", ed1);
- if (!db_sql_query(jcr->db, buf.c_str(), db_int64_handler, &job)) {
- Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
- return false;
- }
- jcr->VolSessionTime = job.value;
- Dmsg4(100, "JobId=%s JobFiles=%ld VolSessionId=%ld VolSessionTime=%ld\n", ed1,
- jcr->JobFiles, jcr->VolSessionId, jcr->VolSessionTime);
- }
-
/*
* Open a message channel connection with the Storage
* daemon. This is to let him know that our client
jcr->setJobStatus(JS_Running);
fd = jcr->file_bsock;
- if (!send_include_list(jcr)) {
+ if (!send_level_command(jcr)) {
goto bail_out;
}
- if (!send_exclude_list(jcr)) {
+ if (!send_include_list(jcr)) {
goto bail_out;
}
- if (!send_level_command(jcr)) {
+ if (!send_exclude_list(jcr)) {
goto bail_out;
}
- /* TODO: See priority with bandwidth parameter */
- if (jcr->job->max_bandwidth > 0) {
- jcr->max_bandwidth = jcr->job->max_bandwidth;
- } else if (jcr->client->max_bandwidth > 0) {
- jcr->max_bandwidth = jcr->client->max_bandwidth;
- }
-
- if (jcr->max_bandwidth > 0) {
- send_bwlimit(jcr, jcr->Job); /* Old clients don't have this command */
- }
-
/*
* send Storage daemon address to the File daemon
*/
}
if (is_bnet_error(fd)) {
+ int i = 0;
Jmsg(jcr, M_FATAL, 0, _("Network error with FD during %s: ERR=%s\n"),
job_type_to_str(jcr->getJobType()), fd->bstrerror());
+ while (i++ < 10 && jcr->job->RescheduleIncompleteJobs && jcr->is_canceled()) {
+ bmicrosleep(3, 0);
+ }
+
}
fd->signal(BNET_TERMINATE); /* tell Client we are terminating */
}
* Force cancel in SD if failing, but not for Incomplete jobs
* so that we let the SD despool.
*/
- if (jcr->is_canceled() || !fd_ok) {
+ Dmsg5(100, "cancel=%d fd_ok=%d FDJS=%d JS=%d SDJS=%d\n", jcr->is_canceled(), fd_ok, jcr->FDJobStatus,
+ jcr->JobStatus, jcr->SDJobStatus);
+ if (jcr->is_canceled() || (!jcr->job->RescheduleIncompleteJobs && !fd_ok)) {
+ Dmsg4(100, "fd_ok=%d FDJS=%d JS=%d SDJS=%d\n", fd_ok, jcr->FDJobStatus,
+ jcr->JobStatus, jcr->SDJobStatus);
cancel_storage_daemon_job(jcr);
}
}
Dmsg2(100, "Enter backup_cleanup %d %c\n", TermCode, TermCode);
- memset(&mr, 0, sizeof(mr));
memset(&cr, 0, sizeof(cr));
#ifdef xxxx
+ /* The current implementation of the JS_Warning status is not
+ * completed. SQL part looks to be ok, but the code is using
+ * JS_Terminated almost everywhere instead of (JS_Terminated || JS_Warning)
+ * as we do with is_canceled()
+ */
if (jcr->getJobStatus() == JS_Terminated &&
(jcr->JobErrors || jcr->SDErrors || jcr->JobWarnings)) {
TermCode = JS_Warnings;