]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/job.c
ebl add joberrors to job record
[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    jcr->jr.JobErrors = jcr->Errors;
743    if (!db_update_job_end_record(jcr, jcr->db, &jcr->jr)) {
744       Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"),
745          db_strerror(jcr->db));
746    }
747 }
748
749 /*
750  * Takes base_name and appends (unique) current
751  *   date and time to form unique job name.
752  *
753  *  Returns: unique job name in jcr->Job
754  *    date/time in jcr->start_time
755  */
756 void create_unique_job_name(JCR *jcr, const char *base_name)
757 {
758    /* Job start mutex */
759    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
760    static time_t last_start_time = 0;
761    time_t now;
762    struct tm tm;
763    char dt[MAX_TIME_LENGTH];
764    char name[MAX_NAME_LENGTH];
765    char *p;
766
767    /* Guarantee unique start time -- maximum one per second, and
768     * thus unique Job Name
769     */
770    P(mutex);                          /* lock creation of jobs */
771    now = time(NULL);
772    while (now == last_start_time) {
773       bmicrosleep(0, 500000);
774       now = time(NULL);
775    }
776    last_start_time = now;
777    V(mutex);                          /* allow creation of jobs */
778    jcr->start_time = now;
779    /* Form Unique JobName */
780    (void)localtime_r(&now, &tm);
781    /* Use only characters that are permitted in Windows filenames */
782    strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm);
783    bstrncpy(name, base_name, sizeof(name));
784    name[sizeof(name)-22] = 0;          /* truncate if too long */
785    bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s", name, dt); /* add date & time */
786    /* Convert spaces into underscores */
787    for (p=jcr->Job; *p; p++) {
788       if (*p == ' ') {
789          *p = '_';
790       }
791    }
792 }
793
794 /* Called directly from job rescheduling */
795 void dird_free_jcr_pointers(JCR *jcr)
796 {
797    if (jcr->sd_auth_key) {
798       free(jcr->sd_auth_key);
799       jcr->sd_auth_key = NULL;
800    }
801    if (jcr->where) {
802       free(jcr->where);
803       jcr->where = NULL;
804    }
805    if (jcr->file_bsock) {
806       Dmsg0(200, "Close File bsock\n");
807       bnet_close(jcr->file_bsock);
808       jcr->file_bsock = NULL;
809    }
810    if (jcr->store_bsock) {
811       Dmsg0(200, "Close Store bsock\n");
812       bnet_close(jcr->store_bsock);
813       jcr->store_bsock = NULL;
814    }
815    if (jcr->fname) {
816       Dmsg0(200, "Free JCR fname\n");
817       free_pool_memory(jcr->fname);
818       jcr->fname = NULL;
819    }
820    if (jcr->pool_source) {
821       free_pool_memory(jcr->pool_source);
822       jcr->pool_source = NULL;
823    }
824    if (jcr->storage_source) {
825       free_pool_memory(jcr->storage_source);
826       jcr->storage_source = NULL;
827    }
828    if (jcr->stime) {
829       Dmsg0(200, "Free JCR stime\n");
830       free_pool_memory(jcr->stime);
831       jcr->stime = NULL;
832    }
833    if (jcr->RestoreBootstrap) {
834       free(jcr->RestoreBootstrap);
835       jcr->RestoreBootstrap = NULL;
836    }
837    if (jcr->client_uname) {
838       free_pool_memory(jcr->client_uname);
839       jcr->client_uname = NULL;
840    }
841    if (jcr->attr) {
842       free_pool_memory(jcr->attr);
843       jcr->attr = NULL;
844    }
845    if (jcr->ar) {
846       free(jcr->ar);
847       jcr->ar = NULL;
848    }
849 }
850
851 /*
852  * Free the Job Control Record if no one is still using it.
853  *  Called from main free_jcr() routine in src/lib/jcr.c so
854  *  that we can do our Director specific cleanup of the jcr.
855  */
856 void dird_free_jcr(JCR *jcr)
857 {
858    Dmsg0(200, "Start dird free_jcr\n");
859
860    dird_free_jcr_pointers(jcr);
861    if (jcr->term_wait_inited) {
862       pthread_cond_destroy(&jcr->term_wait);
863       jcr->term_wait_inited = false;
864    }
865
866    /* Delete lists setup to hold storage pointers */
867    free_rwstorage(jcr);
868
869    jcr->job_end_push.destroy();
870    Dmsg0(200, "End dird free_jcr\n");
871 }
872
873 /*
874  * Set some defaults in the JCR necessary to
875  * run. These items are pulled from the job
876  * definition as defaults, but can be overridden
877  * later either by the Run record in the Schedule resource,
878  * or by the Console program.
879  */
880 void set_jcr_defaults(JCR *jcr, JOB *job)
881 {
882    jcr->job = job;
883    jcr->JobType = job->JobType;
884    switch (jcr->JobType) {
885    case JT_ADMIN:
886    case JT_RESTORE:
887       jcr->JobLevel = L_NONE;
888       break;
889    default:
890       jcr->JobLevel = job->JobLevel;
891       break;
892    }
893    if (!jcr->fname) {
894       jcr->fname = get_pool_memory(PM_FNAME);
895    }
896    if (!jcr->pool_source) {
897       jcr->pool_source = get_pool_memory(PM_MESSAGE);
898       pm_strcpy(jcr->pool_source, _("unknown source"));
899    }
900    if (!jcr->storage_source) {
901       jcr->storage_source = get_pool_memory(PM_MESSAGE);
902       pm_strcpy(jcr->storage_source, _("unknown source"));
903    }
904    jcr->JobPriority = job->Priority;
905    /* Copy storage definitions -- deleted in dir_free_jcr above */
906    copy_rwstorage(jcr, job->storage, _("Job resource"));
907    jcr->client = job->client;
908    if (!jcr->client_name) {
909       jcr->client_name = get_pool_memory(PM_NAME);
910    }
911    pm_strcpy(jcr->client_name, jcr->client->hdr.name);
912    pm_strcpy(jcr->pool_source, _("Job resource"));
913    jcr->pool = job->pool;
914    jcr->full_pool = job->full_pool;
915    jcr->inc_pool = job->inc_pool;
916    jcr->diff_pool = job->diff_pool;
917    jcr->catalog = job->client->catalog;
918    jcr->fileset = job->fileset;
919    jcr->messages = job->messages;
920    jcr->spool_data = job->spool_data;
921    jcr->write_part_after_job = job->write_part_after_job;
922    if (jcr->RestoreBootstrap) {
923       free(jcr->RestoreBootstrap);
924       jcr->RestoreBootstrap = NULL;
925    }
926    /* This can be overridden by Console program */
927    if (job->RestoreBootstrap) {
928       jcr->RestoreBootstrap = bstrdup(job->RestoreBootstrap);
929    }
930    /* This can be overridden by Console program */
931    jcr->verify_job = job->verify_job;
932    /* If no default level given, set one */
933    if (jcr->JobLevel == 0) {
934       switch (jcr->JobType) {
935       case JT_VERIFY:
936          jcr->JobLevel = L_VERIFY_CATALOG;
937          break;
938       case JT_BACKUP:
939          jcr->JobLevel = L_INCREMENTAL;
940          break;
941       case JT_RESTORE:
942       case JT_ADMIN:
943          jcr->JobLevel = L_NONE;
944          break;
945       default:
946          break;
947       }
948    }
949 }
950
951 /* 
952  * Copy the storage definitions from an alist to the JCR
953  */
954 void copy_rwstorage(JCR *jcr, alist *storage, const char *where)
955 {
956    copy_rstorage(jcr, storage, where);
957    copy_wstorage(jcr, storage, where);
958 }
959
960
961 /* Set storage override */
962 void set_rwstorage(JCR *jcr, STORE *store)
963 {
964    set_rstorage(jcr, store);
965    set_wstorage(jcr, store);
966 }
967
968 void free_rwstorage(JCR *jcr)
969 {
970    free_rstorage(jcr);
971    free_wstorage(jcr);
972 }
973
974 /* 
975  * Copy the storage definitions from an alist to the JCR
976  */
977 void copy_rstorage(JCR *jcr, alist *storage, const char *where)
978 {
979    if (storage) {
980       STORE *st;
981       if (jcr->rstorage) {
982          delete jcr->rstorage;
983       }
984       jcr->rstorage = New(alist(10, not_owned_by_alist));
985       foreach_alist(st, storage) {
986          jcr->rstorage->append(st);
987       }
988       pm_strcpy(jcr->storage_source, where);
989    }               
990    if (jcr->rstorage) {
991       jcr->rstore = (STORE *)jcr->rstorage->first();
992    }
993 }
994
995
996 /* Set storage override */
997 void set_rstorage(JCR *jcr, STORE *store)
998 {
999    STORE *storage;
1000
1001    jcr->rstore = store;
1002    foreach_alist(storage, jcr->rstorage) {
1003       if (store == storage) {
1004          return;
1005       }
1006    }
1007    /* Store not in list, so add it */
1008    jcr->rstorage->prepend(store);
1009 }
1010
1011 void free_rstorage(JCR *jcr)
1012 {
1013    if (jcr->rstorage) {
1014       delete jcr->rstorage;
1015       jcr->rstorage = NULL;
1016    }
1017    jcr->rstore = NULL;
1018 }
1019
1020 /* 
1021  * Copy the storage definitions from an alist to the JCR
1022  */
1023 void copy_wstorage(JCR *jcr, alist *storage, const char *where)
1024 {
1025    if (storage) {
1026       STORE *st;
1027       if (jcr->wstorage) {
1028          delete jcr->wstorage;
1029       }
1030       jcr->wstorage = New(alist(10, not_owned_by_alist));
1031       foreach_alist(st, storage) {
1032          jcr->wstorage->append(st);
1033       }
1034       pm_strcpy(jcr->storage_source, where);
1035    }               
1036    if (jcr->wstorage) {
1037       jcr->wstore = (STORE *)jcr->wstorage->first();
1038    }
1039 }
1040
1041
1042 /* Set storage override */
1043 void set_wstorage(JCR *jcr, STORE *store)
1044 {
1045    STORE *storage;
1046
1047    jcr->wstore = store;
1048    foreach_alist(storage, jcr->wstorage) {
1049       if (store == storage) {
1050          return;
1051       }
1052    }
1053    /* Store not in list, so add it */
1054    jcr->wstorage->prepend(store);
1055 }
1056
1057 void free_wstorage(JCR *jcr)
1058 {
1059    if (jcr->wstorage) {
1060       delete jcr->wstorage;
1061       jcr->wstorage = NULL;
1062    }
1063    jcr->wstore = NULL;
1064 }
1065
1066
1067
1068 void create_clones(JCR *jcr)
1069 {
1070    /*
1071     * Fire off any clone jobs (run directives)
1072     */
1073    Dmsg2(900, "cloned=%d run_cmds=%p\n", jcr->cloned, jcr->job->run_cmds);
1074    if (!jcr->cloned && jcr->job->run_cmds) {
1075       char *runcmd;
1076       JOB *job = jcr->job;
1077       POOLMEM *cmd = get_pool_memory(PM_FNAME);
1078       UAContext *ua = new_ua_context(jcr);
1079       ua->batch = true;
1080       foreach_alist(runcmd, job->run_cmds) {
1081          cmd = edit_job_codes(jcr, cmd, runcmd, "");              
1082          Mmsg(ua->cmd, "run %s cloned=yes", cmd);
1083          Dmsg1(900, "=============== Clone cmd=%s\n", ua->cmd);
1084          parse_ua_args(ua);                 /* parse command */
1085          int stat = run_cmd(ua, ua->cmd);
1086          if (stat == 0) {
1087             Jmsg(jcr, M_ERROR, 0, _("Could not start clone job.\n"));
1088          } else {
1089             Jmsg(jcr, M_INFO, 0, _("Clone JobId %d started.\n"), stat);
1090          }
1091       }
1092       free_ua_context(ua);
1093       free_pool_memory(cmd);
1094    }
1095 }
1096
1097 bool create_restore_bootstrap_file(JCR *jcr)
1098 {
1099    RESTORE_CTX rx;
1100    UAContext *ua;
1101    memset(&rx, 0, sizeof(rx));
1102    rx.bsr = new_bsr();
1103    rx.JobIds = "";                       
1104    rx.bsr->JobId = jcr->previous_jr.JobId;
1105    ua = new_ua_context(jcr);
1106    complete_bsr(ua, rx.bsr);
1107    rx.bsr->fi = new_findex();
1108    rx.bsr->fi->findex = 1;
1109    rx.bsr->fi->findex2 = jcr->previous_jr.JobFiles;
1110    jcr->ExpectedFiles = write_bsr_file(ua, rx);
1111    if (jcr->ExpectedFiles == 0) {
1112       free_ua_context(ua);
1113       free_bsr(rx.bsr);
1114       return false;
1115    }
1116    free_ua_context(ua);
1117    free_bsr(rx.bsr);
1118    jcr->needs_sd = true;
1119    return true;
1120 }