/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2011 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.
* to do the backup.
* When the File daemon finishes the job, update the DB.
*
- * Version $Id$
*/
#include "bacula.h"
#include "ua.h"
/* Commands sent to File daemon */
-static char backupcmd[] = "backup\n";
+static char backupcmd[] = "backup FileIndex=%ld\n";
static char storaddr[] = "storage address=%s port=%d ssl=%d\n";
/* Responses received from File daemon */
bool do_backup_init(JCR *jcr)
{
- if (jcr->getJobLevel() == L_VIRTUAL_FULL) {
+ if (jcr->is_JobLevel(L_VIRTUAL_FULL)) {
return do_vbackup_init(jcr);
}
free_rstorage(jcr); /* we don't read so release */
have_basejob_option = in_block = jcr->HasBase;
break;
case 'C': /* Accurate keyword */
- in_block = (jcr->getJobLevel() != L_FULL);
+ in_block = !jcr->is_JobLevel(L_FULL);
break;
case ':': /* End of keyword */
in_block = false;
bool send_accurate_current_files(JCR *jcr)
{
POOL_MEM buf;
- bool ret=true;
db_list_ctx jobids;
db_list_ctx nb;
+ char ed1[50];
- if (!jcr->accurate || job_canceled(jcr)) {
- return true;
- }
- /* In base level, no previous job is used */
- if (jcr->getJobLevel() == L_BASE) {
- return true;
- }
-
- if (jcr->getJobLevel() == L_FULL) {
- /* On Full mode, if no previous base job, no accurate things */
- if (!get_base_jobids(jcr, &jobids)) {
- goto bail_out;
+ /* 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;
}
- jcr->HasBase = true;
- Jmsg(jcr, M_INFO, 0, _("Using BaseJobId(s): %s\n"), jobids.list);
+ /* 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;
+ }
+ 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);
-
- /* We are in Incr/Diff, but no Full to build the accurate list... */
- if (jobids.count == 0) {
- ret=false;
- Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n"));
- goto bail_out;
+ } 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 */
+ }
}
}
if (!db_open_batch_connexion(jcr, jcr->db)) {
Jmsg0(jcr, M_FATAL, 0, "Can't get batch sql connexion");
- return false;
+ return false; /* Fail */
}
if (jcr->HasBase) {
} else {
db_get_file_list(jcr, jcr->db_batch,
- jobids.list, jcr->use_accurate_chksum,
+ jobids.list, jcr->use_accurate_chksum, false /* no delta */,
accurate_list_handler, (void *)jcr);
}
- /* TODO: close the batch connexion ? (can be used very soon) */
+ /* TODO: close the batch connection ? (can be used very soon) */
jcr->file_bsock->signal(BNET_EOD);
-
-bail_out:
- return ret;
+ return true;
}
/*
BSOCK *fd;
STORE *store;
char ed1[100];
+ db_int64_ctx job;
+ POOL_MEM buf;
- if (jcr->getJobLevel() == L_VIRTUAL_FULL) {
+ if (jcr->is_JobLevel(L_VIRTUAL_FULL)) {
return do_vbackup(jcr);
}
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
* to avoid two threads from using the BSOCK structure at
* the same time.
*/
- if (!bnet_fsend(jcr->store_bsock, "run")) {
+ if (!jcr->store_bsock->fsend("run")) {
return false;
}
* all files to FD.
*/
if (!send_accurate_current_files(jcr)) {
- goto bail_out;
+ goto bail_out; /* error */
}
/* Send backup command */
- fd->fsend(backupcmd);
+ fd->fsend(backupcmd, jcr->JobFiles);
+ Dmsg1(100, ">filed: %s", fd->msg);
if (!response(jcr, fd, OKbackup, "backup", DISPLAY_ERROR)) {
goto bail_out;
}
stat = wait_for_job_termination(jcr);
db_write_batch_file_records(jcr); /* used by bulk batch file insert */
- if (jcr->HasBase &&
- !db_commit_base_file_attributes_record(jcr, jcr->db))
- {
- Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
+ if (jcr->HasBase && !db_commit_base_file_attributes_record(jcr, jcr->db)) {
+ Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
}
if (stat == JS_Terminated) {
fd->signal(BNET_TERMINATE); /* tell Client we are terminating */
}
- /* Force cancel in SD if failing */
- if (job_canceled(jcr) || !fd_ok) {
+ /*
+ * Force cancel in SD if failing, but not for Incomplete jobs
+ * so that we let the SD despool.
+ */
+ if (jcr->is_canceled() || !fd_ok) {
cancel_storage_daemon_job(jcr);
}
utime_t RunTime;
POOL_MEM base_info;
- if (jcr->getJobLevel() == L_VIRTUAL_FULL) {
+ if (jcr->is_JobLevel(L_VIRTUAL_FULL)) {
vbackup_cleanup(jcr, TermCode);
return;
}
term_msg = _("Backup OK");
}
break;
+ case JS_Incomplete:
+ term_msg = _("Backup failed -- incomplete");
+ break;
case JS_Warnings:
term_msg = _("Backup OK -- with warnings");
break;
fd = bpipe ? bpipe->wfd : NULL;
} else {
/* ***FIXME*** handle BASE */
- fd = fopen(fname, jcr->getJobLevel()==L_FULL?"w+b":"a+b");
+ fd = fopen(fname, jcr->is_JobLevel(L_FULL)?"w+b":"a+b");
}
if (fd) {
VolCount = db_get_job_volume_parameters(jcr, jcr->db, jcr->JobId,