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