]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/job.c
ebl Try to fix bug on RunScript {} resource parsing
[bacula/bacula] / bacula / src / dird / job.c
1 /*
2  *
3  *   Bacula Director Job processing routines
4  *
5  *     Kern Sibbald, October MM
6  *
7  *    Version $Id$
8  */
9 /*
10    Copyright (C) 2000-2006 Kern Sibbald
11
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License
14    version 2 as amended with additional clauses defined in the
15    file LICENSE in the main source directory.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
20    the file LICENSE for additional details.
21
22  */
23
24 #include "bacula.h"
25 #include "dird.h"
26
27 /* Forward referenced subroutines */
28 static void *job_thread(void *arg);
29 static void job_monitor_watchdog(watchdog_t *self);
30 static void job_monitor_destructor(watchdog_t *self);
31 static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr);
32 static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr);
33
34 /* Imported subroutines */
35 extern void term_scheduler();
36 extern void term_ua_server();
37
38 /* Imported variables */
39
40 jobq_t job_queue;
41
42 void init_job_server(int max_workers)
43 {
44    int stat;
45    watchdog_t *wd;
46
47    if ((stat = jobq_init(&job_queue, max_workers, job_thread)) != 0) {
48       berrno be;
49       Emsg1(M_ABORT, 0, _("Could not init job queue: ERR=%s\n"), be.strerror(stat));
50    }
51    wd = new_watchdog();
52    wd->callback = job_monitor_watchdog;
53    wd->destructor = job_monitor_destructor;
54    wd->one_shot = false;
55    wd->interval = 60;
56    wd->data = new_control_jcr("*JobMonitor*", JT_SYSTEM);
57    register_watchdog(wd);
58 }
59
60 void term_job_server()
61 {
62    jobq_destroy(&job_queue);          /* ignore any errors */
63 }
64
65 /*
66  * Run a job -- typically called by the scheduler, but may also
67  *              be called by the UA (Console program).
68  *
69  *  Returns: 0 on failure
70  *           JobId on success
71  *
72  */
73 JobId_t run_job(JCR *jcr)
74 {
75    int stat;
76    if (setup_job(jcr)) {
77       /* Queue the job to be run */
78       if ((stat = jobq_add(&job_queue, jcr)) != 0) {
79          berrno be;
80          Jmsg(jcr, M_FATAL, 0, _("Could not add job queue: ERR=%s\n"), be.strerror(stat));
81          return 0;
82       }
83       return jcr->JobId;
84    }
85    return 0;
86 }            
87
88 bool setup_job(JCR *jcr) 
89 {
90    int errstat;
91
92    jcr->lock();
93    sm_check(__FILE__, __LINE__, true);
94    init_msg(jcr, jcr->messages);
95
96    /* Initialize termination condition variable */
97    if ((errstat = pthread_cond_init(&jcr->term_wait, NULL)) != 0) {
98       berrno be;
99       Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.strerror(errstat));
100       goto bail_out;
101    }
102    jcr->term_wait_inited = true;
103
104    create_unique_job_name(jcr, jcr->job->hdr.name);
105    set_jcr_job_status(jcr, JS_Created);
106    jcr->unlock();
107
108    /*
109     * Open database
110     */
111    Dmsg0(50, "Open database\n");
112    jcr->db=db_init_database(jcr, jcr->catalog->db_name, jcr->catalog->db_user,
113                             jcr->catalog->db_password, jcr->catalog->db_address,
114                             jcr->catalog->db_port, jcr->catalog->db_socket,
115                             jcr->catalog->mult_db_connections);
116    if (!jcr->db || !db_open_database(jcr, jcr->db)) {
117       Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"),
118                  jcr->catalog->db_name);
119       if (jcr->db) {
120          Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
121       }
122       goto bail_out;
123    }
124    Dmsg0(50, "DB opened\n");
125
126    if (!jcr->fname) {
127       jcr->fname = get_pool_memory(PM_FNAME);
128    }
129    if (!jcr->pool_source) {
130       jcr->pool_source = get_pool_memory(PM_MESSAGE);
131       pm_strcpy(jcr->pool_source, _("unknown source"));
132    }
133    if (!jcr->storage_source) {
134       jcr->storage_source = get_pool_memory(PM_MESSAGE);
135       pm_strcpy(jcr->storage_source, _("unknown source"));
136    }
137
138    /*
139     * Create Job record
140     */
141    init_jcr_job_record(jcr);
142    if (!db_create_job_record(jcr, jcr->db, &jcr->jr)) {
143       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
144       goto bail_out;
145    }
146    jcr->JobId = jcr->jr.JobId;
147    Dmsg4(100, "Created job record JobId=%d Name=%s Type=%c Level=%c\n",
148        jcr->JobId, jcr->Job, jcr->jr.JobType, jcr->jr.JobLevel);
149
150    generate_daemon_event(jcr, "JobStart");
151
152    if (!get_or_create_client_record(jcr)) {
153       goto bail_out;
154    }
155
156    if (job_canceled(jcr)) {
157       goto bail_out;
158    }
159
160
161    /*
162     * Now, do pre-run stuff, like setting job level (Inc/diff, ...)
163     *  this allows us to setup a proper job start record for restarting
164     *  in case of later errors.
165     */
166    switch (jcr->JobType) {
167    case JT_BACKUP:
168       if (!do_backup_init(jcr)) {
169          backup_cleanup(jcr, JS_ErrorTerminated);
170       }
171       break;
172    case JT_VERIFY:
173       if (!do_verify_init(jcr)) {
174          verify_cleanup(jcr, JS_ErrorTerminated);
175       }
176       break;
177    case JT_RESTORE:
178       if (!do_restore_init(jcr)) {
179          restore_cleanup(jcr, JS_ErrorTerminated);
180       }
181       break;
182    case JT_ADMIN:
183       if (!do_admin_init(jcr)) {
184          admin_cleanup(jcr, JS_ErrorTerminated);
185       }
186       break;
187    case JT_MIGRATE:
188       if (!do_migration_init(jcr)) { 
189          migration_cleanup(jcr, JS_ErrorTerminated);
190       }
191       break;
192    default:
193       Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->JobType);
194       set_jcr_job_status(jcr, JS_ErrorTerminated);
195       break;
196    }
197
198    generate_job_event(jcr, "JobInit");
199
200    Dmsg0(200, "Add jrc to work queue\n");
201    return true;
202
203 bail_out:
204    return false;
205 }
206
207
208 /*
209  * This is the engine called by jobq.c:jobq_add() when we were pulled
210  *  from the work queue.
211  *  At this point, we are running in our own thread and all
212  *    necessary resources are allocated -- see jobq.c
213  */
214 static void *job_thread(void *arg)
215 {
216    JCR *jcr = (JCR *)arg;
217
218    jcr->my_thread_id = pthread_self();
219    pthread_detach(jcr->my_thread_id);
220    sm_check(__FILE__, __LINE__, true);
221
222    Dmsg0(200, "=====Start Job=========\n");
223    set_jcr_job_status(jcr, JS_Running);   /* this will be set only if no error */
224    jcr->start_time = time(NULL);      /* set the real start time */
225    jcr->jr.StartTime = jcr->start_time;
226
227    if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
228        (utime_t)(jcr->start_time - jcr->sched_time)) {
229       Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
230       set_jcr_job_status(jcr, JS_Canceled);
231    }
232
233    /* TODO : check if it is used somewhere */
234    if (jcr->job->RunScripts == NULL) {
235       Dmsg0(200, "Warning, job->RunScripts is empty\n");
236       jcr->job->RunScripts = New(alist(10, not_owned_by_alist));
237    }
238
239    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
240       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
241    }
242
243    /* Run any script BeforeJob on dird */
244    run_scripts(jcr, jcr->job->RunScripts, "BeforeJob");
245
246    if (job_canceled(jcr)) {
247       update_job_end_record(jcr);
248
249    } else {
250       /*
251        * We re-update the job start record so that the start
252        *  time is set after the run before job.  This avoids
253        *  that any files created by the run before job will
254        *  be saved twice.  They will be backed up in the current
255        *  job, but not in the next one unless they are changed.
256        *  Without this, they will be backed up in this job and
257        *  in the next job run because in that case, their date
258        *   is after the start of this run.
259        */
260       jcr->start_time = time(NULL);
261       jcr->jr.StartTime = jcr->start_time;
262       if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
263          Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
264       }
265       generate_job_event(jcr, "JobRun");
266
267       switch (jcr->JobType) {
268       case JT_BACKUP:
269          if (do_backup(jcr)) {
270             do_autoprune(jcr);
271          } else {
272             backup_cleanup(jcr, JS_ErrorTerminated);
273          }
274          break;
275       case JT_VERIFY:
276          if (do_verify(jcr)) {
277             do_autoprune(jcr);
278          } else {
279             verify_cleanup(jcr, JS_ErrorTerminated);
280          }
281          break;
282       case JT_RESTORE:
283          if (do_restore(jcr)) {
284             do_autoprune(jcr);
285          } else {
286             restore_cleanup(jcr, JS_ErrorTerminated);
287          }
288          break;
289       case JT_ADMIN:
290          if (do_admin(jcr)) {
291             do_autoprune(jcr);
292          } else {
293             admin_cleanup(jcr, JS_ErrorTerminated);
294          }
295          break;
296       case JT_MIGRATE:
297       case JT_COPY:
298       case JT_ARCHIVE:
299          if (do_migration(jcr)) {
300             do_autoprune(jcr);
301          } else {
302             migration_cleanup(jcr, JS_ErrorTerminated);
303          }
304          break;
305       default:
306          Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->JobType);
307          break;
308       }
309
310       run_scripts(jcr, jcr->job->RunScripts, "AfterJob");
311
312       /* Send off any queued messages */
313       if (jcr->msg_queue && jcr->msg_queue->size() > 0) {
314          dequeue_messages(jcr);
315       }
316    }
317
318    generate_daemon_event(jcr, "JobEnd");
319    Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus);
320    sm_check(__FILE__, __LINE__, true);
321    return NULL;
322 }
323
324
325 /*
326  * Cancel a job -- typically called by the UA (Console program), but may also
327  *              be called by the job watchdog.
328  *
329  *  Returns: true  if cancel appears to be successful
330  *           false on failure. Message sent to ua->jcr.
331  */
332 bool cancel_job(UAContext *ua, JCR *jcr)
333 {
334    BSOCK *sd, *fd;
335
336    set_jcr_job_status(jcr, JS_Canceled);
337
338    switch (jcr->JobStatus) {
339    case JS_Created:
340    case JS_WaitJobRes:
341    case JS_WaitClientRes:
342    case JS_WaitStoreRes:
343    case JS_WaitPriority:
344    case JS_WaitMaxJobs:
345    case JS_WaitStartTime:
346       bsendmsg(ua, _("JobId %d, Job %s marked to be canceled.\n"),
347               jcr->JobId, jcr->Job);
348       jobq_remove(&job_queue, jcr); /* attempt to remove it from queue */
349       return true;
350
351    default:
352       /* Cancel File daemon */
353       if (jcr->file_bsock) {
354          ua->jcr->client = jcr->client;
355          if (!connect_to_file_daemon(ua->jcr, 10, FDConnectTimeout, 1)) {
356             bsendmsg(ua, _("Failed to connect to File daemon.\n"));
357             return 0;
358          }
359          Dmsg0(200, "Connected to file daemon\n");
360          fd = ua->jcr->file_bsock;
361          bnet_fsend(fd, "cancel Job=%s\n", jcr->Job);
362          while (bnet_recv(fd) >= 0) {
363             bsendmsg(ua, "%s", fd->msg);
364          }
365          bnet_sig(fd, BNET_TERMINATE);
366          bnet_close(fd);
367          ua->jcr->file_bsock = NULL;
368       }
369
370       /* Cancel Storage daemon */
371       if (jcr->store_bsock) {
372          if (!ua->jcr->wstorage) {
373             if (jcr->rstorage) {
374                copy_wstorage(ua->jcr, jcr->rstorage, _("Job resource")); 
375             } else {
376                copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource")); 
377             }
378          } else {
379             if (jcr->rstorage) {
380                set_wstorage(ua->jcr, jcr->rstore);
381             } else {
382                set_wstorage(ua->jcr, jcr->wstore);
383             }
384          }
385          if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
386             bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
387             return false;
388          }
389          Dmsg0(200, "Connected to storage daemon\n");
390          sd = ua->jcr->store_bsock;
391          bnet_fsend(sd, "cancel Job=%s\n", jcr->Job);
392          while (bnet_recv(sd) >= 0) {
393             bsendmsg(ua, "%s", sd->msg);
394          }
395          bnet_sig(sd, BNET_TERMINATE);
396          bnet_close(sd);
397          ua->jcr->store_bsock = NULL;
398       }
399    }
400
401    return true;
402 }
403
404
405 static void job_monitor_destructor(watchdog_t *self)
406 {
407    JCR *control_jcr = (JCR *)self->data;
408
409    free_jcr(control_jcr);
410 }
411
412 static void job_monitor_watchdog(watchdog_t *self)
413 {
414    JCR *control_jcr, *jcr;
415
416    control_jcr = (JCR *)self->data;
417
418    Dmsg1(800, "job_monitor_watchdog %p called\n", self);
419
420    foreach_jcr(jcr) {
421       bool cancel;
422
423       if (jcr->JobId == 0) {
424          Dmsg2(800, "Skipping JCR %p (%s) with JobId 0\n",
425                jcr, jcr->Job);
426          continue;
427       }
428
429       /* check MaxWaitTime */
430       cancel = job_check_maxwaittime(control_jcr, jcr);
431
432       /* check MaxRunTime */
433       cancel |= job_check_maxruntime(control_jcr, jcr);
434
435       if (cancel) {
436          Dmsg3(800, "Cancelling JCR %p jobid %d (%s)\n",
437                jcr, jcr->JobId, jcr->Job);
438
439          UAContext *ua = new_ua_context(jcr);
440          ua->jcr = control_jcr;
441          cancel_job(ua, jcr);
442          free_ua_context(ua);
443
444          Dmsg2(800, "Have cancelled JCR %p Job=%d\n", jcr, jcr->JobId);
445       }
446
447       /* Keep reference counts correct */
448    }
449    endeach_jcr(jcr);
450 }
451
452 /*
453  * Check if the maxwaittime has expired and it is possible
454  *  to cancel the job.
455  */
456 static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
457 {
458    bool cancel = false;
459    bool ok_to_cancel = false;
460    JOB *job = jcr->job;
461
462    if (job->MaxWaitTime == 0 && job->FullMaxWaitTime == 0 &&
463        job->IncMaxWaitTime == 0 && job->DiffMaxWaitTime == 0) {
464       return false;
465    } 
466    if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
467          (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
468       ok_to_cancel = true;
469    } else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxWaitTime != 0 &&
470          (watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
471       ok_to_cancel = true;
472    } else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxWaitTime != 0 &&
473          (watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
474       ok_to_cancel = true;
475    } else if (job->MaxWaitTime != 0 &&
476          (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
477       ok_to_cancel = true;
478    }
479    if (!ok_to_cancel) {
480       return false;
481    }
482    Dmsg3(800, "Job %d (%s): MaxWaitTime of %d seconds exceeded, "
483          "checking status\n",
484          jcr->JobId, jcr->Job, job->MaxWaitTime);
485    switch (jcr->JobStatus) {
486    case JS_Created:
487    case JS_Blocked:
488    case JS_WaitFD:
489    case JS_WaitSD:
490    case JS_WaitStoreRes:
491    case JS_WaitClientRes:
492    case JS_WaitJobRes:
493    case JS_WaitPriority:
494    case JS_WaitMaxJobs:
495    case JS_WaitStartTime:
496       cancel = true;
497       Dmsg0(200, "JCR blocked in #1\n");
498       break;
499    case JS_Running:
500       Dmsg0(800, "JCR running, checking SD status\n");
501       switch (jcr->SDJobStatus) {
502       case JS_WaitMount:
503       case JS_WaitMedia:
504       case JS_WaitFD:
505          cancel = true;
506          Dmsg0(800, "JCR blocked in #2\n");
507          break;
508       default:
509          Dmsg0(800, "JCR not blocked in #2\n");
510          break;
511       }
512       break;
513    case JS_Terminated:
514    case JS_ErrorTerminated:
515    case JS_Canceled:
516    case JS_FatalError:
517       Dmsg0(800, "JCR already dead in #3\n");
518       break;
519    default:
520       Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
521             jcr->JobStatus);
522    }
523    Dmsg3(800, "MaxWaitTime result: %scancel JCR %p (%s)\n",
524          cancel ? "" : "do not ", jcr, jcr->job);
525
526    return cancel;
527 }
528
529 /*
530  * Check if maxruntime has expired and if the job can be
531  *   canceled.
532  */
533 static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
534 {
535    bool cancel = false;
536
537    if (jcr->job->MaxRunTime == 0) {
538       return false;
539    }
540    if ((watchdog_time - jcr->start_time) < jcr->job->MaxRunTime) {
541       Dmsg3(200, "Job %p (%s) with MaxRunTime %d not expired\n",
542             jcr, jcr->Job, jcr->job->MaxRunTime);
543       return false;
544    }
545
546    switch (jcr->JobStatus) {
547    case JS_Created:
548    case JS_Running:
549    case JS_Blocked:
550    case JS_WaitFD:
551    case JS_WaitSD:
552    case JS_WaitStoreRes:
553    case JS_WaitClientRes:
554    case JS_WaitJobRes:
555    case JS_WaitPriority:
556    case JS_WaitMaxJobs:
557    case JS_WaitStartTime:
558    case JS_Differences:
559       cancel = true;
560       break;
561    case JS_Terminated:
562    case JS_ErrorTerminated:
563    case JS_Canceled:
564    case JS_FatalError:
565       cancel = false;
566       break;
567    default:
568       Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
569             jcr->JobStatus);
570    }
571
572    Dmsg3(200, "MaxRunTime result: %scancel JCR %p (%s)\n",
573          cancel ? "" : "do not ", jcr, jcr->job);
574
575    return cancel;
576 }
577
578 /*
579  * Get or create a Pool record with the given name.
580  * Returns: 0 on error
581  *          poolid if OK
582  */
583 DBId_t get_or_create_pool_record(JCR *jcr, char *pool_name)
584 {
585    POOL_DBR pr;
586
587    memset(&pr, 0, sizeof(pr));
588    bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
589
590    while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
591       /* Try to create the pool */
592       if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
593          Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
594             db_strerror(jcr->db));
595          return 0;
596       } else {
597          Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
598       }
599    }
600    return pr.PoolId;
601 }
602
603 void apply_pool_overrides(JCR *jcr)
604 {
605    if (jcr->run_pool_override) {
606       pm_strcpy(jcr->pool_source, _("Run Pool override"));
607    }
608    /*
609     * Apply any level related Pool selections
610     */
611    switch (jcr->JobLevel) {
612    case L_FULL:
613       if (jcr->full_pool) {
614          jcr->pool = jcr->full_pool;
615          if (jcr->run_full_pool_override) {
616             pm_strcpy(jcr->pool_source, _("Run FullPool override"));
617          } else {
618             pm_strcpy(jcr->pool_source, _("Job FullPool override"));
619          }
620       }
621       break;
622    case L_INCREMENTAL:
623       if (jcr->inc_pool) {
624          jcr->pool = jcr->inc_pool;
625          if (jcr->run_inc_pool_override) {
626             pm_strcpy(jcr->pool_source, _("Run IncPool override"));
627          } else {
628             pm_strcpy(jcr->pool_source, _("Job IncPool override"));
629          }
630       }
631       break;
632    case L_DIFFERENTIAL:
633       if (jcr->diff_pool) {
634          jcr->pool = jcr->diff_pool;
635          if (jcr->run_diff_pool_override) {
636             pm_strcpy(jcr->pool_source, _("Run DiffPool override"));
637          } else {
638             pm_strcpy(jcr->pool_source, _("Job DiffPool override"));
639          }
640       }
641       break;
642    }
643 }
644
645
646 /*
647  * Get or create a Client record for this Job
648  */
649 bool get_or_create_client_record(JCR *jcr)
650 {
651    CLIENT_DBR cr;
652
653    memset(&cr, 0, sizeof(cr));
654    bstrncpy(cr.Name, jcr->client->hdr.name, sizeof(cr.Name));
655    cr.AutoPrune = jcr->client->AutoPrune;
656    cr.FileRetention = jcr->client->FileRetention;
657    cr.JobRetention = jcr->client->JobRetention;
658    if (!jcr->client_name) {
659       jcr->client_name = get_pool_memory(PM_NAME);
660    }
661    pm_strcpy(jcr->client_name, jcr->client->hdr.name);
662    if (!db_create_client_record(jcr, jcr->db, &cr)) {
663       Jmsg(jcr, M_FATAL, 0, _("Could not create Client record. ERR=%s\n"),
664          db_strerror(jcr->db));
665       return false;
666    }
667    jcr->jr.ClientId = cr.ClientId;
668    if (cr.Uname[0]) {
669       if (!jcr->client_uname) {
670          jcr->client_uname = get_pool_memory(PM_NAME);
671       }
672       pm_strcpy(jcr->client_uname, cr.Uname);
673    }
674    Dmsg2(100, "Created Client %s record %d\n", jcr->client->hdr.name,
675       jcr->jr.ClientId);
676    return true;
677 }
678
679 bool get_or_create_fileset_record(JCR *jcr)
680 {
681    FILESET_DBR fsr;
682    /*
683     * Get or Create FileSet record
684     */
685    memset(&fsr, 0, sizeof(FILESET_DBR));
686    bstrncpy(fsr.FileSet, jcr->fileset->hdr.name, sizeof(fsr.FileSet));
687    if (jcr->fileset->have_MD5) {
688       struct MD5Context md5c;
689       unsigned char digest[MD5HashSize];
690       memcpy(&md5c, &jcr->fileset->md5c, sizeof(md5c));
691       MD5Final(digest, &md5c);
692       /*
693        * Keep the flag (last arg) set to false otherwise old FileSets will
694        * get new MD5 sums and the user will get Full backups on everything
695        */
696       bin_to_base64(fsr.MD5, sizeof(fsr.MD5), (char *)digest, MD5HashSize, false);
697       bstrncpy(jcr->fileset->MD5, fsr.MD5, sizeof(jcr->fileset->MD5));
698    } else {
699       Jmsg(jcr, M_WARNING, 0, _("FileSet MD5 digest not found.\n"));
700    }
701    if (!jcr->fileset->ignore_fs_changes ||
702        !db_get_fileset_record(jcr, jcr->db, &fsr)) {
703       if (!db_create_fileset_record(jcr, jcr->db, &fsr)) {
704          Jmsg(jcr, M_ERROR, 0, _("Could not create FileSet \"%s\" record. ERR=%s\n"),
705             fsr.FileSet, db_strerror(jcr->db));
706          return false;
707       }
708    }
709    jcr->jr.FileSetId = fsr.FileSetId;
710    bstrncpy(jcr->FSCreateTime, fsr.cCreateTime, sizeof(jcr->FSCreateTime));
711    Dmsg2(119, "Created FileSet %s record %u\n", jcr->fileset->hdr.name,
712       jcr->jr.FileSetId);
713    return true;
714 }
715
716 void init_jcr_job_record(JCR *jcr)
717 {
718    jcr->jr.SchedTime = jcr->sched_time;
719    jcr->jr.StartTime = jcr->start_time;
720    jcr->jr.EndTime = 0;               /* perhaps rescheduled, clear it */
721    jcr->jr.JobType = jcr->JobType;
722    jcr->jr.JobLevel = jcr->JobLevel;
723    jcr->jr.JobStatus = jcr->JobStatus;
724    jcr->jr.JobId = jcr->JobId;
725    bstrncpy(jcr->jr.Name, jcr->job->hdr.name, sizeof(jcr->jr.Name));
726    bstrncpy(jcr->jr.Job, jcr->Job, sizeof(jcr->jr.Job));
727 }
728
729 /*
730  * Write status and such in DB
731  */
732 void update_job_end_record(JCR *jcr)
733 {
734    jcr->jr.EndTime = time(NULL);
735    jcr->end_time = jcr->jr.EndTime;
736    jcr->jr.JobId = jcr->JobId;
737    jcr->jr.JobStatus = jcr->JobStatus;
738    jcr->jr.JobFiles = jcr->JobFiles;
739    jcr->jr.JobBytes = jcr->JobBytes;
740    jcr->jr.VolSessionId = jcr->VolSessionId;
741    jcr->jr.VolSessionTime = jcr->VolSessionTime;
742    if (!db_update_job_end_record(jcr, jcr->db, &jcr->jr)) {
743       Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"),
744          db_strerror(jcr->db));
745    }
746 }
747
748 /*
749  * Takes base_name and appends (unique) current
750  *   date and time to form unique job name.
751  *
752  *  Returns: unique job name in jcr->Job
753  *    date/time in jcr->start_time
754  */
755 void create_unique_job_name(JCR *jcr, const char *base_name)
756 {
757    /* Job start mutex */
758    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
759    static time_t last_start_time = 0;
760    time_t now;
761    struct tm tm;
762    char dt[MAX_TIME_LENGTH];
763    char name[MAX_NAME_LENGTH];
764    char *p;
765
766    /* Guarantee unique start time -- maximum one per second, and
767     * thus unique Job Name
768     */
769    P(mutex);                          /* lock creation of jobs */
770    now = time(NULL);
771    while (now == last_start_time) {
772       bmicrosleep(0, 500000);
773       now = time(NULL);
774    }
775    last_start_time = now;
776    V(mutex);                          /* allow creation of jobs */
777    jcr->start_time = now;
778    /* Form Unique JobName */
779    (void)localtime_r(&now, &tm);
780    /* Use only characters that are permitted in Windows filenames */
781    strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm);
782    bstrncpy(name, base_name, sizeof(name));
783    name[sizeof(name)-22] = 0;          /* truncate if too long */
784    bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s", name, dt); /* add date & time */
785    /* Convert spaces into underscores */
786    for (p=jcr->Job; *p; p++) {
787       if (*p == ' ') {
788          *p = '_';
789       }
790    }
791 }
792
793 /* Called directly from job rescheduling */
794 void dird_free_jcr_pointers(JCR *jcr)
795 {
796    if (jcr->sd_auth_key) {
797       free(jcr->sd_auth_key);
798       jcr->sd_auth_key = NULL;
799    }
800    if (jcr->where) {
801       free(jcr->where);
802       jcr->where = NULL;
803    }
804    if (jcr->file_bsock) {
805       Dmsg0(200, "Close File bsock\n");
806       bnet_close(jcr->file_bsock);
807       jcr->file_bsock = NULL;
808    }
809    if (jcr->store_bsock) {
810       Dmsg0(200, "Close Store bsock\n");
811       bnet_close(jcr->store_bsock);
812       jcr->store_bsock = NULL;
813    }
814    if (jcr->fname) {
815       Dmsg0(200, "Free JCR fname\n");
816       free_pool_memory(jcr->fname);
817       jcr->fname = NULL;
818    }
819    if (jcr->pool_source) {
820       free_pool_memory(jcr->pool_source);
821       jcr->pool_source = NULL;
822    }
823    if (jcr->storage_source) {
824       free_pool_memory(jcr->storage_source);
825       jcr->storage_source = NULL;
826    }
827    if (jcr->stime) {
828       Dmsg0(200, "Free JCR stime\n");
829       free_pool_memory(jcr->stime);
830       jcr->stime = NULL;
831    }
832    if (jcr->RestoreBootstrap) {
833       free(jcr->RestoreBootstrap);
834       jcr->RestoreBootstrap = NULL;
835    }
836    if (jcr->client_uname) {
837       free_pool_memory(jcr->client_uname);
838       jcr->client_uname = NULL;
839    }
840    if (jcr->attr) {
841       free_pool_memory(jcr->attr);
842       jcr->attr = NULL;
843    }
844    if (jcr->ar) {
845       free(jcr->ar);
846       jcr->ar = NULL;
847    }
848 }
849
850 /*
851  * Free the Job Control Record if no one is still using it.
852  *  Called from main free_jcr() routine in src/lib/jcr.c so
853  *  that we can do our Director specific cleanup of the jcr.
854  */
855 void dird_free_jcr(JCR *jcr)
856 {
857    Dmsg0(200, "Start dird free_jcr\n");
858
859    dird_free_jcr_pointers(jcr);
860    if (jcr->term_wait_inited) {
861       pthread_cond_destroy(&jcr->term_wait);
862       jcr->term_wait_inited = false;
863    }
864
865    /* Delete lists setup to hold storage pointers */
866    free_rwstorage(jcr);
867
868    jcr->job_end_push.destroy();
869    Dmsg0(200, "End dird free_jcr\n");
870 }
871
872 /*
873  * Set some defaults in the JCR necessary to
874  * run. These items are pulled from the job
875  * definition as defaults, but can be overridden
876  * later either by the Run record in the Schedule resource,
877  * or by the Console program.
878  */
879 void set_jcr_defaults(JCR *jcr, JOB *job)
880 {
881    jcr->job = job;
882    jcr->JobType = job->JobType;
883    switch (jcr->JobType) {
884    case JT_ADMIN:
885    case JT_RESTORE:
886       jcr->JobLevel = L_NONE;
887       break;
888    default:
889       jcr->JobLevel = job->JobLevel;
890       break;
891    }
892    if (!jcr->fname) {
893       jcr->fname = get_pool_memory(PM_FNAME);
894    }
895    if (!jcr->pool_source) {
896       jcr->pool_source = get_pool_memory(PM_MESSAGE);
897       pm_strcpy(jcr->pool_source, _("unknown source"));
898    }
899    if (!jcr->storage_source) {
900       jcr->storage_source = get_pool_memory(PM_MESSAGE);
901       pm_strcpy(jcr->storage_source, _("unknown source"));
902    }
903    jcr->JobPriority = job->Priority;
904    /* Copy storage definitions -- deleted in dir_free_jcr above */
905    copy_rwstorage(jcr, job->storage, _("Job resource"));
906    jcr->client = job->client;
907    if (!jcr->client_name) {
908       jcr->client_name = get_pool_memory(PM_NAME);
909    }
910    pm_strcpy(jcr->client_name, jcr->client->hdr.name);
911    pm_strcpy(jcr->pool_source, _("Job resource"));
912    jcr->pool = job->pool;
913    jcr->full_pool = job->full_pool;
914    jcr->inc_pool = job->inc_pool;
915    jcr->diff_pool = job->diff_pool;
916    jcr->catalog = job->client->catalog;
917    jcr->fileset = job->fileset;
918    jcr->messages = job->messages;
919    jcr->spool_data = job->spool_data;
920    jcr->write_part_after_job = job->write_part_after_job;
921    if (jcr->RestoreBootstrap) {
922       free(jcr->RestoreBootstrap);
923       jcr->RestoreBootstrap = NULL;
924    }
925    /* This can be overridden by Console program */
926    if (job->RestoreBootstrap) {
927       jcr->RestoreBootstrap = bstrdup(job->RestoreBootstrap);
928    }
929    /* This can be overridden by Console program */
930    jcr->verify_job = job->verify_job;
931    /* If no default level given, set one */
932    if (jcr->JobLevel == 0) {
933       switch (jcr->JobType) {
934       case JT_VERIFY:
935          jcr->JobLevel = L_VERIFY_CATALOG;
936          break;
937       case JT_BACKUP:
938          jcr->JobLevel = L_INCREMENTAL;
939          break;
940       case JT_RESTORE:
941       case JT_ADMIN:
942          jcr->JobLevel = L_NONE;
943          break;
944       default:
945          break;
946       }
947    }
948 }
949
950 /* 
951  * Copy the storage definitions from an alist to the JCR
952  */
953 void copy_rwstorage(JCR *jcr, alist *storage, const char *where)
954 {
955    copy_rstorage(jcr, storage, where);
956    copy_wstorage(jcr, storage, where);
957 }
958
959
960 /* Set storage override */
961 void set_rwstorage(JCR *jcr, STORE *store)
962 {
963    set_rstorage(jcr, store);
964    set_wstorage(jcr, store);
965 }
966
967 void free_rwstorage(JCR *jcr)
968 {
969    free_rstorage(jcr);
970    free_wstorage(jcr);
971 }
972
973 /* 
974  * Copy the storage definitions from an alist to the JCR
975  */
976 void copy_rstorage(JCR *jcr, alist *storage, const char *where)
977 {
978    if (storage) {
979       STORE *st;
980       if (jcr->rstorage) {
981          delete jcr->rstorage;
982       }
983       jcr->rstorage = New(alist(10, not_owned_by_alist));
984       foreach_alist(st, storage) {
985          jcr->rstorage->append(st);
986       }
987       pm_strcpy(jcr->storage_source, where);
988    }               
989    if (jcr->rstorage) {
990       jcr->rstore = (STORE *)jcr->rstorage->first();
991    }
992 }
993
994
995 /* Set storage override */
996 void set_rstorage(JCR *jcr, STORE *store)
997 {
998    STORE *storage;
999
1000    jcr->rstore = store;
1001    foreach_alist(storage, jcr->rstorage) {
1002       if (store == storage) {
1003          return;
1004       }
1005    }
1006    /* Store not in list, so add it */
1007    jcr->rstorage->prepend(store);
1008 }
1009
1010 void free_rstorage(JCR *jcr)
1011 {
1012    if (jcr->rstorage) {
1013       delete jcr->rstorage;
1014       jcr->rstorage = NULL;
1015    }
1016    jcr->rstore = NULL;
1017 }
1018
1019 /* 
1020  * Copy the storage definitions from an alist to the JCR
1021  */
1022 void copy_wstorage(JCR *jcr, alist *storage, const char *where)
1023 {
1024    if (storage) {
1025       STORE *st;
1026       if (jcr->wstorage) {
1027          delete jcr->wstorage;
1028       }
1029       jcr->wstorage = New(alist(10, not_owned_by_alist));
1030       foreach_alist(st, storage) {
1031          jcr->wstorage->append(st);
1032       }
1033       pm_strcpy(jcr->storage_source, where);
1034    }               
1035    if (jcr->wstorage) {
1036       jcr->wstore = (STORE *)jcr->wstorage->first();
1037    }
1038 }
1039
1040
1041 /* Set storage override */
1042 void set_wstorage(JCR *jcr, STORE *store)
1043 {
1044    STORE *storage;
1045
1046    jcr->wstore = store;
1047    foreach_alist(storage, jcr->wstorage) {
1048       if (store == storage) {
1049          return;
1050       }
1051    }
1052    /* Store not in list, so add it */
1053    jcr->wstorage->prepend(store);
1054 }
1055
1056 void free_wstorage(JCR *jcr)
1057 {
1058    if (jcr->wstorage) {
1059       delete jcr->wstorage;
1060       jcr->wstorage = NULL;
1061    }
1062    jcr->wstore = NULL;
1063 }
1064
1065
1066
1067 void create_clones(JCR *jcr)
1068 {
1069    /*
1070     * Fire off any clone jobs (run directives)
1071     */
1072    Dmsg2(900, "cloned=%d run_cmds=%p\n", jcr->cloned, jcr->job->run_cmds);
1073    if (!jcr->cloned && jcr->job->run_cmds) {
1074       char *runcmd;
1075       JOB *job = jcr->job;
1076       POOLMEM *cmd = get_pool_memory(PM_FNAME);
1077       UAContext *ua = new_ua_context(jcr);
1078       ua->batch = true;
1079       foreach_alist(runcmd, job->run_cmds) {
1080          cmd = edit_job_codes(jcr, cmd, runcmd, "");              
1081          Mmsg(ua->cmd, "run %s cloned=yes", cmd);
1082          Dmsg1(900, "=============== Clone cmd=%s\n", ua->cmd);
1083          parse_ua_args(ua);                 /* parse command */
1084          int stat = run_cmd(ua, ua->cmd);
1085          if (stat == 0) {
1086             Jmsg(jcr, M_ERROR, 0, _("Could not start clone job.\n"));
1087          } else {
1088             Jmsg(jcr, M_INFO, 0, _("Clone JobId %d started.\n"), stat);
1089          }
1090       }
1091       free_ua_context(ua);
1092       free_pool_memory(cmd);
1093    }
1094 }
1095
1096 bool create_restore_bootstrap_file(JCR *jcr)
1097 {
1098    RESTORE_CTX rx;
1099    UAContext *ua;
1100    memset(&rx, 0, sizeof(rx));
1101    rx.bsr = new_bsr();
1102    rx.JobIds = "";                       
1103    rx.bsr->JobId = jcr->previous_jr.JobId;
1104    ua = new_ua_context(jcr);
1105    complete_bsr(ua, rx.bsr);
1106    rx.bsr->fi = new_findex();
1107    rx.bsr->fi->findex = 1;
1108    rx.bsr->fi->findex2 = jcr->previous_jr.JobFiles;
1109    jcr->ExpectedFiles = write_bsr_file(ua, rx);
1110    if (jcr->ExpectedFiles == 0) {
1111       free_ua_context(ua);
1112       free_bsr(rx.bsr);
1113       return false;
1114    }
1115    free_ua_context(ua);
1116    free_bsr(rx.bsr);
1117    jcr->needs_sd = true;
1118    return true;
1119 }