+/*
+ * Setup a job for a resume command
+ */
+static bool setup_resume_job(JCR *jcr, JOB_DBR *jr)
+{
+ int errstat;
+ jcr->lock();
+ Dsm_check(100);
+ init_msg(jcr, jcr->messages);
+
+ /* Initialize termination condition variable */
+ if ((errstat = pthread_cond_init(&jcr->term_wait, NULL)) != 0) {
+ berrno be;
+ Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
+ jcr->unlock();
+ goto bail_out;
+ }
+ jcr->term_wait_inited = true;
+
+ jcr->setJobStatus(JS_Created);
+ jcr->unlock();
+
+ /*
+ * Open database
+ */
+ Dmsg0(100, "Open database\n");
+ jcr->db = db_init_database(jcr, jcr->catalog->db_driver, jcr->catalog->db_name,
+ jcr->catalog->db_user, jcr->catalog->db_password,
+ jcr->catalog->db_address, jcr->catalog->db_port,
+ jcr->catalog->db_socket, jcr->catalog->db_ssl_key,
+ jcr->catalog->db_ssl_cert, jcr->catalog->db_ssl_ca,
+ jcr->catalog->db_ssl_capath, jcr->catalog->db_ssl_cipher,
+ jcr->catalog->mult_db_connections,
+ jcr->catalog->disable_batch_insert);
+ if (!jcr->db || !db_open_database(jcr, jcr->db)) {
+ Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"),
+ jcr->catalog->db_name);
+ if (jcr->db) {
+ Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
+ db_close_database(jcr, jcr->db);
+ jcr->db = NULL;
+ }
+ goto bail_out;
+ }
+ Dmsg0(100, "DB opened\n");
+ if (!jcr->fname) {
+ jcr->fname = get_pool_memory(PM_FNAME);
+ }
+ if (!jcr->pool_source) {
+ jcr->pool_source = get_pool_memory(PM_MESSAGE);
+ pm_strcpy(jcr->pool_source, _("unknown source"));
+ }
+ if (!jcr->next_pool_source) {
+ jcr->next_pool_source = get_pool_memory(PM_MESSAGE);
+ pm_strcpy(jcr->next_pool_source, _("unknown source"));
+ }
+
+
+ /*
+ * Setup Job record. Make sure original job is Incomplete.
+ */
+ memcpy(&jcr->jr, jr, sizeof(JOB_DBR));
+ jcr->sched_time = jcr->jr.SchedTime;
+ jcr->start_time = jcr->jr.StartTime;
+ jcr->jr.EndTime = 0; /* perhaps rescheduled, clear it */
+ jcr->setJobType(jcr->jr.JobType);
+ jcr->setJobLevel(jcr->jr.JobLevel);
+ jcr->JobId = jcr->jr.JobId;
+ if (!get_or_create_client_record(jcr)) {
+ Dmsg0(100, "Could not create client record.\n");
+ goto bail_out;
+ }
+
+ Dmsg6(100, "Got job record JobId=%d Job=%s Name=%s Type=%c Level=%c Status=%c\n",
+ jcr->jr.JobId, jcr->jr.Job, jcr->jr.Name, jcr->jr.JobType, jcr->jr.JobLevel,
+ jcr->jr.JobStatus);
+ if (jcr->jr.JobStatus != JS_Incomplete) {
+ /* ***FIXME*** add error message */
+ Dmsg1(100, "Job is not an Incomplete: status=%c\n", jcr->jr.JobStatus);
+ goto bail_out;
+ }
+ bstrncpy(jcr->Job, jcr->jr.Job, sizeof(jcr->Job));
+ jcr->setJobType(jcr->jr.JobType);
+ jcr->setJobLevel(jcr->jr.JobLevel);
+
+ generate_daemon_event(jcr, "JobStart");
+ new_plugins(jcr); /* instantiate plugins for this jcr */
+ generate_plugin_event(jcr, bDirEventJobStart);
+
+ if (job_canceled(jcr)) {
+ Dmsg0(100, "Oops. Job canceled\n");
+ goto bail_out;
+ }
+
+ /* Re-run the old job */
+ jcr->rerunning = true;
+
+ /*
+ * Now, do pre-run stuff, like setting job level (Inc/diff, ...)
+ * this allows us to setup a proper job start record for restarting
+ * in case of later errors.
+ */
+ switch (jcr->getJobType()) {
+ case JT_BACKUP:
+ if (!do_backup_init(jcr)) {
+ backup_cleanup(jcr, JS_ErrorTerminated);
+ goto bail_out;
+ }
+ break;
+ default:
+ Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->getJobType());
+ jcr->setJobStatus(JS_ErrorTerminated);
+ goto bail_out;
+ }
+
+ generate_plugin_event(jcr, bDirEventJobInit);
+ Dsm_check(100);
+ return true;
+
+bail_out:
+ return false;
+}
+
+JobId_t resume_job(JCR *jcr, JOB_DBR *jr)
+{
+ int stat;
+ if (setup_resume_job(jcr, jr)) {
+ Dmsg0(200, "Add jrc to work queue\n");
+ /* Queue the job to be run */
+ if ((stat = jobq_add(&job_queue, jcr)) != 0) {
+ berrno be;
+ Jmsg(jcr, M_FATAL, 0, _("Could not add job queue: ERR=%s\n"), be.bstrerror(stat));
+ return 0;
+ }
+ return jcr->JobId;
+ }
+ return 0;
+}
+
+
+