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