/*
Bacula® - The Network Backup Solution
- Copyright (C) 2008-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2008-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.
This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
+ modify it under the terms of version three of the GNU Affero General Public
License as published by the Free Software Foundation and included
in the file LICENSE.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
* to do the backup.
* When the File daemon finishes the job, update the DB.
*
- * Version $Id: $
*/
#include "bacula.h"
static const int dbglevel = 10;
-static char OKbootstrap[] = "3000 OK bootstrap\n";
-
-static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids);
+static bool create_bootstrap_file(JCR *jcr, char *jobids);
void vbackup_cleanup(JCR *jcr, int TermCode);
/*
*/
bool do_vbackup_init(JCR *jcr)
{
- char *p;
if (!get_or_create_fileset_record(jcr)) {
Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId);
Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
}
- POOLMEM *jobids = get_pool_memory(PM_FNAME);
- jcr->jr.JobLevel = L_VIRTUAL_FULL;
- db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
- jcr->jr.JobLevel = L_FULL;
- Dmsg1(10, "Accurate jobids=%s\n", jobids);
- if (*jobids == 0) {
- free_pool_memory(jobids);
- Jmsg(jcr, M_FATAL, 0, _("Cannot find previous JobIds.\n"));
- return false;
- }
-
- /*
- * Now we find the last job that ran and store it's info in
- * the previous_jr record. We will set our times to the
- * values from that job so that anything changed after that
- * time will be picked up on the next backup.
- */
- p = strrchr(jobids, ','); /* find last jobid */
- if (p != NULL) {
- p++;
- } else {
- p = jobids;
- }
- memset(&jcr->previous_jr, 0, sizeof(jcr->previous_jr));
- jcr->previous_jr.JobId = str_to_int64(p);
- if (!db_get_job_record(jcr, jcr->db, &jcr->previous_jr)) {
- Jmsg(jcr, M_FATAL, 0, _("Error getting Job record for previous Job: ERR=%s"),
- db_strerror(jcr->db));
- return false;
- }
-
- if (!create_bootstrap_file(jcr, jobids)) {
- Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n"));
- free_pool_memory(jobids);
- return false;
- }
- free_pool_memory(jobids);
/*
* If the original backup pool has a NextPool, make sure a
{
char ed1[100];
BSOCK *sd;
+ char *p;
+ db_list_ctx jobids;
Dmsg2(100, "rstorage=%p wstorage=%p\n", jcr->rstorage, jcr->wstorage);
Dmsg2(100, "Read store=%s, write store=%s\n",
((STORE *)jcr->rstorage->first())->name(),
((STORE *)jcr->wstorage->first())->name());
- /* ***FIXME*** we really should simply verify that the pools are different */
-#ifdef xxx
- if (((STORE *)jcr->rstorage->first())->name() == ((STORE *)jcr->wstorage->first())->name()) {
- Jmsg(jcr, M_FATAL, 0, _("Read storage \"%s\" same as write storage.\n"),
- ((STORE *)jcr->rstorage->first())->name());
- return false;
- }
-#endif
+
+ jcr->wasVirtualFull = true; /* remember where we came from */
/* Print Job Start message */
Jmsg(jcr, M_INFO, 0, _("Start Virtual Backup JobId %s, Job=%s\n"),
_("This Job is not an Accurate backup so is not equivalent to a Full backup.\n"));
}
+ jcr->jr.JobLevel = L_VIRTUAL_FULL;
+ db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
+ Dmsg1(10, "Accurate jobids=%s\n", jobids.list);
+ if (jobids.count == 0) {
+ Jmsg(jcr, M_FATAL, 0, _("No previous Jobs found.\n"));
+ return false;
+ }
+
+ jcr->jr.JobLevel = L_FULL;
+
+ /*
+ * Now we find the last job that ran and store it's info in
+ * the previous_jr record. We will set our times to the
+ * values from that job so that anything changed after that
+ * time will be picked up on the next backup.
+ */
+ p = strrchr(jobids.list, ','); /* find last jobid */
+ if (p != NULL) {
+ p++;
+ } else {
+ p = jobids.list;
+ }
+ memset(&jcr->previous_jr, 0, sizeof(jcr->previous_jr));
+ jcr->previous_jr.JobId = str_to_int64(p);
+ Dmsg1(10, "Previous JobId=%s\n", p);
+ if (!db_get_job_record(jcr, jcr->db, &jcr->previous_jr)) {
+ Jmsg(jcr, M_FATAL, 0, _("Error getting Job record for previous Job: ERR=%s"),
+ db_strerror(jcr->db));
+ return false;
+ }
+
+ if (!create_bootstrap_file(jcr, jobids.list)) {
+ Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n"));
+ return false;
+ }
+
/*
* Open a message channel connection with the Storage
* daemon. This is to let him know that our client
*
*/
Dmsg0(110, "Open connection with storage daemon\n");
- set_jcr_job_status(jcr, JS_WaitSD);
+ jcr->setJobStatus(JS_WaitSD);
/*
* Start conversation with Storage daemon
*/
/*
* Now start a job with the Storage daemon
*/
- if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage)) {
+ if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage, /*send_bsr*/true)) {
return false;
}
Dmsg0(100, "Storage daemon connection OK\n");
- if (!send_bootstrap_file(jcr, sd) ||
- !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
- return false;
- }
-
/*
* We re-update the job start record so that the start
* time is set after the run before job. This avoids
jcr->start_time = time(NULL);
jcr->jr.StartTime = jcr->start_time;
jcr->jr.JobTDate = jcr->start_time;
- set_jcr_job_status(jcr, JS_Running);
+ jcr->setJobStatus(JS_Running);
/* Update job start record */
if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
return false;
}
- set_jcr_job_status(jcr, JS_Running);
+ jcr->setJobStatus(JS_Running);
/* Pickup Job termination data */
- /* Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/Errors */
+ /* Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/JobErrors */
wait_for_storage_daemon_termination(jcr);
- set_jcr_job_status(jcr, jcr->SDJobStatus);
+ jcr->setJobStatus(jcr->SDJobStatus);
db_write_batch_file_records(jcr); /* used by bulk batch file insert */
if (jcr->JobStatus != JS_Terminated) {
return false;
POOL_MEM query(PM_MESSAGE);
Dmsg2(100, "Enter backup_cleanup %d %c\n", TermCode, TermCode);
- memset(&mr, 0, sizeof(mr));
memset(&cr, 0, sizeof(cr));
- jcr->set_JobLevel(L_FULL); /* we want this to appear as a Full backup */
+ jcr->setJobLevel(L_FULL); /* we want this to appear as a Full backup */
jcr->jr.JobLevel = L_FULL; /* we want this to appear as a Full backup */
jcr->JobFiles = jcr->SDJobFiles;
jcr->JobBytes = jcr->SDJobBytes;
if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) {
Jmsg(jcr, M_WARNING, 0, _("Error getting Job record for Job report: ERR=%s"),
db_strerror(jcr->db));
- set_jcr_job_status(jcr, JS_ErrorTerminated);
+ jcr->setJobStatus(JS_ErrorTerminated);
}
bstrncpy(cr.Name, jcr->client->name(), sizeof(cr.Name));
if (!db_get_media_record(jcr, jcr->db, &mr)) {
Jmsg(jcr, M_WARNING, 0, _("Error getting Media record for Volume \"%s\": ERR=%s"),
mr.VolumeName, db_strerror(jcr->db));
- set_jcr_job_status(jcr, JS_ErrorTerminated);
+ jcr->setJobStatus(JS_ErrorTerminated);
}
update_bootstrap_file(jcr);
switch (jcr->JobStatus) {
case JS_Terminated:
- if (jcr->Errors || jcr->SDErrors) {
+ if (jcr->JobErrors || jcr->SDErrors) {
term_msg = _("Backup OK -- with warnings");
} else {
term_msg = _("Backup OK");
}
jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
- Jmsg(jcr, msg_type, 0, _("Bacula %s %s (%s): %s\n"
+ Jmsg(jcr, msg_type, 0, _("%s %s %s (%s):\n"
" Build OS: %s %s %s\n"
" JobId: %d\n"
" Job: %s\n"
" SD Errors: %d\n"
" SD termination status: %s\n"
" Termination: %s\n\n"),
- my_name, VERSION, LSMDATE, edt,
+ BACULA, my_name, VERSION, LSMDATE,
HOST_OS, DISTNAME, DISTVER,
jcr->jr.JobId,
jcr->jr.Job,
}
-static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids)
+static bool create_bootstrap_file(JCR *jcr, char *jobids)
{
RESTORE_CTX rx;
UAContext *ua;
#define new_get_file_list
#ifdef new_get_file_list
- if (!db_get_file_list(jcr, ua->db, jobids, insert_bootstrap_handler, (void *)rx.bsr)) {
- Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(ua->db));
+ if (!db_open_batch_connexion(jcr, jcr->db)) {
+ Jmsg0(jcr, M_FATAL, 0, "Can't get batch sql connexion");
+ return false;
+ }
+
+ if (!db_get_file_list(jcr, jcr->db_batch, jobids, false /* don't use md5 */,
+ true /* use delta */,
+ insert_bootstrap_handler, (void *)rx.bsr))
+ {
+ Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db_batch));
}
#else
char *p;