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