*/
bool do_backup_init(JCR *jcr)
{
- POOL_DBR pr;
if (!get_or_create_fileset_record(jcr)) {
return false;
*/
get_level_since_time(jcr, jcr->since, sizeof(jcr->since));
- /*
- * Apply any level related Pool selections
- */
- switch (jcr->JobLevel) {
- case L_FULL:
- if (jcr->full_pool) {
- jcr->pool = jcr->full_pool;
- }
- break;
- case L_INCREMENTAL:
- if (jcr->inc_pool) {
- jcr->pool = jcr->inc_pool;
- }
- break;
- case L_DIFFERENTIAL:
- if (jcr->dif_pool) {
- jcr->pool = jcr->dif_pool;
- }
- break;
- }
- memset(&pr, 0, sizeof(pr));
- bstrncpy(pr.Name, jcr->pool->hdr.name, sizeof(pr.Name));
+ apply_pool_overrides(jcr);
- if (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
- /* Try to create the pool */
- if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
- Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
- db_strerror(jcr->db));
- return false;
- } else {
- Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
- if (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
- Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
- db_strerror(jcr->db));
- return false;
- }
- }
+ jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->pool->hdr.name);
+ if (jcr->jr.PoolId == 0) {
+ return false;
}
- jcr->PoolId = pr.PoolId;
- jcr->jr.PoolId = pr.PoolId;
- /*
- * Fire off any clone jobs (run directives)
- */
- Dmsg2(900, "cloned=%d run_cmds=%p\n", jcr->cloned, jcr->job->run_cmds);
- if (!jcr->cloned && jcr->job->run_cmds) {
- char *runcmd;
- JOB *job = jcr->job;
- POOLMEM *cmd = get_pool_memory(PM_FNAME);
- UAContext *ua = new_ua_context(jcr);
- ua->batch = true;
- foreach_alist(runcmd, job->run_cmds) {
- cmd = edit_job_codes(jcr, cmd, runcmd, "");
- Mmsg(ua->cmd, "run %s cloned=yes", cmd);
- Dmsg1(900, "=============== Clone cmd=%s\n", ua->cmd);
- parse_ua_args(ua); /* parse command */
- int stat = run_cmd(ua, ua->cmd);
- if (stat == 0) {
- Jmsg(jcr, M_ERROR, 0, _("Could not start clone job.\n"));
- } else {
- Jmsg(jcr, M_INFO, 0, _("Clone JobId %d started.\n"), stat);
- }
- }
- free_ua_context(ua);
- free_pool_memory(cmd);
+ /* If pool storage specified, use it instead of job storage */
+ copy_storage(jcr, jcr->pool->storage, _("Pool resource"));
+
+ if (!jcr->storage) {
+ Jmsg(jcr, M_FATAL, 0, _("No Storage specification found in Job or Pool.\n"));
+ return false;
}
+ create_clones(jcr); /* run any clone jobs */
+
return true;
}
if (!start_storage_daemon_job(jcr, NULL, jcr->storage)) {
return false;
}
+
+ /*
+ * Start the job prior to starting the message thread below
+ * to avoid two threads from using the BSOCK structure at
+ * the same time.
+ */
+ if (!bnet_fsend(jcr->store_bsock, "run")) {
+ return false;
+ }
+
/*
* Now start a Storage daemon message thread. Note,
* this thread is used to provide the catalog services
}
Dmsg0(150, "Storage daemon connection OK\n");
- if (!bnet_fsend(jcr->store_bsock, "run")) {
- return false;
- }
-
set_jcr_job_status(jcr, JS_WaitFD);
if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
- return false;
+ goto bail_out;
}
set_jcr_job_status(jcr, JS_Running);
fd = jcr->file_bsock;
if (!send_include_list(jcr)) {
- return false;
+ goto bail_out;
}
if (!send_exclude_list(jcr)) {
- return false;
+ goto bail_out;
}
if (!send_level_command(jcr)) {
- return false;
+ goto bail_out;
}
/*
bnet_fsend(fd, storaddr, store->address, store->SDDport, tls_need);
if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
- return false;
+ goto bail_out;
}
- if (!send_run_before_and_after_commands(jcr)) {
- return false;
+ if (!send_runscripts_commands(jcr)) {
+ goto bail_out;
+ }
+
+ /*
+ * We re-update the job start record so that the start
+ * time is set after the run before job. This avoids
+ * that any files created by the run before job will
+ * be saved twice. They will be backed up in the current
+ * job, but not in the next one unless they are changed.
+ * Without this, they will be backed up in this job and
+ * in the next job run because in that case, their date
+ * is after the start of this run.
+ */
+ jcr->start_time = time(NULL);
+ jcr->jr.StartTime = jcr->start_time;
+ if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
+ Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
}
/* Send backup command */
bnet_fsend(fd, backupcmd);
if (!response(jcr, fd, OKbackup, "backup", DISPLAY_ERROR)) {
- return false;
+ goto bail_out;
}
/* Pickup Job termination data */
return true;
}
return false;
+
+/* Come here only after starting SD thread */
+bail_out:
+ set_jcr_job_status(jcr, JS_ErrorTerminated);
+ Dmsg1(400, "wait for sd. use=%d\n", jcr->use_count());
+ wait_for_storage_daemon_termination(jcr);
+ Dmsg1(400, "after wait for sd. use=%d\n", jcr->use_count());
+ return false;
}
{
char sdt[50], edt[50], schedt[50];
char ec1[30], ec2[30], ec3[30], ec4[30], ec5[30], compress[50];
- char ec6[30], ec7[30], elapsed[50];
+ char ec6[30], ec7[30], ec8[30], elapsed[50];
char term_code[100], fd_term_msg[100], sd_term_msg[100];
const char *term_msg;
int msg_type;
update_bootstrap_file(jcr);
-
msg_type = M_INFO; /* by default INFO message */
switch (jcr->JobStatus) {
case JS_Terminated:
" Backup Level: %s%s\n"
" Client: \"%s\" %s\n"
" FileSet: \"%s\" %s\n"
-" Pool: \"%s\"\n"
-" Storage: \"%s\"\n"
+" Pool: \"%s\" (From %s)\n"
+" Storage: \"%s\" (From %s)\n"
" Scheduled time: %s\n"
" Start time: %s\n"
" End time: %s\n"
" Volume name(s): %s\n"
" Volume Session Id: %d\n"
" Volume Session Time: %d\n"
-" Last Volume Bytes: %s\n"
+" Last Volume Bytes: %s (%sB)\n"
" Non-fatal FD errors: %d\n"
" SD Errors: %d\n"
" FD termination status: %s\n"
level_to_str(jcr->JobLevel), jcr->since,
jcr->client->hdr.name, cr.Uname,
jcr->fileset->hdr.name, jcr->FSCreateTime,
- jcr->pool->hdr.name,
- jcr->store->hdr.name,
+ jcr->pool->hdr.name, jcr->pool_source,
+ jcr->store->hdr.name, jcr->storage_source,
schedt,
sdt,
edt,
jcr->VolSessionId,
jcr->VolSessionTime,
edit_uint64_with_commas(mr.VolBytes, ec7),
+ edit_uint64_with_suffix(mr.VolBytes, ec8),
jcr->Errors,
jcr->SDErrors,
fd_term_msg,