#include "bacula.h"
#include "filed.h"
+#include "ch.h"
#if defined(WIN32_VSS)
#include "vss.h"
static int bootstrap_cmd(JCR *jcr);
static int cancel_cmd(JCR *jcr);
static int setdebug_cmd(JCR *jcr);
-static int setbandwidth_cmd(JCR *jcr);
static int estimate_cmd(JCR *jcr);
static int hello_cmd(JCR *jcr);
static int job_cmd(JCR *jcr);
{"backup", backup_cmd, 0},
{"cancel", cancel_cmd, 0},
{"setdebug=", setdebug_cmd, 0},
- {"setbandwidth=",setbandwidth_cmd, 0},
{"estimate", estimate_cmd, 0},
{"Hello", hello_cmd, 1},
{"fileset", fileset_cmd, 0},
static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n";
static char restorecmdR[] = "restore replace=%c prelinks=%d regexwhere=%s\n";
-static char restoreobjcmd[] = "restoreobject JobId=%u %d,%d,%d,%d,%d,%d\n";
+static char restoreobjcmd[] = "restoreobject JobId=%u %d,%d,%d,%d,%d,%d,%s";
+static char restoreobjcmd1[] = "restoreobject JobId=%u %d,%d,%d,%d,%d,%d\n";
static char endrestoreobjectcmd[] = "restoreobject end\n";
static char verifycmd[] = "verify level=%30s";
static char estimatecmd[] = "estimate listing=%d";
static char runbefore[] = "RunBeforeJob %s";
static char runafter[] = "RunAfterJob %s";
static char runscript[] = "Run OnSuccess=%d OnFailure=%d AbortOnError=%d When=%d Command=%s";
-static char setbandwidth[]= "setbandwidth=%lld Job=%127s";
/* Responses sent to Director */
static char errmsg[] = "2999 Invalid command\n";
static char no_auth[] = "2998 No Authorization\n";
static char invalid_cmd[] = "2997 Invalid command for a Director with Monitor directive enabled.\n";
-static char OKBandwidth[] = "2000 OK Bandwidth\n";
static char OKinc[] = "2000 OK include\n";
static char OKest[] = "2000 OK estimate files=%s bytes=%s\n";
static char OKlevel[] = "2000 OK level\n";
findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
for (j=0; j<incexe->opts_list.size(); j++) {
findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
+ if (fo->plugin) {
+ free(fo->plugin);
+ }
for (k=0; k<fo->regex.size(); k++) {
regfree((regex_t *)fo->regex.get(k));
}
Dmsg0(100, "Done with term_find_files\n");
free_jcr(jcr); /* destroy JCR record */
Dmsg0(100, "Done with free_jcr\n");
- Dsm_check(1);
+ Dsm_check(100);
garbage_collect_memory_pool();
return NULL;
}
dir->fsend(_("2901 Job %s not found.\n"), Job);
} else {
generate_plugin_event(cjcr, bEventCancelCommand, NULL);
- set_jcr_job_status(cjcr, JS_Canceled);
+ cjcr->setJobStatus(JS_Canceled);
if (cjcr->store_bsock) {
cjcr->store_bsock->set_timed_out();
cjcr->store_bsock->set_terminated();
return 1;
}
-/**
- * Set bandwidth limit as requested by the Director
- *
- */
-static int setbandwidth_cmd(JCR *jcr)
-{
- BSOCK *dir = jcr->dir_bsock;
- int64_t bw=0;
- JCR *cjcr;
- char Job[MAX_NAME_LENGTH];
- *Job=0;
-
- if (sscanf(dir->msg, setbandwidth, &bw, Job) != 2 || bw < 0) {
- pm_strcpy(jcr->errmsg, dir->msg);
- dir->fsend(_("2991 Bad setbandwidth command: %s\n"), jcr->errmsg);
- return 0;
- }
-
- if (*Job) {
- if(!(cjcr=get_jcr_by_full_name(Job))) {
- dir->fsend(_("2901 Job %s not found.\n"), Job);
- } else {
- cjcr->max_bandwidth = bw;
- if (cjcr->store_bsock) {
- cjcr->store_bsock->set_bwlimit(bw);
- }
- free_jcr(cjcr);
- }
-
- } else { /* No job requested, apply globally */
- me->max_bandwidth_per_job = bw; /* Overwrite directive */
- }
-
- return dir->fsend(OKBandwidth);
-}
-
/**
* Set debug level as requested by the Director
*
Mmsg(jcr->errmsg, "JobId=%d Job=%s", jcr->JobId, jcr->Job);
new_plugins(jcr); /* instantiate plugins for this jcr */
generate_plugin_event(jcr, bEventJobStart, (void *)jcr->errmsg);
+#ifdef HAVE_WIN32
+ return dir->fsend(OKjob, VERSION, LSMDATE, win_os, DISTNAME, DISTVER);
+#else
return dir->fsend(OKjob, VERSION, LSMDATE, HOST_OS, DISTNAME, DISTVER);
+#endif
+}
+
+extern "C" char *job_code_callback_filed(JCR *jcr, const char* param)
+{
+ switch (param[0]) {
+ case 'D':
+ if (jcr->director) {
+ return jcr->director->hdr.name;
+ }
+ break;
+ }
+ return NULL;
+
}
static int runbefore_cmd(JCR *jcr)
/* Run the command now */
script = new_runscript();
+ script->set_job_code_callback(job_code_callback_filed);
script->set_command(cmd);
script->when = SCRIPT_Before;
ok = script->run(jcr, "ClientRunBeforeJob");
unbash_spaces(msg);
cmd = new_runscript();
+ cmd->set_job_code_callback(job_code_callback_filed);
cmd->set_command(msg);
cmd->on_success = true;
cmd->on_failure = false;
int on_success, on_failure, fail_on_error;
RUNSCRIPT *cmd = new_runscript() ;
+ cmd->set_job_code_callback(job_code_callback_filed);
Dmsg1(100, "runscript_cmd: '%s'\n", dir->msg);
/* Note, we cannot sscanf into bools */
memset(&rop, 0, sizeof(rop));
rop.pkt_size = sizeof(rop);
rop.pkt_end = sizeof(rop);
+
Dmsg1(100, "Enter restoreobject_cmd: %s", dir->msg);
if (strcmp(dir->msg, endrestoreobjectcmd) == 0) {
generate_plugin_event(jcr, bEventRestoreObject, NULL);
return dir->fsend(OKRestoreObject);
}
+ rop.plugin_name = (char *) malloc (dir->msglen);
+ *rop.plugin_name = 0;
+
if (sscanf(dir->msg, restoreobjcmd, &rop.JobId, &rop.object_len,
&rop.object_full_len, &rop.object_index,
- &rop.object_type, &rop.object_compression, &FileIndex) != 7) {
- Dmsg0(5, "Bad restore object command\n");
- pm_strcpy(jcr->errmsg, dir->msg);
- Jmsg1(jcr, M_FATAL, 0, _("Bad RestoreObject command: %s\n"), jcr->errmsg);
- goto bail_out;
+ &rop.object_type, &rop.object_compression, &FileIndex,
+ rop.plugin_name) != 8) {
+
+ /* Old version, no plugin_name */
+ if (sscanf(dir->msg, restoreobjcmd1, &rop.JobId, &rop.object_len,
+ &rop.object_full_len, &rop.object_index,
+ &rop.object_type, &rop.object_compression, &FileIndex) != 7) {
+ Dmsg0(5, "Bad restore object command\n");
+ pm_strcpy(jcr->errmsg, dir->msg);
+ Jmsg1(jcr, M_FATAL, 0, _("Bad RestoreObject command: %s\n"), jcr->errmsg);
+ goto bail_out;
+ }
}
- Dmsg6(100, "Recv object: JobId=%u objlen=%d full_len=%d objinx=%d objtype=%d FI=%d\n",
+ unbash_spaces(rop.plugin_name);
+
+ Dmsg7(100, "Recv object: JobId=%u objlen=%d full_len=%d objinx=%d objtype=%d "
+ "FI=%d plugin_name=%s\n",
rop.JobId, rop.object_len, rop.object_full_len,
- rop.object_index, rop.object_type, FileIndex);
+ rop.object_index, rop.object_type, FileIndex, rop.plugin_name);
/* Read Object name */
if (dir->recv() < 0) {
goto bail_out;
rop.object_len = out_len;
}
Dmsg2(100, "Recv Object: len=%d Object=%s\n", rop.object_len, rop.object);
- /* Special Job meta data */
+ /* we still need to do this to detect a vss restore */
if (strcmp(rop.object_name, "job_metadata.xml") == 0) {
Dmsg0(100, "got job metadata\n");
- free_and_null_pool_memory(jcr->job_metadata);
- jcr->job_metadata = rop.object;
- rop.object = NULL;
- } else {
- /* pass to plugin */
- generate_plugin_event(jcr, bEventRestoreObject, (void *)&rop);
+ //free_and_null_pool_memory(jcr->job_metadata);
+ jcr->job_metadata = rop.object; /* this is like a boolean in the restore case */
+ // rop.object = NULL; /* but not this */
}
+
+ generate_plugin_event(jcr, bEventRestoreObject, (void *)&rop);
if (rop.object_name) {
free(rop.object_name);
if (rop.object) {
free_pool_memory(rop.object);
}
+ if (rop.plugin_name) {
+ free(rop.plugin_name);
+ }
Dmsg1(100, "Send: %s", OKRestoreObject);
return 1;
case '|':
p++; /* skip over | */
fn = get_pool_memory(PM_FNAME);
- fn = edit_job_codes(jcr, fn, p, "");
+ fn = edit_job_codes(jcr, fn, p, "", job_code_callback_filed);
bpipe = open_bpipe(fn, 0, "r");
if (!bpipe) {
berrno be;
// current_opts->writer = bstrdup(item); /* deprecated */
state = state_options;
break;
+ case 'G': /* Plugin command for this Option block */
+ current_opts = start_options(ff);
+ current_opts->plugin = bstrdup(item);
+ state = state_options;
+ break;
default:
Jmsg(jcr, M_FATAL, 0, _("Invalid FileSet command: %s\n"), item);
state = state_error;
}
}
dlistString *node;
- foreach_dlist(node, incexe->name_list) {
+ foreach_dlist(node, &incexe->name_list) {
Dmsg1(400, "F %s\n", node->c_str());
}
foreach_dlist(node, &incexe->plugin_list) {
case 'W':
fo->flags |= FO_ENHANCEDWILD;
break;
- case 'Z': /* gzip compression */
- fo->flags |= FO_GZIP;
- fo->GZIP_level = *++p - '0';
+ case 'Z': /* compression */
+ p++; /* skip Z */
+ if (*p >= '0' && *p <= '9') {
+ fo->flags |= FO_COMPRESS;
+ fo->Compress_algo = COMPRESS_GZIP;
+ fo->Compress_level = *p - '0';
+ }
+ else if (*p == 'o') {
+ fo->flags |= FO_COMPRESS;
+ fo->Compress_algo = COMPRESS_LZO1X;
+ fo->Compress_level = 1; /* not used with LZO */
+ }
break;
case 'K':
fo->flags |= FO_NOATIME;
while (dir->recv() >= 0)
{ }
free_bootstrap(jcr);
- set_jcr_job_status(jcr, JS_ErrorTerminated);
+ jcr->setJobStatus(JS_ErrorTerminated);
return 0;
}
if (strstr(dir->msg, "accurate")) {
jcr->accurate = true;
}
- if (strstr(dir->msg, "incomplete")) {
- jcr->incomplete = true;
+ if (strstr(dir->msg, "rerunning")) {
+ jcr->rerunning = true;
}
if (sscanf(dir->msg, "level = %s ", level) != 1) {
goto bail_out;
}
/* Base backup requested? */
if (strcmp(level, "base") == 0) {
- jcr->set_JobLevel(L_BASE);
+ jcr->setJobLevel(L_BASE);
/* Full backup requested? */
} else if (strcmp(level, "full") == 0) {
- jcr->set_JobLevel(L_FULL);
+ jcr->setJobLevel(L_FULL);
} else if (strstr(level, "differential")) {
- jcr->set_JobLevel(L_DIFFERENTIAL);
+ jcr->setJobLevel(L_DIFFERENTIAL);
free_memory(level);
return 1;
} else if (strstr(level, "incremental")) {
- jcr->set_JobLevel(L_INCREMENTAL);
+ jcr->setJobLevel(L_INCREMENTAL);
free_memory(level);
return 1;
/*
utime_t since_time, adj;
btime_t his_time, bt_start, rt=0, bt_adj=0;
if (jcr->getJobLevel() == L_NONE) {
- jcr->set_JobLevel(L_SINCE); /* if no other job level set, do it now */
+ 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
if (buf) {
free_memory(buf);
}
- generate_plugin_event(jcr, bEventLevel, (void *)jcr->getJobLevel());
+ generate_plugin_event(jcr, bEventLevel, (void*)(intptr_t)jcr->getJobLevel());
return dir->fsend(OKlevel);
bail_out:
sd->set_source_address(me->FDsrc_addr);
- /* TODO: see if we put limit on restore and backup... */
- if (!jcr->max_bandwidth) {
- if (jcr->director->max_bandwidth_per_job) {
- jcr->max_bandwidth = jcr->director->max_bandwidth_per_job;
-
- } else if (me->max_bandwidth_per_job) {
- jcr->max_bandwidth = me->max_bandwidth_per_job;
- }
- }
- sd->set_bwlimit(jcr->max_bandwidth);
-
if (!sd->connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval,
_("Storage daemon"), jcr->stored_addr, NULL, stored_port, 1)) {
sd->destroy();
goto cleanup;
}
- set_jcr_job_status(jcr, JS_Blocked);
- jcr->set_JobType(JT_BACKUP);
+ jcr->setJobStatus(JS_Blocked);
+ jcr->setJobType(JT_BACKUP);
Dmsg1(100, "begin backup ff=%p\n", jcr->ff);
if (sd == NULL) {
/* tell vss which drives to snapshot */
char szWinDriveLetters[27];
*szWinDriveLetters=0;
+ /* Plugin driver can return drive letters */
generate_plugin_event(jcr, bEventVssPrepareSnapshot, szWinDriveLetters);
if (get_win32_driveletters(jcr->ff, szWinDriveLetters)) {
Jmsg(jcr, M_INFO, 0, _("Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n"), g_pVSSClient->GetDriverName(), szWinDriveLetters);
if (!g_pVSSClient->CreateSnapshots(szWinDriveLetters)) {
- berrno be;
- Jmsg(jcr, M_FATAL, 0, _("Generate VSS snapshots failed. ERR=%s\n"), be.bstrerror());
+ Jmsg(jcr, M_FATAL, 0, _("CreateSGenerate VSS snapshots failed.\n"));
} else {
/* tell user if snapshot creation of a specific drive failed */
int i;
Jmsg(jcr, M_FATAL, 0, _("No drive letters found for generating VSS snapshots.\n"));
}
} else {
- berrno be;
- Jmsg(jcr, M_FATAL, 0, _("VSS was not initialized properly. ERR=%s\n"), be.bstrerror());
+ Jmsg(jcr, M_FATAL, 0, _("VSS was not initialized properly.\n"));
}
run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS");
}
*/
Dmsg1(110, "begin blast ff=%p\n", (FF_PKT *)jcr->ff);
if (!blast_data_to_storage_daemon(jcr, NULL)) {
- set_jcr_job_status(jcr, JS_ErrorTerminated);
+ jcr->setJobStatus(JS_ErrorTerminated);
bnet_suppress_error_messages(sd, 1);
Dmsg0(110, "Error in blast_data.\n");
} else {
- set_jcr_job_status(jcr, JS_Terminated);
+ jcr->setJobStatus(JS_Terminated);
/* Note, the above set status will not override an error */
if (!(jcr->JobStatus == JS_Terminated || jcr->JobStatus == JS_Warnings)) {
bnet_suppress_error_messages(sd, 1);
* Expect to get response to append_data from Storage daemon
*/
if (!response(jcr, sd, OK_append, "Append Data")) {
- set_jcr_job_status(jcr, JS_ErrorTerminated);
+ jcr->setJobStatus(JS_ErrorTerminated);
goto cleanup;
}
sd->fsend(append_end, jcr->Ticket);
/* Get end OK */
if (!response(jcr, sd, OK_end, "Append End")) {
- set_jcr_job_status(jcr, JS_ErrorTerminated);
+ jcr->setJobStatus(JS_ErrorTerminated);
goto cleanup;
}
BSOCK *sd = jcr->store_bsock;
char level[100];
- jcr->set_JobType(JT_VERIFY);
+ jcr->setJobType(JT_VERIFY);
if (sscanf(dir->msg, verifycmd, level) != 1) {
dir->fsend(_("2994 Bad verify command: %s\n"), dir->msg);
return 0;
}
if (strcasecmp(level, "init") == 0) {
- jcr->set_JobLevel(L_VERIFY_INIT);
+ jcr->setJobLevel(L_VERIFY_INIT);
} else if (strcasecmp(level, "catalog") == 0){
- jcr->set_JobLevel(L_VERIFY_CATALOG);
+ jcr->setJobLevel(L_VERIFY_CATALOG);
} else if (strcasecmp(level, "volume") == 0){
- jcr->set_JobLevel(L_VERIFY_VOLUME_TO_CATALOG);
+ jcr->setJobLevel(L_VERIFY_VOLUME_TO_CATALOG);
} else if (strcasecmp(level, "data") == 0){
- jcr->set_JobLevel(L_VERIFY_DATA);
+ jcr->setJobLevel(L_VERIFY_DATA);
} else if (strcasecmp(level, "disk_to_catalog") == 0) {
- jcr->set_JobLevel(L_VERIFY_DISK_TO_CATALOG);
+ jcr->setJobLevel(L_VERIFY_DISK_TO_CATALOG);
} else {
dir->fsend(_("2994 Bad verify level: %s\n"), dir->msg);
return 0;
dir->fsend(OKverify);
generate_daemon_event(jcr, "JobStart");
- generate_plugin_event(jcr, bEventLevel, (void *)jcr->getJobLevel());
+ generate_plugin_event(jcr, bEventLevel,(void *)(intptr_t)jcr->getJobLevel());
generate_plugin_event(jcr, bEventStartVerifyJob);
Dmsg1(110, "filed>dird: %s", dir->msg);
return 0; /* return and terminate command loop */
}
+#if 0
#ifdef WIN32_VSS
static bool vss_restore_init_callback(JCR *jcr, int init_type)
{
}
}
#endif
+#endif
/**
* Do a Restore for Director
* data to restore
*/
enable_vss = jcr->job_metadata != NULL;
+ jcr->job_metadata = NULL;
Dmsg2(50, "g_pVSSClient = %p, enable_vss = %d\n", g_pVSSClient, enable_vss);
// capture state here, if client is backed up by multiple directors
Dmsg2(150, "Got replace %c, where=%s\n", replace, args);
unbash_spaces(args);
+ /* Keep track of newly created directories to apply them correct attributes */
+ if (replace == REPLACE_NEVER) {
+ jcr->keep_path_list = true;
+ }
+
if (use_regexwhere) {
jcr->where_bregexp = get_bregexps(args);
if (!jcr->where_bregexp) {
dir->fsend(OKrestore);
Dmsg1(110, "filed>dird: %s", dir->msg);
- jcr->set_JobType(JT_RESTORE);
+ jcr->setJobType(JT_RESTORE);
- set_jcr_job_status(jcr, JS_Blocked);
+ jcr->setJobStatus(JS_Blocked);
if (!open_sd_read_session(jcr)) {
- set_jcr_job_status(jcr, JS_ErrorTerminated);
+ jcr->setJobStatus(JS_ErrorTerminated);
goto bail_out;
}
- set_jcr_job_status(jcr, JS_Running);
+ jcr->setJobStatus(JS_Running);
/**
* Do restore of files and data
#if defined(WIN32_VSS)
/* START VSS ON WIN32 */
if (jcr->VSS) {
- if (g_pVSSClient->InitializeForRestore(jcr, vss_restore_init_callback,
- (WCHAR *)jcr->job_metadata)) {
-
- /* inform user about writer states */
- int i;
- for (i=0; i < (int)g_pVSSClient->GetWriterCount(); i++) {
- if (g_pVSSClient->GetWriterState(i) < 1) {
- Jmsg(jcr, M_INFO, 0, _("VSS Writer (PreRestore): %s\n"), g_pVSSClient->GetWriterInfo(i));
- //jcr->JobErrors++;
- }
- }
- } else {
-/*
- int fd = open("C:\\eric.xml", O_CREAT | O_WRONLY | O_TRUNC, 0777);
- write(fd, (WCHAR *)jcr->job_metadata, wcslen((WCHAR *)jcr->job_metadata) * sizeof(WCHAR));
- close(fd);
-*/
+ if (!g_pVSSClient->InitializeForRestore(jcr)) {
berrno be;
Jmsg(jcr, M_WARNING, 0, _("VSS was not initialized properly. VSS support is disabled. ERR=%s\n"), be.bstrerror());
}
- free_and_null_pool_memory(jcr->job_metadata);
+ //free_and_null_pool_memory(jcr->job_metadata);
run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS");
}
#endif
do_restore(jcr);
stop_dir_heartbeat(jcr);
- set_jcr_job_status(jcr, JS_Terminated);
+ jcr->setJobStatus(JS_Terminated);
if (jcr->JobStatus != JS_Terminated) {
bnet_suppress_error_messages(sd, 1);
}
/* tell vss to close the restore session */
Dmsg0(100, "About to call CloseRestore\n");
if (jcr->VSS) {
+#if 0
generate_plugin_event(jcr, bEventVssBeforeCloseRestore);
+#endif
Dmsg0(100, "Really about to call CloseRestore\n");
if (g_pVSSClient->CloseRestore()) {
Dmsg0(100, "CloseRestore success\n");
+#if 0
/* inform user about writer states */
for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) {
int msg_type = M_INFO;
}
Jmsg(jcr, msg_type, 0, _("VSS Writer (RestoreComplete): %s\n"), g_pVSSClient->GetWriterInfo(i));
}
+#endif
}
else
Dmsg1(100, "CloseRestore fail - %08x\n", errno);
bfree_and_null(jcr->where);
if (jcr->JobErrors) {
- set_jcr_job_status(jcr, JS_ErrorTerminated);
+ jcr->setJobStatus(JS_ErrorTerminated);
}
Dmsg0(100, "Done in job.c\n");
}
free_runscripts(jcr->RunScripts);
delete jcr->RunScripts;
+ free_path_list(jcr);
if (jcr->JobId != 0)
write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
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);
+ jcr->setJobStatus(JS_ErrorTerminated);
goto bail_out;
}
sd->msglen = pm_strcpy(sd->msg, bootstrap);
sd->signal(BNET_EOD);
fclose(bs);
if (!response(jcr, sd, OKSDbootstrap, "Bootstrap")) {
- set_jcr_job_status(jcr, JS_ErrorTerminated);
+ jcr->setJobStatus(JS_ErrorTerminated);
goto bail_out;
}
stat = 1;