+
+/*
+ * Copy the storage definitions from an alist to the JCR
+ */
+void copy_rwstorage(JCR *jcr, alist *storage, const char *where)
+{
+ switch(jcr->JobType) {
+ case JT_RESTORE:
+ case JT_VERIFY:
+ case JT_MIGRATE:
+ copy_rstorage(jcr, storage, where);
+ break;
+ default:
+ copy_wstorage(jcr, storage, where);
+ break;
+ }
+}
+
+
+/* Set storage override. Releases any previous storage definition */
+void set_rwstorage(JCR *jcr, USTORE *store)
+{
+ if (!store) {
+ Jmsg(jcr, M_FATAL, 0, _("No storage specified.\n"));
+ return;
+ }
+ switch(jcr->JobType) {
+ case JT_RESTORE:
+ case JT_VERIFY:
+ case JT_MIGRATE:
+ set_rstorage(jcr, store);
+ break;
+ default:
+ set_wstorage(jcr, store);
+ break;
+ }
+}
+
+void free_rwstorage(JCR *jcr)
+{
+ free_rstorage(jcr);
+ free_wstorage(jcr);
+}
+
+/*
+ * Copy the storage definitions from an alist to the JCR
+ */
+void copy_rstorage(JCR *jcr, alist *storage, const char *where)
+{
+ if (storage) {
+ STORE *st;
+ if (jcr->rstorage) {
+ delete jcr->rstorage;
+ }
+ jcr->rstorage = New(alist(10, not_owned_by_alist));
+ foreach_alist(st, storage) {
+ jcr->rstorage->append(st);
+ }
+ if (!jcr->rstore_source) {
+ jcr->rstore_source = get_pool_memory(PM_MESSAGE);
+ }
+ pm_strcpy(jcr->rstore_source, where);
+ if (jcr->rstorage) {
+ jcr->rstore = (STORE *)jcr->rstorage->first();
+ }
+ }
+}
+
+
+/* Set storage override. Remove all previous storage */
+void set_rstorage(JCR *jcr, USTORE *store)
+{
+ STORE *storage;
+
+ if (!store->store) {
+ return;
+ }
+ if (jcr->rstorage) {
+ free_rstorage(jcr);
+ }
+ if (!jcr->rstorage) {
+ jcr->rstorage = New(alist(10, not_owned_by_alist));
+ }
+ jcr->rstore = store->store;
+ if (!jcr->rstore_source) {
+ jcr->rstore_source = get_pool_memory(PM_MESSAGE);
+ }
+ pm_strcpy(jcr->rstore_source, store->store_source);
+ foreach_alist(storage, jcr->rstorage) {
+ if (store->store == storage) {
+ return;
+ }
+ }
+ /* Store not in list, so add it */
+ jcr->rstorage->prepend(store->store);
+}
+
+void free_rstorage(JCR *jcr)
+{
+ if (jcr->rstorage) {
+ delete jcr->rstorage;
+ jcr->rstorage = NULL;
+ }
+ jcr->rstore = NULL;
+}
+
+/*
+ * Copy the storage definitions from an alist to the JCR
+ */
+void copy_wstorage(JCR *jcr, alist *storage, const char *where)
+{
+ if (storage) {
+ STORE *st;
+ if (jcr->wstorage) {
+ delete jcr->wstorage;
+ }
+ jcr->wstorage = New(alist(10, not_owned_by_alist));
+ foreach_alist(st, storage) {
+ Dmsg1(100, "wstorage=%s\n", st->name());
+ jcr->wstorage->append(st);
+ }
+ if (!jcr->wstore_source) {
+ jcr->wstore_source = get_pool_memory(PM_MESSAGE);
+ }
+ pm_strcpy(jcr->wstore_source, where);
+ if (jcr->wstorage) {
+ jcr->wstore = (STORE *)jcr->wstorage->first();
+ Dmsg2(100, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
+ }
+ }
+}
+
+
+/* Set storage override. Remove all previous storage */
+void set_wstorage(JCR *jcr, USTORE *store)
+{
+ STORE *storage;
+
+ if (!store->store) {
+ return;
+ }
+ if (jcr->wstorage) {
+ free_wstorage(jcr);
+ }
+ if (!jcr->wstorage) {
+ jcr->wstorage = New(alist(10, not_owned_by_alist));
+ }
+ jcr->wstore = store->store;
+ if (!jcr->wstore_source) {
+ jcr->wstore_source = get_pool_memory(PM_MESSAGE);
+ }
+ pm_strcpy(jcr->wstore_source, store->store_source);
+ Dmsg2(50, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
+ foreach_alist(storage, jcr->wstorage) {
+ if (store->store == storage) {
+ return;
+ }
+ }
+ /* Store not in list, so add it */
+ jcr->wstorage->prepend(store->store);
+}
+
+void free_wstorage(JCR *jcr)
+{
+ if (jcr->wstorage) {
+ delete jcr->wstorage;
+ jcr->wstorage = NULL;
+ }
+ jcr->wstore = NULL;
+}
+
+void create_clones(JCR *jcr)
+{
+ /*
+ * 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);
+ }
+}
+
+bool create_restore_bootstrap_file(JCR *jcr)
+{
+ RESTORE_CTX rx;
+ UAContext *ua;
+ memset(&rx, 0, sizeof(rx));
+ rx.bsr = new_bsr();
+ rx.JobIds = (char *)"";
+ rx.bsr->JobId = jcr->previous_jr.JobId;
+ ua = new_ua_context(jcr);
+ complete_bsr(ua, rx.bsr);
+ rx.bsr->fi = new_findex();
+ rx.bsr->fi->findex = 1;
+ rx.bsr->fi->findex2 = jcr->previous_jr.JobFiles;
+ jcr->ExpectedFiles = write_bsr_file(ua, rx);
+ if (jcr->ExpectedFiles == 0) {
+ free_ua_context(ua);
+ free_bsr(rx.bsr);
+ return false;
+ }
+ free_ua_context(ua);
+ free_bsr(rx.bsr);
+ jcr->needs_sd = true;
+ return true;
+}