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