3 * Bacula Director Job processing routines
5 * Kern Sibbald, October MM
10 Bacula® - The Network Backup Solution
12 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
14 The main author of Bacula is Kern Sibbald, with contributions from
15 many others, a complete list can be found in the file AUTHORS.
16 This program is Free Software; you can redistribute it and/or
17 modify it under the terms of version two of the GNU General Public
18 License as published by the Free Software Foundation plus additions
19 that are listed in the file LICENSE.
21 This program is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31 Bacula® is a registered trademark of John Walker.
32 The licensor of Bacula is the Free Software Foundation Europe
33 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
34 Switzerland, email:ftf@fsfeurope.org.
40 /* Forward referenced subroutines */
41 static void *job_thread(void *arg);
42 static void job_monitor_watchdog(watchdog_t *self);
43 static void job_monitor_destructor(watchdog_t *self);
44 static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr);
45 static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr);
47 /* Imported subroutines */
48 extern void term_scheduler();
49 extern void term_ua_server();
51 /* Imported variables */
55 void init_job_server(int max_workers)
60 if ((stat = jobq_init(&job_queue, max_workers, job_thread)) != 0) {
62 Emsg1(M_ABORT, 0, _("Could not init job queue: ERR=%s\n"), be.strerror(stat));
65 wd->callback = job_monitor_watchdog;
66 wd->destructor = job_monitor_destructor;
69 wd->data = new_control_jcr("*JobMonitor*", JT_SYSTEM);
70 register_watchdog(wd);
73 void term_job_server()
75 jobq_destroy(&job_queue); /* ignore any errors */
79 * Run a job -- typically called by the scheduler, but may also
80 * be called by the UA (Console program).
82 * Returns: 0 on failure
86 JobId_t run_job(JCR *jcr)
90 Dmsg0(200, "Add jrc to work queue\n");
91 /* Queue the job to be run */
92 if ((stat = jobq_add(&job_queue, jcr)) != 0) {
94 Jmsg(jcr, M_FATAL, 0, _("Could not add job queue: ERR=%s\n"), be.strerror(stat));
102 bool setup_job(JCR *jcr)
107 sm_check(__FILE__, __LINE__, true);
108 init_msg(jcr, jcr->messages);
110 /* Initialize termination condition variable */
111 if ((errstat = pthread_cond_init(&jcr->term_wait, NULL)) != 0) {
113 Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.strerror(errstat));
116 jcr->term_wait_inited = true;
118 create_unique_job_name(jcr, jcr->job->name());
119 set_jcr_job_status(jcr, JS_Created);
125 Dmsg0(50, "Open database\n");
126 jcr->db=db_init_database(jcr, jcr->catalog->db_name, jcr->catalog->db_user,
127 jcr->catalog->db_password, jcr->catalog->db_address,
128 jcr->catalog->db_port, jcr->catalog->db_socket,
129 jcr->catalog->mult_db_connections);
130 if (!jcr->db || !db_open_database(jcr, jcr->db)) {
131 Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"),
132 jcr->catalog->db_name);
134 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
138 Dmsg0(50, "DB opened\n");
141 jcr->fname = get_pool_memory(PM_FNAME);
143 if (!jcr->pool_source) {
144 jcr->pool_source = get_pool_memory(PM_MESSAGE);
145 pm_strcpy(jcr->pool_source, _("unknown source"));
147 Dmsg2(500, "pool=%s (From %s)\n", jcr->pool->name(), jcr->pool_source);
148 if (jcr->JobType == JT_MIGRATE) {
149 if (!jcr->rpool_source) {
150 jcr->rpool_source = get_pool_memory(PM_MESSAGE);
151 pm_strcpy(jcr->rpool_source, _("unknown source"));
158 init_jcr_job_record(jcr);
159 if (!db_create_job_record(jcr, jcr->db, &jcr->jr)) {
160 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
163 jcr->JobId = jcr->jr.JobId;
164 Dmsg4(100, "Created job record JobId=%d Name=%s Type=%c Level=%c\n",
165 jcr->JobId, jcr->Job, jcr->jr.JobType, jcr->jr.JobLevel);
167 if (!get_or_create_client_record(jcr)) {
171 generate_daemon_event(jcr, "JobStart");
173 if (job_canceled(jcr)) {
179 * Now, do pre-run stuff, like setting job level (Inc/diff, ...)
180 * this allows us to setup a proper job start record for restarting
181 * in case of later errors.
183 switch (jcr->JobType) {
185 if (!do_backup_init(jcr)) {
186 backup_cleanup(jcr, JS_ErrorTerminated);
190 if (!do_verify_init(jcr)) {
191 verify_cleanup(jcr, JS_ErrorTerminated);
195 if (!do_restore_init(jcr)) {
196 restore_cleanup(jcr, JS_ErrorTerminated);
200 if (!do_admin_init(jcr)) {
201 admin_cleanup(jcr, JS_ErrorTerminated);
205 if (!do_migration_init(jcr)) {
206 migration_cleanup(jcr, JS_ErrorTerminated);
210 Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->JobType);
211 set_jcr_job_status(jcr, JS_ErrorTerminated);
215 generate_job_event(jcr, "JobInit");
222 void update_job_end(JCR *jcr, int TermCode)
224 dequeue_messages(jcr); /* display any queued messages */
225 set_jcr_job_status(jcr, TermCode);
226 run_scripts(jcr, jcr->job->RunScripts, "AfterJob");
227 update_job_end_record(jcr);
231 * This is the engine called by jobq.c:jobq_add() when we were pulled
232 * from the work queue.
233 * At this point, we are running in our own thread and all
234 * necessary resources are allocated -- see jobq.c
236 static void *job_thread(void *arg)
238 JCR *jcr = (JCR *)arg;
240 jcr->my_thread_id = pthread_self();
241 pthread_detach(jcr->my_thread_id);
242 sm_check(__FILE__, __LINE__, true);
244 Dmsg0(200, "=====Start Job=========\n");
245 set_jcr_job_status(jcr, JS_Running); /* this will be set only if no error */
246 jcr->start_time = time(NULL); /* set the real start time */
247 jcr->jr.StartTime = jcr->start_time;
249 if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
250 (utime_t)(jcr->start_time - jcr->sched_time)) {
251 Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
252 set_jcr_job_status(jcr, JS_Canceled);
255 /* TODO : check if it is used somewhere */
256 if (jcr->job->RunScripts == NULL) {
257 Dmsg0(200, "Warning, job->RunScripts is empty\n");
258 jcr->job->RunScripts = New(alist(10, not_owned_by_alist));
261 if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
262 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
265 /* Run any script BeforeJob on dird */
266 run_scripts(jcr, jcr->job->RunScripts, "BeforeJob");
268 if (job_canceled(jcr)) {
269 update_job_end(jcr, jcr->JobStatus);
273 * We re-update the job start record so that the start
274 * time is set after the run before job. This avoids
275 * that any files created by the run before job will
276 * be saved twice. They will be backed up in the current
277 * job, but not in the next one unless they are changed.
278 * Without this, they will be backed up in this job and
279 * in the next job run because in that case, their date
280 * is after the start of this run.
282 jcr->start_time = time(NULL);
283 jcr->jr.StartTime = jcr->start_time;
284 if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
285 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
287 generate_job_event(jcr, "JobRun");
289 switch (jcr->JobType) {
291 if (do_backup(jcr)) {
294 backup_cleanup(jcr, JS_ErrorTerminated);
298 if (do_verify(jcr)) {
301 verify_cleanup(jcr, JS_ErrorTerminated);
305 if (do_restore(jcr)) {
308 restore_cleanup(jcr, JS_ErrorTerminated);
315 admin_cleanup(jcr, JS_ErrorTerminated);
321 if (do_migration(jcr)) {
324 migration_cleanup(jcr, JS_ErrorTerminated);
328 Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->JobType);
332 /* Send off any queued messages */
333 if (jcr->msg_queue && jcr->msg_queue->size() > 0) {
334 dequeue_messages(jcr);
338 generate_daemon_event(jcr, "JobEnd");
339 Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus);
340 sm_check(__FILE__, __LINE__, true);
346 * Cancel a job -- typically called by the UA (Console program), but may also
347 * be called by the job watchdog.
349 * Returns: true if cancel appears to be successful
350 * false on failure. Message sent to ua->jcr.
352 bool cancel_job(UAContext *ua, JCR *jcr)
356 set_jcr_job_status(jcr, JS_Canceled);
358 switch (jcr->JobStatus) {
361 case JS_WaitClientRes:
362 case JS_WaitStoreRes:
363 case JS_WaitPriority:
365 case JS_WaitStartTime:
366 bsendmsg(ua, _("JobId %d, Job %s marked to be canceled.\n"),
367 jcr->JobId, jcr->Job);
368 jobq_remove(&job_queue, jcr); /* attempt to remove it from queue */
372 /* Cancel File daemon */
373 if (jcr->file_bsock) {
374 ua->jcr->client = jcr->client;
375 if (!connect_to_file_daemon(ua->jcr, 10, FDConnectTimeout, 1)) {
376 bsendmsg(ua, _("Failed to connect to File daemon.\n"));
379 Dmsg0(200, "Connected to file daemon\n");
380 fd = ua->jcr->file_bsock;
381 bnet_fsend(fd, "cancel Job=%s\n", jcr->Job);
382 while (bnet_recv(fd) >= 0) {
383 bsendmsg(ua, "%s", fd->msg);
385 bnet_sig(fd, BNET_TERMINATE);
387 ua->jcr->file_bsock = NULL;
390 /* Cancel Storage daemon */
391 if (jcr->store_bsock) {
392 if (!ua->jcr->wstorage) {
394 copy_wstorage(ua->jcr, jcr->rstorage, _("Job resource"));
396 copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource"));
401 store.store = jcr->rstore;
402 pm_strcpy(store.store_source, jcr->rstore_source);
404 store.store = jcr->wstore;
405 pm_strcpy(store.store_source, jcr->wstore_source);
407 set_wstorage(ua->jcr, &store);
410 if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
411 bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
414 Dmsg0(200, "Connected to storage daemon\n");
415 sd = ua->jcr->store_bsock;
416 bnet_fsend(sd, "cancel Job=%s\n", jcr->Job);
417 while (bnet_recv(sd) >= 0) {
418 bsendmsg(ua, "%s", sd->msg);
420 bnet_sig(sd, BNET_TERMINATE);
422 ua->jcr->store_bsock = NULL;
430 static void job_monitor_destructor(watchdog_t *self)
432 JCR *control_jcr = (JCR *)self->data;
434 free_jcr(control_jcr);
437 static void job_monitor_watchdog(watchdog_t *self)
439 JCR *control_jcr, *jcr;
441 control_jcr = (JCR *)self->data;
443 Dmsg1(800, "job_monitor_watchdog %p called\n", self);
448 if (jcr->JobId == 0) {
449 Dmsg2(800, "Skipping JCR %p (%s) with JobId 0\n",
454 /* check MaxWaitTime */
455 cancel = job_check_maxwaittime(control_jcr, jcr);
457 /* check MaxRunTime */
458 cancel |= job_check_maxruntime(control_jcr, jcr);
461 Dmsg3(800, "Cancelling JCR %p jobid %d (%s)\n",
462 jcr, jcr->JobId, jcr->Job);
464 UAContext *ua = new_ua_context(jcr);
465 ua->jcr = control_jcr;
469 Dmsg2(800, "Have cancelled JCR %p Job=%d\n", jcr, jcr->JobId);
472 /* Keep reference counts correct */
478 * Check if the maxwaittime has expired and it is possible
481 static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
484 bool ok_to_cancel = false;
487 if (job->MaxWaitTime == 0 && job->FullMaxWaitTime == 0 &&
488 job->IncMaxWaitTime == 0 && job->DiffMaxWaitTime == 0) {
491 if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
492 (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
494 } else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxWaitTime != 0 &&
495 (watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
497 } else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxWaitTime != 0 &&
498 (watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
500 } else if (job->MaxWaitTime != 0 &&
501 (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
507 Dmsg3(800, "Job %d (%s): MaxWaitTime of %d seconds exceeded, "
509 jcr->JobId, jcr->Job, job->MaxWaitTime);
510 switch (jcr->JobStatus) {
515 case JS_WaitStoreRes:
516 case JS_WaitClientRes:
518 case JS_WaitPriority:
520 case JS_WaitStartTime:
522 Dmsg0(200, "JCR blocked in #1\n");
525 Dmsg0(800, "JCR running, checking SD status\n");
526 switch (jcr->SDJobStatus) {
531 Dmsg0(800, "JCR blocked in #2\n");
534 Dmsg0(800, "JCR not blocked in #2\n");
539 case JS_ErrorTerminated:
542 Dmsg0(800, "JCR already dead in #3\n");
545 Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
548 Dmsg3(800, "MaxWaitTime result: %scancel JCR %p (%s)\n",
549 cancel ? "" : "do not ", jcr, jcr->job);
555 * Check if maxruntime has expired and if the job can be
558 static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
562 if (jcr->job->MaxRunTime == 0) {
565 if ((watchdog_time - jcr->start_time) < jcr->job->MaxRunTime) {
566 Dmsg3(200, "Job %p (%s) with MaxRunTime %d not expired\n",
567 jcr, jcr->Job, jcr->job->MaxRunTime);
571 switch (jcr->JobStatus) {
577 case JS_WaitStoreRes:
578 case JS_WaitClientRes:
580 case JS_WaitPriority:
582 case JS_WaitStartTime:
587 case JS_ErrorTerminated:
593 Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
597 Dmsg3(200, "MaxRunTime result: %scancel JCR %p (%s)\n",
598 cancel ? "" : "do not ", jcr, jcr->job);
604 * Get or create a Pool record with the given name.
605 * Returns: 0 on error
608 DBId_t get_or_create_pool_record(JCR *jcr, char *pool_name)
612 memset(&pr, 0, sizeof(pr));
613 bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
614 Dmsg1(010, "get_or_create_pool=%s\n", pool_name);
616 while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
617 /* Try to create the pool */
618 if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
619 Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
620 db_strerror(jcr->db));
623 Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
629 void apply_pool_overrides(JCR *jcr)
631 if (jcr->run_pool_override) {
632 pm_strcpy(jcr->pool_source, _("Run pool override"));
635 * Apply any level related Pool selections
637 switch (jcr->JobLevel) {
639 if (jcr->full_pool) {
640 jcr->pool = jcr->full_pool;
641 if (jcr->run_full_pool_override) {
642 pm_strcpy(jcr->pool_source, _("Run FullPool override"));
644 pm_strcpy(jcr->pool_source, _("Job FullPool override"));
650 jcr->pool = jcr->inc_pool;
651 if (jcr->run_inc_pool_override) {
652 pm_strcpy(jcr->pool_source, _("Run IncPool override"));
654 pm_strcpy(jcr->pool_source, _("Job IncPool override"));
659 if (jcr->diff_pool) {
660 jcr->pool = jcr->diff_pool;
661 if (jcr->run_diff_pool_override) {
662 pm_strcpy(jcr->pool_source, _("Run DiffPool override"));
664 pm_strcpy(jcr->pool_source, _("Job DiffPool override"));
673 * Get or create a Client record for this Job
675 bool get_or_create_client_record(JCR *jcr)
679 memset(&cr, 0, sizeof(cr));
680 bstrncpy(cr.Name, jcr->client->hdr.name, sizeof(cr.Name));
681 cr.AutoPrune = jcr->client->AutoPrune;
682 cr.FileRetention = jcr->client->FileRetention;
683 cr.JobRetention = jcr->client->JobRetention;
684 if (!jcr->client_name) {
685 jcr->client_name = get_pool_memory(PM_NAME);
687 pm_strcpy(jcr->client_name, jcr->client->hdr.name);
688 if (!db_create_client_record(jcr, jcr->db, &cr)) {
689 Jmsg(jcr, M_FATAL, 0, _("Could not create Client record. ERR=%s\n"),
690 db_strerror(jcr->db));
693 jcr->jr.ClientId = cr.ClientId;
695 if (!jcr->client_uname) {
696 jcr->client_uname = get_pool_memory(PM_NAME);
698 pm_strcpy(jcr->client_uname, cr.Uname);
700 Dmsg2(100, "Created Client %s record %d\n", jcr->client->hdr.name,
705 bool get_or_create_fileset_record(JCR *jcr)
709 * Get or Create FileSet record
711 memset(&fsr, 0, sizeof(FILESET_DBR));
712 bstrncpy(fsr.FileSet, jcr->fileset->hdr.name, sizeof(fsr.FileSet));
713 if (jcr->fileset->have_MD5) {
714 struct MD5Context md5c;
715 unsigned char digest[MD5HashSize];
716 memcpy(&md5c, &jcr->fileset->md5c, sizeof(md5c));
717 MD5Final(digest, &md5c);
719 * Keep the flag (last arg) set to false otherwise old FileSets will
720 * get new MD5 sums and the user will get Full backups on everything
722 bin_to_base64(fsr.MD5, sizeof(fsr.MD5), (char *)digest, MD5HashSize, false);
723 bstrncpy(jcr->fileset->MD5, fsr.MD5, sizeof(jcr->fileset->MD5));
725 Jmsg(jcr, M_WARNING, 0, _("FileSet MD5 digest not found.\n"));
727 if (!jcr->fileset->ignore_fs_changes ||
728 !db_get_fileset_record(jcr, jcr->db, &fsr)) {
729 if (!db_create_fileset_record(jcr, jcr->db, &fsr)) {
730 Jmsg(jcr, M_ERROR, 0, _("Could not create FileSet \"%s\" record. ERR=%s\n"),
731 fsr.FileSet, db_strerror(jcr->db));
735 jcr->jr.FileSetId = fsr.FileSetId;
736 bstrncpy(jcr->FSCreateTime, fsr.cCreateTime, sizeof(jcr->FSCreateTime));
737 Dmsg2(119, "Created FileSet %s record %u\n", jcr->fileset->hdr.name,
742 void init_jcr_job_record(JCR *jcr)
744 jcr->jr.SchedTime = jcr->sched_time;
745 jcr->jr.StartTime = jcr->start_time;
746 jcr->jr.EndTime = 0; /* perhaps rescheduled, clear it */
747 jcr->jr.JobType = jcr->JobType;
748 jcr->jr.JobLevel = jcr->JobLevel;
749 jcr->jr.JobStatus = jcr->JobStatus;
750 jcr->jr.JobId = jcr->JobId;
751 bstrncpy(jcr->jr.Name, jcr->job->name(), sizeof(jcr->jr.Name));
752 bstrncpy(jcr->jr.Job, jcr->Job, sizeof(jcr->jr.Job));
756 * Write status and such in DB
758 void update_job_end_record(JCR *jcr)
760 jcr->jr.EndTime = time(NULL);
761 jcr->end_time = jcr->jr.EndTime;
762 jcr->jr.JobId = jcr->JobId;
763 jcr->jr.JobStatus = jcr->JobStatus;
764 jcr->jr.JobFiles = jcr->JobFiles;
765 jcr->jr.JobBytes = jcr->JobBytes;
766 jcr->jr.VolSessionId = jcr->VolSessionId;
767 jcr->jr.VolSessionTime = jcr->VolSessionTime;
768 jcr->jr.JobErrors = jcr->Errors;
769 if (!db_update_job_end_record(jcr, jcr->db, &jcr->jr)) {
770 Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"),
771 db_strerror(jcr->db));
776 * Takes base_name and appends (unique) current
777 * date and time to form unique job name.
779 * Returns: unique job name in jcr->Job
780 * date/time in jcr->start_time
782 void create_unique_job_name(JCR *jcr, const char *base_name)
784 /* Job start mutex */
785 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
786 static time_t last_start_time = 0;
789 char dt[MAX_TIME_LENGTH];
790 char name[MAX_NAME_LENGTH];
793 /* Guarantee unique start time -- maximum one per second, and
794 * thus unique Job Name
796 P(mutex); /* lock creation of jobs */
798 while (now == last_start_time) {
799 bmicrosleep(0, 500000);
802 last_start_time = now;
803 V(mutex); /* allow creation of jobs */
804 jcr->start_time = now;
805 /* Form Unique JobName */
806 (void)localtime_r(&now, &tm);
807 /* Use only characters that are permitted in Windows filenames */
808 strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm);
809 bstrncpy(name, base_name, sizeof(name));
810 name[sizeof(name)-22] = 0; /* truncate if too long */
811 bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s", name, dt); /* add date & time */
812 /* Convert spaces into underscores */
813 for (p=jcr->Job; *p; p++) {
820 /* Called directly from job rescheduling */
821 void dird_free_jcr_pointers(JCR *jcr)
823 if (jcr->sd_auth_key) {
824 free(jcr->sd_auth_key);
825 jcr->sd_auth_key = NULL;
831 if (jcr->file_bsock) {
832 Dmsg0(200, "Close File bsock\n");
833 bnet_close(jcr->file_bsock);
834 jcr->file_bsock = NULL;
836 if (jcr->store_bsock) {
837 Dmsg0(200, "Close Store bsock\n");
838 bnet_close(jcr->store_bsock);
839 jcr->store_bsock = NULL;
842 Dmsg0(200, "Free JCR fname\n");
843 free_pool_memory(jcr->fname);
846 if (jcr->pool_source) {
847 free_pool_memory(jcr->pool_source);
848 jcr->pool_source = NULL;
850 if (jcr->rpool_source) {
851 free_pool_memory(jcr->rpool_source);
852 jcr->rpool_source = NULL;
854 if (jcr->wstore_source) {
855 free_pool_memory(jcr->wstore_source);
856 jcr->wstore_source = NULL;
858 if (jcr->rstore_source) {
859 free_pool_memory(jcr->rstore_source);
860 jcr->rstore_source = NULL;
863 Dmsg0(200, "Free JCR stime\n");
864 free_pool_memory(jcr->stime);
867 if (jcr->RestoreBootstrap) {
868 free(jcr->RestoreBootstrap);
869 jcr->RestoreBootstrap = NULL;
871 if (jcr->client_uname) {
872 free_pool_memory(jcr->client_uname);
873 jcr->client_uname = NULL;
876 free_pool_memory(jcr->attr);
886 * Free the Job Control Record if no one is still using it.
887 * Called from main free_jcr() routine in src/lib/jcr.c so
888 * that we can do our Director specific cleanup of the jcr.
890 void dird_free_jcr(JCR *jcr)
892 Dmsg0(200, "Start dird free_jcr\n");
894 dird_free_jcr_pointers(jcr);
895 if (jcr->term_wait_inited) {
896 pthread_cond_destroy(&jcr->term_wait);
897 jcr->term_wait_inited = false;
900 /* Delete lists setup to hold storage pointers */
903 jcr->job_end_push.destroy();
904 Dmsg0(200, "End dird free_jcr\n");
908 * The Job storage definition must be either in the Job record
909 * or in the Pool record. The Pool record overrides the Job
912 void get_job_storage(USTORE *store, JOB *job, RUN *run)
914 if (run && run->pool && run->pool->storage) {
915 store->store = (STORE *)run->pool->storage->first();
916 pm_strcpy(store->store_source, _("Run pool override"));
919 if (run && run->storage) {
920 store->store = run->storage;
921 pm_strcpy(store->store_source, _("Run storage override"));
924 if (job->pool->storage) {
925 store->store = (STORE *)job->pool->storage->first();
926 pm_strcpy(store->store_source, _("Pool resource"));
928 store->store = (STORE *)job->storage->first();
929 pm_strcpy(store->store_source, _("Job resource"));
934 * Set some defaults in the JCR necessary to
935 * run. These items are pulled from the job
936 * definition as defaults, but can be overridden
937 * later either by the Run record in the Schedule resource,
938 * or by the Console program.
940 void set_jcr_defaults(JCR *jcr, JOB *job)
943 jcr->JobType = job->JobType;
944 switch (jcr->JobType) {
947 jcr->JobLevel = L_NONE;
950 jcr->JobLevel = job->JobLevel;
954 jcr->fname = get_pool_memory(PM_FNAME);
956 if (!jcr->pool_source) {
957 jcr->pool_source = get_pool_memory(PM_MESSAGE);
958 pm_strcpy(jcr->pool_source, _("unknown source"));
960 jcr->JobPriority = job->Priority;
961 /* Copy storage definitions -- deleted in dir_free_jcr above */
963 copy_rwstorage(jcr, job->storage, _("Job resource"));
965 copy_rwstorage(jcr, job->pool->storage, _("Pool resource"));
967 jcr->client = job->client;
968 if (!jcr->client_name) {
969 jcr->client_name = get_pool_memory(PM_NAME);
971 pm_strcpy(jcr->client_name, jcr->client->hdr.name);
972 pm_strcpy(jcr->pool_source, _("Job resource"));
973 jcr->pool = job->pool;
974 jcr->full_pool = job->full_pool;
975 jcr->inc_pool = job->inc_pool;
976 jcr->diff_pool = job->diff_pool;
977 jcr->catalog = job->client->catalog;
978 jcr->fileset = job->fileset;
979 jcr->messages = job->messages;
980 jcr->spool_data = job->spool_data;
981 jcr->write_part_after_job = job->write_part_after_job;
982 if (jcr->RestoreBootstrap) {
983 free(jcr->RestoreBootstrap);
984 jcr->RestoreBootstrap = NULL;
986 /* This can be overridden by Console program */
987 if (job->RestoreBootstrap) {
988 jcr->RestoreBootstrap = bstrdup(job->RestoreBootstrap);
990 /* This can be overridden by Console program */
991 jcr->verify_job = job->verify_job;
992 /* If no default level given, set one */
993 if (jcr->JobLevel == 0) {
994 switch (jcr->JobType) {
996 jcr->JobLevel = L_VERIFY_CATALOG;
999 jcr->JobLevel = L_INCREMENTAL;
1003 jcr->JobLevel = L_NONE;
1006 jcr->JobLevel = L_FULL;
1013 * Copy the storage definitions from an alist to the JCR
1015 void copy_rwstorage(JCR *jcr, alist *storage, const char *where)
1017 switch(jcr->JobType) {
1021 copy_rstorage(jcr, storage, where);
1024 copy_wstorage(jcr, storage, where);
1030 /* Set storage override */
1031 void set_rwstorage(JCR *jcr, USTORE *store)
1034 Jmsg(jcr, M_FATAL, 0, _("No storage specified.\n"));
1037 switch(jcr->JobType) {
1041 set_rstorage(jcr, store);
1044 set_wstorage(jcr, store);
1049 void free_rwstorage(JCR *jcr)
1056 * Copy the storage definitions from an alist to the JCR
1058 void copy_rstorage(JCR *jcr, alist *storage, const char *where)
1062 if (jcr->rstorage) {
1063 delete jcr->rstorage;
1065 jcr->rstorage = New(alist(10, not_owned_by_alist));
1066 foreach_alist(st, storage) {
1067 jcr->rstorage->append(st);
1069 if (!jcr->rstore_source) {
1070 jcr->rstore_source = get_pool_memory(PM_MESSAGE);
1072 pm_strcpy(jcr->rstore_source, where);
1073 if (jcr->rstorage) {
1074 jcr->rstore = (STORE *)jcr->rstorage->first();
1080 /* Set storage override */
1081 void set_rstorage(JCR *jcr, USTORE *store)
1085 if (!store->store) {
1088 if (!jcr->rstorage) {
1089 jcr->rstorage = New(alist(10, not_owned_by_alist));
1091 jcr->rstore = store->store;
1092 if (!jcr->rstore_source) {
1093 jcr->rstore_source = get_pool_memory(PM_MESSAGE);
1095 pm_strcpy(jcr->rstore_source, store->store_source);
1096 foreach_alist(storage, jcr->rstorage) {
1097 if (store->store == storage) {
1101 /* Store not in list, so add it */
1102 jcr->rstorage->prepend(store->store);
1105 void free_rstorage(JCR *jcr)
1107 if (jcr->rstorage) {
1108 delete jcr->rstorage;
1109 jcr->rstorage = NULL;
1115 * Copy the storage definitions from an alist to the JCR
1117 void copy_wstorage(JCR *jcr, alist *storage, const char *where)
1121 if (jcr->wstorage) {
1122 delete jcr->wstorage;
1124 jcr->wstorage = New(alist(10, not_owned_by_alist));
1125 foreach_alist(st, storage) {
1126 Dmsg1(50, "storage=%s\n", st->name());
1127 jcr->wstorage->append(st);
1129 if (!jcr->wstore_source) {
1130 jcr->wstore_source = get_pool_memory(PM_MESSAGE);
1132 pm_strcpy(jcr->wstore_source, where);
1133 if (jcr->wstorage) {
1134 jcr->wstore = (STORE *)jcr->wstorage->first();
1135 Dmsg2(100, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
1141 /* Set storage override */
1142 void set_wstorage(JCR *jcr, USTORE *store)
1146 if (!store->store) {
1149 if (!jcr->wstorage) {
1150 jcr->wstorage = New(alist(10, not_owned_by_alist));
1152 jcr->wstore = store->store;
1153 if (!jcr->wstore_source) {
1154 jcr->wstore_source = get_pool_memory(PM_MESSAGE);
1156 pm_strcpy(jcr->wstore_source, store->store_source);
1157 Dmsg2(50, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
1158 foreach_alist(storage, jcr->wstorage) {
1159 if (store->store == storage) {
1163 /* Store not in list, so add it */
1164 jcr->wstorage->prepend(store->store);
1167 void free_wstorage(JCR *jcr)
1169 if (jcr->wstorage) {
1170 delete jcr->wstorage;
1171 jcr->wstorage = NULL;
1176 void create_clones(JCR *jcr)
1179 * Fire off any clone jobs (run directives)
1181 Dmsg2(900, "cloned=%d run_cmds=%p\n", jcr->cloned, jcr->job->run_cmds);
1182 if (!jcr->cloned && jcr->job->run_cmds) {
1184 JOB *job = jcr->job;
1185 POOLMEM *cmd = get_pool_memory(PM_FNAME);
1186 UAContext *ua = new_ua_context(jcr);
1188 foreach_alist(runcmd, job->run_cmds) {
1189 cmd = edit_job_codes(jcr, cmd, runcmd, "");
1190 Mmsg(ua->cmd, "run %s cloned=yes", cmd);
1191 Dmsg1(900, "=============== Clone cmd=%s\n", ua->cmd);
1192 parse_ua_args(ua); /* parse command */
1193 int stat = run_cmd(ua, ua->cmd);
1195 Jmsg(jcr, M_ERROR, 0, _("Could not start clone job.\n"));
1197 Jmsg(jcr, M_INFO, 0, _("Clone JobId %d started.\n"), stat);
1200 free_ua_context(ua);
1201 free_pool_memory(cmd);
1205 bool create_restore_bootstrap_file(JCR *jcr)
1209 memset(&rx, 0, sizeof(rx));
1212 rx.bsr->JobId = jcr->previous_jr.JobId;
1213 ua = new_ua_context(jcr);
1214 complete_bsr(ua, rx.bsr);
1215 rx.bsr->fi = new_findex();
1216 rx.bsr->fi->findex = 1;
1217 rx.bsr->fi->findex2 = jcr->previous_jr.JobFiles;
1218 jcr->ExpectedFiles = write_bsr_file(ua, rx);
1219 if (jcr->ExpectedFiles == 0) {
1220 free_ua_context(ua);
1224 free_ua_context(ua);
1226 jcr->needs_sd = true;