]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/job.c
Fix header file includes.
[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    Dmsg0(200, "Add jrc to work queue\n");
161    return true;
162
163 bail_out:
164    return false;
165 }
166
167
168 /*
169  * This is the engine called by jobq.c:jobq_add() when we were pulled
170  *  from the work queue.
171  *  At this point, we are running in our own thread and all
172  *    necessary resources are allocated -- see jobq.c
173  */
174 static void *job_thread(void *arg)
175 {
176    JCR *jcr = (JCR *)arg;
177
178    jcr->my_thread_id = pthread_self();
179    pthread_detach(jcr->my_thread_id);
180    sm_check(__FILE__, __LINE__, true);
181
182    Dmsg0(200, "=====Start Job=========\n");
183    jcr->start_time = time(NULL);      /* set the real start time */
184    jcr->jr.StartTime = jcr->start_time;
185
186    if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
187        (utime_t)(jcr->start_time - jcr->sched_time)) {
188       Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
189       set_jcr_job_status(jcr, JS_Canceled);
190    }
191
192    /* TODO : check if it is used somewhere */
193    if (jcr->job->RunScripts == NULL)
194    {
195       Dmsg0(200, "Warning, job->RunScripts is empty\n");
196       jcr->job->RunScripts = New(alist(10, not_owned_by_alist));
197    }
198
199    /*                                
200     * Note, we continue, even if the job is canceled above. This
201     *  will permit proper setting of the job start record and
202     *  the error (cancel) will be picked up below.
203     */
204
205    generate_job_event(jcr, "JobInit");
206    set_jcr_job_status(jcr, JS_Running);   /* this will be set only if no error */
207
208
209    /*
210     * Now, do pre-run stuff, like setting job level (Inc/diff, ...)
211     *  this allows us to setup a proper job start record for restarting
212     *  in case of later errors.
213     */
214    switch (jcr->JobType) {
215    case JT_BACKUP:
216       if (!do_backup_init(jcr)) {
217          backup_cleanup(jcr, JS_ErrorTerminated);
218       }
219       break;
220    case JT_VERIFY:
221       if (!do_verify_init(jcr)) {
222          verify_cleanup(jcr, JS_ErrorTerminated);
223       }
224       break;
225    case JT_RESTORE:
226       if (!do_restore_init(jcr)) {
227          restore_cleanup(jcr, JS_ErrorTerminated);
228       }
229       break;
230    case JT_ADMIN:
231       if (!do_admin_init(jcr)) {
232          admin_cleanup(jcr, JS_ErrorTerminated);
233       }
234       break;
235    case JT_MIGRATE:
236       if (!do_migration_init(jcr)) { 
237          migration_cleanup(jcr, JS_ErrorTerminated);
238       }
239       break;
240    default:
241       Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->JobType);
242       set_jcr_job_status(jcr, JS_ErrorTerminated);
243       break;
244    }
245
246    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
247       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
248    }
249
250    if (job_canceled(jcr)) {
251       update_job_end_record(jcr);
252    } else {
253       /* Run any script BeforeJob on dird */
254       run_scripts(jcr, jcr->job->RunScripts, "BeforeJob");
255
256       /*
257        * We re-update the job start record so that the start
258        *  time is set after the run before job.  This avoids
259        *  that any files created by the run before job will
260        *  be saved twice.  They will be backed up in the current
261        *  job, but not in the next one unless they are changed.
262        *  Without this, they will be backed up in this job and
263        *  in the next job run because in that case, their date
264        *   is after the start of this run.
265        */
266       jcr->start_time = time(NULL);
267       jcr->jr.StartTime = jcr->start_time;
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       generate_job_event(jcr, "JobRun");
272
273       switch (jcr->JobType) {
274       case JT_BACKUP:
275          if (do_backup(jcr)) {
276             do_autoprune(jcr);
277          } else {
278             backup_cleanup(jcr, JS_ErrorTerminated);
279          }
280          break;
281       case JT_VERIFY:
282          if (do_verify(jcr)) {
283             do_autoprune(jcr);
284          } else {
285             verify_cleanup(jcr, JS_ErrorTerminated);
286          }
287          break;
288       case JT_RESTORE:
289          if (do_restore(jcr)) {
290             do_autoprune(jcr);
291          } else {
292             restore_cleanup(jcr, JS_ErrorTerminated);
293          }
294          break;
295       case JT_ADMIN:
296          if (do_admin(jcr)) {
297             do_autoprune(jcr);
298          } else {
299             admin_cleanup(jcr, JS_ErrorTerminated);
300          }
301          break;
302       case JT_MIGRATE:
303       case JT_COPY:
304       case JT_ARCHIVE:
305          if (do_migration(jcr)) {
306             do_autoprune(jcr);
307          } else {
308             migration_cleanup(jcr, JS_ErrorTerminated);
309          }
310          break;
311       default:
312          Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->JobType);
313          break;
314       }
315
316       run_scripts(jcr, jcr->job->RunScripts, "AfterJob");
317
318       /* Send off any queued messages */
319       if (jcr->msg_queue->size() > 0) {
320          dequeue_messages(jcr);
321       }
322    }
323
324    generate_daemon_event(jcr, "JobEnd");
325    Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus);
326    sm_check(__FILE__, __LINE__, true);
327    return NULL;
328 }
329
330
331 /*
332  * Cancel a job -- typically called by the UA (Console program), but may also
333  *              be called by the job watchdog.
334  *
335  *  Returns: true  if cancel appears to be successful
336  *           false on failure. Message sent to ua->jcr.
337  */
338 bool cancel_job(UAContext *ua, JCR *jcr)
339 {
340    BSOCK *sd, *fd;
341
342    set_jcr_job_status(jcr, JS_Canceled);
343
344    switch (jcr->JobStatus) {
345    case JS_Created:
346    case JS_WaitJobRes:
347    case JS_WaitClientRes:
348    case JS_WaitStoreRes:
349    case JS_WaitPriority:
350    case JS_WaitMaxJobs:
351    case JS_WaitStartTime:
352       bsendmsg(ua, _("JobId %d, Job %s marked to be canceled.\n"),
353               jcr->JobId, jcr->Job);
354       jobq_remove(&job_queue, jcr); /* attempt to remove it from queue */
355       return true;
356
357    default:
358       /* Cancel File daemon */
359       if (jcr->file_bsock) {
360          ua->jcr->client = jcr->client;
361          if (!connect_to_file_daemon(ua->jcr, 10, FDConnectTimeout, 1)) {
362             bsendmsg(ua, _("Failed to connect to File daemon.\n"));
363             return 0;
364          }
365          Dmsg0(200, "Connected to file daemon\n");
366          fd = ua->jcr->file_bsock;
367          bnet_fsend(fd, "cancel Job=%s\n", jcr->Job);
368          while (bnet_recv(fd) >= 0) {
369             bsendmsg(ua, "%s", fd->msg);
370          }
371          bnet_sig(fd, BNET_TERMINATE);
372          bnet_close(fd);
373          ua->jcr->file_bsock = NULL;
374       }
375
376       /* Cancel Storage daemon */
377       if (jcr->store_bsock) {
378          if (!ua->jcr->storage) {
379             copy_storage(ua->jcr, jcr->storage, _("Job resource")); 
380          } else {
381             set_storage(ua->jcr, jcr->store);
382          }
383          if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
384             bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
385             return false;
386          }
387          Dmsg0(200, "Connected to storage daemon\n");
388          sd = ua->jcr->store_bsock;
389          bnet_fsend(sd, "cancel Job=%s\n", jcr->Job);
390          while (bnet_recv(sd) >= 0) {
391             bsendmsg(ua, "%s", sd->msg);
392          }
393          bnet_sig(sd, BNET_TERMINATE);
394          bnet_close(sd);
395          ua->jcr->store_bsock = NULL;
396       }
397    }
398
399    return true;
400 }
401
402
403 static void job_monitor_destructor(watchdog_t *self)
404 {
405    JCR *control_jcr = (JCR *)self->data;
406
407    free_jcr(control_jcr);
408 }
409
410 static void job_monitor_watchdog(watchdog_t *self)
411 {
412    JCR *control_jcr, *jcr;
413
414    control_jcr = (JCR *)self->data;
415
416    Dmsg1(800, "job_monitor_watchdog %p called\n", self);
417
418    foreach_jcr(jcr) {
419       bool cancel;
420
421       if (jcr->JobId == 0) {
422          Dmsg2(800, "Skipping JCR %p (%s) with JobId 0\n",
423                jcr, jcr->Job);
424          continue;
425       }
426
427       /* check MaxWaitTime */
428       cancel = job_check_maxwaittime(control_jcr, jcr);
429
430       /* check MaxRunTime */
431       cancel |= job_check_maxruntime(control_jcr, jcr);
432
433       if (cancel) {
434          Dmsg3(800, "Cancelling JCR %p jobid %d (%s)\n",
435                jcr, jcr->JobId, jcr->Job);
436
437          UAContext *ua = new_ua_context(jcr);
438          ua->jcr = control_jcr;
439          cancel_job(ua, jcr);
440          free_ua_context(ua);
441
442          Dmsg2(800, "Have cancelled JCR %p Job=%d\n", jcr, jcr->JobId);
443       }
444
445       /* Keep reference counts correct */
446    }
447    endeach_jcr(jcr);
448 }
449
450 /*
451  * Check if the maxwaittime has expired and it is possible
452  *  to cancel the job.
453  */
454 static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
455 {
456    bool cancel = false;
457    bool ok_to_cancel = false;
458    JOB *job = jcr->job;
459
460    if (job->MaxWaitTime == 0 && job->FullMaxWaitTime == 0 &&
461        job->IncMaxWaitTime == 0 && job->DiffMaxWaitTime == 0) {
462       return false;
463    } 
464    if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
465          (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
466       ok_to_cancel = true;
467    } else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxWaitTime != 0 &&
468          (watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
469       ok_to_cancel = true;
470    } else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxWaitTime != 0 &&
471          (watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
472       ok_to_cancel = true;
473    } else if (job->MaxWaitTime != 0 &&
474          (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
475       ok_to_cancel = true;
476    }
477    if (!ok_to_cancel) {
478       return false;
479    }
480    Dmsg3(800, "Job %d (%s): MaxWaitTime of %d seconds exceeded, "
481          "checking status\n",
482          jcr->JobId, jcr->Job, job->MaxWaitTime);
483    switch (jcr->JobStatus) {
484    case JS_Created:
485    case JS_Blocked:
486    case JS_WaitFD:
487    case JS_WaitSD:
488    case JS_WaitStoreRes:
489    case JS_WaitClientRes:
490    case JS_WaitJobRes:
491    case JS_WaitPriority:
492    case JS_WaitMaxJobs:
493    case JS_WaitStartTime:
494       cancel = true;
495       Dmsg0(200, "JCR blocked in #1\n");
496       break;
497    case JS_Running:
498       Dmsg0(800, "JCR running, checking SD status\n");
499       switch (jcr->SDJobStatus) {
500       case JS_WaitMount:
501       case JS_WaitMedia:
502       case JS_WaitFD:
503          cancel = true;
504          Dmsg0(800, "JCR blocked in #2\n");
505          break;
506       default:
507          Dmsg0(800, "JCR not blocked in #2\n");
508          break;
509       }
510       break;
511    case JS_Terminated:
512    case JS_ErrorTerminated:
513    case JS_Canceled:
514    case JS_FatalError:
515       Dmsg0(800, "JCR already dead in #3\n");
516       break;
517    default:
518       Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
519             jcr->JobStatus);
520    }
521    Dmsg3(800, "MaxWaitTime result: %scancel JCR %p (%s)\n",
522          cancel ? "" : "do not ", jcr, jcr->job);
523
524    return cancel;
525 }
526
527 /*
528  * Check if maxruntime has expired and if the job can be
529  *   canceled.
530  */
531 static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
532 {
533    bool cancel = false;
534
535    if (jcr->job->MaxRunTime == 0) {
536       return false;
537    }
538    if ((watchdog_time - jcr->start_time) < jcr->job->MaxRunTime) {
539       Dmsg3(200, "Job %p (%s) with MaxRunTime %d not expired\n",
540             jcr, jcr->Job, jcr->job->MaxRunTime);
541       return false;
542    }
543
544    switch (jcr->JobStatus) {
545    case JS_Created:
546    case JS_Running:
547    case JS_Blocked:
548    case JS_WaitFD:
549    case JS_WaitSD:
550    case JS_WaitStoreRes:
551    case JS_WaitClientRes:
552    case JS_WaitJobRes:
553    case JS_WaitPriority:
554    case JS_WaitMaxJobs:
555    case JS_WaitStartTime:
556    case JS_Differences:
557       cancel = true;
558       break;
559    case JS_Terminated:
560    case JS_ErrorTerminated:
561    case JS_Canceled:
562    case JS_FatalError:
563       cancel = false;
564       break;
565    default:
566       Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
567             jcr->JobStatus);
568    }
569
570    Dmsg3(200, "MaxRunTime result: %scancel JCR %p (%s)\n",
571          cancel ? "" : "do not ", jcr, jcr->job);
572
573    return cancel;
574 }
575
576 /*
577  * Get or create a Pool record with the given name.
578  * Returns: 0 on error
579  *          poolid if OK
580  */
581 DBId_t get_or_create_pool_record(JCR *jcr, char *pool_name)
582 {
583    POOL_DBR pr;
584
585    memset(&pr, 0, sizeof(pr));
586    bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
587
588    while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
589       /* Try to create the pool */
590       if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
591          Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
592             db_strerror(jcr->db));
593          return 0;
594       } else {
595          Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
596       }
597    }
598    return pr.PoolId;
599 }
600
601 void apply_pool_overrides(JCR *jcr)
602 {
603    if (jcr->run_pool_override) {
604       pm_strcpy(jcr->pool_source, _("Run Pool override"));
605    }
606    /*
607     * Apply any level related Pool selections
608     */
609    switch (jcr->JobLevel) {
610    case L_FULL:
611       if (jcr->full_pool) {
612          jcr->pool = jcr->full_pool;
613          if (jcr->run_full_pool_override) {
614             pm_strcpy(jcr->pool_source, _("Run FullPool override"));
615          } else {
616             pm_strcpy(jcr->pool_source, _("Job FullPool override"));
617          }
618       }
619       break;
620    case L_INCREMENTAL:
621       if (jcr->inc_pool) {
622          jcr->pool = jcr->inc_pool;
623          if (jcr->run_inc_pool_override) {
624             pm_strcpy(jcr->pool_source, _("Run IncPool override"));
625          } else {
626             pm_strcpy(jcr->pool_source, _("Job IncPool override"));
627          }
628       }
629       break;
630    case L_DIFFERENTIAL:
631       if (jcr->diff_pool) {
632          jcr->pool = jcr->diff_pool;
633          if (jcr->run_diff_pool_override) {
634             pm_strcpy(jcr->pool_source, _("Run DiffPool override"));
635          } else {
636             pm_strcpy(jcr->pool_source, _("Job DiffPool override"));
637          }
638       }
639       break;
640    }
641 }
642
643
644 /*
645  * Get or create a Client record for this Job
646  */
647 bool get_or_create_client_record(JCR *jcr)
648 {
649    CLIENT_DBR cr;
650
651    memset(&cr, 0, sizeof(cr));
652    bstrncpy(cr.Name, jcr->client->hdr.name, sizeof(cr.Name));
653    cr.AutoPrune = jcr->client->AutoPrune;
654    cr.FileRetention = jcr->client->FileRetention;
655    cr.JobRetention = jcr->client->JobRetention;
656    if (!jcr->client_name) {
657       jcr->client_name = get_pool_memory(PM_NAME);
658    }
659    pm_strcpy(jcr->client_name, jcr->client->hdr.name);
660    if (!db_create_client_record(jcr, jcr->db, &cr)) {
661       Jmsg(jcr, M_FATAL, 0, _("Could not create Client record. ERR=%s\n"),
662          db_strerror(jcr->db));
663       return false;
664    }
665    jcr->jr.ClientId = cr.ClientId;
666    if (cr.Uname[0]) {
667       if (!jcr->client_uname) {
668          jcr->client_uname = get_pool_memory(PM_NAME);
669       }
670       pm_strcpy(jcr->client_uname, cr.Uname);
671    }
672    Dmsg2(100, "Created Client %s record %d\n", jcr->client->hdr.name,
673       jcr->jr.ClientId);
674    return true;
675 }
676
677 bool get_or_create_fileset_record(JCR *jcr)
678 {
679    FILESET_DBR fsr;
680    /*
681     * Get or Create FileSet record
682     */
683    memset(&fsr, 0, sizeof(FILESET_DBR));
684    bstrncpy(fsr.FileSet, jcr->fileset->hdr.name, sizeof(fsr.FileSet));
685    if (jcr->fileset->have_MD5) {
686       struct MD5Context md5c;
687       unsigned char digest[MD5HashSize];
688       memcpy(&md5c, &jcr->fileset->md5c, sizeof(md5c));
689       MD5Final(digest, &md5c);
690       bin_to_base64(fsr.MD5, (char *)digest, MD5HashSize);
691       bstrncpy(jcr->fileset->MD5, fsr.MD5, sizeof(jcr->fileset->MD5));
692    } else {
693       Jmsg(jcr, M_WARNING, 0, _("FileSet MD5 digest not found.\n"));
694    }
695    if (!jcr->fileset->ignore_fs_changes ||
696        !db_get_fileset_record(jcr, jcr->db, &fsr)) {
697       if (!db_create_fileset_record(jcr, jcr->db, &fsr)) {
698          Jmsg(jcr, M_ERROR, 0, _("Could not create FileSet \"%s\" record. ERR=%s\n"),
699             fsr.FileSet, db_strerror(jcr->db));
700          return false;
701       }
702    }
703    jcr->jr.FileSetId = fsr.FileSetId;
704    bstrncpy(jcr->FSCreateTime, fsr.cCreateTime, sizeof(jcr->FSCreateTime));
705    Dmsg2(119, "Created FileSet %s record %u\n", jcr->fileset->hdr.name,
706       jcr->jr.FileSetId);
707    return true;
708 }
709
710 void init_jcr_job_record(JCR *jcr)
711 {
712    jcr->jr.SchedTime = jcr->sched_time;
713    jcr->jr.StartTime = jcr->start_time;
714    jcr->jr.EndTime = 0;               /* perhaps rescheduled, clear it */
715    jcr->jr.JobType = jcr->JobType;
716    jcr->jr.JobLevel = jcr->JobLevel;
717    jcr->jr.JobStatus = jcr->JobStatus;
718    jcr->jr.JobId = jcr->JobId;
719    bstrncpy(jcr->jr.Name, jcr->job->hdr.name, sizeof(jcr->jr.Name));
720    bstrncpy(jcr->jr.Job, jcr->Job, sizeof(jcr->jr.Job));
721 }
722
723 /*
724  * Write status and such in DB
725  */
726 void update_job_end_record(JCR *jcr)
727 {
728    jcr->jr.EndTime = time(NULL);
729    jcr->end_time = jcr->jr.EndTime;
730    jcr->jr.JobId = jcr->JobId;
731    jcr->jr.JobStatus = jcr->JobStatus;
732    jcr->jr.JobFiles = jcr->JobFiles;
733    jcr->jr.JobBytes = jcr->JobBytes;
734    jcr->jr.VolSessionId = jcr->VolSessionId;
735    jcr->jr.VolSessionTime = jcr->VolSessionTime;
736    if (!db_update_job_end_record(jcr, jcr->db, &jcr->jr)) {
737       Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"),
738          db_strerror(jcr->db));
739    }
740 }
741
742 /*
743  * Takes base_name and appends (unique) current
744  *   date and time to form unique job name.
745  *
746  *  Returns: unique job name in jcr->Job
747  *    date/time in jcr->start_time
748  */
749 void create_unique_job_name(JCR *jcr, const char *base_name)
750 {
751    /* Job start mutex */
752    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
753    static time_t last_start_time = 0;
754    time_t now;
755    struct tm tm;
756    char dt[MAX_TIME_LENGTH];
757    char name[MAX_NAME_LENGTH];
758    char *p;
759
760    /* Guarantee unique start time -- maximum one per second, and
761     * thus unique Job Name
762     */
763    P(mutex);                          /* lock creation of jobs */
764    now = time(NULL);
765    while (now == last_start_time) {
766       bmicrosleep(0, 500000);
767       now = time(NULL);
768    }
769    last_start_time = now;
770    V(mutex);                          /* allow creation of jobs */
771    jcr->start_time = now;
772    /* Form Unique JobName */
773    (void)localtime_r(&now, &tm);
774    /* Use only characters that are permitted in Windows filenames */
775    strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm);
776    bstrncpy(name, base_name, sizeof(name));
777    name[sizeof(name)-22] = 0;          /* truncate if too long */
778    bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s", name, dt); /* add date & time */
779    /* Convert spaces into underscores */
780    for (p=jcr->Job; *p; p++) {
781       if (*p == ' ') {
782          *p = '_';
783       }
784    }
785 }
786
787 /* Called directly from job rescheduling */
788 void dird_free_jcr_pointers(JCR *jcr)
789 {
790    if (jcr->sd_auth_key) {
791       free(jcr->sd_auth_key);
792       jcr->sd_auth_key = NULL;
793    }
794    if (jcr->where) {
795       free(jcr->where);
796       jcr->where = NULL;
797    }
798    if (jcr->file_bsock) {
799       Dmsg0(200, "Close File bsock\n");
800       bnet_close(jcr->file_bsock);
801       jcr->file_bsock = NULL;
802    }
803    if (jcr->store_bsock) {
804       Dmsg0(200, "Close Store bsock\n");
805       bnet_close(jcr->store_bsock);
806       jcr->store_bsock = NULL;
807    }
808    if (jcr->fname) {
809       Dmsg0(200, "Free JCR fname\n");
810       free_pool_memory(jcr->fname);
811       jcr->fname = NULL;
812    }
813    if (jcr->pool_source) {
814       free_pool_memory(jcr->pool_source);
815       jcr->pool_source = NULL;
816    }
817    if (jcr->storage_source) {
818       free_pool_memory(jcr->storage_source);
819       jcr->storage_source = NULL;
820    }
821    if (jcr->stime) {
822       Dmsg0(200, "Free JCR stime\n");
823       free_pool_memory(jcr->stime);
824       jcr->stime = NULL;
825    }
826    if (jcr->RestoreBootstrap) {
827       free(jcr->RestoreBootstrap);
828       jcr->RestoreBootstrap = NULL;
829    }
830    if (jcr->client_uname) {
831       free_pool_memory(jcr->client_uname);
832       jcr->client_uname = NULL;
833    }
834    if (jcr->attr) {
835       free_pool_memory(jcr->attr);
836       jcr->attr = NULL;
837    }
838    if (jcr->ar) {
839       free(jcr->ar);
840       jcr->ar = NULL;
841    }
842 }
843
844 /*
845  * Free the Job Control Record if no one is still using it.
846  *  Called from main free_jcr() routine in src/lib/jcr.c so
847  *  that we can do our Director specific cleanup of the jcr.
848  */
849 void dird_free_jcr(JCR *jcr)
850 {
851    Dmsg0(200, "Start dird free_jcr\n");
852
853    dird_free_jcr_pointers(jcr);
854    if (jcr->term_wait_inited) {
855       pthread_cond_destroy(&jcr->term_wait);
856       jcr->term_wait_inited = false;
857    }
858
859    /* Delete lists setup to hold storage pointers */
860    if (jcr->storage) {
861       delete jcr->storage;
862    }
863    jcr->job_end_push.destroy();
864    Dmsg0(200, "End dird free_jcr\n");
865 }
866
867 /*
868  * Set some defaults in the JCR necessary to
869  * run. These items are pulled from the job
870  * definition as defaults, but can be overridden
871  * later either by the Run record in the Schedule resource,
872  * or by the Console program.
873  */
874 void set_jcr_defaults(JCR *jcr, JOB *job)
875 {
876    jcr->job = job;
877    jcr->JobType = job->JobType;
878    switch (jcr->JobType) {
879    case JT_ADMIN:
880    case JT_RESTORE:
881       jcr->JobLevel = L_NONE;
882       break;
883    default:
884       jcr->JobLevel = job->JobLevel;
885       break;
886    }
887    if (!jcr->fname) {
888       jcr->fname = get_pool_memory(PM_FNAME);
889    }
890    if (!jcr->pool_source) {
891       jcr->pool_source = get_pool_memory(PM_MESSAGE);
892       pm_strcpy(jcr->pool_source, _("unknown source"));
893    }
894    if (!jcr->storage_source) {
895       jcr->storage_source = get_pool_memory(PM_MESSAGE);
896       pm_strcpy(jcr->storage_source, _("unknown source"));
897    }
898    jcr->JobPriority = job->Priority;
899    /* Copy storage definitions -- deleted in dir_free_jcr above */
900    copy_storage(jcr, job->storage, _("Job resource"));
901    jcr->client = job->client;
902    if (!jcr->client_name) {
903       jcr->client_name = get_pool_memory(PM_NAME);
904    }
905    pm_strcpy(jcr->client_name, jcr->client->hdr.name);
906    pm_strcpy(jcr->pool_source, _("Job resource"));
907    jcr->pool = job->pool;
908    jcr->full_pool = job->full_pool;
909    jcr->inc_pool = job->inc_pool;
910    jcr->diff_pool = job->diff_pool;
911    jcr->catalog = job->client->catalog;
912    jcr->fileset = job->fileset;
913    jcr->messages = job->messages;
914    jcr->spool_data = job->spool_data;
915    jcr->write_part_after_job = job->write_part_after_job;
916    if (jcr->RestoreBootstrap) {
917       free(jcr->RestoreBootstrap);
918       jcr->RestoreBootstrap = NULL;
919    }
920    /* This can be overridden by Console program */
921    if (job->RestoreBootstrap) {
922       jcr->RestoreBootstrap = bstrdup(job->RestoreBootstrap);
923    }
924    /* This can be overridden by Console program */
925    jcr->verify_job = job->verify_job;
926    /* If no default level given, set one */
927    if (jcr->JobLevel == 0) {
928       switch (jcr->JobType) {
929       case JT_VERIFY:
930          jcr->JobLevel = L_VERIFY_CATALOG;
931          break;
932       case JT_BACKUP:
933          jcr->JobLevel = L_INCREMENTAL;
934          break;
935       case JT_RESTORE:
936       case JT_ADMIN:
937          jcr->JobLevel = L_NONE;
938          break;
939       default:
940          break;
941       }
942    }
943 }
944
945
946 /* 
947  * Copy the storage definitions from an alist to the JCR
948  */
949 void copy_storage(JCR *jcr, alist *storage, const char *where)
950 {
951    if (storage) {
952       STORE *st;
953       if (jcr->storage) {
954          delete jcr->storage;
955       }
956       jcr->storage = New(alist(10, not_owned_by_alist));
957       foreach_alist(st, storage) {
958          jcr->storage->append(st);
959       }
960       pm_strcpy(jcr->storage_source, where);
961    }               
962    if (jcr->storage) {
963       jcr->store = (STORE *)jcr->storage->first();
964    }
965 }
966
967
968 /* Set storage override */
969 void set_storage(JCR *jcr, STORE *store)
970 {
971    STORE *storage;
972
973    jcr->store = store;
974    foreach_alist(storage, jcr->storage) {
975       if (store == storage) {
976          return;
977       }
978    }
979    /* Store not in list, so add it */
980    jcr->storage->prepend(store);
981 }
982
983 void create_clones(JCR *jcr)
984 {
985    /*
986     * Fire off any clone jobs (run directives)
987     */
988    Dmsg2(900, "cloned=%d run_cmds=%p\n", jcr->cloned, jcr->job->run_cmds);
989    if (!jcr->cloned && jcr->job->run_cmds) {
990       char *runcmd;
991       JOB *job = jcr->job;
992       POOLMEM *cmd = get_pool_memory(PM_FNAME);
993       UAContext *ua = new_ua_context(jcr);
994       ua->batch = true;
995       foreach_alist(runcmd, job->run_cmds) {
996          cmd = edit_job_codes(jcr, cmd, runcmd, "");              
997          Mmsg(ua->cmd, "run %s cloned=yes", cmd);
998          Dmsg1(900, "=============== Clone cmd=%s\n", ua->cmd);
999          parse_ua_args(ua);                 /* parse command */
1000          int stat = run_cmd(ua, ua->cmd);
1001          if (stat == 0) {
1002             Jmsg(jcr, M_ERROR, 0, _("Could not start clone job.\n"));
1003          } else {
1004             Jmsg(jcr, M_INFO, 0, _("Clone JobId %d started.\n"), stat);
1005          }
1006       }
1007       free_ua_context(ua);
1008       free_pool_memory(cmd);
1009    }
1010 }
1011
1012 bool create_restore_bootstrap_file(JCR *jcr)
1013 {
1014    RESTORE_CTX rx;
1015    UAContext *ua;
1016    memset(&rx, 0, sizeof(rx));
1017    rx.bsr = new_bsr();
1018    rx.JobIds = "";                       
1019    rx.bsr->JobId = jcr->previous_jr.JobId;
1020    ua = new_ua_context(jcr);
1021    complete_bsr(ua, rx.bsr);
1022    rx.bsr->fi = new_findex();
1023    rx.bsr->fi->findex = 1;
1024    rx.bsr->fi->findex2 = jcr->previous_jr.JobFiles;
1025    jcr->ExpectedFiles = write_bsr_file(ua, rx);
1026    if (jcr->ExpectedFiles == 0) {
1027       free_ua_context(ua);
1028       free_bsr(rx.bsr);
1029       return false;
1030    }
1031    free_ua_context(ua);
1032    free_bsr(rx.bsr);
1033    jcr->needs_sd = true;
1034    return true;
1035 }