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