]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/job.c
77b3181d7b916b67a82ef921997caef2406c7003
[bacula/bacula] / bacula / src / dird / job.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *
30  *   Bacula Director Job processing routines
31  *
32  *     Kern Sibbald, October MM
33  *
34  */
35
36 #include "bacula.h"
37 #include "dird.h"
38
39 /* Forward referenced subroutines */
40 static void *job_thread(void *arg);
41 static void job_monitor_watchdog(watchdog_t *self);
42 static void job_monitor_destructor(watchdog_t *self);
43 static bool job_check_maxwaittime(JCR *jcr);
44 static bool job_check_maxruntime(JCR *jcr);
45 static bool job_check_maxschedruntime(JCR *jcr);
46
47 /* Imported subroutines */
48 extern void term_scheduler();
49 extern void term_ua_server();
50
51 /* Imported variables */
52
53 jobq_t job_queue;
54
55 void init_job_server(int max_workers)
56 {
57    int stat;
58    watchdog_t *wd;
59
60    if ((stat = jobq_init(&job_queue, max_workers, job_thread)) != 0) {
61       berrno be;
62       Emsg1(M_ABORT, 0, _("Could not init job queue: ERR=%s\n"), be.bstrerror(stat));
63    }
64    wd = new_watchdog();
65    wd->callback = job_monitor_watchdog;
66    wd->destructor = job_monitor_destructor;
67    wd->one_shot = false;
68    wd->interval = 60;
69    wd->data = new_control_jcr("*JobMonitor*", JT_SYSTEM);
70    register_watchdog(wd);
71 }
72
73 void term_job_server()
74 {
75    jobq_destroy(&job_queue);          /* ignore any errors */
76 }
77
78 /*
79  * Run a job -- typically called by the scheduler, but may also
80  *              be called by the UA (Console program).
81  *
82  *  Returns: 0 on failure
83  *           JobId on success
84  *
85  */
86 JobId_t run_job(JCR *jcr)
87 {
88    int stat;
89    if (setup_job(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) {
93          berrno be;
94          Jmsg(jcr, M_FATAL, 0, _("Could not add job queue: ERR=%s\n"), be.bstrerror(stat));
95          return 0;
96       }
97       return jcr->JobId;
98    }
99    return 0;
100 }            
101
102 bool setup_job(JCR *jcr) 
103 {
104    int errstat;
105
106    jcr->lock();
107    sm_check(__FILE__, __LINE__, true);
108    init_msg(jcr, jcr->messages);
109
110    /* Initialize termination condition variable */
111    if ((errstat = pthread_cond_init(&jcr->term_wait, NULL)) != 0) {
112       berrno be;
113       Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
114       jcr->unlock();
115       goto bail_out;
116    }
117    jcr->term_wait_inited = true;
118
119    create_unique_job_name(jcr, jcr->job->name());
120    jcr->setJobStatus(JS_Created);
121    jcr->unlock();
122
123    /*
124     * Open database
125     */
126    Dmsg0(100, "Open database\n");
127    jcr->db=db_init(jcr, jcr->catalog->db_driver, jcr->catalog->db_name, 
128                    jcr->catalog->db_user,
129                    jcr->catalog->db_password, jcr->catalog->db_address,
130                    jcr->catalog->db_port, jcr->catalog->db_socket,
131                    jcr->catalog->mult_db_connections);
132    if (!jcr->db || !db_open_database(jcr, jcr->db)) {
133       Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"),
134                  jcr->catalog->db_name);
135       if (jcr->db) {
136          Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
137          db_close_database(jcr, jcr->db);
138       }
139       goto bail_out;
140    }
141    Dmsg0(150, "DB opened\n");
142
143    if (!jcr->fname) {
144       jcr->fname = get_pool_memory(PM_FNAME);
145    }
146    if (!jcr->pool_source) {
147       jcr->pool_source = get_pool_memory(PM_MESSAGE);
148       pm_strcpy(jcr->pool_source, _("unknown source"));
149    }
150
151    if (jcr->JobReads()) {
152       if (!jcr->rpool_source) {
153          jcr->rpool_source = get_pool_memory(PM_MESSAGE);
154          pm_strcpy(jcr->rpool_source, _("unknown source"));
155       }
156    }
157
158    /*
159     * Create Job record
160     */
161    init_jcr_job_record(jcr);
162    if (!get_or_create_client_record(jcr)) {
163       goto bail_out;
164    }
165
166    if (!db_create_job_record(jcr, jcr->db, &jcr->jr)) {
167       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
168       goto bail_out;
169    }
170    jcr->JobId = jcr->jr.JobId;
171    Dmsg4(100, "Created job record JobId=%d Name=%s Type=%c Level=%c\n",
172        jcr->JobId, jcr->Job, jcr->jr.JobType, jcr->jr.JobLevel);
173
174    generate_daemon_event(jcr, "JobStart");
175    new_plugins(jcr);                  /* instantiate plugins for this jcr */
176    generate_plugin_event(jcr, bEventJobStart);
177
178    if (job_canceled(jcr)) {
179       goto bail_out;
180    }
181
182    if (jcr->JobReads() && !jcr->rstorage) {
183       if (jcr->job->storage) {
184          copy_rwstorage(jcr, jcr->job->storage, _("Job resource"));
185       } else {
186          copy_rwstorage(jcr, jcr->job->pool->storage, _("Pool resource"));
187       }
188    }
189    if (!jcr->JobReads()) {
190       free_rstorage(jcr);
191    }
192
193    /*
194     * Now, do pre-run stuff, like setting job level (Inc/diff, ...)
195     *  this allows us to setup a proper job start record for restarting
196     *  in case of later errors.
197     */
198    switch (jcr->getJobType()) {
199    case JT_BACKUP:
200       if (!do_backup_init(jcr)) {
201          backup_cleanup(jcr, JS_ErrorTerminated);
202          goto bail_out;
203       }
204       break;
205    case JT_VERIFY:
206       if (!do_verify_init(jcr)) {
207          verify_cleanup(jcr, JS_ErrorTerminated);
208          goto bail_out;
209       }
210       break;
211    case JT_RESTORE:
212       if (!do_restore_init(jcr)) {
213          restore_cleanup(jcr, JS_ErrorTerminated);
214          goto bail_out;
215       }
216       break;
217    case JT_ADMIN:
218       if (!do_admin_init(jcr)) {
219          admin_cleanup(jcr, JS_ErrorTerminated);
220          goto bail_out;
221       }
222       break;
223    case JT_COPY:
224    case JT_MIGRATE:
225       if (!do_migration_init(jcr)) { 
226          migration_cleanup(jcr, JS_ErrorTerminated);
227          goto bail_out;
228       }
229       break;
230    default:
231       Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->getJobType());
232       jcr->setJobStatus(JS_ErrorTerminated);
233       goto bail_out;
234    }
235
236    generate_job_event(jcr, "JobInit");
237    generate_plugin_event(jcr, bEventJobInit);
238    Dsm_check(1);
239    return true;
240
241 bail_out:
242    return false;
243 }
244
245 void update_job_end(JCR *jcr, int TermCode)
246 {
247    dequeue_messages(jcr);             /* display any queued messages */
248    jcr->setJobStatus(TermCode);
249    update_job_end_record(jcr);
250 }
251
252 /*
253  * This is the engine called by jobq.c:jobq_add() when we were pulled
254  *  from the work queue.
255  *  At this point, we are running in our own thread and all
256  *    necessary resources are allocated -- see jobq.c
257  */
258 static void *job_thread(void *arg)
259 {
260    JCR *jcr = (JCR *)arg;
261
262    pthread_detach(pthread_self());
263    Dsm_check(1);
264
265    Dmsg0(200, "=====Start Job=========\n");
266    jcr->setJobStatus(JS_Running);   /* this will be set only if no error */
267    jcr->start_time = time(NULL);      /* set the real start time */
268    jcr->jr.StartTime = jcr->start_time;
269
270    if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
271        (utime_t)(jcr->start_time - jcr->sched_time)) {
272       jcr->setJobStatus(JS_Canceled);
273       Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
274    }
275
276    if (job_check_maxschedruntime(jcr)) {
277       jcr->setJobStatus(JS_Canceled);
278       Jmsg(jcr, M_FATAL, 0, _("Job canceled because max sched run time exceeded.\n"));
279    }
280
281    /* TODO : check if it is used somewhere */
282    if (jcr->job->RunScripts == NULL) {
283       Dmsg0(200, "Warning, job->RunScripts is empty\n");
284       jcr->job->RunScripts = New(alist(10, not_owned_by_alist));
285    }
286
287    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
288       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
289    }
290
291    /* Run any script BeforeJob on dird */
292    run_scripts(jcr, jcr->job->RunScripts, "BeforeJob");
293
294    /*
295     * We re-update the job start record so that the start
296     *  time is set after the run before job.  This avoids
297     *  that any files created by the run before job will
298     *  be saved twice.  They will be backed up in the current
299     *  job, but not in the next one unless they are changed.
300     *  Without this, they will be backed up in this job and
301     *  in the next job run because in that case, their date
302     *   is after the start of this run.
303     */
304    jcr->start_time = time(NULL);
305    jcr->jr.StartTime = jcr->start_time;
306    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
307       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
308    }
309    generate_job_event(jcr, "JobRun");
310    generate_plugin_event(jcr, bEventJobRun);
311
312    switch (jcr->getJobType()) {
313    case JT_BACKUP:
314       if (!job_canceled(jcr) && do_backup(jcr)) {
315          do_autoprune(jcr);
316       } else {
317          backup_cleanup(jcr, JS_ErrorTerminated);
318       }
319       break;
320    case JT_VERIFY:
321       if (!job_canceled(jcr) && do_verify(jcr)) {
322          do_autoprune(jcr);
323       } else {
324          verify_cleanup(jcr, JS_ErrorTerminated);
325       }
326       break;
327    case JT_RESTORE:
328       if (!job_canceled(jcr) && do_restore(jcr)) {
329          do_autoprune(jcr);
330       } else {
331          restore_cleanup(jcr, JS_ErrorTerminated);
332       }
333       break;
334    case JT_ADMIN:
335       if (!job_canceled(jcr) && do_admin(jcr)) {
336          do_autoprune(jcr);
337       } else {
338          admin_cleanup(jcr, JS_ErrorTerminated);
339       }
340       break;
341    case JT_COPY:
342    case JT_MIGRATE:
343       if (!job_canceled(jcr) && do_migration(jcr)) {
344          do_autoprune(jcr);
345       } else {
346          migration_cleanup(jcr, JS_ErrorTerminated);
347       }
348       break;
349    default:
350       Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->getJobType());
351       break;
352    }
353
354    run_scripts(jcr, jcr->job->RunScripts, "AfterJob");
355
356    /* Send off any queued messages */
357    if (jcr->msg_queue && jcr->msg_queue->size() > 0) {
358       dequeue_messages(jcr);
359    }
360
361    generate_daemon_event(jcr, "JobEnd");
362    generate_plugin_event(jcr, bEventJobEnd);
363    Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus);
364    sm_check(__FILE__, __LINE__, true);
365    return NULL;
366 }
367
368
369 /*
370  * Cancel a job -- typically called by the UA (Console program), but may also
371  *              be called by the job watchdog.
372  *
373  *  Returns: true  if cancel appears to be successful
374  *           false on failure. Message sent to ua->jcr.
375  */
376 bool cancel_job(UAContext *ua, JCR *jcr)
377 {
378    BSOCK *sd, *fd;
379    char ed1[50];
380    int32_t old_status = jcr->JobStatus;
381
382    jcr->setJobStatus(JS_Canceled);
383
384    switch (old_status) {
385    case JS_Created:
386    case JS_WaitJobRes:
387    case JS_WaitClientRes:
388    case JS_WaitStoreRes:
389    case JS_WaitPriority:
390    case JS_WaitMaxJobs:
391    case JS_WaitStartTime:
392       ua->info_msg(_("JobId %s, Job %s marked to be canceled.\n"),
393               edit_uint64(jcr->JobId, ed1), jcr->Job);
394       jobq_remove(&job_queue, jcr); /* attempt to remove it from queue */
395       break;
396
397    default:
398       /* Cancel File daemon */
399       if (jcr->file_bsock) {
400          ua->jcr->client = jcr->client;
401          if (!connect_to_file_daemon(ua->jcr, 10, FDConnectTimeout, 1)) {
402             ua->error_msg(_("Failed to connect to File daemon.\n"));
403             return 0;
404          }
405          Dmsg0(200, "Connected to file daemon\n");
406          fd = ua->jcr->file_bsock;
407          fd->fsend("cancel Job=%s\n", jcr->Job);
408          while (fd->recv() >= 0) {
409             ua->send_msg("%s", fd->msg);
410          }
411          fd->signal(BNET_TERMINATE);
412          fd->close();
413          ua->jcr->file_bsock = NULL;
414          jcr->file_bsock->set_terminated();
415          if (jcr->my_thread_id && !pthread_equal(jcr->my_thread_id, pthread_self())) {
416             pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
417             Dmsg1(800, "Send kill to jid=%d\n", jcr->JobId);
418          }
419       }
420
421       /* Cancel Storage daemon */
422       if (jcr->store_bsock) {
423          if (!ua->jcr->wstorage) {
424             if (jcr->rstorage) {
425                copy_wstorage(ua->jcr, jcr->rstorage, _("Job resource")); 
426             } else {
427                copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource")); 
428             }
429          } else {
430             USTORE store;
431             if (jcr->rstorage) {
432                store.store = jcr->rstore;
433             } else {
434                store.store = jcr->wstore;
435             }
436             set_wstorage(ua->jcr, &store);
437          }
438
439          if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
440             ua->error_msg(_("Failed to connect to Storage daemon.\n"));
441             return false;
442          }
443          Dmsg0(200, "Connected to storage daemon\n");
444          sd = ua->jcr->store_bsock;
445          sd->fsend("cancel Job=%s\n", jcr->Job);
446          while (sd->recv() >= 0) {
447             ua->send_msg("%s", sd->msg);
448          }
449          sd->signal(BNET_TERMINATE);
450          sd->close();
451          ua->jcr->store_bsock = NULL;
452          jcr->store_bsock->set_timed_out();
453          jcr->store_bsock->set_terminated();
454          if (jcr->SD_msg_chan && !pthread_equal(jcr->SD_msg_chan, pthread_self())) {
455             Dmsg2(400, "kill jobid=%d use=%d\n", (int)jcr->JobId, jcr->use_count());
456             pthread_kill(jcr->SD_msg_chan, TIMEOUT_SIGNAL);
457          }
458          if (jcr->my_thread_id && !pthread_equal(jcr->my_thread_id, pthread_self())) {
459             pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
460          }
461       }
462       break;
463    }
464
465    return true;
466 }
467
468 void cancel_storage_daemon_job(JCR *jcr)
469 {
470    if (jcr->sd_canceled) { 
471       return;                   /* cancel only once */
472    }
473
474    UAContext *ua = new_ua_context(jcr);
475    JCR *control_jcr = new_control_jcr("*JobCancel*", JT_SYSTEM);
476    BSOCK *sd;
477
478    ua->jcr = control_jcr;
479    if (jcr->store_bsock) {
480       if (!ua->jcr->wstorage) {
481          if (jcr->rstorage) {
482             copy_wstorage(ua->jcr, jcr->rstorage, _("Job resource")); 
483          } else {
484             copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource")); 
485          }
486       } else {
487          USTORE store;
488          if (jcr->rstorage) {
489             store.store = jcr->rstore;
490          } else {
491             store.store = jcr->wstore;
492          }
493          set_wstorage(ua->jcr, &store);
494       }
495
496       if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
497          goto bail_out;
498       }
499       Dmsg0(200, "Connected to storage daemon\n");
500       sd = ua->jcr->store_bsock;
501       sd->fsend("cancel Job=%s\n", jcr->Job);
502       while (sd->recv() >= 0) {
503       }
504       sd->signal(BNET_TERMINATE);
505       sd->close();
506       ua->jcr->store_bsock = NULL;
507       jcr->sd_canceled = true;
508       jcr->store_bsock->set_timed_out();
509       jcr->store_bsock->set_terminated();
510       if (jcr->SD_msg_chan && !pthread_equal(jcr->SD_msg_chan, pthread_self())) {
511          Dmsg2(400, "kill jobid=%d use=%d\n", (int)jcr->JobId, jcr->use_count());
512          pthread_kill(jcr->SD_msg_chan, TIMEOUT_SIGNAL);
513       }
514       if (jcr->my_thread_id && !pthread_equal(jcr->my_thread_id, pthread_self())) {
515          pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
516       }
517    }
518 bail_out:
519    free_jcr(control_jcr);
520    free_ua_context(ua);
521 }
522
523 static void job_monitor_destructor(watchdog_t *self)
524 {
525    JCR *control_jcr = (JCR *)self->data;
526
527    free_jcr(control_jcr);
528 }
529
530 static void job_monitor_watchdog(watchdog_t *self)
531 {
532    JCR *control_jcr, *jcr;
533
534    control_jcr = (JCR *)self->data;
535
536    Dsm_check(1);
537    Dmsg1(800, "job_monitor_watchdog %p called\n", self);
538
539    foreach_jcr(jcr) {
540       bool cancel = false;
541
542       if (jcr->JobId == 0 || job_canceled(jcr) || jcr->no_maxtime) {
543          Dmsg2(800, "Skipping JCR=%p Job=%s\n", jcr, jcr->Job);
544          continue;
545       }
546
547       /* check MaxWaitTime */
548       if (job_check_maxwaittime(jcr)) {
549          jcr->setJobStatus(JS_Canceled);
550          Qmsg(jcr, M_FATAL, 0, _("Max wait time exceeded. Job canceled.\n"));
551          cancel = true;
552       /* check MaxRunTime */
553       } else if (job_check_maxruntime(jcr)) {
554          jcr->setJobStatus(JS_Canceled);
555          Qmsg(jcr, M_FATAL, 0, _("Max run time exceeded. Job canceled.\n"));
556          cancel = true;
557       /* check MaxRunSchedTime */ 
558       } else if (job_check_maxschedruntime(jcr)) {
559          jcr->setJobStatus(JS_Canceled);
560          Qmsg(jcr, M_FATAL, 0, _("Max sched run time exceeded. Job canceled.\n"));
561          cancel = true;
562       }
563
564       if (cancel) {
565          Dmsg3(800, "Cancelling JCR %p jobid %d (%s)\n", jcr, jcr->JobId, jcr->Job);
566          UAContext *ua = new_ua_context(jcr);
567          ua->jcr = control_jcr;
568          cancel_job(ua, jcr);
569          free_ua_context(ua);
570          Dmsg2(800, "Have cancelled JCR %p Job=%d\n", jcr, jcr->JobId);
571       }
572
573    }
574    /* Keep reference counts correct */
575    endeach_jcr(jcr);
576 }
577
578 /*
579  * Check if the maxwaittime has expired and it is possible
580  *  to cancel the job.
581  */
582 static bool job_check_maxwaittime(JCR *jcr)
583 {
584    bool cancel = false;
585    JOB *job = jcr->job;
586    utime_t current=0;
587
588    if (!job_waiting(jcr)) {
589       return false;
590    }
591
592    if (jcr->wait_time) {
593       current = watchdog_time - jcr->wait_time;
594    }
595
596    Dmsg2(200, "check maxwaittime %u >= %u\n", 
597          current + jcr->wait_time_sum, job->MaxWaitTime);
598    if (job->MaxWaitTime != 0 &&
599        (current + jcr->wait_time_sum) >= job->MaxWaitTime) {
600       cancel = true;
601    }
602
603    return cancel;
604 }
605
606 /*
607  * Check if maxruntime has expired and if the job can be
608  *   canceled.
609  */
610 static bool job_check_maxruntime(JCR *jcr)
611 {
612    bool cancel = false;
613    JOB *job = jcr->job;
614    utime_t run_time;
615
616    if (job_canceled(jcr) || jcr->JobStatus == JS_Created) {
617       return false;
618    }
619    if (jcr->job->MaxRunTime == 0 && job->FullMaxRunTime == 0 &&
620        job->IncMaxRunTime == 0 && job->DiffMaxRunTime == 0) {
621       return false;
622    }
623    run_time = watchdog_time - jcr->start_time;
624    Dmsg7(200, "check_maxruntime %llu-%u=%llu >= %llu|%llu|%llu|%llu\n",
625          watchdog_time, jcr->start_time, run_time, job->MaxRunTime, job->FullMaxRunTime, 
626          job->IncMaxRunTime, job->DiffMaxRunTime);
627
628    if (jcr->getJobLevel() == L_FULL && job->FullMaxRunTime != 0 &&
629          run_time >= job->FullMaxRunTime) {
630       Dmsg0(200, "check_maxwaittime: FullMaxcancel\n");
631       cancel = true;
632    } else if (jcr->getJobLevel() == L_DIFFERENTIAL && job->DiffMaxRunTime != 0 &&
633          run_time >= job->DiffMaxRunTime) {
634       Dmsg0(200, "check_maxwaittime: DiffMaxcancel\n");
635       cancel = true;
636    } else if (jcr->getJobLevel() == L_INCREMENTAL && job->IncMaxRunTime != 0 &&
637          run_time >= job->IncMaxRunTime) {
638       Dmsg0(200, "check_maxwaittime: IncMaxcancel\n");
639       cancel = true;
640    } else if (job->MaxRunTime > 0 && run_time >= job->MaxRunTime) {
641       Dmsg0(200, "check_maxwaittime: Maxcancel\n");
642       cancel = true;
643    }
644  
645    return cancel;
646 }
647
648 /*
649  * Check if MaxRunSchedTime has expired and if the job can be
650  *   canceled.
651  */
652 static bool job_check_maxschedruntime(JCR *jcr)
653 {
654    if (jcr->job->MaxRunSchedTime == 0 || job_canceled(jcr)) {
655       return false;
656    }
657    if ((watchdog_time - jcr->sched_time) < jcr->job->MaxRunSchedTime) {
658       Dmsg3(200, "Job %p (%s) with MaxRunSchedTime %d not expired\n",
659             jcr, jcr->Job, jcr->job->MaxRunSchedTime);
660       return false;
661    }
662
663    return true;
664 }
665
666 /*
667  * Get or create a Pool record with the given name.
668  * Returns: 0 on error
669  *          poolid if OK
670  */
671 DBId_t get_or_create_pool_record(JCR *jcr, char *pool_name)
672 {
673    POOL_DBR pr;
674
675    memset(&pr, 0, sizeof(pr));
676    bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
677    Dmsg1(110, "get_or_create_pool=%s\n", pool_name);
678
679    while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
680       /* Try to create the pool */
681       if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
682          Jmsg(jcr, M_FATAL, 0, _("Pool \"%s\" not in database. ERR=%s"), pr.Name,
683             db_strerror(jcr->db));
684          return 0;
685       } else {
686          Jmsg(jcr, M_INFO, 0, _("Created database record for Pool \"%s\".\n"), pr.Name);
687       }
688    }
689    return pr.PoolId;
690 }
691
692 /*
693  * Check for duplicate jobs.
694  *  Returns: true  if current job should continue
695  *           false if current job should terminate
696  */
697 bool allow_duplicate_job(JCR *jcr)
698 {
699    JOB *job = jcr->job;
700    JCR *djcr;                /* possible duplicate job */
701
702    if (job->AllowDuplicateJobs) {
703       return true;
704    }
705    Dmsg0(800, "Enter allow_duplicate_job\n");
706    /*
707     * After this point, we do not want to allow any duplicate
708     * job to run.
709     */
710
711    foreach_jcr(djcr) {
712       if (jcr == djcr || djcr->JobId == 0) {
713          continue;                   /* do not cancel this job or consoles */
714       }
715       if (strcmp(job->name(), djcr->job->name()) == 0) {
716          bool cancel_dup = false;
717          bool cancel_me = false; 
718          if (job->DuplicateJobProximity > 0) {
719             utime_t now = (utime_t)time(NULL);
720             if ((now - djcr->start_time) > job->DuplicateJobProximity) {
721                continue;               /* not really a duplicate */
722             }
723          }
724          if (job->CancelLowerLevelDuplicates &&                         
725              djcr->getJobType() == 'B' && jcr->getJobType() == 'B') {
726             switch (jcr->getJobLevel()) {
727             case L_FULL:
728                if (djcr->getJobLevel() == L_DIFFERENTIAL ||
729                    djcr->getJobLevel() == L_INCREMENTAL) {
730                   cancel_dup = true;
731                }
732                break;
733             case L_DIFFERENTIAL:
734                if (djcr->getJobLevel() == L_INCREMENTAL) {
735                   cancel_dup = true;
736                }
737                if (djcr->getJobLevel() == L_FULL) {
738                   cancel_me = true;
739                }
740                break;
741             case L_INCREMENTAL:
742                if (djcr->getJobLevel() == L_FULL ||
743                    djcr->getJobLevel() == L_DIFFERENTIAL) {
744                   cancel_me = true;
745                }
746             }
747             /*
748              * cancel_dup will be done below   
749              */
750             if (cancel_me) {
751               /* Zap current job */
752               Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"),
753                  djcr->JobId);
754               break;     /* get out of foreach_jcr */
755             }
756          }   
757          /* Cancel one of the two jobs (me or dup) */
758          /* If CancelQueuedDuplicates is set do so only if job is queued */
759          if (job->CancelQueuedDuplicates) {
760              switch (djcr->JobStatus) {
761              case JS_Created:
762              case JS_WaitJobRes:
763              case JS_WaitClientRes:
764              case JS_WaitStoreRes:
765              case JS_WaitPriority:
766              case JS_WaitMaxJobs:
767              case JS_WaitStartTime:
768                 cancel_dup = true;  /* cancel queued duplicate */
769                 break;
770              default:
771                 break;
772              }
773          }
774          if (cancel_dup || job->CancelRunningDuplicates) {
775             /* Zap the duplicated job djcr */
776             UAContext *ua = new_ua_context(jcr);
777             Jmsg(jcr, M_INFO, 0, _("Cancelling duplicate JobId=%d.\n"), djcr->JobId);
778             cancel_job(ua, djcr);
779             bmicrosleep(0, 500000);
780             cancel_job(ua, djcr);
781             free_ua_context(ua);
782             Dmsg2(800, "Cancel dup %p JobId=%d\n", djcr, djcr->JobId);
783          } else {
784             /* Zap current job */
785             Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"),
786                djcr->JobId);
787             Dmsg2(800, "Cancel me %p JobId=%d\n", jcr, jcr->JobId);
788          }
789          Dmsg4(800, "curJobId=%d use_cnt=%d dupJobId=%d use_cnt=%d\n",
790                jcr->JobId, jcr->use_count(), djcr->JobId, djcr->use_count());
791          break;                 /* did our work, get out of foreach loop */
792       }
793    }
794    endeach_jcr(djcr);
795
796    return true;   
797 }
798
799 void apply_pool_overrides(JCR *jcr)
800 {
801    bool pool_override = false;
802
803    if (jcr->run_pool_override) {
804       pm_strcpy(jcr->pool_source, _("Run pool override"));
805    }
806    /*
807     * Apply any level related Pool selections
808     */
809    switch (jcr->getJobLevel()) {
810    case L_FULL:
811       if (jcr->full_pool) {
812          jcr->pool = jcr->full_pool;
813          pool_override = true;
814          if (jcr->run_full_pool_override) {
815             pm_strcpy(jcr->pool_source, _("Run FullPool override"));
816          } else {
817             pm_strcpy(jcr->pool_source, _("Job FullPool override"));
818          }
819       }
820       break;
821    case L_INCREMENTAL:
822       if (jcr->inc_pool) {
823          jcr->pool = jcr->inc_pool;
824          pool_override = true;
825          if (jcr->run_inc_pool_override) {
826             pm_strcpy(jcr->pool_source, _("Run IncPool override"));
827          } else {
828             pm_strcpy(jcr->pool_source, _("Job IncPool override"));
829          }
830       }
831       break;
832    case L_DIFFERENTIAL:
833       if (jcr->diff_pool) {
834          jcr->pool = jcr->diff_pool;
835          pool_override = true;
836          if (jcr->run_diff_pool_override) {
837             pm_strcpy(jcr->pool_source, _("Run DiffPool override"));
838          } else {
839             pm_strcpy(jcr->pool_source, _("Job DiffPool override"));
840          }
841       }
842       break;
843    }
844    /* Update catalog if pool overridden */
845    if (pool_override && jcr->pool->catalog) {
846       jcr->catalog = jcr->pool->catalog;
847       pm_strcpy(jcr->catalog_source, _("Pool resource"));
848    }
849 }
850
851
852 /*
853  * Get or create a Client record for this Job
854  */
855 bool get_or_create_client_record(JCR *jcr)
856 {
857    CLIENT_DBR cr;
858
859    memset(&cr, 0, sizeof(cr));
860    bstrncpy(cr.Name, jcr->client->hdr.name, sizeof(cr.Name));
861    cr.AutoPrune = jcr->client->AutoPrune;
862    cr.FileRetention = jcr->client->FileRetention;
863    cr.JobRetention = jcr->client->JobRetention;
864    if (!jcr->client_name) {
865       jcr->client_name = get_pool_memory(PM_NAME);
866    }
867    pm_strcpy(jcr->client_name, jcr->client->hdr.name);
868    if (!db_create_client_record(jcr, jcr->db, &cr)) {
869       Jmsg(jcr, M_FATAL, 0, _("Could not create Client record. ERR=%s\n"),
870          db_strerror(jcr->db));
871       return false;
872    }
873    jcr->jr.ClientId = cr.ClientId;
874    if (cr.Uname[0]) {
875       if (!jcr->client_uname) {
876          jcr->client_uname = get_pool_memory(PM_NAME);
877       }
878       pm_strcpy(jcr->client_uname, cr.Uname);
879    }
880    Dmsg2(100, "Created Client %s record %d\n", jcr->client->hdr.name,
881       jcr->jr.ClientId);
882    return true;
883 }
884
885 bool get_or_create_fileset_record(JCR *jcr)
886 {
887    FILESET_DBR fsr;
888    /*
889     * Get or Create FileSet record
890     */
891    memset(&fsr, 0, sizeof(FILESET_DBR));
892    bstrncpy(fsr.FileSet, jcr->fileset->hdr.name, sizeof(fsr.FileSet));
893    if (jcr->fileset->have_MD5) {
894       struct MD5Context md5c;
895       unsigned char digest[MD5HashSize];
896       memcpy(&md5c, &jcr->fileset->md5c, sizeof(md5c));
897       MD5Final(digest, &md5c);
898       /*
899        * Keep the flag (last arg) set to false otherwise old FileSets will
900        * get new MD5 sums and the user will get Full backups on everything
901        */
902       bin_to_base64(fsr.MD5, sizeof(fsr.MD5), (char *)digest, MD5HashSize, false);
903       bstrncpy(jcr->fileset->MD5, fsr.MD5, sizeof(jcr->fileset->MD5));
904    } else {
905       Jmsg(jcr, M_WARNING, 0, _("FileSet MD5 digest not found.\n"));
906    }
907    if (!jcr->fileset->ignore_fs_changes ||
908        !db_get_fileset_record(jcr, jcr->db, &fsr)) {
909       if (!db_create_fileset_record(jcr, jcr->db, &fsr)) {
910          Jmsg(jcr, M_ERROR, 0, _("Could not create FileSet \"%s\" record. ERR=%s\n"),
911             fsr.FileSet, db_strerror(jcr->db));
912          return false;
913       }
914    }
915    jcr->jr.FileSetId = fsr.FileSetId;
916    bstrncpy(jcr->FSCreateTime, fsr.cCreateTime, sizeof(jcr->FSCreateTime));
917    Dmsg2(119, "Created FileSet %s record %u\n", jcr->fileset->hdr.name,
918       jcr->jr.FileSetId);
919    return true;
920 }
921
922 void init_jcr_job_record(JCR *jcr)
923 {
924    jcr->jr.SchedTime = jcr->sched_time;
925    jcr->jr.StartTime = jcr->start_time;
926    jcr->jr.EndTime = 0;               /* perhaps rescheduled, clear it */
927    jcr->jr.JobType = jcr->getJobType();
928    jcr->jr.JobLevel = jcr->getJobLevel();
929    jcr->jr.JobStatus = jcr->JobStatus;
930    jcr->jr.JobId = jcr->JobId;
931    bstrncpy(jcr->jr.Name, jcr->job->name(), sizeof(jcr->jr.Name));
932    bstrncpy(jcr->jr.Job, jcr->Job, sizeof(jcr->jr.Job));
933 }
934
935 /*
936  * Write status and such in DB
937  */
938 void update_job_end_record(JCR *jcr)
939 {
940    jcr->jr.EndTime = time(NULL);
941    jcr->end_time = jcr->jr.EndTime;
942    jcr->jr.JobId = jcr->JobId;
943    jcr->jr.JobStatus = jcr->JobStatus;
944    jcr->jr.JobFiles = jcr->JobFiles;
945    jcr->jr.JobBytes = jcr->JobBytes;
946    jcr->jr.ReadBytes = jcr->ReadBytes;
947    jcr->jr.VolSessionId = jcr->VolSessionId;
948    jcr->jr.VolSessionTime = jcr->VolSessionTime;
949    jcr->jr.JobErrors = jcr->JobErrors;
950    jcr->jr.HasBase = jcr->HasBase;
951    if (!db_update_job_end_record(jcr, jcr->db, &jcr->jr)) {
952       Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"),
953          db_strerror(jcr->db));
954    }
955 }
956
957 /*
958  * Takes base_name and appends (unique) current
959  *   date and time to form unique job name.
960  *
961  *  Note, the seconds are actually a sequence number. This
962  *   permits us to start a maximum fo 59 unique jobs a second, which
963  *   should be sufficient.
964  *
965  *  Returns: unique job name in jcr->Job
966  *    date/time in jcr->start_time
967  */
968 void create_unique_job_name(JCR *jcr, const char *base_name)
969 {
970    /* Job start mutex */
971    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
972    static time_t last_start_time = 0;
973    static int seq = 0;
974    time_t now = time(NULL);
975    struct tm tm;
976    char dt[MAX_TIME_LENGTH];
977    char name[MAX_NAME_LENGTH];
978    char *p;
979    int len;
980
981    /* Guarantee unique start time -- maximum one per second, and
982     * thus unique Job Name
983     */
984    P(mutex);                          /* lock creation of jobs */
985    seq++;
986    if (seq > 59) {                    /* wrap as if it is seconds */
987       seq = 0;
988       while (now == last_start_time) {
989          bmicrosleep(0, 500000);
990          now = time(NULL);
991       }
992    }
993    last_start_time = now;
994    V(mutex);                          /* allow creation of jobs */
995    jcr->start_time = now;
996    /* Form Unique JobName */
997    (void)localtime_r(&now, &tm);
998    /* Use only characters that are permitted in Windows filenames */
999    strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm);
1000    len = strlen(dt) + 5;   /* dt + .%02d EOS */
1001    bstrncpy(name, base_name, sizeof(name));
1002    name[sizeof(name)-len] = 0;          /* truncate if too long */
1003    bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s_%02d", name, dt, seq); /* add date & time */
1004    /* Convert spaces into underscores */
1005    for (p=jcr->Job; *p; p++) {
1006       if (*p == ' ') {
1007          *p = '_';
1008       }
1009    }
1010    Dmsg2(100, "JobId=%u created Job=%s\n", jcr->JobId, jcr->Job);
1011 }
1012
1013 /* Called directly from job rescheduling */
1014 void dird_free_jcr_pointers(JCR *jcr)
1015 {
1016    if (jcr->sd_auth_key) {
1017       free(jcr->sd_auth_key);
1018       jcr->sd_auth_key = NULL;
1019    }
1020    if (jcr->where) {
1021       free(jcr->where);
1022       jcr->where = NULL;
1023    }
1024    if (jcr->file_bsock) {
1025       Dmsg0(200, "Close File bsock\n");
1026       bnet_close(jcr->file_bsock);
1027       jcr->file_bsock = NULL;
1028    }
1029    if (jcr->store_bsock) {
1030       Dmsg0(200, "Close Store bsock\n");
1031       bnet_close(jcr->store_bsock);
1032       jcr->store_bsock = NULL;
1033    }
1034    if (jcr->fname) {
1035       Dmsg0(200, "Free JCR fname\n");
1036       free_pool_memory(jcr->fname);
1037       jcr->fname = NULL;
1038    }
1039    if (jcr->RestoreBootstrap) {
1040       free(jcr->RestoreBootstrap);
1041       jcr->RestoreBootstrap = NULL;
1042    }
1043    if (jcr->client_uname) {
1044       free_pool_memory(jcr->client_uname);
1045       jcr->client_uname = NULL;
1046    }
1047    if (jcr->attr) {
1048       free_pool_memory(jcr->attr);
1049       jcr->attr = NULL;
1050    }
1051    if (jcr->ar) {
1052       free(jcr->ar);
1053       jcr->ar = NULL;
1054    }
1055 }
1056
1057 /*
1058  * Free the Job Control Record if no one is still using it.
1059  *  Called from main free_jcr() routine in src/lib/jcr.c so
1060  *  that we can do our Director specific cleanup of the jcr.
1061  */
1062 void dird_free_jcr(JCR *jcr)
1063 {
1064    Dmsg0(200, "Start dird free_jcr\n");
1065
1066    dird_free_jcr_pointers(jcr);
1067    if (jcr->term_wait_inited) {
1068       pthread_cond_destroy(&jcr->term_wait);
1069       jcr->term_wait_inited = false;
1070    }
1071    if (jcr->db_batch) {
1072       db_close_database(jcr, jcr->db_batch);
1073       jcr->db_batch = NULL;
1074       jcr->batch_started = false;
1075    }
1076    if (jcr->db) {
1077       db_close_database(jcr, jcr->db);
1078       jcr->db = NULL;
1079    }
1080    if (jcr->stime) {
1081       Dmsg0(200, "Free JCR stime\n");
1082       free_pool_memory(jcr->stime);
1083       jcr->stime = NULL;
1084    }
1085    if (jcr->fname) {
1086       Dmsg0(200, "Free JCR fname\n");
1087       free_pool_memory(jcr->fname);
1088       jcr->fname = NULL;
1089    }
1090    if (jcr->pool_source) {
1091       free_pool_memory(jcr->pool_source);
1092       jcr->pool_source = NULL;
1093    }
1094    if (jcr->catalog_source) {
1095       free_pool_memory(jcr->catalog_source);
1096       jcr->catalog_source = NULL;
1097    }
1098    if (jcr->rpool_source) {
1099       free_pool_memory(jcr->rpool_source);
1100       jcr->rpool_source = NULL;
1101    }
1102    if (jcr->wstore_source) {
1103       free_pool_memory(jcr->wstore_source);
1104       jcr->wstore_source = NULL;
1105    }
1106    if (jcr->rstore_source) {
1107       free_pool_memory(jcr->rstore_source);
1108       jcr->rstore_source = NULL;
1109    }
1110
1111    /* Delete lists setup to hold storage pointers */
1112    free_rwstorage(jcr);
1113
1114    jcr->job_end_push.destroy();
1115
1116    if (jcr->JobId != 0)
1117       write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
1118
1119    free_plugins(jcr);                 /* release instantiated plugins */
1120
1121    Dmsg0(200, "End dird free_jcr\n");
1122 }
1123
1124 /* 
1125  * The Job storage definition must be either in the Job record
1126  *  or in the Pool record.  The Pool record overrides the Job 
1127  *  record.
1128  */
1129 void get_job_storage(USTORE *store, JOB *job, RUN *run) 
1130 {
1131    if (run && run->pool && run->pool->storage) {
1132       store->store = (STORE *)run->pool->storage->first();
1133       pm_strcpy(store->store_source, _("Run pool override"));
1134       return;
1135    }
1136    if (run && run->storage) {
1137       store->store = run->storage;
1138       pm_strcpy(store->store_source, _("Run storage override"));
1139       return;
1140    }
1141    if (job->pool->storage) {
1142       store->store = (STORE *)job->pool->storage->first();
1143       pm_strcpy(store->store_source, _("Pool resource"));
1144    } else {
1145       store->store = (STORE *)job->storage->first();
1146       pm_strcpy(store->store_source, _("Job resource"));
1147    }
1148 }
1149
1150 /*
1151  * Set some defaults in the JCR necessary to
1152  * run. These items are pulled from the job
1153  * definition as defaults, but can be overridden
1154  * later either by the Run record in the Schedule resource,
1155  * or by the Console program.
1156  */
1157 void set_jcr_defaults(JCR *jcr, JOB *job)
1158 {
1159    jcr->job = job;
1160    jcr->set_JobType(job->JobType);
1161    jcr->JobStatus = JS_Created;
1162
1163    switch (jcr->getJobType()) {
1164    case JT_ADMIN:
1165       jcr->set_JobLevel(L_NONE);
1166       break;
1167    default:
1168       jcr->set_JobLevel(job->JobLevel);
1169       break;
1170    }
1171
1172    if (!jcr->fname) {
1173       jcr->fname = get_pool_memory(PM_FNAME);
1174    }
1175    if (!jcr->pool_source) {
1176       jcr->pool_source = get_pool_memory(PM_MESSAGE);
1177       pm_strcpy(jcr->pool_source, _("unknown source"));
1178    }
1179    if (!jcr->catalog_source) {
1180       jcr->catalog_source = get_pool_memory(PM_MESSAGE);
1181       pm_strcpy(jcr->catalog_source, _("unknown source"));
1182    }
1183
1184    jcr->JobPriority = job->Priority;
1185    /* Copy storage definitions -- deleted in dir_free_jcr above */
1186    if (job->storage) {
1187       copy_rwstorage(jcr, job->storage, _("Job resource"));
1188    } else {
1189       copy_rwstorage(jcr, job->pool->storage, _("Pool resource"));
1190    }
1191    jcr->client = job->client;
1192    if (!jcr->client_name) {
1193       jcr->client_name = get_pool_memory(PM_NAME);
1194    }
1195    pm_strcpy(jcr->client_name, jcr->client->hdr.name);
1196    pm_strcpy(jcr->pool_source, _("Job resource"));
1197    jcr->pool = job->pool;
1198    jcr->full_pool = job->full_pool;
1199    jcr->inc_pool = job->inc_pool;
1200    jcr->diff_pool = job->diff_pool;
1201    if (job->pool->catalog) {
1202       jcr->catalog = job->pool->catalog;
1203       pm_strcpy(jcr->catalog_source, _("Pool resource"));
1204    } else {
1205       jcr->catalog = job->client->catalog;
1206       pm_strcpy(jcr->catalog_source, _("Client resource"));
1207    }
1208    jcr->fileset = job->fileset;
1209    jcr->messages = job->messages;
1210    jcr->spool_data = job->spool_data;
1211    jcr->spool_size = job->spool_size;
1212    jcr->write_part_after_job = job->write_part_after_job;
1213    jcr->accurate = job->accurate;
1214    if (jcr->RestoreBootstrap) {
1215       free(jcr->RestoreBootstrap);
1216       jcr->RestoreBootstrap = NULL;
1217    }
1218    /* This can be overridden by Console program */
1219    if (job->RestoreBootstrap) {
1220       jcr->RestoreBootstrap = bstrdup(job->RestoreBootstrap);
1221    }
1222    /* This can be overridden by Console program */
1223    jcr->verify_job = job->verify_job;
1224    /* If no default level given, set one */
1225    if (jcr->getJobLevel() == 0) {
1226       switch (jcr->getJobType()) {
1227       case JT_VERIFY:
1228          jcr->set_JobLevel(L_VERIFY_CATALOG);
1229          break;
1230       case JT_BACKUP:
1231          jcr->set_JobLevel(L_INCREMENTAL);
1232          break;
1233       case JT_RESTORE:
1234       case JT_ADMIN:
1235          jcr->set_JobLevel(L_NONE);
1236          break;
1237       default:
1238          jcr->set_JobLevel(L_FULL);
1239          break;
1240       }
1241    }
1242 }
1243
1244 /* 
1245  * Copy the storage definitions from an alist to the JCR
1246  */
1247 void copy_rwstorage(JCR *jcr, alist *storage, const char *where)
1248 {
1249    if (jcr->JobReads()) {
1250       copy_rstorage(jcr, storage, where);
1251    }
1252    copy_wstorage(jcr, storage, where);
1253 }
1254
1255
1256 /* Set storage override.  Releases any previous storage definition */
1257 void set_rwstorage(JCR *jcr, USTORE *store)
1258 {
1259    if (!store) {
1260       Jmsg(jcr, M_FATAL, 0, _("No storage specified.\n"));
1261       return;
1262    }
1263    if (jcr->JobReads()) {
1264       set_rstorage(jcr, store);
1265    }
1266    set_wstorage(jcr, store);
1267 }
1268
1269 void free_rwstorage(JCR *jcr)
1270 {
1271    free_rstorage(jcr);
1272    free_wstorage(jcr);
1273 }
1274
1275 /* 
1276  * Copy the storage definitions from an alist to the JCR
1277  */
1278 void copy_rstorage(JCR *jcr, alist *storage, const char *where)
1279 {
1280    if (storage) {
1281       STORE *st;
1282       if (jcr->rstorage) {
1283          delete jcr->rstorage;
1284       }
1285       jcr->rstorage = New(alist(10, not_owned_by_alist));
1286       foreach_alist(st, storage) {
1287          jcr->rstorage->append(st);
1288       }
1289       if (!jcr->rstore_source) {
1290          jcr->rstore_source = get_pool_memory(PM_MESSAGE);
1291       }
1292       pm_strcpy(jcr->rstore_source, where);
1293       if (jcr->rstorage) {
1294          jcr->rstore = (STORE *)jcr->rstorage->first();
1295       }
1296    }
1297 }
1298
1299
1300 /* Set storage override.  Remove all previous storage */
1301 void set_rstorage(JCR *jcr, USTORE *store)
1302 {
1303    STORE *storage;
1304
1305    if (!store->store) {
1306       return;
1307    }
1308    if (jcr->rstorage) {
1309       free_rstorage(jcr);
1310    }
1311    if (!jcr->rstorage) {
1312       jcr->rstorage = New(alist(10, not_owned_by_alist));
1313    }
1314    jcr->rstore = store->store;
1315    if (!jcr->rstore_source) {
1316       jcr->rstore_source = get_pool_memory(PM_MESSAGE);
1317    }
1318    pm_strcpy(jcr->rstore_source, store->store_source);
1319    foreach_alist(storage, jcr->rstorage) {
1320       if (store->store == storage) {
1321          return;
1322       }
1323    }
1324    /* Store not in list, so add it */
1325    jcr->rstorage->prepend(store->store);
1326 }
1327
1328 void free_rstorage(JCR *jcr)
1329 {
1330    if (jcr->rstorage) {
1331       delete jcr->rstorage;
1332       jcr->rstorage = NULL;
1333    }
1334    jcr->rstore = NULL;
1335 }
1336
1337 /* 
1338  * Copy the storage definitions from an alist to the JCR
1339  */
1340 void copy_wstorage(JCR *jcr, alist *storage, const char *where)
1341 {
1342    if (storage) {
1343       STORE *st;
1344       if (jcr->wstorage) {
1345          delete jcr->wstorage;
1346       }
1347       jcr->wstorage = New(alist(10, not_owned_by_alist));
1348       foreach_alist(st, storage) {
1349          Dmsg1(100, "wstorage=%s\n", st->name());
1350          jcr->wstorage->append(st);
1351       }
1352       if (!jcr->wstore_source) {
1353          jcr->wstore_source = get_pool_memory(PM_MESSAGE);
1354       }
1355       pm_strcpy(jcr->wstore_source, where);
1356       if (jcr->wstorage) {
1357          jcr->wstore = (STORE *)jcr->wstorage->first();
1358          Dmsg2(100, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
1359       }
1360    }
1361 }
1362
1363
1364 /* Set storage override. Remove all previous storage */
1365 void set_wstorage(JCR *jcr, USTORE *store)
1366 {
1367    STORE *storage;
1368
1369    if (!store->store) {
1370       return;
1371    }
1372    if (jcr->wstorage) {
1373       free_wstorage(jcr);
1374    }
1375    if (!jcr->wstorage) {
1376       jcr->wstorage = New(alist(10, not_owned_by_alist));
1377    }
1378    jcr->wstore = store->store;
1379    if (!jcr->wstore_source) {
1380       jcr->wstore_source = get_pool_memory(PM_MESSAGE);
1381    }
1382    pm_strcpy(jcr->wstore_source, store->store_source);
1383    Dmsg2(50, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
1384    foreach_alist(storage, jcr->wstorage) {
1385       if (store->store == storage) {
1386          return;
1387       }
1388    }
1389    /* Store not in list, so add it */
1390    jcr->wstorage->prepend(store->store);
1391 }
1392
1393 void free_wstorage(JCR *jcr)
1394 {
1395    if (jcr->wstorage) {
1396       delete jcr->wstorage;
1397       jcr->wstorage = NULL;
1398    }
1399    jcr->wstore = NULL;
1400 }
1401
1402 char *job_code_callback_clones(JCR *jcr, const char* param) 
1403 {
1404    if (param[0] == 'p') {
1405       return jcr->pool->name();
1406    }
1407    return NULL;
1408 }
1409
1410 void create_clones(JCR *jcr)
1411 {
1412    /*
1413     * Fire off any clone jobs (run directives)
1414     */
1415    Dmsg2(900, "cloned=%d run_cmds=%p\n", jcr->cloned, jcr->job->run_cmds);
1416    if (!jcr->cloned && jcr->job->run_cmds) {
1417       char *runcmd;
1418       JOB *job = jcr->job;
1419       POOLMEM *cmd = get_pool_memory(PM_FNAME);
1420       UAContext *ua = new_ua_context(jcr);
1421       ua->batch = true;
1422       foreach_alist(runcmd, job->run_cmds) {
1423          cmd = edit_job_codes(jcr, cmd, runcmd, "", job_code_callback_clones);
1424          Mmsg(ua->cmd, "run %s cloned=yes", cmd);
1425          Dmsg1(900, "=============== Clone cmd=%s\n", ua->cmd);
1426          parse_ua_args(ua);                 /* parse command */
1427          int stat = run_cmd(ua, ua->cmd);
1428          if (stat == 0) {
1429             Jmsg(jcr, M_ERROR, 0, _("Could not start clone job: \"%s\".\n"),
1430                  ua->cmd);
1431          } else {
1432             Jmsg(jcr, M_INFO, 0, _("Clone JobId %d started.\n"), stat);
1433          }
1434       }
1435       free_ua_context(ua);
1436       free_pool_memory(cmd);
1437    }
1438 }
1439
1440 /*
1441  * Given: a JobId in jcr->previous_jr.JobId,
1442  *  this subroutine writes a bsr file to restore that job.
1443  * Returns: -1 on error
1444  *           number of files if OK
1445  */
1446 int create_restore_bootstrap_file(JCR *jcr)
1447 {
1448    RESTORE_CTX rx;
1449    UAContext *ua;
1450    int files;
1451
1452    memset(&rx, 0, sizeof(rx));
1453    rx.bsr = new_bsr();
1454    rx.JobIds = (char *)"";                       
1455    rx.bsr->JobId = jcr->previous_jr.JobId;
1456    ua = new_ua_context(jcr);
1457    if (!complete_bsr(ua, rx.bsr)) {
1458       files = -1;
1459       goto bail_out;
1460    }
1461    rx.bsr->fi = new_findex();
1462    rx.bsr->fi->findex = 1;
1463    rx.bsr->fi->findex2 = jcr->previous_jr.JobFiles;
1464    jcr->ExpectedFiles = write_bsr_file(ua, rx);
1465    if (jcr->ExpectedFiles == 0) {
1466       files = 0;
1467       goto bail_out;
1468    }
1469    free_ua_context(ua);
1470    free_bsr(rx.bsr);
1471    jcr->needs_sd = true;
1472    return jcr->ExpectedFiles;
1473
1474 bail_out:
1475    free_ua_context(ua);
1476    free_bsr(rx.bsr);
1477    return files;
1478 }
1479
1480 /* TODO: redirect command ouput to job log */
1481 bool run_console_command(JCR *jcr, const char *cmd)
1482 {
1483    UAContext *ua;
1484    bool ok;
1485    JCR *ljcr = new_control_jcr("-RunScript-", JT_CONSOLE);
1486    ua = new_ua_context(ljcr);
1487    /* run from runscript and check if commands are autorized */
1488    ua->runscript = true;
1489    Mmsg(ua->cmd, "%s", cmd);
1490    Dmsg1(100, "Console command: %s\n", ua->cmd);
1491    parse_ua_args(ua);
1492    ok= do_a_command(ua);
1493    free_ua_context(ua);
1494    free_jcr(ljcr);
1495    return ok;
1496 }