]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/job.c
Patch to add MySQL ssl access
[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_INCREMENTAL:
1179       if (jcr->inc_pool) {
1180          jcr->pool = jcr->inc_pool;
1181          pool_override = true;
1182          if (jcr->run_inc_pool_override) {
1183             pm_strcpy(jcr->pool_source, _("Run IncPool override"));
1184          } else {
1185             pm_strcpy(jcr->pool_source, _("Job IncPool override"));
1186          }
1187       }
1188       break;
1189    case L_DIFFERENTIAL:
1190       if (jcr->diff_pool) {
1191          jcr->pool = jcr->diff_pool;
1192          pool_override = true;
1193          if (jcr->run_diff_pool_override) {
1194             pm_strcpy(jcr->pool_source, _("Run DiffPool override"));
1195          } else {
1196             pm_strcpy(jcr->pool_source, _("Job DiffPool override"));
1197          }
1198       }
1199       break;
1200    }
1201    /* Update catalog if pool overridden */
1202    if (pool_override && jcr->pool->catalog) {
1203       jcr->catalog = jcr->pool->catalog;
1204       pm_strcpy(jcr->catalog_source, _("Pool resource"));
1205    }
1206 }
1207
1208
1209 /*
1210  * Get or create a Client record for this Job
1211  */
1212 bool get_or_create_client_record(JCR *jcr)
1213 {
1214    CLIENT_DBR cr;
1215
1216    if (!jcr->client) {
1217       Jmsg(jcr, M_FATAL, 0, _("No Client specified.\n"));
1218       return false;
1219    }
1220    memset(&cr, 0, sizeof(cr));
1221    bstrncpy(cr.Name, jcr->client->hdr.name, sizeof(cr.Name));
1222    cr.AutoPrune = jcr->client->AutoPrune;
1223    cr.FileRetention = jcr->client->FileRetention;
1224    cr.JobRetention = jcr->client->JobRetention;
1225    if (!jcr->client_name) {
1226       jcr->client_name = get_pool_memory(PM_NAME);
1227    }
1228    pm_strcpy(jcr->client_name, jcr->client->hdr.name);
1229    if (!db_create_client_record(jcr, jcr->db, &cr)) {
1230       Jmsg(jcr, M_FATAL, 0, _("Could not create Client record. ERR=%s\n"),
1231          db_strerror(jcr->db));
1232       return false;
1233    }
1234    jcr->jr.ClientId = cr.ClientId;
1235    if (cr.Uname[0]) {
1236       if (!jcr->client_uname) {
1237          jcr->client_uname = get_pool_memory(PM_NAME);
1238       }
1239       pm_strcpy(jcr->client_uname, cr.Uname);
1240    }
1241    Dmsg2(100, "Created Client %s record %d\n", jcr->client->hdr.name,
1242       jcr->jr.ClientId);
1243    return true;
1244 }
1245
1246 /*
1247  * Get or Create FileSet record
1248  */
1249 bool get_or_create_fileset_record(JCR *jcr)
1250 {
1251    FILESET_DBR fsr;
1252
1253    memset(&fsr, 0, sizeof(FILESET_DBR));
1254    bstrncpy(fsr.FileSet, jcr->fileset->hdr.name, sizeof(fsr.FileSet));
1255    if (jcr->fileset->have_MD5) {
1256       struct MD5Context md5c;
1257       unsigned char digest[MD5HashSize];
1258       memcpy(&md5c, &jcr->fileset->md5c, sizeof(md5c));
1259       MD5Final(digest, &md5c);
1260       /*
1261        * Keep the flag (last arg) set to false otherwise old FileSets will
1262        * get new MD5 sums and the user will get Full backups on everything
1263        */
1264       bin_to_base64(fsr.MD5, sizeof(fsr.MD5), (char *)digest, MD5HashSize, false);
1265       bstrncpy(jcr->fileset->MD5, fsr.MD5, sizeof(jcr->fileset->MD5));
1266    } else {
1267       Jmsg(jcr, M_WARNING, 0, _("FileSet MD5 digest not found.\n"));
1268    }
1269    if (!jcr->fileset->ignore_fs_changes ||
1270        !db_get_fileset_record(jcr, jcr->db, &fsr)) {
1271       if (!db_create_fileset_record(jcr, jcr->db, &fsr)) {
1272          Jmsg(jcr, M_ERROR, 0, _("Could not create FileSet \"%s\" record. ERR=%s\n"),
1273             fsr.FileSet, db_strerror(jcr->db));
1274          return false;
1275       }
1276    }
1277    jcr->jr.FileSetId = fsr.FileSetId;
1278    bstrncpy(jcr->FSCreateTime, fsr.cCreateTime, sizeof(jcr->FSCreateTime));
1279    Dmsg2(119, "Created FileSet %s record %u\n", jcr->fileset->hdr.name,
1280       jcr->jr.FileSetId);
1281    return true;
1282 }
1283
1284 void init_jcr_job_record(JCR *jcr)
1285 {
1286    jcr->jr.SchedTime = jcr->sched_time;
1287    jcr->jr.StartTime = jcr->start_time;
1288    jcr->jr.EndTime = 0;               /* perhaps rescheduled, clear it */
1289    jcr->jr.JobType = jcr->getJobType();
1290    jcr->jr.JobLevel = jcr->getJobLevel();
1291    jcr->jr.JobStatus = jcr->JobStatus;
1292    jcr->jr.JobId = jcr->JobId;
1293    bstrncpy(jcr->jr.Name, jcr->job->name(), sizeof(jcr->jr.Name));
1294    bstrncpy(jcr->jr.Job, jcr->Job, sizeof(jcr->jr.Job));
1295 }
1296
1297 /*
1298  * Write status and such in DB
1299  */
1300 void update_job_end_record(JCR *jcr)
1301 {
1302    jcr->jr.EndTime = time(NULL);
1303    jcr->end_time = jcr->jr.EndTime;
1304    jcr->jr.JobId = jcr->JobId;
1305    jcr->jr.JobStatus = jcr->JobStatus;
1306    jcr->jr.JobFiles = jcr->JobFiles;
1307    jcr->jr.JobBytes = jcr->JobBytes;
1308    jcr->jr.ReadBytes = jcr->ReadBytes;
1309    jcr->jr.VolSessionId = jcr->VolSessionId;
1310    jcr->jr.VolSessionTime = jcr->VolSessionTime;
1311    jcr->jr.JobErrors = jcr->JobErrors;
1312    jcr->jr.HasBase = jcr->HasBase;
1313    if (!db_update_job_end_record(jcr, jcr->db, &jcr->jr)) {
1314       Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"),
1315          db_strerror(jcr->db));
1316    }
1317 }
1318
1319 /*
1320  * Takes base_name and appends (unique) current
1321  *   date and time to form unique job name.
1322  *
1323  *  Note, the seconds are actually a sequence number. This
1324  *   permits us to start a maximum fo 59 unique jobs a second, which
1325  *   should be sufficient.
1326  *
1327  *  Returns: unique job name in jcr->Job
1328  *    date/time in jcr->start_time
1329  */
1330 void create_unique_job_name(JCR *jcr, const char *base_name)
1331 {
1332    /* Job start mutex */
1333    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
1334    static time_t last_start_time = 0;
1335    static int seq = 0;
1336    time_t now = time(NULL);
1337    struct tm tm;
1338    char dt[MAX_TIME_LENGTH];
1339    char name[MAX_NAME_LENGTH];
1340    char *p;
1341    int len;
1342    int local_seq;
1343
1344    /* Guarantee unique start time -- maximum one per second, and
1345     * thus unique Job Name
1346     */
1347    P(mutex);                          /* lock creation of jobs */
1348    seq++;
1349    if (seq > 59) {                    /* wrap as if it is seconds */
1350       seq = 0;
1351       while (now == last_start_time) {
1352          bmicrosleep(0, 500000);
1353          now = time(NULL);
1354       }
1355    }
1356    last_start_time = now;
1357    local_seq = seq;
1358    V(mutex);                          /* allow creation of jobs */
1359    jcr->start_time = now;
1360    /* Form Unique JobName */
1361    (void)localtime_r(&now, &tm);
1362    /* Use only characters that are permitted in Windows filenames */
1363    strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm);
1364    len = strlen(dt) + 5;   /* dt + .%02d EOS */
1365    bstrncpy(name, base_name, sizeof(name));
1366    name[sizeof(name)-len] = 0;          /* truncate if too long */
1367    bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s_%02d", name, dt, local_seq); /* add date & time */
1368    /* Convert spaces into underscores */
1369    for (p=jcr->Job; *p; p++) {
1370       if (*p == ' ') {
1371          *p = '_';
1372       }
1373    }
1374    Dmsg2(100, "JobId=%u created Job=%s\n", jcr->JobId, jcr->Job);
1375 }
1376
1377 /* Called directly from job rescheduling */
1378 void dird_free_jcr_pointers(JCR *jcr)
1379 {
1380    /* Close but do not free bsock packets */
1381    if (jcr->file_bsock) {
1382       Dmsg0(200, "Close File bsock\n");
1383       jcr->file_bsock->close();
1384    }
1385    if (jcr->store_bsock) {
1386       Dmsg0(200, "Close Store bsock\n");
1387       jcr->store_bsock->close();
1388    }
1389
1390    bfree_and_null(jcr->sd_auth_key);
1391    bfree_and_null(jcr->where);
1392    bfree_and_null(jcr->RestoreBootstrap);
1393    jcr->cached_attribute = false;
1394    bfree_and_null(jcr->ar);
1395
1396    free_and_null_pool_memory(jcr->JobIds);
1397    free_and_null_pool_memory(jcr->client_uname);
1398    free_and_null_pool_memory(jcr->attr);
1399    free_and_null_pool_memory(jcr->fname);
1400    free_and_null_pool_memory(jcr->media_type);
1401 }
1402
1403 /*
1404  * Free the Job Control Record if no one is still using it.
1405  *  Called from main free_jcr() routine in src/lib/jcr.c so
1406  *  that we can do our Director specific cleanup of the jcr.
1407  */
1408 void dird_free_jcr(JCR *jcr)
1409 {
1410    Dmsg0(200, "Start dird free_jcr\n");
1411
1412    dird_free_jcr_pointers(jcr);
1413    if (jcr->wjcr) {
1414       free_jcr(jcr->wjcr);
1415       jcr->wjcr = NULL;
1416    }
1417    /* Free bsock packets */
1418    free_bsock(jcr->file_bsock);
1419    free_bsock(jcr->store_bsock);
1420    if (jcr->term_wait_inited) {
1421       pthread_cond_destroy(&jcr->term_wait);
1422       jcr->term_wait_inited = false;
1423    }
1424    if (jcr->db_batch) {
1425       db_close_database(jcr, jcr->db_batch);
1426       jcr->db_batch = NULL;
1427       jcr->batch_started = false;
1428    }
1429    if (jcr->db) {
1430       db_close_database(jcr, jcr->db);
1431       jcr->db = NULL;
1432    }
1433
1434    free_and_null_pool_memory(jcr->stime);
1435    free_and_null_pool_memory(jcr->fname);
1436    free_and_null_pool_memory(jcr->pool_source);
1437    free_and_null_pool_memory(jcr->next_pool_source);
1438    free_and_null_pool_memory(jcr->catalog_source);
1439    free_and_null_pool_memory(jcr->rpool_source);
1440    free_and_null_pool_memory(jcr->wstore_source);
1441    free_and_null_pool_memory(jcr->rstore_source);
1442    free_and_null_pool_memory(jcr->next_vol_list);
1443
1444    /* Delete lists setup to hold storage pointers */
1445    free_rwstorage(jcr);
1446
1447    jcr->job_end_push.destroy();
1448
1449    if (jcr->JobId != 0) {
1450       write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
1451    }
1452
1453    free_plugins(jcr);                 /* release instantiated plugins */
1454
1455    Dmsg0(200, "End dird free_jcr\n");
1456 }
1457
1458 /*
1459  * The Job storage definition must be either in the Job record
1460  *  or in the Pool record.  The Pool record overrides the Job
1461  *  record.
1462  */
1463 void get_job_storage(USTORE *store, JOB *job, RUN *run)
1464 {
1465    if (run && run->pool && run->pool->storage) {
1466       store->store = (STORE *)run->pool->storage->first();
1467       pm_strcpy(store->store_source, _("Run pool override"));
1468       return;
1469    }
1470    if (run && run->storage) {
1471       store->store = run->storage;
1472       pm_strcpy(store->store_source, _("Run storage override"));
1473       return;
1474    }
1475    if (job->pool->storage) {
1476       store->store = (STORE *)job->pool->storage->first();
1477       pm_strcpy(store->store_source, _("Pool resource"));
1478    } else {
1479       store->store = (STORE *)job->storage->first();
1480       pm_strcpy(store->store_source, _("Job resource"));
1481    }
1482 }
1483
1484 /*
1485  * Set some defaults in the JCR necessary to
1486  * run. These items are pulled from the job
1487  * definition as defaults, but can be overridden
1488  * later either by the Run record in the Schedule resource,
1489  * or by the Console program.
1490  */
1491 void set_jcr_defaults(JCR *jcr, JOB *job)
1492 {
1493    jcr->job = job;
1494    jcr->setJobType(job->JobType);
1495    jcr->JobStatus = JS_Created;
1496
1497    switch (jcr->getJobType()) {
1498    case JT_ADMIN:
1499       jcr->setJobLevel(L_NONE);
1500       break;
1501    default:
1502       jcr->setJobLevel(job->JobLevel);
1503       break;
1504    }
1505    if (!jcr->next_vol_list) {
1506       jcr->next_vol_list = get_pool_memory(PM_FNAME);
1507    }
1508    if (!jcr->fname) {
1509       jcr->fname = get_pool_memory(PM_FNAME);
1510    }
1511    if (!jcr->pool_source) {
1512       jcr->pool_source = get_pool_memory(PM_MESSAGE);
1513    }
1514    if (!jcr->next_pool_source) {
1515       jcr->next_pool_source = get_pool_memory(PM_MESSAGE);
1516    }
1517    if (!jcr->catalog_source) {
1518       jcr->catalog_source = get_pool_memory(PM_MESSAGE);
1519    }
1520
1521    jcr->JobPriority = job->Priority;
1522    /* Copy storage definitions -- deleted in dir_free_jcr above */
1523    if (job->storage) {
1524       copy_rwstorage(jcr, job->storage, _("Job resource"));
1525    } else {
1526       copy_rwstorage(jcr, job->pool->storage, _("Pool resource"));
1527    }
1528    jcr->client = job->client;
1529    ASSERT2(jcr->client, "jcr->client==NULL!!!");
1530    if (!jcr->client_name) {
1531       jcr->client_name = get_pool_memory(PM_NAME);
1532    }
1533    pm_strcpy(jcr->client_name, jcr->client->name());
1534    jcr->pool = job->pool;
1535    pm_strcpy(jcr->pool_source, _("Job resource"));
1536    if (job->next_pool) {
1537       /* Use Job's Next Pool */
1538       jcr->next_pool = job->next_pool;
1539       pm_strcpy(jcr->next_pool_source, _("Job's NextPool resource"));
1540    } else {
1541       /* Default to original pool->NextPool */
1542       jcr->next_pool = job->pool->NextPool;
1543       pm_strcpy(jcr->next_pool_source, _("Job Pool's NextPool resource"));
1544    }
1545    jcr->full_pool = job->full_pool;
1546    jcr->inc_pool = job->inc_pool;
1547    jcr->diff_pool = job->diff_pool;
1548    if (job->pool->catalog) {
1549       jcr->catalog = job->pool->catalog;
1550       pm_strcpy(jcr->catalog_source, _("Pool resource"));
1551    } else {
1552       jcr->catalog = job->client->catalog;
1553       pm_strcpy(jcr->catalog_source, _("Client resource"));
1554    }
1555    jcr->fileset = job->fileset;
1556    jcr->accurate = job->accurate;
1557    jcr->messages = job->messages;
1558    jcr->spool_data = job->spool_data;
1559    jcr->spool_size = job->spool_size;
1560    jcr->write_part_after_job = job->write_part_after_job;
1561    jcr->IgnoreDuplicateJobChecking = job->IgnoreDuplicateJobChecking;
1562    jcr->MaxRunSchedTime = job->MaxRunSchedTime;
1563    if (jcr->RestoreBootstrap) {
1564       free(jcr->RestoreBootstrap);
1565       jcr->RestoreBootstrap = NULL;
1566    }
1567    /* This can be overridden by Console program */
1568    if (job->RestoreBootstrap) {
1569       jcr->RestoreBootstrap = bstrdup(job->RestoreBootstrap);
1570    }
1571    /* This can be overridden by Console program */
1572    jcr->verify_job = job->verify_job;
1573    /* If no default level given, set one */
1574    if (jcr->getJobLevel() == 0) {
1575       switch (jcr->getJobType()) {
1576       case JT_VERIFY:
1577          jcr->setJobLevel(L_VERIFY_CATALOG);
1578          break;
1579       case JT_BACKUP:
1580          jcr->setJobLevel(L_INCREMENTAL);
1581          break;
1582       case JT_RESTORE:
1583       case JT_ADMIN:
1584          jcr->setJobLevel(L_NONE);
1585          break;
1586       default:
1587          jcr->setJobLevel(L_FULL);
1588          break;
1589       }
1590    }
1591 }
1592
1593 /*
1594  * Copy the storage definitions from an alist to the JCR
1595  */
1596 void copy_rwstorage(JCR *jcr, alist *storage, const char *where)
1597 {
1598    if (jcr->JobReads()) {
1599       copy_rstorage(jcr, storage, where);
1600    }
1601    copy_wstorage(jcr, storage, where);
1602 }
1603
1604
1605 /* Set storage override.  Releases any previous storage definition */
1606 void set_rwstorage(JCR *jcr, USTORE *store)
1607 {
1608    if (!store) {
1609       Jmsg(jcr, M_FATAL, 0, _("No storage specified.\n"));
1610       return;
1611    }
1612    if (jcr->JobReads()) {
1613       set_rstorage(jcr, store);
1614    }
1615    set_wstorage(jcr, store);
1616 }
1617
1618 void free_rwstorage(JCR *jcr)
1619 {
1620    free_rstorage(jcr);
1621    free_wstorage(jcr);
1622 }
1623
1624 /*
1625  * Copy the storage definitions from an alist to the JCR
1626  */
1627 void copy_rstorage(JCR *jcr, alist *storage, const char *where)
1628 {
1629    if (storage) {
1630       STORE *st;
1631       if (jcr->rstorage) {
1632          delete jcr->rstorage;
1633       }
1634       jcr->rstorage = New(alist(10, not_owned_by_alist));
1635       foreach_alist(st, storage) {
1636          jcr->rstorage->append(st);
1637       }
1638       if (!jcr->rstore_source) {
1639          jcr->rstore_source = get_pool_memory(PM_MESSAGE);
1640       }
1641       pm_strcpy(jcr->rstore_source, where);
1642       if (jcr->rstorage) {
1643          jcr->rstore = (STORE *)jcr->rstorage->first();
1644       }
1645    }
1646 }
1647
1648
1649 /* Set storage override.  Remove all previous storage */
1650 void set_rstorage(JCR *jcr, USTORE *store)
1651 {
1652    STORE *storage;
1653
1654    if (!store->store) {
1655       return;
1656    }
1657    if (jcr->rstorage) {
1658       free_rstorage(jcr);
1659    }
1660    if (!jcr->rstorage) {
1661       jcr->rstorage = New(alist(10, not_owned_by_alist));
1662    }
1663    jcr->rstore = store->store;
1664    if (!jcr->rstore_source) {
1665       jcr->rstore_source = get_pool_memory(PM_MESSAGE);
1666    }
1667    pm_strcpy(jcr->rstore_source, store->store_source);
1668    foreach_alist(storage, jcr->rstorage) {
1669       if (store->store == storage) {
1670          return;
1671       }
1672    }
1673    /* Store not in list, so add it */
1674    jcr->rstorage->prepend(store->store);
1675 }
1676
1677 void free_rstorage(JCR *jcr)
1678 {
1679    if (jcr->rstorage) {
1680       delete jcr->rstorage;
1681       jcr->rstorage = NULL;
1682    }
1683    jcr->rstore = NULL;
1684 }
1685
1686 /*
1687  * Copy the storage definitions from an alist to the JCR
1688  */
1689 void copy_wstorage(JCR *jcr, alist *storage, const char *where)
1690 {
1691    if (storage) {
1692       STORE *st;
1693       if (jcr->wstorage) {
1694          delete jcr->wstorage;
1695       }
1696       jcr->wstorage = New(alist(10, not_owned_by_alist));
1697       foreach_alist(st, storage) {
1698          Dmsg1(100, "wstorage=%s\n", st->name());
1699          jcr->wstorage->append(st);
1700       }
1701       if (!jcr->wstore_source) {
1702          jcr->wstore_source = get_pool_memory(PM_MESSAGE);
1703       }
1704       pm_strcpy(jcr->wstore_source, where);
1705       if (jcr->wstorage) {
1706          jcr->wstore = (STORE *)jcr->wstorage->first();
1707          Dmsg2(100, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
1708       }
1709    }
1710 }
1711
1712
1713 /* Set storage override. Remove all previous storage */
1714 void set_wstorage(JCR *jcr, USTORE *store)
1715 {
1716    STORE *storage;
1717
1718    if (!store->store) {
1719       return;
1720    }
1721    if (jcr->wstorage) {
1722       free_wstorage(jcr);
1723    }
1724    if (!jcr->wstorage) {
1725       jcr->wstorage = New(alist(10, not_owned_by_alist));
1726    }
1727    jcr->wstore = store->store;
1728    if (!jcr->wstore_source) {
1729       jcr->wstore_source = get_pool_memory(PM_MESSAGE);
1730    }
1731    pm_strcpy(jcr->wstore_source, store->store_source);
1732    Dmsg2(50, "wstore=%s where=%s\n", jcr->wstore->name(), jcr->wstore_source);
1733    foreach_alist(storage, jcr->wstorage) {
1734       if (store->store == storage) {
1735          return;
1736       }
1737    }
1738    /* Store not in list, so add it */
1739    jcr->wstorage->prepend(store->store);
1740 }
1741
1742 void free_wstorage(JCR *jcr)
1743 {
1744    if (jcr->wstorage) {
1745       delete jcr->wstorage;
1746       jcr->wstorage = NULL;
1747    }
1748    jcr->wstore = NULL;
1749 }
1750
1751 void create_clones(JCR *jcr)
1752 {
1753    /*
1754     * Fire off any clone jobs (run directives)
1755     */
1756    Dmsg2(900, "cloned=%d run_cmds=%p\n", jcr->cloned, jcr->job->run_cmds);
1757    if (!jcr->cloned && jcr->job->run_cmds) {
1758       char *runcmd;
1759       JOB *job = jcr->job;
1760       POOLMEM *cmd = get_pool_memory(PM_FNAME);
1761       UAContext *ua = new_ua_context(jcr);
1762       ua->batch = true;
1763       foreach_alist(runcmd, job->run_cmds) {
1764          cmd = edit_job_codes(jcr, cmd, runcmd, "", job_code_callback_director);
1765          Mmsg(ua->cmd, "run %s cloned=yes", cmd);
1766          Dmsg1(900, "=============== Clone cmd=%s\n", ua->cmd);
1767          parse_ua_args(ua);                 /* parse command */
1768          int stat = run_cmd(ua, ua->cmd);
1769          if (stat == 0) {
1770             Jmsg(jcr, M_ERROR, 0, _("Could not start clone job: \"%s\".\n"),
1771                  ua->cmd);
1772          } else {
1773             Jmsg(jcr, M_INFO, 0, _("Clone JobId %d started.\n"), stat);
1774          }
1775       }
1776       free_ua_context(ua);
1777       free_pool_memory(cmd);
1778    }
1779 }
1780
1781 /*
1782  * Given: a JobId in jcr->previous_jr.JobId,
1783  *  this subroutine writes a bsr file to restore that job.
1784  * Returns: -1 on error
1785  *           number of files if OK
1786  */
1787 int create_restore_bootstrap_file(JCR *jcr)
1788 {
1789    RESTORE_CTX rx;
1790    UAContext *ua;
1791    int files;
1792
1793    memset(&rx, 0, sizeof(rx));
1794    rx.bsr = new_bsr();
1795    rx.JobIds = (char *)"";
1796    rx.bsr->JobId = jcr->previous_jr.JobId;
1797    ua = new_ua_context(jcr);
1798    if (!complete_bsr(ua, rx.bsr)) {
1799       files = -1;
1800       goto bail_out;
1801    }
1802    rx.bsr->fi = new_findex();
1803    rx.bsr->fi->findex = 1;
1804    rx.bsr->fi->findex2 = jcr->previous_jr.JobFiles;
1805    jcr->ExpectedFiles = write_bsr_file(ua, rx);
1806    if (jcr->ExpectedFiles == 0) {
1807       files = 0;
1808       goto bail_out;
1809    }
1810    free_ua_context(ua);
1811    free_bsr(rx.bsr);
1812    jcr->needs_sd = true;
1813    return jcr->ExpectedFiles;
1814
1815 bail_out:
1816    free_ua_context(ua);
1817    free_bsr(rx.bsr);
1818    return files;
1819 }
1820
1821 /* TODO: redirect command ouput to job log */
1822 bool run_console_command(JCR *jcr, const char *cmd)
1823 {
1824    UAContext *ua;
1825    bool ok;
1826    JCR *ljcr = new_control_jcr("-RunScript-", JT_CONSOLE);
1827    ua = new_ua_context(ljcr);
1828    /* run from runscript and check if commands are authorized */
1829    ua->runscript = true;
1830    Mmsg(ua->cmd, "%s", cmd);
1831    Dmsg1(100, "Console command: %s\n", ua->cmd);
1832    parse_ua_args(ua);
1833    if (ua->argc > 0 && ua->argk[0][0] == '.') {
1834       ok = do_a_dot_command(ua);
1835    } else {
1836      ok = do_a_command(ua);
1837    }
1838    free_ua_context(ua);
1839    free_jcr(ljcr);
1840    return ok;
1841 }