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