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