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