]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/job.c
Rename cats_pgsql to cats_postgresql and cats_sqlite to cats_sqlite3. This makes...
[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       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.strerror(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.strerror(errstat));
114       goto bail_out;
115    }
116    jcr->term_wait_inited = true;
117
118    create_unique_job_name(jcr, jcr->job->hdr.name);
119    set_jcr_job_status(jcr, JS_Created);
120    jcr->unlock();
121
122    /*
123     * Open database
124     */
125    Dmsg0(50, "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       }
136       goto bail_out;
137    }
138    Dmsg0(50, "DB opened\n");
139
140    if (!jcr->fname) {
141       jcr->fname = get_pool_memory(PM_FNAME);
142    }
143    if (!jcr->pool_source) {
144       jcr->pool_source = get_pool_memory(PM_MESSAGE);
145       pm_strcpy(jcr->pool_source, _("unknown source"));
146    }
147
148    /*
149     * Create Job record
150     */
151    init_jcr_job_record(jcr);
152    if (!db_create_job_record(jcr, jcr->db, &jcr->jr)) {
153       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
154       goto bail_out;
155    }
156    jcr->JobId = jcr->jr.JobId;
157    Dmsg4(100, "Created job record JobId=%d Name=%s Type=%c Level=%c\n",
158        jcr->JobId, jcr->Job, jcr->jr.JobType, jcr->jr.JobLevel);
159
160    if (!get_or_create_client_record(jcr)) {
161       goto bail_out;
162    }
163
164    generate_daemon_event(jcr, "JobStart");
165
166    if (job_canceled(jcr)) {
167       goto bail_out;
168    }
169
170
171    /*
172     * Now, do pre-run stuff, like setting job level (Inc/diff, ...)
173     *  this allows us to setup a proper job start record for restarting
174     *  in case of later errors.
175     */
176    switch (jcr->JobType) {
177    case JT_BACKUP:
178       if (!do_backup_init(jcr)) {
179          backup_cleanup(jcr, JS_ErrorTerminated);
180       }
181       break;
182    case JT_VERIFY:
183       if (!do_verify_init(jcr)) {
184          verify_cleanup(jcr, JS_ErrorTerminated);
185       }
186       break;
187    case JT_RESTORE:
188       if (!do_restore_init(jcr)) {
189          restore_cleanup(jcr, JS_ErrorTerminated);
190       }
191       break;
192    case JT_ADMIN:
193       if (!do_admin_init(jcr)) {
194          admin_cleanup(jcr, JS_ErrorTerminated);
195       }
196       break;
197    case JT_MIGRATE:
198       if (!do_migration_init(jcr)) { 
199          migration_cleanup(jcr, JS_ErrorTerminated);
200       }
201       break;
202    default:
203       Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->JobType);
204       set_jcr_job_status(jcr, JS_ErrorTerminated);
205       break;
206    }
207
208    generate_job_event(jcr, "JobInit");
209    return true;
210
211 bail_out:
212    return false;
213 }
214
215
216 /*
217  * This is the engine called by jobq.c:jobq_add() when we were pulled
218  *  from the work queue.
219  *  At this point, we are running in our own thread and all
220  *    necessary resources are allocated -- see jobq.c
221  */
222 static void *job_thread(void *arg)
223 {
224    JCR *jcr = (JCR *)arg;
225
226    jcr->my_thread_id = pthread_self();
227    pthread_detach(jcr->my_thread_id);
228    sm_check(__FILE__, __LINE__, true);
229
230    Dmsg0(200, "=====Start Job=========\n");
231    set_jcr_job_status(jcr, JS_Running);   /* this will be set only if no error */
232    jcr->start_time = time(NULL);      /* set the real start time */
233    jcr->jr.StartTime = jcr->start_time;
234
235    if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
236        (utime_t)(jcr->start_time - jcr->sched_time)) {
237       Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
238       set_jcr_job_status(jcr, JS_Canceled);
239    }
240
241    /* TODO : check if it is used somewhere */
242    if (jcr->job->RunScripts == NULL) {
243       Dmsg0(200, "Warning, job->RunScripts is empty\n");
244       jcr->job->RunScripts = New(alist(10, not_owned_by_alist));
245    }
246
247    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
248       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
249    }
250
251    /* Run any script BeforeJob on dird */
252    run_scripts(jcr, jcr->job->RunScripts, "BeforeJob");
253
254    if (job_canceled(jcr)) {
255       update_job_end_record(jcr);
256
257    } else {
258       /*
259        * We re-update the job start record so that the start
260        *  time is set after the run before job.  This avoids
261        *  that any files created by the run before job will
262        *  be saved twice.  They will be backed up in the current
263        *  job, but not in the next one unless they are changed.
264        *  Without this, they will be backed up in this job and
265        *  in the next job run because in that case, their date
266        *   is after the start of this run.
267        */
268       jcr->start_time = time(NULL);
269       jcr->jr.StartTime = jcr->start_time;
270       if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
271          Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
272       }
273       generate_job_event(jcr, "JobRun");
274
275       switch (jcr->JobType) {
276       case JT_BACKUP:
277          if (do_backup(jcr)) {
278             do_autoprune(jcr);
279          } else {
280             backup_cleanup(jcr, JS_ErrorTerminated);
281          }
282          break;
283       case JT_VERIFY:
284          if (do_verify(jcr)) {
285             do_autoprune(jcr);
286          } else {
287             verify_cleanup(jcr, JS_ErrorTerminated);
288          }
289          break;
290       case JT_RESTORE:
291          if (do_restore(jcr)) {
292             do_autoprune(jcr);
293          } else {
294             restore_cleanup(jcr, JS_ErrorTerminated);
295          }
296          break;
297       case JT_ADMIN:
298          if (do_admin(jcr)) {
299             do_autoprune(jcr);
300          } else {
301             admin_cleanup(jcr, JS_ErrorTerminated);
302          }
303          break;
304       case JT_MIGRATE:
305       case JT_COPY:
306       case JT_ARCHIVE:
307          if (do_migration(jcr)) {
308             do_autoprune(jcr);
309          } else {
310             migration_cleanup(jcr, JS_ErrorTerminated);
311          }
312          break;
313       default:
314          Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->JobType);
315          break;
316       }
317
318       run_scripts(jcr, jcr->job->RunScripts, "AfterJob");
319
320       /* Send off any queued messages */
321       if (jcr->msg_queue && jcr->msg_queue->size() > 0) {
322          dequeue_messages(jcr);
323       }
324    }
325
326    generate_daemon_event(jcr, "JobEnd");
327    Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus);
328    sm_check(__FILE__, __LINE__, true);
329    return NULL;
330 }
331
332
333 /*
334  * Cancel a job -- typically called by the UA (Console program), but may also
335  *              be called by the job watchdog.
336  *
337  *  Returns: true  if cancel appears to be successful
338  *           false on failure. Message sent to ua->jcr.
339  */
340 bool cancel_job(UAContext *ua, JCR *jcr)
341 {
342    BSOCK *sd, *fd;
343
344    set_jcr_job_status(jcr, JS_Canceled);
345
346    switch (jcr->JobStatus) {
347    case JS_Created:
348    case JS_WaitJobRes:
349    case JS_WaitClientRes:
350    case JS_WaitStoreRes:
351    case JS_WaitPriority:
352    case JS_WaitMaxJobs:
353    case JS_WaitStartTime:
354       bsendmsg(ua, _("JobId %d, Job %s marked to be canceled.\n"),
355               jcr->JobId, jcr->Job);
356       jobq_remove(&job_queue, jcr); /* attempt to remove it from queue */
357       return true;
358
359    default:
360       /* Cancel File daemon */
361       if (jcr->file_bsock) {
362          ua->jcr->client = jcr->client;
363          if (!connect_to_file_daemon(ua->jcr, 10, FDConnectTimeout, 1)) {
364             bsendmsg(ua, _("Failed to connect to File daemon.\n"));
365             return 0;
366          }
367          Dmsg0(200, "Connected to file daemon\n");
368          fd = ua->jcr->file_bsock;
369          bnet_fsend(fd, "cancel Job=%s\n", jcr->Job);
370          while (bnet_recv(fd) >= 0) {
371             bsendmsg(ua, "%s", fd->msg);
372          }
373          bnet_sig(fd, BNET_TERMINATE);
374          bnet_close(fd);
375          ua->jcr->file_bsock = NULL;
376       }
377
378       /* Cancel Storage daemon */
379       if (jcr->store_bsock) {
380          if (!ua->jcr->wstorage) {
381             if (jcr->rstorage) {
382                copy_wstorage(ua->jcr, jcr->rstorage, _("Job resource")); 
383             } else {
384                copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource")); 
385             }
386          } else {
387             USTORE store;
388             if (jcr->rstorage) {
389                store.store = jcr->rstore;
390                pm_strcpy(store.store_source, jcr->rstore_source);
391             } else {
392                store.store = jcr->wstore;
393                pm_strcpy(store.store_source, jcr->wstore_source);
394             }
395             set_wstorage(ua->jcr, &store);
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->wstore_source) {
838       free_pool_memory(jcr->wstore_source);
839       jcr->wstore_source = NULL;
840    }
841    if (jcr->rstore_source) {
842       free_pool_memory(jcr->rstore_source);
843       jcr->rstore_source = NULL;
844    }
845    if (jcr->stime) {
846       Dmsg0(200, "Free JCR stime\n");
847       free_pool_memory(jcr->stime);
848       jcr->stime = NULL;
849    }
850    if (jcr->RestoreBootstrap) {
851       free(jcr->RestoreBootstrap);
852       jcr->RestoreBootstrap = NULL;
853    }
854    if (jcr->client_uname) {
855       free_pool_memory(jcr->client_uname);
856       jcr->client_uname = NULL;
857    }
858    if (jcr->attr) {
859       free_pool_memory(jcr->attr);
860       jcr->attr = NULL;
861    }
862    if (jcr->ar) {
863       free(jcr->ar);
864       jcr->ar = NULL;
865    }
866 }
867
868 /*
869  * Free the Job Control Record if no one is still using it.
870  *  Called from main free_jcr() routine in src/lib/jcr.c so
871  *  that we can do our Director specific cleanup of the jcr.
872  */
873 void dird_free_jcr(JCR *jcr)
874 {
875    Dmsg0(200, "Start dird free_jcr\n");
876
877    dird_free_jcr_pointers(jcr);
878    if (jcr->term_wait_inited) {
879       pthread_cond_destroy(&jcr->term_wait);
880       jcr->term_wait_inited = false;
881    }
882
883    /* Delete lists setup to hold storage pointers */
884    free_rwstorage(jcr);
885
886    jcr->job_end_push.destroy();
887    Dmsg0(200, "End dird free_jcr\n");
888 }
889
890 /* 
891  * The Job storage definition must be either in the Job record
892  *  or in the Pool record.  The Pool record overrides the Job 
893  *  record.
894  */
895 void get_job_storage(USTORE *store, JOB *job, RUN *run) 
896 {
897    if (run && run->pool && run->pool->storage) {
898       store->store = (STORE *)run->pool->storage->first();
899       pm_strcpy(store->store_source, _("Run pool override"));
900       return;
901    }
902    if (run && run->storage) {
903       store->store = run->storage;
904       pm_strcpy(store->store_source, _("Run storage override"));
905       return;
906    }
907    if (job->pool->storage) {
908       store->store = (STORE *)job->pool->storage->first();
909       pm_strcpy(store->store_source, _("Pool resource"));
910    } else {
911       store->store = (STORE *)job->storage->first();
912       pm_strcpy(store->store_source, _("Job resource"));
913    }
914 }
915
916 /*
917  * Set some defaults in the JCR necessary to
918  * run. These items are pulled from the job
919  * definition as defaults, but can be overridden
920  * later either by the Run record in the Schedule resource,
921  * or by the Console program.
922  */
923 void set_jcr_defaults(JCR *jcr, JOB *job)
924 {
925    jcr->job = job;
926    jcr->JobType = job->JobType;
927    switch (jcr->JobType) {
928    case JT_ADMIN:
929    case JT_RESTORE:
930       jcr->JobLevel = L_NONE;
931       break;
932    default:
933       jcr->JobLevel = job->JobLevel;
934       break;
935    }
936    if (!jcr->fname) {
937       jcr->fname = get_pool_memory(PM_FNAME);
938    }
939    if (!jcr->pool_source) {
940       jcr->pool_source = get_pool_memory(PM_MESSAGE);
941       pm_strcpy(jcr->pool_source, _("unknown source"));
942    }
943    jcr->JobPriority = job->Priority;
944    /* Copy storage definitions -- deleted in dir_free_jcr above */
945    if (job->storage) {
946       copy_rwstorage(jcr, job->storage, _("Job resource"));
947    } else {
948       copy_rwstorage(jcr, job->pool->storage, _("Pool resource"));
949    }
950    jcr->client = job->client;
951    if (!jcr->client_name) {
952       jcr->client_name = get_pool_memory(PM_NAME);
953    }
954    pm_strcpy(jcr->client_name, jcr->client->hdr.name);
955    pm_strcpy(jcr->pool_source, _("Job resource"));
956    jcr->pool = job->pool;
957    jcr->full_pool = job->full_pool;
958    jcr->inc_pool = job->inc_pool;
959    jcr->diff_pool = job->diff_pool;
960    jcr->catalog = job->client->catalog;
961    jcr->fileset = job->fileset;
962    jcr->messages = job->messages;
963    jcr->spool_data = job->spool_data;
964    jcr->write_part_after_job = job->write_part_after_job;
965    if (jcr->RestoreBootstrap) {
966       free(jcr->RestoreBootstrap);
967       jcr->RestoreBootstrap = NULL;
968    }
969    /* This can be overridden by Console program */
970    if (job->RestoreBootstrap) {
971       jcr->RestoreBootstrap = bstrdup(job->RestoreBootstrap);
972    }
973    /* This can be overridden by Console program */
974    jcr->verify_job = job->verify_job;
975    /* If no default level given, set one */
976    if (jcr->JobLevel == 0) {
977       switch (jcr->JobType) {
978       case JT_VERIFY:
979          jcr->JobLevel = L_VERIFY_CATALOG;
980          break;
981       case JT_BACKUP:
982          jcr->JobLevel = L_INCREMENTAL;
983          break;
984       case JT_RESTORE:
985       case JT_ADMIN:
986          jcr->JobLevel = L_NONE;
987          break;
988       default:
989          jcr->JobLevel = L_FULL;
990          break;
991       }
992    }
993 }
994
995 /* 
996  * Copy the storage definitions from an alist to the JCR
997  */
998 void copy_rwstorage(JCR *jcr, alist *storage, const char *where)
999 {
1000    switch(jcr->JobType) {
1001    case JT_RESTORE:
1002    case JT_VERIFY:
1003    case JT_MIGRATE:
1004       copy_rstorage(jcr, storage, where);
1005       break;
1006    default:
1007       copy_wstorage(jcr, storage, where);
1008       break;
1009    }
1010 }
1011
1012
1013 /* Set storage override */
1014 void set_rwstorage(JCR *jcr, USTORE *store)
1015 {
1016    if (!store) {
1017       Jmsg(jcr, M_FATAL, 0, _("No storage specified.\n"));
1018       return;
1019    }
1020    switch(jcr->JobType) {
1021    case JT_RESTORE:
1022    case JT_VERIFY:
1023    case JT_MIGRATE:
1024       set_rstorage(jcr, store);
1025       break;
1026    default:
1027       set_wstorage(jcr, store);
1028       break;
1029    }
1030 }
1031
1032 void free_rwstorage(JCR *jcr)
1033 {
1034    free_rstorage(jcr);
1035    free_wstorage(jcr);
1036 }
1037
1038 /* 
1039  * Copy the storage definitions from an alist to the JCR
1040  */
1041 void copy_rstorage(JCR *jcr, alist *storage, const char *where)
1042 {
1043    if (storage) {
1044       STORE *st;
1045       if (jcr->rstorage) {
1046          delete jcr->rstorage;
1047       }
1048       jcr->rstorage = New(alist(10, not_owned_by_alist));
1049       foreach_alist(st, storage) {
1050          jcr->rstorage->append(st);
1051       }
1052       if (!jcr->rstore_source) {
1053          jcr->rstore_source = get_pool_memory(PM_MESSAGE);
1054       }
1055       pm_strcpy(jcr->rstore_source, where);
1056       if (jcr->rstorage) {
1057          jcr->rstore = (STORE *)jcr->rstorage->first();
1058       }
1059    }
1060 }
1061
1062
1063 /* Set storage override */
1064 void set_rstorage(JCR *jcr, USTORE *store)
1065 {
1066    STORE *storage;
1067
1068    if (!store->store) {
1069       return;
1070    }
1071    if (!jcr->rstorage) {
1072       jcr->rstorage = New(alist(10, not_owned_by_alist));
1073    }
1074    jcr->rstore = store->store;
1075    if (!jcr->rstore_source) {
1076       jcr->rstore_source = get_pool_memory(PM_MESSAGE);
1077    }
1078    pm_strcpy(jcr->rstore_source, store->store_source);
1079    foreach_alist(storage, jcr->rstorage) {
1080       if (store->store == storage) {
1081          return;
1082       }
1083    }
1084    /* Store not in list, so add it */
1085    jcr->rstorage->prepend(store->store);
1086 }
1087
1088 void free_rstorage(JCR *jcr)
1089 {
1090    if (jcr->rstorage) {
1091       delete jcr->rstorage;
1092       jcr->rstorage = NULL;
1093    }
1094    jcr->rstore = NULL;
1095 }
1096
1097 /* 
1098  * Copy the storage definitions from an alist to the JCR
1099  */
1100 void copy_wstorage(JCR *jcr, alist *storage, const char *where)
1101 {
1102    if (storage) {
1103       STORE *st;
1104       if (jcr->wstorage) {
1105          delete jcr->wstorage;
1106       }
1107       jcr->wstorage = New(alist(10, not_owned_by_alist));
1108       foreach_alist(st, storage) {
1109          Dmsg1(50, "storage=%s\n", st->name());
1110          jcr->wstorage->append(st);
1111       }
1112       if (!jcr->wstore_source) {
1113          jcr->wstore_source = get_pool_memory(PM_MESSAGE);
1114       }
1115       pm_strcpy(jcr->wstore_source, where);
1116       if (jcr->wstorage) {
1117          jcr->wstore = (STORE *)jcr->wstorage->first();
1118          Dmsg2(100, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
1119       }
1120    }
1121 }
1122
1123
1124 /* Set storage override */
1125 void set_wstorage(JCR *jcr, USTORE *store)
1126 {
1127    STORE *storage;
1128
1129    if (!store->store) {
1130       return;
1131    }
1132    if (!jcr->wstorage) {
1133       jcr->wstorage = New(alist(10, not_owned_by_alist));
1134    }
1135    jcr->wstore = store->store;
1136    if (!jcr->wstore_source) {
1137       jcr->wstore_source = get_pool_memory(PM_MESSAGE);
1138    }
1139    pm_strcpy(jcr->wstore_source, store->store_source);
1140    Dmsg2(50, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
1141    foreach_alist(storage, jcr->wstorage) {
1142       if (store->store == storage) {
1143          return;
1144       }
1145    }
1146    /* Store not in list, so add it */
1147    jcr->wstorage->prepend(store->store);
1148 }
1149
1150 void free_wstorage(JCR *jcr)
1151 {
1152    if (jcr->wstorage) {
1153       delete jcr->wstorage;
1154       jcr->wstorage = NULL;
1155    }
1156    jcr->wstore = NULL;
1157 }
1158
1159 void create_clones(JCR *jcr)
1160 {
1161    /*
1162     * Fire off any clone jobs (run directives)
1163     */
1164    Dmsg2(900, "cloned=%d run_cmds=%p\n", jcr->cloned, jcr->job->run_cmds);
1165    if (!jcr->cloned && jcr->job->run_cmds) {
1166       char *runcmd;
1167       JOB *job = jcr->job;
1168       POOLMEM *cmd = get_pool_memory(PM_FNAME);
1169       UAContext *ua = new_ua_context(jcr);
1170       ua->batch = true;
1171       foreach_alist(runcmd, job->run_cmds) {
1172          cmd = edit_job_codes(jcr, cmd, runcmd, "");              
1173          Mmsg(ua->cmd, "run %s cloned=yes", cmd);
1174          Dmsg1(900, "=============== Clone cmd=%s\n", ua->cmd);
1175          parse_ua_args(ua);                 /* parse command */
1176          int stat = run_cmd(ua, ua->cmd);
1177          if (stat == 0) {
1178             Jmsg(jcr, M_ERROR, 0, _("Could not start clone job.\n"));
1179          } else {
1180             Jmsg(jcr, M_INFO, 0, _("Clone JobId %d started.\n"), stat);
1181          }
1182       }
1183       free_ua_context(ua);
1184       free_pool_memory(cmd);
1185    }
1186 }
1187
1188 bool create_restore_bootstrap_file(JCR *jcr)
1189 {
1190    RESTORE_CTX rx;
1191    UAContext *ua;
1192    memset(&rx, 0, sizeof(rx));
1193    rx.bsr = new_bsr();
1194    rx.JobIds = "";                       
1195    rx.bsr->JobId = jcr->previous_jr.JobId;
1196    ua = new_ua_context(jcr);
1197    complete_bsr(ua, rx.bsr);
1198    rx.bsr->fi = new_findex();
1199    rx.bsr->fi->findex = 1;
1200    rx.bsr->fi->findex2 = jcr->previous_jr.JobFiles;
1201    jcr->ExpectedFiles = write_bsr_file(ua, rx);
1202    if (jcr->ExpectedFiles == 0) {
1203       free_ua_context(ua);
1204       free_bsr(rx.bsr);
1205       return false;
1206    }
1207    free_ua_context(ua);
1208    free_bsr(rx.bsr);
1209    jcr->needs_sd = true;
1210    return true;
1211 }