]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/job.c
985469926783f7943d9b1046032adea634cfeb85
[bacula/bacula] / bacula / src / dird / job.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from many
7    others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    Bacula® is a registered trademark of Kern Sibbald.
15 */
16 /*
17  *
18  *   Bacula Director Job processing routines
19  *
20  *     Kern Sibbald, October MM
21  *
22  */
23
24 #include "bacula.h"
25 #include "dird.h"
26
27 /* Forward referenced subroutines */
28 static void *job_thread(void *arg);
29 static void job_monitor_watchdog(watchdog_t *self);
30 static void job_monitor_destructor(watchdog_t *self);
31 static bool job_check_maxwaittime(JCR *jcr);
32 static bool job_check_maxruntime(JCR *jcr);
33 static bool job_check_maxrunschedtime(JCR *jcr);
34
35 /* Imported subroutines */
36 extern void term_scheduler();
37 extern void term_ua_server();
38
39 /* Imported variables */
40
41 jobq_t job_queue;
42
43 void init_job_server(int max_workers)
44 {
45    int stat;
46    watchdog_t *wd;
47
48    if ((stat = jobq_init(&job_queue, max_workers, job_thread)) != 0) {
49       berrno be;
50       Emsg1(M_ABORT, 0, _("Could not init job queue: ERR=%s\n"), be.bstrerror(stat));
51    }
52    wd = new_watchdog();
53    wd->callback = job_monitor_watchdog;
54    wd->destructor = job_monitor_destructor;
55    wd->one_shot = false;
56    wd->interval = 60;
57    wd->data = new_control_jcr("*JobMonitor*", JT_SYSTEM);
58    register_watchdog(wd);
59 }
60
61 void term_job_server()
62 {
63    jobq_destroy(&job_queue);          /* ignore any errors */
64 }
65
66 /*
67  * Run a job -- typically called by the scheduler, but may also
68  *              be called by the UA (Console program).
69  *
70  *  Returns: 0 on failure
71  *           JobId on success
72  *
73  */
74 JobId_t run_job(JCR *jcr)
75 {
76    int stat;
77    if (setup_job(jcr)) {
78       Dmsg0(200, "Add jrc to work queue\n");
79       /* Queue the job to be run */
80       if ((stat = jobq_add(&job_queue, jcr)) != 0) {
81          berrno be;
82          Jmsg(jcr, M_FATAL, 0, _("Could not add job queue: ERR=%s\n"), be.bstrerror(stat));
83          return 0;
84       }
85       return jcr->JobId;
86    }
87    return 0;
88 }
89
90 bool setup_job(JCR *jcr)
91 {
92    int errstat;
93
94    jcr->lock();
95    Dsm_check(100);
96    init_msg(jcr, jcr->messages, job_code_callback_director);
97
98    /* Initialize termination condition variable */
99    if ((errstat = pthread_cond_init(&jcr->term_wait, NULL)) != 0) {
100       berrno be;
101       Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
102       jcr->unlock();
103       goto bail_out;
104    }
105    jcr->term_wait_inited = true;
106
107    create_unique_job_name(jcr, jcr->job->name());
108    jcr->setJobStatus(JS_Created);
109    jcr->unlock();
110
111    /*
112     * Open database
113     */
114    Dmsg0(100, "Open database\n");
115    jcr->db = db_init_database(jcr, jcr->catalog->db_driver, jcr->catalog->db_name,
116                               jcr->catalog->db_user, jcr->catalog->db_password,
117                               jcr->catalog->db_address, jcr->catalog->db_port,
118                               jcr->catalog->db_socket, jcr->catalog->mult_db_connections,
119                               jcr->catalog->disable_batch_insert);
120    if (!jcr->db || !db_open_database(jcr, jcr->db)) {
121       Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"),
122                  jcr->catalog->db_name);
123       if (jcr->db) {
124          Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
125          db_close_database(jcr, jcr->db);
126       }
127       goto bail_out;
128    }
129    Dmsg0(150, "DB opened\n");
130    if (!jcr->fname) {
131       jcr->fname = get_pool_memory(PM_FNAME);
132    }
133    if (!jcr->pool_source) {
134       jcr->pool_source = get_pool_memory(PM_MESSAGE);
135       pm_strcpy(jcr->pool_source, _("unknown source"));
136    }
137    if (!jcr->next_pool_source) {
138       jcr->next_pool_source = get_pool_memory(PM_MESSAGE);
139       pm_strcpy(jcr->next_pool_source, _("unknown source"));
140    }
141
142    if (jcr->JobReads()) {
143       if (!jcr->rpool_source) {
144          jcr->rpool_source = get_pool_memory(PM_MESSAGE);
145          pm_strcpy(jcr->rpool_source, _("unknown source"));
146       }
147    }
148
149    /*
150     * Create Job record
151     */
152    init_jcr_job_record(jcr);
153    if (!get_or_create_client_record(jcr)) {
154       goto bail_out;
155    }
156
157    if (!db_create_job_record(jcr, jcr->db, &jcr->jr)) {
158       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
159       goto bail_out;
160    }
161    jcr->JobId = jcr->jr.JobId;
162    Dmsg4(100, "Created job record JobId=%d Name=%s Type=%c Level=%c\n",
163        jcr->JobId, jcr->Job, jcr->jr.JobType, jcr->jr.JobLevel);
164
165    generate_daemon_event(jcr, "JobStart");
166    new_plugins(jcr);                  /* instantiate plugins for this jcr */
167    generate_plugin_event(jcr, bDirEventJobStart);
168
169    if (job_canceled(jcr)) {
170       goto bail_out;
171    }
172
173    if (jcr->JobReads() && !jcr->rstorage) {
174       if (jcr->job->storage) {
175          copy_rwstorage(jcr, jcr->job->storage, _("Job resource"));
176       } else {
177          copy_rwstorage(jcr, jcr->job->pool->storage, _("Pool resource"));
178       }
179    }
180    if (!jcr->JobReads()) {
181       free_rstorage(jcr);
182    }
183
184    /*
185     * Now, do pre-run stuff, like setting job level (Inc/diff, ...)
186     *  this allows us to setup a proper job start record for restarting
187     *  in case of later errors.
188     */
189    switch (jcr->getJobType()) {
190    case JT_BACKUP:
191       if (!do_backup_init(jcr)) {
192          backup_cleanup(jcr, JS_ErrorTerminated);
193          goto bail_out;
194       }
195       break;
196    case JT_VERIFY:
197       if (!do_verify_init(jcr)) {
198          verify_cleanup(jcr, JS_ErrorTerminated);
199          goto bail_out;
200       }
201       break;
202    case JT_RESTORE:
203       if (!do_restore_init(jcr)) {
204          restore_cleanup(jcr, JS_ErrorTerminated);
205          goto bail_out;
206       }
207       break;
208    case JT_ADMIN:
209       if (!do_admin_init(jcr)) {
210          admin_cleanup(jcr, JS_ErrorTerminated);
211          goto bail_out;
212       }
213       break;
214    case JT_COPY:
215    case JT_MIGRATE:
216       if (!do_mac_init(jcr)) {
217          mac_cleanup(jcr, JS_ErrorTerminated, JS_ErrorTerminated);
218          goto bail_out;
219       }
220       break;
221    default:
222       Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->getJobType());
223       jcr->setJobStatus(JS_ErrorTerminated);
224       goto bail_out;
225    }
226
227    generate_plugin_event(jcr, bDirEventJobInit);
228    Dsm_check(100);
229    return true;
230
231 bail_out:
232    return false;
233 }
234
235 void update_job_end(JCR *jcr, int TermCode)
236 {
237    dequeue_messages(jcr);             /* display any queued messages */
238    jcr->setJobStatus(TermCode);
239    update_job_end_record(jcr);
240 }
241
242 /*
243  * This is the engine called by jobq.c:jobq_add() when we were pulled
244  *  from the work queue.
245  *  At this point, we are running in our own thread and all
246  *    necessary resources are allocated -- see jobq.c
247  */
248 static void *job_thread(void *arg)
249 {
250    JCR *jcr = (JCR *)arg;
251
252    pthread_detach(pthread_self());
253    Dsm_check(100);
254
255    Dmsg0(200, "=====Start Job=========\n");
256    jcr->setJobStatus(JS_Running);   /* this will be set only if no error */
257    jcr->start_time = time(NULL);      /* set the real start time */
258    jcr->jr.StartTime = jcr->start_time;
259
260    if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
261        (utime_t)(jcr->start_time - jcr->sched_time)) {
262       jcr->setJobStatus(JS_Canceled);
263       Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
264    }
265
266    if (job_check_maxrunschedtime(jcr)) {
267       jcr->setJobStatus(JS_Canceled);
268       Jmsg(jcr, M_FATAL, 0, _("Job canceled because max run sched time exceeded.\n"));
269    }
270
271    /* TODO : check if it is used somewhere */
272    if (jcr->job->RunScripts == NULL) {
273       Dmsg0(200, "Warning, job->RunScripts is empty\n");
274       jcr->job->RunScripts = New(alist(10, not_owned_by_alist));
275    }
276
277    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
278       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
279    }
280
281    /* Run any script BeforeJob on dird */
282    run_scripts(jcr, jcr->job->RunScripts, "BeforeJob");
283
284    /*
285     * We re-update the job start record so that the start
286     *  time is set after the run before job.  This avoids
287     *  that any files created by the run before job will
288     *  be saved twice.  They will be backed up in the current
289     *  job, but not in the next one unless they are changed.
290     *  Without this, they will be backed up in this job and
291     *  in the next job run because in that case, their date
292     *   is after the start of this run.
293     */
294    jcr->start_time = time(NULL);
295    jcr->jr.StartTime = jcr->start_time;
296    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
297       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
298    }
299    generate_plugin_event(jcr, bDirEventJobRun);
300
301    switch (jcr->getJobType()) {
302    case JT_BACKUP:
303       if (!job_canceled(jcr) && do_backup(jcr)) {
304          do_autoprune(jcr);
305       } else {
306          backup_cleanup(jcr, JS_ErrorTerminated);
307       }
308       break;
309    case JT_VERIFY:
310       if (!job_canceled(jcr) && do_verify(jcr)) {
311          do_autoprune(jcr);
312       } else {
313          verify_cleanup(jcr, JS_ErrorTerminated);
314       }
315       break;
316    case JT_RESTORE:
317       if (!job_canceled(jcr) && do_restore(jcr)) {
318          do_autoprune(jcr);
319       } else {
320          restore_cleanup(jcr, JS_ErrorTerminated);
321       }
322       break;
323    case JT_ADMIN:
324       if (!job_canceled(jcr) && do_admin(jcr)) {
325          do_autoprune(jcr);
326       } else {
327          admin_cleanup(jcr, JS_ErrorTerminated);
328       }
329       break;
330    case JT_COPY:
331    case JT_MIGRATE:
332       if (!job_canceled(jcr) && do_mac(jcr)) {
333          do_autoprune(jcr);
334       } else {
335          mac_cleanup(jcr, JS_ErrorTerminated, JS_ErrorTerminated);
336       }
337       break;
338    default:
339       Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->getJobType());
340       break;
341    }
342
343    run_scripts(jcr, jcr->job->RunScripts, "AfterJob");
344
345    /* Send off any queued messages */
346    if (jcr->msg_queue && jcr->msg_queue->size() > 0) {
347       dequeue_messages(jcr);
348    }
349
350    generate_daemon_event(jcr, "JobEnd");
351    generate_plugin_event(jcr, bDirEventJobEnd);
352    Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus);
353    Dsm_check(100);
354    return NULL;
355 }
356
357 void sd_msg_thread_send_signal(JCR *jcr, int sig)
358 {
359    jcr->lock();
360    if (  !jcr->sd_msg_thread_done
361        && jcr->SD_msg_chan_started
362        && !pthread_equal(jcr->SD_msg_chan, pthread_self()))
363    {
364       Dmsg1(800, "Send kill to SD msg chan jid=%d\n", jcr->JobId);
365       pthread_kill(jcr->SD_msg_chan, sig);
366    }
367    jcr->unlock();
368 }
369
370 static int cancel_file_daemon_job(UAContext *ua, const char *cmd, JCR *jcr)
371 {
372    if (!jcr->client) {
373       Dmsg0(100, "No client to cancel\n");
374       return 0;
375    }
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(100, "Connected to file daemon\n");
382    BSOCK *fd = ua->jcr->file_bsock;
383    fd->fsend("%s Job=%s\n", cmd, jcr->Job);
384    while (fd->recv() >= 0) {
385       ua->send_msg("%s", fd->msg);
386    }
387    fd->signal(BNET_TERMINATE);
388    free_bsock(ua->jcr->file_bsock);
389    ua->jcr->client = NULL;
390    return 1;
391 }
392
393 static bool cancel_sd_job(UAContext *ua, const char *cmd, JCR *jcr)
394 {
395    if (jcr->store_bsock) {
396       if (jcr->rstorage) {
397          copy_wstorage(ua->jcr, jcr->rstorage, _("Job resource"));
398       } else {
399          copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource"));
400       }
401    } else {
402       USTORE store;
403       if (jcr->rstorage) {
404          store.store = jcr->rstore;
405       } else {
406          store.store = jcr->wstore;
407       }
408       set_wstorage(ua->jcr, &store);
409    }
410
411    if (!ua->jcr->wstore) {
412       ua->error_msg(_("Failed to select Storage daemon.\n"));
413       return false;
414    }
415
416    if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
417       ua->error_msg(_("Failed to connect to Storage daemon.\n"));
418       return false;
419    }
420    Dmsg0(200, "Connected to storage daemon\n");
421    BSOCK *sd = ua->jcr->store_bsock;
422    sd->fsend("%s Job=%s\n", cmd, jcr->Job);
423    while (sd->recv() >= 0) {
424       ua->send_msg("%s", sd->msg);
425    }
426    sd->signal(BNET_TERMINATE);
427    free_bsock(ua->jcr->store_bsock);
428    return true;
429 }
430
431 /* The FD is not connected, so we try to complete JCR fields and send
432  * the cancel command.
433  */
434 static int cancel_inactive_job(UAContext *ua, JCR *jcr)
435 {
436    CLIENT_DBR cr;
437    JOB_DBR    jr;
438    int        i;
439    USTORE     store;
440
441    if (!jcr->client) {
442       memset(&cr, 0, sizeof(cr));
443
444       /* User is kind enough to provide the client name */
445       if ((i = find_arg_with_value(ua, "client")) > 0) {
446          bstrncpy(cr.Name, ua->argv[i], sizeof(cr.Name));
447
448       } else {
449          memset(&jr, 0, sizeof(jr));
450          bstrncpy(jr.Job, jcr->Job, sizeof(jr.Job));
451
452          if (!open_client_db(ua)) {
453             goto bail_out;
454          }
455          if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
456             goto bail_out;
457          }
458          cr.ClientId = jr.ClientId;
459          if (!cr.ClientId || !db_get_client_record(ua->jcr, ua->db, &cr)) {
460             goto bail_out;
461          }
462       }
463
464       if (acl_access_ok(ua, Client_ACL, cr.Name)) {
465          jcr->client = (CLIENT *)GetResWithName(R_CLIENT, cr.Name);
466       }
467    }
468
469    cancel_file_daemon_job(ua, "cancel", jcr);
470
471    /* At this time, we can't really guess the storage name from
472     * the job record
473     */
474    store.store = get_storage_resource(ua, false/*no default*/, true/*unique*/);
475    if (!store.store) {
476       goto bail_out;
477    }
478
479    set_wstorage(ua->jcr, &store);
480
481    cancel_sd_job(ua, "cancel", jcr);
482
483 bail_out:
484    return 1;
485 }
486
487 /*
488  * Cancel a job -- typically called by the UA (Console program), but may also
489  *              be called by the job watchdog.
490  *
491  *  Returns: true  if cancel appears to be successful
492  *           false on failure. Message sent to ua->jcr.
493  */
494 bool cancel_job(UAContext *ua, JCR *jcr, bool cancel)
495 {
496    char ed1[50];
497    int32_t old_status = jcr->JobStatus;
498    int status;
499    const char *reason, *cmd;
500    bool force = find_arg(ua, "inactive") > 0;
501    JCR *wjcr = jcr->wjcr;
502
503
504    /* If the user explicitely ask, we can send the cancel command to
505     * the FD.
506     */
507    if (cancel && force) {
508       return cancel_inactive_job(ua, jcr);
509    }
510
511    status = JS_Canceled;
512    reason = _("canceled");
513    cmd = NT_("cancel");
514
515    jcr->setJobStatus(status);
516
517    switch (old_status) {
518    case JS_Created:
519    case JS_WaitJobRes:
520    case JS_WaitClientRes:
521    case JS_WaitStoreRes:
522    case JS_WaitPriority:
523    case JS_WaitMaxJobs:
524    case JS_WaitStartTime:
525    case JS_WaitDevice:
526       ua->info_msg(_("JobId %s, Job %s marked to be %s.\n"),
527               edit_uint64(jcr->JobId, ed1), jcr->Job,
528               reason);
529       jobq_remove(&job_queue, jcr); /* attempt to remove it from queue */
530       break;
531
532    default:
533
534       /* Cancel File daemon */
535       if (jcr->file_bsock) {
536          /* do not return now, we want to try to cancel the sd */
537          cancel_file_daemon_job(ua, cmd, jcr);
538       }
539
540       /* We test file_bsock because the previous operation can take
541        * several minutes
542        */
543       if (jcr->file_bsock && cancel) {
544          jcr->file_bsock->set_terminated();
545          jcr->my_thread_send_signal(TIMEOUT_SIGNAL);
546       }
547
548       /* Cancel Storage daemon */
549       if (jcr->store_bsock) {
550          /* do not return now, we want to try to cancel the sd socket */
551          cancel_sd_job(ua, cmd, jcr);
552       }
553
554       /* We test file_bsock because the previous operation can take
555        * several minutes
556        */
557       if (jcr->store_bsock && cancel) {
558          jcr->store_bsock->set_timed_out();
559          jcr->store_bsock->set_terminated();
560          sd_msg_thread_send_signal(jcr, TIMEOUT_SIGNAL);
561          jcr->my_thread_send_signal(TIMEOUT_SIGNAL);
562       }
563
564       /* Cancel Copy/Migration Storage daemon */
565       if (wjcr  && wjcr->store_bsock) {
566          /* do not return now, we want to try to cancel the sd socket */
567          cancel_sd_job(ua, cmd, wjcr);
568
569          /* We test file_bsock because the previous operation can take
570           * several minutes
571           */
572          if (wjcr->store_bsock && cancel) {
573             wjcr->store_bsock->set_timed_out();
574             wjcr->store_bsock->set_terminated();
575             sd_msg_thread_send_signal(wjcr, TIMEOUT_SIGNAL);
576             wjcr->my_thread_send_signal(TIMEOUT_SIGNAL);
577          }
578       }
579       break;
580    }
581
582    return true;
583 }
584
585 void cancel_storage_daemon_job(JCR *jcr)
586 {
587    if (jcr->sd_canceled) {
588       return;                   /* cancel only once */
589    }
590
591    UAContext *ua = new_ua_context(jcr);
592    JCR *control_jcr = new_control_jcr("*JobCancel*", JT_SYSTEM);
593    BSOCK *sd;
594
595    ua->jcr = control_jcr;
596    if (jcr->store_bsock) {
597       if (!ua->jcr->wstorage) {
598          if (jcr->rstorage) {
599             copy_wstorage(ua->jcr, jcr->rstorage, _("Job resource"));
600          } else {
601             copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource"));
602          }
603       } else {
604          USTORE store;
605          if (jcr->rstorage) {
606             store.store = jcr->rstore;
607          } else {
608             store.store = jcr->wstore;
609          }
610          set_wstorage(ua->jcr, &store);
611       }
612
613       if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
614          goto bail_out;
615       }
616       Dmsg0(200, "Connected to storage daemon\n");
617       sd = ua->jcr->store_bsock;
618       sd->fsend("cancel Job=%s\n", jcr->Job);
619       while (sd->recv() >= 0) {
620       }
621       sd->signal(BNET_TERMINATE);
622       free_bsock(ua->jcr->store_bsock);
623       jcr->sd_canceled = true;
624       jcr->store_bsock->set_timed_out();
625       jcr->store_bsock->set_terminated();
626       sd_msg_thread_send_signal(jcr, TIMEOUT_SIGNAL);
627       jcr->my_thread_send_signal(TIMEOUT_SIGNAL);
628    }
629 bail_out:
630    free_jcr(control_jcr);
631    free_ua_context(ua);
632 }
633
634 static void job_monitor_destructor(watchdog_t *self)
635 {
636    JCR *control_jcr = (JCR *)self->data;
637
638    free_jcr(control_jcr);
639 }
640
641 static void job_monitor_watchdog(watchdog_t *self)
642 {
643    JCR *control_jcr, *jcr;
644
645    control_jcr = (JCR *)self->data;
646
647    Dsm_check(100);
648    Dmsg1(800, "job_monitor_watchdog %p called\n", self);
649
650    foreach_jcr(jcr) {
651       bool cancel = false;
652
653       if (jcr->JobId == 0 || job_canceled(jcr) || jcr->no_maxtime) {
654          Dmsg2(800, "Skipping JCR=%p Job=%s\n", jcr, jcr->Job);
655          continue;
656       }
657
658       /* check MaxWaitTime */
659       if (job_check_maxwaittime(jcr)) {
660          jcr->setJobStatus(JS_Canceled);
661          Qmsg(jcr, M_FATAL, 0, _("Max wait time exceeded. Job canceled.\n"));
662          cancel = true;
663       /* check MaxRunTime */
664       } else if (job_check_maxruntime(jcr)) {
665          jcr->setJobStatus(JS_Canceled);
666          Qmsg(jcr, M_FATAL, 0, _("Max run time exceeded. Job canceled.\n"));
667          cancel = true;
668       /* check MaxRunSchedTime */
669       } else if (job_check_maxrunschedtime(jcr)) {
670          jcr->setJobStatus(JS_Canceled);
671          Qmsg(jcr, M_FATAL, 0, _("Max run sched time exceeded. Job canceled.\n"));
672          cancel = true;
673       }
674
675       if (cancel) {
676          Dmsg3(800, "Cancelling JCR %p jobid %d (%s)\n", jcr, jcr->JobId, jcr->Job);
677          UAContext *ua = new_ua_context(jcr);
678          ua->jcr = control_jcr;
679          cancel_job(ua, jcr);
680          free_ua_context(ua);
681          Dmsg2(800, "Have cancelled JCR %p Job=%d\n", jcr, jcr->JobId);
682       }
683
684    }
685    /* Keep reference counts correct */
686    endeach_jcr(jcr);
687 }
688
689 /*
690  * Check if the maxwaittime has expired and it is possible
691  *  to cancel the job.
692  */
693 static bool job_check_maxwaittime(JCR *jcr)
694 {
695    bool cancel = false;
696    JOB *job = jcr->job;
697    utime_t current=0;
698
699    if (!job_waiting(jcr)) {
700       return false;
701    }
702
703    if (jcr->wait_time) {
704       current = watchdog_time - jcr->wait_time;
705    }
706
707    Dmsg2(200, "check maxwaittime %u >= %u\n",
708          current + jcr->wait_time_sum, job->MaxWaitTime);
709    if (job->MaxWaitTime != 0 &&
710        (current + jcr->wait_time_sum) >= job->MaxWaitTime) {
711       cancel = true;
712    }
713
714    return cancel;
715 }
716
717 /*
718  * Check if maxruntime has expired and if the job can be
719  *   canceled.
720  */
721 static bool job_check_maxruntime(JCR *jcr)
722 {
723    bool cancel = false;
724    JOB *job = jcr->job;
725    utime_t run_time;
726
727    if (job_canceled(jcr) || !jcr->job_started) {
728       return false;
729    }
730    if (jcr->job->MaxRunTime == 0 && job->FullMaxRunTime == 0 &&
731        job->IncMaxRunTime == 0 && job->DiffMaxRunTime == 0) {
732       return false;
733    }
734    run_time = watchdog_time - jcr->start_time;
735    Dmsg7(200, "check_maxruntime %llu-%u=%llu >= %llu|%llu|%llu|%llu\n",
736          watchdog_time, jcr->start_time, run_time, job->MaxRunTime, job->FullMaxRunTime,
737          job->IncMaxRunTime, job->DiffMaxRunTime);
738
739    if (jcr->getJobLevel() == L_FULL && job->FullMaxRunTime != 0 &&
740          run_time >= job->FullMaxRunTime) {
741       Dmsg0(200, "check_maxwaittime: FullMaxcancel\n");
742       cancel = true;
743    } else if (jcr->getJobLevel() == L_DIFFERENTIAL && job->DiffMaxRunTime != 0 &&
744          run_time >= job->DiffMaxRunTime) {
745       Dmsg0(200, "check_maxwaittime: DiffMaxcancel\n");
746       cancel = true;
747    } else if (jcr->getJobLevel() == L_INCREMENTAL && job->IncMaxRunTime != 0 &&
748          run_time >= job->IncMaxRunTime) {
749       Dmsg0(200, "check_maxwaittime: IncMaxcancel\n");
750       cancel = true;
751    } else if (job->MaxRunTime > 0 && run_time >= job->MaxRunTime) {
752       Dmsg0(200, "check_maxwaittime: Maxcancel\n");
753       cancel = true;
754    }
755
756    return cancel;
757 }
758
759 /*
760  * Check if MaxRunSchedTime has expired and if the job can be
761  *   canceled.
762  */
763 static bool job_check_maxrunschedtime(JCR *jcr)
764 {
765    if (jcr->MaxRunSchedTime == 0 || job_canceled(jcr)) {
766       return false;
767    }
768    if ((watchdog_time - jcr->initial_sched_time) < jcr->MaxRunSchedTime) {
769       Dmsg3(200, "Job %p (%s) with MaxRunSchedTime %d not expired\n",
770             jcr, jcr->Job, jcr->MaxRunSchedTime);
771       return false;
772    }
773
774    return true;
775 }
776
777 /*
778  * Get or create a Pool record with the given name.
779  * Returns: 0 on error
780  *          poolid if OK
781  */
782 DBId_t get_or_create_pool_record(JCR *jcr, char *pool_name)
783 {
784    POOL_DBR pr;
785
786    memset(&pr, 0, sizeof(pr));
787    bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
788    Dmsg1(110, "get_or_create_pool=%s\n", pool_name);
789
790    while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
791       /* Try to create the pool */
792       if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
793          Jmsg(jcr, M_FATAL, 0, _("Pool \"%s\" not in database. ERR=%s"), pr.Name,
794             db_strerror(jcr->db));
795          return 0;
796       } else {
797          Jmsg(jcr, M_INFO, 0, _("Created database record for Pool \"%s\".\n"), pr.Name);
798       }
799    }
800    return pr.PoolId;
801 }
802
803 /*
804  * Check for duplicate jobs.
805  *  Returns: true  if current job should continue
806  *           false if current job should terminate
807  */
808 bool allow_duplicate_job(JCR *jcr)
809 {
810    JOB *job = jcr->job;
811    JCR *djcr;                /* possible duplicate job */
812    bool cancel_dup = false;
813    bool cancel_me = false;
814
815    /*
816     * See if AllowDuplicateJobs is set or
817     * if duplicate checking is disabled for this job.
818     */
819    if (job->AllowDuplicateJobs || jcr->IgnoreDuplicateJobChecking) {
820       return true;
821    }
822
823    Dmsg0(800, "Enter allow_duplicate_job\n");
824
825    /*
826     * After this point, we do not want to allow any duplicate
827     * job to run.
828     */
829
830    foreach_jcr(djcr) {
831       if (jcr == djcr || djcr->JobId == 0) {
832          continue;                   /* do not cancel this job or consoles */
833       }
834
835       /*
836        * See if this Job has the IgnoreDuplicateJobChecking flag set, ignore it
837        * for any checking against other jobs.
838        */
839       if (djcr->IgnoreDuplicateJobChecking) {
840          continue;
841       }
842
843       if (strcmp(job->name(), djcr->job->name()) == 0) {
844          if (job->DuplicateJobProximity > 0) {
845             utime_t now = (utime_t)time(NULL);
846             if ((now - djcr->start_time) > job->DuplicateJobProximity) {
847                continue;               /* not really a duplicate */
848             }
849          }
850          if (job->CancelLowerLevelDuplicates &&
851              djcr->getJobType() == 'B' && jcr->getJobType() == 'B') {
852             switch (jcr->getJobLevel()) {
853             case L_FULL:
854                if (djcr->getJobLevel() == L_DIFFERENTIAL ||
855                    djcr->getJobLevel() == L_INCREMENTAL) {
856                   cancel_dup = true;
857                }
858                break;
859             case L_DIFFERENTIAL:
860                if (djcr->getJobLevel() == L_INCREMENTAL) {
861                   cancel_dup = true;
862                }
863                if (djcr->getJobLevel() == L_FULL) {
864                   cancel_me = true;
865                }
866                break;
867             case L_INCREMENTAL:
868                if (djcr->getJobLevel() == L_FULL ||
869                    djcr->getJobLevel() == L_DIFFERENTIAL) {
870                   cancel_me = true;
871                }
872             }
873             /*
874              * cancel_dup will be done below
875              */
876             if (cancel_me) {
877               /* Zap current job */
878               jcr->setJobStatus(JS_Canceled);
879               Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"),
880                  djcr->JobId);
881               break;     /* get out of foreach_jcr */
882             }
883          }
884
885          /*
886           * Cancel one of the two jobs (me or dup)
887           * If CancelQueuedDuplicates is set do so only if job is queued.
888           */
889          if (job->CancelQueuedDuplicates) {
890              switch (djcr->JobStatus) {
891              case JS_Created:
892              case JS_WaitJobRes:
893              case JS_WaitClientRes:
894              case JS_WaitStoreRes:
895              case JS_WaitPriority:
896              case JS_WaitMaxJobs:
897              case JS_WaitStartTime:
898              case JS_WaitDevice:
899                 cancel_dup = true;  /* cancel queued duplicate */
900                 break;
901              default:
902                 break;
903              }
904          }
905
906          if (cancel_dup || job->CancelRunningDuplicates) {
907             /*
908              * Zap the duplicated job djcr
909              */
910             UAContext *ua = new_ua_context(jcr);
911             Jmsg(jcr, M_INFO, 0, _("Cancelling duplicate JobId=%d.\n"), djcr->JobId);
912             cancel_job(ua, djcr);
913             bmicrosleep(0, 500000);
914             djcr->setJobStatus(JS_Canceled);
915             cancel_job(ua, djcr);
916             free_ua_context(ua);
917             Dmsg2(800, "Cancel dup %p JobId=%d\n", djcr, djcr->JobId);
918          } else {
919             /*
920              * Zap current job
921              */
922             jcr->setJobStatus(JS_Canceled);
923             Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"),
924                djcr->JobId);
925             Dmsg2(800, "Cancel me %p JobId=%d\n", jcr, jcr->JobId);
926          }
927          Dmsg4(800, "curJobId=%d use_cnt=%d dupJobId=%d use_cnt=%d\n",
928                jcr->JobId, jcr->use_count(), djcr->JobId, djcr->use_count());
929          break;                 /* did our work, get out of foreach loop */
930       }
931    }
932    endeach_jcr(djcr);
933
934    return true;
935 }
936
937 /*
938  * Apply pool overrides to get the storage properly setup.
939  */
940 bool apply_wstorage_overrides(JCR *jcr, POOL *opool)
941 {
942    const char *source;
943
944    Dmsg1(100, "Original pool=%s\n", opool->name());
945    if (jcr->run_next_pool_override) {
946       pm_strcpy(jcr->next_pool_source, _("Run NextPool override"));
947       pm_strcpy(jcr->pool_source, _("Run NextPool override"));
948       source = _("Run NextPool override");
949    } else if (jcr->job->next_pool) {
950       /* Use Job Next Pool */
951       jcr->next_pool = jcr->job->next_pool;
952       pm_strcpy(jcr->next_pool_source, _("Job's NextPool resource"));
953       pm_strcpy(jcr->pool_source, _("Job's NextPool resource"));
954       source = _("Job's NextPool resource");
955    } else {
956       /* Default to original pool->NextPool */
957       jcr->next_pool = opool->NextPool;
958       Dmsg1(100, "next_pool=%p\n", jcr->next_pool);
959       if (jcr->next_pool) {
960          Dmsg1(100, "Original pool next Pool = %s\n", NPRT(jcr->next_pool->name()));
961       }
962       pm_strcpy(jcr->next_pool_source, _("Job Pool's NextPool resource"));
963       pm_strcpy(jcr->pool_source, _("Job Pool's NextPool resource"));
964       source = _("Pool's NextPool resource");
965    }
966
967    /*
968     * If the original backup pool has a NextPool, make sure a
969     * record exists in the database.
970     */
971    if (jcr->next_pool) {
972       jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->next_pool->name());
973       if (jcr->jr.PoolId == 0) {
974          return false;
975       }
976    }
977
978    if (!set_mac_wstorage(NULL, jcr, jcr->pool, jcr->next_pool, source)) {
979       return false;
980    }
981
982    /* Set write pool and source. Not read pool is in rpool. */
983    jcr->pool = jcr->next_pool;
984    pm_strcpy(jcr->pool_source, source);
985
986    return true;
987 }
988
989
990 void apply_pool_overrides(JCR *jcr)
991 {
992    bool pool_override = false;
993
994    if (jcr->run_pool_override) {
995       pm_strcpy(jcr->pool_source, _("Run Pool override"));
996    }
997    /*
998     * Apply any level related Pool selections
999     */
1000    switch (jcr->getJobLevel()) {
1001    case L_FULL:
1002       if (jcr->full_pool) {
1003          jcr->pool = jcr->full_pool;
1004          pool_override = true;
1005          if (jcr->run_full_pool_override) {
1006             pm_strcpy(jcr->pool_source, _("Run FullPool override"));
1007          } else {
1008             pm_strcpy(jcr->pool_source, _("Job FullPool override"));
1009          }
1010       }
1011       break;
1012    case L_INCREMENTAL:
1013       if (jcr->inc_pool) {
1014          jcr->pool = jcr->inc_pool;
1015          pool_override = true;
1016          if (jcr->run_inc_pool_override) {
1017             pm_strcpy(jcr->pool_source, _("Run IncPool override"));
1018          } else {
1019             pm_strcpy(jcr->pool_source, _("Job IncPool override"));
1020          }
1021       }
1022       break;
1023    case L_DIFFERENTIAL:
1024       if (jcr->diff_pool) {
1025          jcr->pool = jcr->diff_pool;
1026          pool_override = true;
1027          if (jcr->run_diff_pool_override) {
1028             pm_strcpy(jcr->pool_source, _("Run DiffPool override"));
1029          } else {
1030             pm_strcpy(jcr->pool_source, _("Job DiffPool override"));
1031          }
1032       }
1033       break;
1034    }
1035    /* Update catalog if pool overridden */
1036    if (pool_override && jcr->pool->catalog) {
1037       jcr->catalog = jcr->pool->catalog;
1038       pm_strcpy(jcr->catalog_source, _("Pool resource"));
1039    }
1040 }
1041
1042
1043 /*
1044  * Get or create a Client record for this Job
1045  */
1046 bool get_or_create_client_record(JCR *jcr)
1047 {
1048    CLIENT_DBR cr;
1049
1050    memset(&cr, 0, sizeof(cr));
1051    bstrncpy(cr.Name, jcr->client->hdr.name, sizeof(cr.Name));
1052    cr.AutoPrune = jcr->client->AutoPrune;
1053    cr.FileRetention = jcr->client->FileRetention;
1054    cr.JobRetention = jcr->client->JobRetention;
1055    if (!jcr->client_name) {
1056       jcr->client_name = get_pool_memory(PM_NAME);
1057    }
1058    pm_strcpy(jcr->client_name, jcr->client->hdr.name);
1059    if (!db_create_client_record(jcr, jcr->db, &cr)) {
1060       Jmsg(jcr, M_FATAL, 0, _("Could not create Client record. ERR=%s\n"),
1061          db_strerror(jcr->db));
1062       return false;
1063    }
1064    jcr->jr.ClientId = cr.ClientId;
1065    if (cr.Uname[0]) {
1066       if (!jcr->client_uname) {
1067          jcr->client_uname = get_pool_memory(PM_NAME);
1068       }
1069       pm_strcpy(jcr->client_uname, cr.Uname);
1070    }
1071    Dmsg2(100, "Created Client %s record %d\n", jcr->client->hdr.name,
1072       jcr->jr.ClientId);
1073    return true;
1074 }
1075
1076 /*
1077  * Get or Create FileSet record
1078  */
1079 bool get_or_create_fileset_record(JCR *jcr)
1080 {
1081    FILESET_DBR fsr;
1082
1083    memset(&fsr, 0, sizeof(FILESET_DBR));
1084    bstrncpy(fsr.FileSet, jcr->fileset->hdr.name, sizeof(fsr.FileSet));
1085    if (jcr->fileset->have_MD5) {
1086       struct MD5Context md5c;
1087       unsigned char digest[MD5HashSize];
1088       memcpy(&md5c, &jcr->fileset->md5c, sizeof(md5c));
1089       MD5Final(digest, &md5c);
1090       /*
1091        * Keep the flag (last arg) set to false otherwise old FileSets will
1092        * get new MD5 sums and the user will get Full backups on everything
1093        */
1094       bin_to_base64(fsr.MD5, sizeof(fsr.MD5), (char *)digest, MD5HashSize, false);
1095       bstrncpy(jcr->fileset->MD5, fsr.MD5, sizeof(jcr->fileset->MD5));
1096    } else {
1097       Jmsg(jcr, M_WARNING, 0, _("FileSet MD5 digest not found.\n"));
1098    }
1099    if (!jcr->fileset->ignore_fs_changes ||
1100        !db_get_fileset_record(jcr, jcr->db, &fsr)) {
1101       if (!db_create_fileset_record(jcr, jcr->db, &fsr)) {
1102          Jmsg(jcr, M_ERROR, 0, _("Could not create FileSet \"%s\" record. ERR=%s\n"),
1103             fsr.FileSet, db_strerror(jcr->db));
1104          return false;
1105       }
1106    }
1107    jcr->jr.FileSetId = fsr.FileSetId;
1108    bstrncpy(jcr->FSCreateTime, fsr.cCreateTime, sizeof(jcr->FSCreateTime));
1109    Dmsg2(119, "Created FileSet %s record %u\n", jcr->fileset->hdr.name,
1110       jcr->jr.FileSetId);
1111    return true;
1112 }
1113
1114 void init_jcr_job_record(JCR *jcr)
1115 {
1116    jcr->jr.SchedTime = jcr->sched_time;
1117    jcr->jr.StartTime = jcr->start_time;
1118    jcr->jr.EndTime = 0;               /* perhaps rescheduled, clear it */
1119    jcr->jr.JobType = jcr->getJobType();
1120    jcr->jr.JobLevel = jcr->getJobLevel();
1121    jcr->jr.JobStatus = jcr->JobStatus;
1122    jcr->jr.JobId = jcr->JobId;
1123    bstrncpy(jcr->jr.Name, jcr->job->name(), sizeof(jcr->jr.Name));
1124    bstrncpy(jcr->jr.Job, jcr->Job, sizeof(jcr->jr.Job));
1125 }
1126
1127 /*
1128  * Write status and such in DB
1129  */
1130 void update_job_end_record(JCR *jcr)
1131 {
1132    jcr->jr.EndTime = time(NULL);
1133    jcr->end_time = jcr->jr.EndTime;
1134    jcr->jr.JobId = jcr->JobId;
1135    jcr->jr.JobStatus = jcr->JobStatus;
1136    jcr->jr.JobFiles = jcr->JobFiles;
1137    jcr->jr.JobBytes = jcr->JobBytes;
1138    jcr->jr.ReadBytes = jcr->ReadBytes;
1139    jcr->jr.VolSessionId = jcr->VolSessionId;
1140    jcr->jr.VolSessionTime = jcr->VolSessionTime;
1141    jcr->jr.JobErrors = jcr->JobErrors;
1142    jcr->jr.HasBase = jcr->HasBase;
1143    if (!db_update_job_end_record(jcr, jcr->db, &jcr->jr)) {
1144       Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"),
1145          db_strerror(jcr->db));
1146    }
1147 }
1148
1149 /*
1150  * Takes base_name and appends (unique) current
1151  *   date and time to form unique job name.
1152  *
1153  *  Note, the seconds are actually a sequence number. This
1154  *   permits us to start a maximum fo 59 unique jobs a second, which
1155  *   should be sufficient.
1156  *
1157  *  Returns: unique job name in jcr->Job
1158  *    date/time in jcr->start_time
1159  */
1160 void create_unique_job_name(JCR *jcr, const char *base_name)
1161 {
1162    /* Job start mutex */
1163    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
1164    static time_t last_start_time = 0;
1165    static int seq = 0;
1166    time_t now = time(NULL);
1167    struct tm tm;
1168    char dt[MAX_TIME_LENGTH];
1169    char name[MAX_NAME_LENGTH];
1170    char *p;
1171    int len;
1172
1173    /* Guarantee unique start time -- maximum one per second, and
1174     * thus unique Job Name
1175     */
1176    P(mutex);                          /* lock creation of jobs */
1177    seq++;
1178    if (seq > 59) {                    /* wrap as if it is seconds */
1179       seq = 0;
1180       while (now == last_start_time) {
1181          bmicrosleep(0, 500000);
1182          now = time(NULL);
1183       }
1184    }
1185    last_start_time = now;
1186    V(mutex);                          /* allow creation of jobs */
1187    jcr->start_time = now;
1188    /* Form Unique JobName */
1189    (void)localtime_r(&now, &tm);
1190    /* Use only characters that are permitted in Windows filenames */
1191    strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm);
1192    len = strlen(dt) + 5;   /* dt + .%02d EOS */
1193    bstrncpy(name, base_name, sizeof(name));
1194    name[sizeof(name)-len] = 0;          /* truncate if too long */
1195    bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s_%02d", name, dt, seq); /* add date & time */
1196    /* Convert spaces into underscores */
1197    for (p=jcr->Job; *p; p++) {
1198       if (*p == ' ') {
1199          *p = '_';
1200       }
1201    }
1202    Dmsg2(100, "JobId=%u created Job=%s\n", jcr->JobId, jcr->Job);
1203 }
1204
1205 /* Called directly from job rescheduling */
1206 void dird_free_jcr_pointers(JCR *jcr)
1207 {
1208    /* Close but do not free bsock packets */
1209    if (jcr->file_bsock) {
1210       Dmsg0(200, "Close File bsock\n");
1211       jcr->file_bsock->close();
1212    }
1213    if (jcr->store_bsock) {
1214       Dmsg0(200, "Close Store bsock\n");
1215       jcr->store_bsock->close();
1216    }
1217
1218    bfree_and_null(jcr->sd_auth_key);
1219    bfree_and_null(jcr->where);
1220    bfree_and_null(jcr->RestoreBootstrap);
1221    jcr->cached_attribute = false;
1222    bfree_and_null(jcr->ar);
1223
1224    free_and_null_pool_memory(jcr->JobIds);
1225    free_and_null_pool_memory(jcr->client_uname);
1226    free_and_null_pool_memory(jcr->attr);
1227    free_and_null_pool_memory(jcr->fname);
1228    free_and_null_pool_memory(jcr->media_type);
1229 }
1230
1231 /*
1232  * Free the Job Control Record if no one is still using it.
1233  *  Called from main free_jcr() routine in src/lib/jcr.c so
1234  *  that we can do our Director specific cleanup of the jcr.
1235  */
1236 void dird_free_jcr(JCR *jcr)
1237 {
1238    Dmsg0(200, "Start dird free_jcr\n");
1239
1240    dird_free_jcr_pointers(jcr);
1241    /* Free bsock packets */
1242    free_bsock(jcr->file_bsock);
1243    free_bsock(jcr->store_bsock);
1244    if (jcr->term_wait_inited) {
1245       pthread_cond_destroy(&jcr->term_wait);
1246       jcr->term_wait_inited = false;
1247    }
1248    if (jcr->db_batch) {
1249       db_close_database(jcr, jcr->db_batch);
1250       jcr->db_batch = NULL;
1251       jcr->batch_started = false;
1252    }
1253    if (jcr->db) {
1254       db_close_database(jcr, jcr->db);
1255       jcr->db = NULL;
1256    }
1257
1258    free_and_null_pool_memory(jcr->stime);
1259    free_and_null_pool_memory(jcr->fname);
1260    free_and_null_pool_memory(jcr->pool_source);
1261    free_and_null_pool_memory(jcr->next_pool_source);
1262    free_and_null_pool_memory(jcr->catalog_source);
1263    free_and_null_pool_memory(jcr->rpool_source);
1264    free_and_null_pool_memory(jcr->wstore_source);
1265    free_and_null_pool_memory(jcr->rstore_source);
1266
1267    /* Delete lists setup to hold storage pointers */
1268    free_rwstorage(jcr);
1269
1270    jcr->job_end_push.destroy();
1271
1272    if (jcr->JobId != 0) {
1273       write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
1274    }
1275
1276    free_plugins(jcr);                 /* release instantiated plugins */
1277
1278    Dmsg0(200, "End dird free_jcr\n");
1279 }
1280
1281 /*
1282  * The Job storage definition must be either in the Job record
1283  *  or in the Pool record.  The Pool record overrides the Job
1284  *  record.
1285  */
1286 void get_job_storage(USTORE *store, JOB *job, RUN *run)
1287 {
1288    if (run && run->pool && run->pool->storage) {
1289       store->store = (STORE *)run->pool->storage->first();
1290       pm_strcpy(store->store_source, _("Run pool override"));
1291       return;
1292    }
1293    if (run && run->storage) {
1294       store->store = run->storage;
1295       pm_strcpy(store->store_source, _("Run storage override"));
1296       return;
1297    }
1298    if (job->pool->storage) {
1299       store->store = (STORE *)job->pool->storage->first();
1300       pm_strcpy(store->store_source, _("Pool resource"));
1301    } else {
1302       store->store = (STORE *)job->storage->first();
1303       pm_strcpy(store->store_source, _("Job resource"));
1304    }
1305 }
1306
1307 /*
1308  * Set some defaults in the JCR necessary to
1309  * run. These items are pulled from the job
1310  * definition as defaults, but can be overridden
1311  * later either by the Run record in the Schedule resource,
1312  * or by the Console program.
1313  */
1314 void set_jcr_defaults(JCR *jcr, JOB *job)
1315 {
1316    jcr->job = job;
1317    jcr->setJobType(job->JobType);
1318    jcr->JobStatus = JS_Created;
1319
1320    switch (jcr->getJobType()) {
1321    case JT_ADMIN:
1322       jcr->setJobLevel(L_NONE);
1323       break;
1324    default:
1325       jcr->setJobLevel(job->JobLevel);
1326       break;
1327    }
1328
1329    if (!jcr->fname) {
1330       jcr->fname = get_pool_memory(PM_FNAME);
1331    }
1332    if (!jcr->pool_source) {
1333       jcr->pool_source = get_pool_memory(PM_MESSAGE);
1334    }
1335    if (!jcr->next_pool_source) {
1336       jcr->next_pool_source = get_pool_memory(PM_MESSAGE);
1337    }
1338    if (!jcr->catalog_source) {
1339       jcr->catalog_source = get_pool_memory(PM_MESSAGE);
1340    }
1341
1342    jcr->JobPriority = job->Priority;
1343    /* Copy storage definitions -- deleted in dir_free_jcr above */
1344    if (job->storage) {
1345       copy_rwstorage(jcr, job->storage, _("Job resource"));
1346    } else {
1347       copy_rwstorage(jcr, job->pool->storage, _("Pool resource"));
1348    }
1349    jcr->client = job->client;
1350    if (!jcr->client_name) {
1351       jcr->client_name = get_pool_memory(PM_NAME);
1352    }
1353    pm_strcpy(jcr->client_name, jcr->client->name());
1354    jcr->pool = job->pool;
1355    pm_strcpy(jcr->pool_source, _("Job resource"));
1356    if (job->next_pool) {
1357       /* Use Job's Next Pool */
1358       jcr->next_pool = job->next_pool;
1359       pm_strcpy(jcr->next_pool_source, _("Job's NextPool resource"));
1360    } else {
1361       /* Default to original pool->NextPool */
1362       jcr->next_pool = job->pool->NextPool;
1363       pm_strcpy(jcr->next_pool_source, _("Job Pool's NextPool resource"));
1364    }
1365    jcr->full_pool = job->full_pool;
1366    jcr->inc_pool = job->inc_pool;
1367    jcr->diff_pool = job->diff_pool;
1368    if (job->pool->catalog) {
1369       jcr->catalog = job->pool->catalog;
1370       pm_strcpy(jcr->catalog_source, _("Pool resource"));
1371    } else {
1372       jcr->catalog = job->client->catalog;
1373       pm_strcpy(jcr->catalog_source, _("Client resource"));
1374    }
1375    jcr->fileset = job->fileset;
1376    jcr->accurate = job->accurate;
1377    jcr->messages = job->messages;
1378    jcr->spool_data = job->spool_data;
1379    jcr->spool_size = job->spool_size;
1380    jcr->write_part_after_job = job->write_part_after_job;
1381    jcr->IgnoreDuplicateJobChecking = job->IgnoreDuplicateJobChecking;
1382    jcr->MaxRunSchedTime = job->MaxRunSchedTime;
1383    if (jcr->RestoreBootstrap) {
1384       free(jcr->RestoreBootstrap);
1385       jcr->RestoreBootstrap = NULL;
1386    }
1387    /* This can be overridden by Console program */
1388    if (job->RestoreBootstrap) {
1389       jcr->RestoreBootstrap = bstrdup(job->RestoreBootstrap);
1390    }
1391    /* This can be overridden by Console program */
1392    jcr->verify_job = job->verify_job;
1393    /* If no default level given, set one */
1394    if (jcr->getJobLevel() == 0) {
1395       switch (jcr->getJobType()) {
1396       case JT_VERIFY:
1397          jcr->setJobLevel(L_VERIFY_CATALOG);
1398          break;
1399       case JT_BACKUP:
1400          jcr->setJobLevel(L_INCREMENTAL);
1401          break;
1402       case JT_RESTORE:
1403       case JT_ADMIN:
1404          jcr->setJobLevel(L_NONE);
1405          break;
1406       default:
1407          jcr->setJobLevel(L_FULL);
1408          break;
1409       }
1410    }
1411 }
1412
1413 /*
1414  * Copy the storage definitions from an alist to the JCR
1415  */
1416 void copy_rwstorage(JCR *jcr, alist *storage, const char *where)
1417 {
1418    if (jcr->JobReads()) {
1419       copy_rstorage(jcr, storage, where);
1420    }
1421    copy_wstorage(jcr, storage, where);
1422 }
1423
1424
1425 /* Set storage override.  Releases any previous storage definition */
1426 void set_rwstorage(JCR *jcr, USTORE *store)
1427 {
1428    if (!store) {
1429       Jmsg(jcr, M_FATAL, 0, _("No storage specified.\n"));
1430       return;
1431    }
1432    if (jcr->JobReads()) {
1433       set_rstorage(jcr, store);
1434    }
1435    set_wstorage(jcr, store);
1436 }
1437
1438 void free_rwstorage(JCR *jcr)
1439 {
1440    free_rstorage(jcr);
1441    free_wstorage(jcr);
1442 }
1443
1444 /*
1445  * Copy the storage definitions from an alist to the JCR
1446  */
1447 void copy_rstorage(JCR *jcr, alist *storage, const char *where)
1448 {
1449    if (storage) {
1450       STORE *st;
1451       if (jcr->rstorage) {
1452          delete jcr->rstorage;
1453       }
1454       jcr->rstorage = New(alist(10, not_owned_by_alist));
1455       foreach_alist(st, storage) {
1456          jcr->rstorage->append(st);
1457       }
1458       if (!jcr->rstore_source) {
1459          jcr->rstore_source = get_pool_memory(PM_MESSAGE);
1460       }
1461       pm_strcpy(jcr->rstore_source, where);
1462       if (jcr->rstorage) {
1463          jcr->rstore = (STORE *)jcr->rstorage->first();
1464       }
1465    }
1466 }
1467
1468
1469 /* Set storage override.  Remove all previous storage */
1470 void set_rstorage(JCR *jcr, USTORE *store)
1471 {
1472    STORE *storage;
1473
1474    if (!store->store) {
1475       return;
1476    }
1477    if (jcr->rstorage) {
1478       free_rstorage(jcr);
1479    }
1480    if (!jcr->rstorage) {
1481       jcr->rstorage = New(alist(10, not_owned_by_alist));
1482    }
1483    jcr->rstore = store->store;
1484    if (!jcr->rstore_source) {
1485       jcr->rstore_source = get_pool_memory(PM_MESSAGE);
1486    }
1487    pm_strcpy(jcr->rstore_source, store->store_source);
1488    foreach_alist(storage, jcr->rstorage) {
1489       if (store->store == storage) {
1490          return;
1491       }
1492    }
1493    /* Store not in list, so add it */
1494    jcr->rstorage->prepend(store->store);
1495 }
1496
1497 void free_rstorage(JCR *jcr)
1498 {
1499    if (jcr->rstorage) {
1500       delete jcr->rstorage;
1501       jcr->rstorage = NULL;
1502    }
1503    jcr->rstore = NULL;
1504 }
1505
1506 /*
1507  * Copy the storage definitions from an alist to the JCR
1508  */
1509 void copy_wstorage(JCR *jcr, alist *storage, const char *where)
1510 {
1511    if (storage) {
1512       STORE *st;
1513       if (jcr->wstorage) {
1514          delete jcr->wstorage;
1515       }
1516       jcr->wstorage = New(alist(10, not_owned_by_alist));
1517       foreach_alist(st, storage) {
1518          Dmsg1(100, "wstorage=%s\n", st->name());
1519          jcr->wstorage->append(st);
1520       }
1521       if (!jcr->wstore_source) {
1522          jcr->wstore_source = get_pool_memory(PM_MESSAGE);
1523       }
1524       pm_strcpy(jcr->wstore_source, where);
1525       if (jcr->wstorage) {
1526          jcr->wstore = (STORE *)jcr->wstorage->first();
1527          Dmsg2(100, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
1528       }
1529    }
1530 }
1531
1532
1533 /* Set storage override. Remove all previous storage */
1534 void set_wstorage(JCR *jcr, USTORE *store)
1535 {
1536    STORE *storage;
1537
1538    if (!store->store) {
1539       return;
1540    }
1541    if (jcr->wstorage) {
1542       free_wstorage(jcr);
1543    }
1544    if (!jcr->wstorage) {
1545       jcr->wstorage = New(alist(10, not_owned_by_alist));
1546    }
1547    jcr->wstore = store->store;
1548    if (!jcr->wstore_source) {
1549       jcr->wstore_source = get_pool_memory(PM_MESSAGE);
1550    }
1551    pm_strcpy(jcr->wstore_source, store->store_source);
1552    Dmsg2(50, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
1553    foreach_alist(storage, jcr->wstorage) {
1554       if (store->store == storage) {
1555          return;
1556       }
1557    }
1558    /* Store not in list, so add it */
1559    jcr->wstorage->prepend(store->store);
1560 }
1561
1562 void free_wstorage(JCR *jcr)
1563 {
1564    if (jcr->wstorage) {
1565       delete jcr->wstorage;
1566       jcr->wstorage = NULL;
1567    }
1568    jcr->wstore = NULL;
1569 }
1570
1571 void create_clones(JCR *jcr)
1572 {
1573    /*
1574     * Fire off any clone jobs (run directives)
1575     */
1576    Dmsg2(900, "cloned=%d run_cmds=%p\n", jcr->cloned, jcr->job->run_cmds);
1577    if (!jcr->cloned && jcr->job->run_cmds) {
1578       char *runcmd;
1579       JOB *job = jcr->job;
1580       POOLMEM *cmd = get_pool_memory(PM_FNAME);
1581       UAContext *ua = new_ua_context(jcr);
1582       ua->batch = true;
1583       foreach_alist(runcmd, job->run_cmds) {
1584          cmd = edit_job_codes(jcr, cmd, runcmd, "", job_code_callback_director);
1585          Mmsg(ua->cmd, "run %s cloned=yes", cmd);
1586          Dmsg1(900, "=============== Clone cmd=%s\n", ua->cmd);
1587          parse_ua_args(ua);                 /* parse command */
1588          int stat = run_cmd(ua, ua->cmd);
1589          if (stat == 0) {
1590             Jmsg(jcr, M_ERROR, 0, _("Could not start clone job: \"%s\".\n"),
1591                  ua->cmd);
1592          } else {
1593             Jmsg(jcr, M_INFO, 0, _("Clone JobId %d started.\n"), stat);
1594          }
1595       }
1596       free_ua_context(ua);
1597       free_pool_memory(cmd);
1598    }
1599 }
1600
1601 /*
1602  * Given: a JobId in jcr->previous_jr.JobId,
1603  *  this subroutine writes a bsr file to restore that job.
1604  * Returns: -1 on error
1605  *           number of files if OK
1606  */
1607 int create_restore_bootstrap_file(JCR *jcr)
1608 {
1609    RESTORE_CTX rx;
1610    UAContext *ua;
1611    int files;
1612
1613    memset(&rx, 0, sizeof(rx));
1614    rx.bsr = new_bsr();
1615    rx.JobIds = (char *)"";
1616    rx.bsr->JobId = jcr->previous_jr.JobId;
1617    ua = new_ua_context(jcr);
1618    if (!complete_bsr(ua, rx.bsr)) {
1619       files = -1;
1620       goto bail_out;
1621    }
1622    rx.bsr->fi = new_findex();
1623    rx.bsr->fi->findex = 1;
1624    rx.bsr->fi->findex2 = jcr->previous_jr.JobFiles;
1625    jcr->ExpectedFiles = write_bsr_file(ua, rx);
1626    if (jcr->ExpectedFiles == 0) {
1627       files = 0;
1628       goto bail_out;
1629    }
1630    free_ua_context(ua);
1631    free_bsr(rx.bsr);
1632    jcr->needs_sd = true;
1633    return jcr->ExpectedFiles;
1634
1635 bail_out:
1636    free_ua_context(ua);
1637    free_bsr(rx.bsr);
1638    return files;
1639 }
1640
1641 /* TODO: redirect command ouput to job log */
1642 bool run_console_command(JCR *jcr, const char *cmd)
1643 {
1644    UAContext *ua;
1645    bool ok;
1646    JCR *ljcr = new_control_jcr("-RunScript-", JT_CONSOLE);
1647    ua = new_ua_context(ljcr);
1648    /* run from runscript and check if commands are authorized */
1649    ua->runscript = true;
1650    Mmsg(ua->cmd, "%s", cmd);
1651    Dmsg1(100, "Console command: %s\n", ua->cmd);
1652    parse_ua_args(ua);
1653    if (ua->argc > 0 && ua->argk[0][0] == '.') {
1654       ok = do_a_dot_command(ua);
1655    } else {
1656      ok = do_a_command(ua);
1657    }
1658    free_ua_context(ua);
1659    free_jcr(ljcr);
1660    return ok;
1661 }