/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2010 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.
* Utility functions for sending info to File Daemon.
* These functions are used by both backup and verify.
*
- * Version $Id$
*/
#include "bacula.h"
/*
* Now send JobId and authorization key
*/
+ if (jcr->sd_auth_key == NULL) {
+ jcr->sd_auth_key = bstrdup("dummy");
+ }
fd->fsend(jobcmd, edit_int64(jcr->JobId, ed1), jcr->Job, jcr->VolSessionId,
- jcr->VolSessionTime, jcr->sd_auth_key);
- if (strcmp(jcr->sd_auth_key, "dummy") != 0) {
+ jcr->VolSessionTime, jcr->sd_auth_key);
+ if (!jcr->keep_sd_auth_key && strcmp(jcr->sd_auth_key, "dummy")) {
memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
}
Dmsg1(100, ">filed: %s", fd->msg);
bool do_full = false;
bool do_diff = false;
utime_t now;
- utime_t last_full_time;
+ utime_t last_full_time = 0;
utime_t last_diff_time;
since[0] = 0;
* Lookup the last FULL backup job to get the time/date for a
* differential or incremental save.
*/
- switch (jcr->get_JobLevel()) {
+ switch (jcr->getJobLevel()) {
case L_DIFFERENTIAL:
case L_INCREMENTAL:
POOLMEM *stime = get_pool_memory(PM_MESSAGE);
/* Look up start time of last Full job */
now = (utime_t)time(NULL);
jcr->jr.JobId = 0; /* flag to return since time */
- have_full = db_find_job_start_time(jcr, jcr->db, &jcr->jr, &jcr->stime);
+ /*
+ * 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)) {
+ do_full = true;
+ }
+ have_full = db_find_last_job_start_time(jcr, jcr->db, &jcr->jr, &stime, L_FULL);
if (have_full) {
- last_full_time = str_to_utime(jcr->stime);
+ last_full_time = str_to_utime(stime);
} else {
do_full = true; /* No full, upgrade to one */
}
+ Dmsg4(50, "have_full=%d do_full=%d now=%lld full_time=%lld\n", have_full,
+ do_full, now, last_full_time);
/* Make sure the last diff is recent enough */
- if (have_full && jcr->get_JobLevel() == L_INCREMENTAL && jcr->job->MaxDiffInterval > 0) {
+ 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)) {
last_diff_time = str_to_utime(stime);
if (last_diff_time < last_full_time) {
last_diff_time = last_full_time;
}
+ Dmsg2(50, "last_diff_time=%lld last_full_time=%lld\n", last_diff_time,
+ last_full_time);
} else {
/* No last differential, so use last full time */
last_diff_time = last_full_time;
+ Dmsg1(50, "No last_diff_time setting to full_time=%lld\n", last_full_time);
}
do_diff = ((now - last_diff_time) >= jcr->job->MaxDiffInterval);
+ Dmsg2(50, "do_diff=%d diffInter=%lld\n", do_diff, jcr->job->MaxDiffInterval);
}
/* Note, do_full takes precedence over do_diff */
if (have_full && jcr->job->MaxFullInterval > 0) {
Jmsg(jcr, M_INFO, 0, "%s", db_strerror(jcr->db));
Jmsg(jcr, M_INFO, 0, _("No prior or suitable Full backup found in catalog. Doing FULL backup.\n"));
bsnprintf(since, since_len, _(" (upgraded from %s)"),
- level_to_str(jcr->get_JobLevel()));
+ level_to_str(jcr->getJobLevel()));
jcr->set_JobLevel(jcr->jr.JobLevel = L_FULL);
} else if (do_diff) {
/* No recent diff job found, so upgrade this one to Diff */
Jmsg(jcr, M_INFO, 0, _("No prior or suitable Differential backup found in catalog. Doing Differential backup.\n"));
bsnprintf(since, since_len, _(" (upgraded from %s)"),
- level_to_str(jcr->get_JobLevel()));
+ level_to_str(jcr->getJobLevel()));
jcr->set_JobLevel(jcr->jr.JobLevel = L_DIFFERENTIAL);
} else {
if (jcr->job->rerun_failed_levels) {
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)"),
- level_to_str(jcr->get_JobLevel()));
+ level_to_str(jcr->getJobLevel()));
jcr->set_JobLevel(jcr->jr.JobLevel = JobLevel);
jcr->jr.JobId = jcr->JobId;
break;
jcr->jr.JobId = jcr->JobId;
break;
}
- Dmsg2(100, "Level=%c last start time=%s\n", jcr->get_JobLevel(), jcr->stime);
+ Dmsg2(100, "Level=%c last start time=%s\n", jcr->getJobLevel(), jcr->stime);
}
static void send_since_time(JCR *jcr)
bool send_level_command(JCR *jcr)
{
BSOCK *fd = jcr->file_bsock;
- const char *accurate = jcr->job->accurate?"accurate_":"";
+ const char *accurate = jcr->accurate?"accurate_":"";
const char *not_accurate = "";
/*
* Send Level command to File daemon
*/
- switch (jcr->get_JobLevel()) {
+ switch (jcr->getJobLevel()) {
case L_BASE:
fd->fsend(levelcmd, not_accurate, "base", " ", 0);
break;
case L_SINCE:
default:
Jmsg2(jcr, M_FATAL, 0, _("Unimplemented backup level %d %c\n"),
- jcr->get_JobLevel(), jcr->get_JobLevel());
+ jcr->getJobLevel(), jcr->getJobLevel());
return 0;
}
Dmsg1(120, ">filed: %s", fd->msg);
{
FILESET *fileset = jcr->fileset;
BSOCK *fd = jcr->file_bsock;
+ STORE *store = jcr->wstore;
int num;
bool include = true;
ie = fileset->exclude_items[i];
fd->fsend("E\n");
}
+ if (ie->ignoredir) {
+ bnet_fsend(fd, "Z %s\n", ie->ignoredir);
+ }
for (j=0; j<ie->num_opts; j++) {
FOPTS *fo = ie->opts_list[j];
- fd->fsend("O %s\n", fo->opts);
bool enhanced_wild = false;
for (k=0; fo->opts[k]!='\0'; k++) {
}
}
+ /* Strip out compression option Zn if disallowed for this Storage */
+ if (store && !store->AllowCompress) {
+ char newopts[MAX_FOPTS];
+ int j = 0;
+ for (k=0; fo->opts[k]!='\0'; k++) {
+ /* Z compress option is followed by the single-digit compress level */
+ if (fo->opts[k]=='Z') {
+ k++; /* skip option and level */
+ } else {
+ newopts[j] = fo->opts[k];
+ j++;
+ }
+ }
+ newopts[j] = '\0';
+
+ Jmsg(jcr, M_INFO, 0,
+ _("FD compression disabled for this Job because AllowCompress=No in Storage resource.\n") );
+
+ /* Send the new trimmed option set without overwriting fo->opts */
+ fd->fsend("O %s\n", newopts);
+ } else {
+ /* Send the original options */
+ fd->fsend("O %s\n", fo->opts);
+ }
+
for (k=0; k<fo->regex.size(); k++) {
fd->fsend("R %s\n", fo->regex.get(k));
}
if (fo->plugin) {
fd->fsend("G %s\n", fo->plugin);
}
- if (fo->ignoredir) {
- bnet_fsend(fd, "Z %s\n", fo->ignoredir);
- }
if (fo->reader) {
fd->fsend("D %s\n", fo->reader);
}
return true;
}
-
-/*
- * Send bootstrap file if any to the socket given (FD or SD).
- * This is used for restore, verify VolumeToCatalog, and
- * for migration.
- */
-bool send_bootstrap_file(JCR *jcr, BSOCK *sock)
-{
- FILE *bs;
- char buf[1000];
- const char *bootstrap = "bootstrap\n";
-
- Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap);
- if (!jcr->RestoreBootstrap) {
- return true;
- }
- bs = fopen(jcr->RestoreBootstrap, "rb");
- if (!bs) {
- berrno be;
- Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"),
- jcr->RestoreBootstrap, be.bstrerror());
- set_jcr_job_status(jcr, JS_ErrorTerminated);
- return false;
- }
- sock->fsend(bootstrap);
- while (fgets(buf, sizeof(buf), bs)) {
- sock->fsend("%s", buf);
- }
- sock->signal(BNET_EOD);
- fclose(bs);
- if (jcr->unlink_bsr) {
- unlink(jcr->RestoreBootstrap);
- jcr->unlink_bsr = false;
- }
- return true;
-}
-
/* TODO: drop this with runscript.old_proto in bacula 1.42 */
static char runbefore[] = "RunBeforeJob %s\n";
static char runafter[] = "RunAfterJob %s\n";
Dmsg0(120, "bdird: sending runscripts to fd\n");
foreach_alist(cmd, jcr->job->RunScripts) {
- if (cmd->can_run_at_level(jcr->get_JobLevel()) && cmd->target) {
+ if (cmd->can_run_at_level(jcr->getJobLevel()) && cmd->target) {
ehost = edit_job_codes(jcr, ehost, cmd->target, "");
Dmsg2(200, "bdird: runscript %s -> %s\n", cmd->target, ehost);