]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/acquire.c
- Put Dmsg() on inside if() to avoid calling subroutine.
[bacula/bacula] / bacula / src / stored / acquire.c
1 /*
2  *  Routines to acquire and release a device for read/write
3  *
4  *   Kern Sibbald, August MMII
5  *
6  *   Version $Id$
7  */
8 /*
9    Copyright (C) 2002-2005 Kern Sibbald
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License
13    version 2 as ammended with additional clauses defined in the
14    file LICENSE in the main source directory.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
19    the file LICENSE for additional details.
20
21  */
22
23 #include "bacula.h"                   /* pull in global headers */
24 #include "stored.h"                   /* pull in Storage Deamon headers */
25
26 static int can_reserve_drive(DCR *dcr);
27
28 /*
29  * Create a new Device Control Record and attach
30  *   it to the device (if this is a real job).
31  */
32 DCR *new_dcr(JCR *jcr, DEVICE *dev)
33 {
34    if (jcr && jcr->dcr) {
35       return jcr->dcr;
36    }
37    DCR *dcr = (DCR *)malloc(sizeof(DCR));
38    memset(dcr, 0, sizeof(DCR));
39    if (jcr) {
40       jcr->dcr = dcr;
41    }
42    dcr->jcr = jcr;
43    dcr->dev = dev;
44    if (dev) {
45       dcr->device = dev->device;
46    }
47    dcr->block = new_block(dev);
48    dcr->rec = new_record();
49    dcr->spool_fd = -1;
50    dcr->max_spool_size = dev->device->max_spool_size;
51    /* Attach this dcr only if dev is initialized */
52    if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
53       dev->attached_dcrs->append(dcr);  /* attach dcr to device */
54 //    jcr->dcrs->append(dcr);         /* put dcr in list for Job */
55    }
56    return dcr;
57 }
58
59 /*
60  * Search the dcrs list for the given dcr. If it is found,
61  *  as it should be, then remove it. Also zap the jcr pointer
62  *  to the dcr if it is the same one.
63  */
64 #ifdef needed
65 static void remove_dcr_from_dcrs(DCR *dcr)
66 {
67    JCR *jcr = dcr->jcr;
68    if (jcr->dcrs) {
69       int i = 0;
70       DCR *ldcr;
71       int num = jcr->dcrs->size();
72       for (i=0; i < num; i++) {
73          ldcr = (DCR *)jcr->dcrs->get(i);
74          if (ldcr == dcr) {
75             jcr->dcrs->remove(i);
76             if (jcr->dcr == dcr) {
77                jcr->dcr = NULL;
78             }
79          }
80       }
81    }
82 }
83 #endif
84
85 /*
86  * Free up all aspects of the given dcr -- i.e. dechain it,
87  *  release allocated memory, zap pointers, ...
88  */
89 void free_dcr(DCR *dcr)
90 {
91    JCR *jcr = dcr->jcr;
92    DEVICE *dev = dcr->dev;
93
94    /*
95     * If we reserved the device, we must decrement the
96     *  number of writers.
97     */
98    if (dcr->reserved_device) {
99       lock_device(dev);
100       dev->num_writers--;
101       if (dev->num_writers < 0) {
102          Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
103          dev->num_writers = 0;
104          dcr->reserved_device = false;
105       }
106       unlock_device(dev);
107    }
108
109    /* Detach this dcr only if the dev is initialized */
110    if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
111       dev->attached_dcrs->remove(dcr);  /* detach dcr from device */
112 //    remove_dcr_from_dcrs(dcr);      /* remove dcr from jcr list */
113    }
114    if (dcr->block) {
115       free_block(dcr->block);
116    }
117    if (dcr->rec) {
118       free_record(dcr->rec);
119    }
120    if (dcr->jcr) {
121       dcr->jcr->dcr = NULL;
122    }
123    free(dcr);
124 }
125
126
127 /*
128  * We "reserve" the drive by setting the ST_READ bit. No one else
129  *  should touch the drive until that is cleared.
130  *  This allows the DIR to "reserve" the device before actually
131  *  starting the job. 
132  */
133 bool reserve_device_for_read(DCR *dcr)
134 {
135    DEVICE *dev = dcr->dev;
136    JCR *jcr = dcr->jcr;
137    bool ok = false;
138
139    ASSERT(dcr);
140
141    dev->block(BST_DOING_ACQUIRE);
142
143    if (device_is_unmounted(dev)) {             
144       Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"),
145            dev->print_name());
146       goto bail_out;
147    }
148
149    if (dev->is_busy()) {
150       Mmsg1(jcr->errmsg, _("Device %s is busy.\n"),
151             dev->print_name());
152       goto bail_out;
153    }
154
155    dev->clear_append();
156    dev->set_read();
157    ok = true;
158
159 bail_out:
160    dev->unblock();
161    return ok;
162 }
163
164
165 /*********************************************************************
166  * Acquire device for reading. 
167  *  The drive should have previously been reserved by calling 
168  *  reserve_device_for_read(). We read the Volume label from the block and
169  *  leave the block pointers just after the label.
170  *
171  *  Returns: NULL if failed for any reason
172  *           dcr  if successful
173  */
174 DCR *acquire_device_for_read(DCR *dcr)
175 {
176    DEVICE *dev = dcr->dev;
177    JCR *jcr = dcr->jcr;
178    bool vol_ok = false;
179    bool tape_previously_mounted;
180    bool tape_initially_mounted;
181    VOL_LIST *vol;
182    bool try_autochanger = true;
183    int i;
184    int vol_label_status;
185    
186    dev->block(BST_DOING_ACQUIRE);
187
188    if (dev->num_writers > 0) {
189       Jmsg2(jcr, M_FATAL, 0, _("Num_writers=%d not zero. Job %d canceled.\n"), 
190          dev->num_writers, jcr->JobId);
191       goto get_out;
192    }
193
194    /* Find next Volume, if any */
195    vol = jcr->VolList;
196    if (!vol) {
197       Jmsg(jcr, M_FATAL, 0, _("No volumes specified. Job %d canceled.\n"), jcr->JobId);
198       goto get_out;
199    }
200    jcr->CurVolume++;
201    for (i=1; i<jcr->CurVolume; i++) {
202       vol = vol->next;
203    }
204    if (!vol) {
205       goto get_out;                   /* should not happen */   
206    }
207    bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
208
209    init_device_wait_timers(dcr);
210
211    tape_previously_mounted = dev->can_read() || dev->can_append() ||
212                              dev->is_labeled();
213    tape_initially_mounted = tape_previously_mounted;
214
215
216    /* Volume info is always needed because of VolParts */
217    Dmsg0(200, "dir_get_volume_info\n");
218    if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
219       Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
220    }
221    
222    dev->num_parts = dcr->VolCatInfo.VolCatParts;
223    
224    for (i=0; i<5; i++) {
225       dev->clear_labeled();              /* force reread of label */
226       if (job_canceled(jcr)) {
227          Mmsg1(dev->errmsg, _("Job %d canceled.\n"), jcr->JobId);
228          goto get_out;                /* error return */
229       }
230       /*
231        * This code ensures that the device is ready for
232        * reading. If it is a file, it opens it.
233        * If it is a tape, it checks the volume name
234        */
235       for ( ; !dev->is_open(); ) {
236          Dmsg1(120, "bstored: open vol=%s\n", dcr->VolumeName);
237          if (open_dev(dev, dcr->VolumeName, OPEN_READ_ONLY) < 0) {
238             if (dev->dev_errno == EIO) {   /* no tape loaded */
239               Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"),
240                     dev->print_name(), dcr->VolumeName, strerror_dev(dev));
241                goto default_path;
242             }
243             
244             /* If we have a dvd that requires mount, 
245              * we need to try to open the label, so the info can be reported
246              * if a wrong volume has been mounted. */
247             if (dev->is_dvd() && (dcr->VolCatInfo.VolCatParts > 0)) {
248                break;
249             }
250             
251             Jmsg3(jcr, M_FATAL, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"),
252                 dev->print_name(), dcr->VolumeName, strerror_dev(dev));
253             goto get_out;
254          }
255          Dmsg1(129, "open_dev %s OK\n", dev->print_name());
256       }
257       
258       if (dev->is_dvd()) {
259          vol_label_status = read_dev_volume_label_guess(dcr, 0);
260       } else {
261          vol_label_status = read_dev_volume_label(dcr);
262       }
263       
264       Dmsg0(200, "calling read-vol-label\n");
265       switch (vol_label_status) {
266       case VOL_OK:
267          vol_ok = true;
268          memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
269          break;                    /* got it */
270       case VOL_IO_ERROR:
271          /*
272           * Send error message generated by read_dev_volume_label()
273           *  only we really had a tape mounted. This supresses superfluous
274           *  error messages when nothing is mounted.
275           */
276          if (tape_previously_mounted) {
277             Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
278          }
279          goto default_path;
280       case VOL_NAME_ERROR:
281          if (tape_initially_mounted) {
282             tape_initially_mounted = false;
283             goto default_path;
284          }
285          /* Fall through */
286       default:
287          Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
288 default_path:
289          tape_previously_mounted = true;
290          
291          /* If the device requires mount, close it, so the device can be ejected.
292           * FIXME: This should perhaps be done for all devices. */
293          if (dev_cap(dev, CAP_REQMOUNT)) {
294             force_close_dev(dev);
295          }
296          
297          /* Call autochanger only once unless ask_sysop called */
298          if (try_autochanger) {
299             int stat;
300             Dmsg2(200, "calling autoload Vol=%s Slot=%d\n",
301                dcr->VolumeName, dcr->VolCatInfo.Slot);
302             stat = autoload_device(dcr, 0, NULL);
303             if (stat > 0) {
304                try_autochanger = false;
305                continue;              /* try reading volume mounted */
306             }
307          }
308          
309          /* Mount a specific volume and no other */
310          Dmsg0(200, "calling dir_ask_sysop\n");
311          if (!dir_ask_sysop_to_mount_volume(dcr)) {
312             goto get_out;             /* error return */
313          }
314          try_autochanger = true;      /* permit using autochanger again */
315          continue;                    /* try reading again */
316       } /* end switch */
317       break;
318    } /* end for loop */
319    if (!vol_ok) {
320       Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"),
321             dev->print_name());
322       goto get_out;
323    }
324
325    dev->clear_append();
326    dev->set_read();
327    set_jcr_job_status(jcr, JS_Running);
328    dir_send_job_status(jcr);
329    Jmsg(jcr, M_INFO, 0, _("Ready to read from volume \"%s\" on device %s.\n"),
330       dcr->VolumeName, dev->print_name());
331
332 get_out:
333    dev->unblock();
334    if (!vol_ok) {
335       free_dcr(dcr);
336       dcr = NULL;
337    }
338    return dcr;
339 }
340
341 /*
342  * We reserve the device for appending by incrementing the 
343  *  reserved_device. We do virtually all the same work that
344  *  is done in acquire_device_for_append(), but we do
345  *  not attempt to mount the device. This routine allows
346  *  the DIR to reserve multiple devices before *really* 
347  *  starting the job. It also permits the SD to refuse 
348  *  certain devices (not up, ...).
349  *
350  * Note, in reserving a device, if the device is for the
351  *  same pool and the same pool type, then it is acceptable.
352  *  The Media Type has already been checked. If we are
353  *  the first tor reserve the device, we put the pool
354  *  name and pool type in the device record.
355  */
356 bool reserve_device_for_append(DCR *dcr)
357 {
358    JCR *jcr = dcr->jcr;
359    DEVICE *dev = dcr->dev;
360    bool ok = false;
361
362    ASSERT(dcr);
363
364    dev->block(BST_DOING_ACQUIRE);
365
366    if (dev->can_read()) {
367       Mmsg1(jcr->errmsg, _("Device %s is busy reading.\n"), dev->print_name());
368       goto bail_out;
369    }
370
371    if (device_is_unmounted(dev)) {
372       Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"), dev->print_name());
373       goto bail_out;
374    }
375
376    Dmsg1(190, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
377
378    if (can_reserve_drive(dcr) != 1) {
379       Mmsg1(jcr->errmsg, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
380       goto bail_out;
381    }
382
383    dev->reserved_device++;
384    dcr->reserved_device = true;
385    ok = true;
386
387 bail_out:
388    dev->unblock();
389    return ok;
390 }
391
392 /*
393  * Returns: 1 if drive can be reserved
394  *          0 if we should wait
395  *         -1 on error
396  */
397 static int can_reserve_drive(DCR *dcr) 
398 {
399    DEVICE *dev = dcr->dev;
400    JCR *jcr = dcr->jcr;
401    /*
402     * First handle the case that the drive is not yet in append mode
403     */
404    if (!dev->can_append() && dev->num_writers == 0) {
405       /* Now check if there are any reservations on the drive */
406       if (dev->reserved_device) {           
407          /* Yes, now check if we want the same Pool and pool type */
408          if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
409              strcmp(dev->pool_type, dcr->pool_type) == 0) {
410             /* OK, compatible device */
411          } else {
412             /* Drive not suitable for us */
413             return 0;                 /* wait */
414          }
415       } else {
416          /* Device is available but not yet reserved, reserve it for us */
417          bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
418          bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
419       }
420       return 1;                       /* reserve drive */
421    }
422
423    /*
424     * Check if device in append mode with no writers (i.e. available)
425     */
426    if (dev->can_append() && dev->num_writers == 0) {
427       /* Device is available but not yet reserved, reserve it for us */
428       bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
429       bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
430       return 1;
431    }
432
433    /*
434     * Now check if the device is in append mode with writers (i.e.
435     *  available if pool is the same).
436     */
437    if (dev->can_append() || dev->num_writers > 0) {
438       Dmsg0(190, "device already in append.\n");
439       /* Yes, now check if we want the same Pool and pool type */
440       if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
441           strcmp(dev->pool_type, dcr->pool_type) == 0) {
442          /* OK, compatible device */
443       } else {
444          /* Drive not suitable for us */
445          Jmsg(jcr, M_WARNING, 0, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
446          return 0;                    /* wait */
447       }
448    } else {
449       Pmsg0(000, "Logic error!!!! Should not get here.\n");
450       Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
451       return -1;                      /* error, should not get here */
452    }
453    return 1;                          /* reserve drive */
454 }
455
456 /*
457  * Acquire device for writing. We permit multiple writers.
458  *  If this is the first one, we read the label.
459  *
460  *  Returns: NULL if failed for any reason
461  *           dcr if successful.
462  *   Note, normally reserve_device_for_append() is called
463  *   before this routine.
464  */
465 DCR *acquire_device_for_append(DCR *dcr)
466 {
467    bool release = false;
468    bool recycle = false;
469    bool do_mount = false;
470    DEVICE *dev = dcr->dev;
471    JCR *jcr = dcr->jcr;
472
473    init_device_wait_timers(dcr);
474
475    dev->block(BST_DOING_ACQUIRE);
476    Dmsg1(190, "acquire_append device is %s\n", dev->is_tape()?"tape":"disk");
477
478    if (dcr->reserved_device) {
479       dev->reserved_device--;
480       dcr->reserved_device = false;
481    }
482
483    /*
484     * With the reservation system, this should not happen
485     */
486    if (dev->can_read()) {
487       Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev->print_name());
488       goto get_out;
489    }
490
491    if (dev->can_append()) {
492       Dmsg0(190, "device already in append.\n");
493       /*
494        * Device already in append mode
495        *
496        * Check if we have the right Volume mounted
497        *   OK if current volume info OK
498        *   OK if next volume matches current volume
499        *   otherwise mount desired volume obtained from
500        *    dir_find_next_appendable_volume
501        */
502       bstrncpy(dcr->VolumeName, dev->VolHdr.VolName, sizeof(dcr->VolumeName));
503       if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
504           !(dir_find_next_appendable_volume(dcr) &&
505             strcmp(dev->VolHdr.VolName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
506          Dmsg0(190, "Wrong tape mounted.\n");
507          if (dev->num_writers != 0 || dev->reserved_device) {
508             Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
509             goto get_out;
510          }
511          /* Wrong tape mounted, release it, then fall through to get correct one */
512          Dmsg0(190, "Wrong tape mounted, release and try mount.\n");
513          release = true;
514          do_mount = true;
515       } else {
516          /*
517           * At this point, the correct tape is already mounted, so
518           *   we do not need to do mount_next_write_volume(), unless
519           *   we need to recycle the tape.
520           */
521           recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
522           Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle);
523           if (recycle && dev->num_writers != 0) {
524              Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
525                   " on device %s because it is in use by another job.\n"),
526                   dev->VolHdr.VolName, dev->print_name());
527              goto get_out;
528           }
529           if (dev->num_writers == 0) {
530              memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
531           }
532        }
533    } else {
534       /* Not already in append mode, so mount the device */
535       Dmsg0(190, "Not in append mode, try mount.\n");
536       ASSERT(dev->num_writers == 0);
537       do_mount = true;
538    }
539
540    if (do_mount || recycle) {
541       Dmsg0(190, "Do mount_next_write_vol\n");
542       bool mounted = mount_next_write_volume(dcr, release);
543       if (!mounted) {
544          if (!job_canceled(jcr)) {
545             /* Reduce "noise" -- don't print if job canceled */
546             Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
547                dev->print_name());
548          }
549          goto get_out;
550       }
551    }
552
553    dev->num_writers++;                /* we are now a writer */
554    if (jcr->NumVolumes == 0) {
555       jcr->NumVolumes = 1;
556    }
557    goto ok_out;
558
559 /*
560  * If we jump here, it is an error return because
561  *  rtn_dev will still be NULL
562  */
563 get_out:
564    free_dcr(dcr);
565    dcr = NULL;
566 ok_out:
567    dev->unblock();
568    return dcr;
569 }
570
571 /*
572  * This job is done, so release the device. From a Unix standpoint,
573  *  the device remains open.
574  *
575  */
576 bool release_device(DCR *dcr)
577 {
578    JCR *jcr = dcr->jcr;
579    DEVICE *dev = dcr->dev;
580    bool ok = true;
581
582    lock_device(dev);
583    Dmsg1(100, "release_device device is %s\n", dev->is_tape()?"tape":"disk");
584
585    /* if device is reserved, job never started, so release the reserve here */
586    if (dcr->reserved_device) {
587       dev->reserved_device--;
588       dcr->reserved_device = false;
589    }
590
591    if (dev->can_read()) {
592       dev->clear_read();              /* clear read bit */
593
594       /******FIXME**** send read volume usage statistics to director */
595
596    } else if (dev->num_writers > 0) {
597       /* 
598        * Note if WEOT is set, we are at the end of the tape
599        *   and may not be positioned correctly, so the
600        *   job_media_record and update_vol_info have already been
601        *   done, which means we skip them here.
602        */
603       dev->num_writers--;
604       Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
605       if (dev->is_labeled()) {
606          Dmsg0(100, "dir_create_jobmedia_record. Release\n");
607          if (!dev->at_weot() && !dir_create_jobmedia_record(dcr)) {
608             Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
609                dcr->VolCatInfo.VolCatName, jcr->Job);
610          }
611          /* If no more writers, write an EOF */
612          if (!dev->num_writers && dev->can_write()) {
613             weof_dev(dev, 1);
614             write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolName);
615          }
616          if (!dev->at_weot()) {
617             dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
618             dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs */
619             /* Note! do volume update before close, which zaps VolCatInfo */
620             Dmsg0(100, "dir_update_vol_info. Release0\n");
621             dir_update_volume_info(dcr, false); /* send Volume info to Director */
622          }
623       }
624
625    } else {
626       /*                
627        * If we reach here, it is most likely because the job
628        *   has failed, since the device is not in read mode and
629        *   there are no writers. It was probably reserved.
630        */
631    }
632
633    /* If no writers, close if file or !CAP_ALWAYS_OPEN */
634    if (dev->num_writers == 0 && (!dev->is_tape() || !dev_cap(dev, CAP_ALWAYSOPEN))) {
635       offline_or_rewind_dev(dev);
636       close_dev(dev);
637    }
638
639    /* Fire off Alert command and include any output */
640    if (!job_canceled(jcr) && dcr->device->alert_command) {
641       POOLMEM *alert;
642       int status = 1;
643       BPIPE *bpipe;
644       char line[MAXSTRING];
645       alert = get_pool_memory(PM_FNAME);
646       alert = edit_device_codes(dcr, alert, dcr->device->alert_command, "");
647       bpipe = open_bpipe(alert, 0, "r");
648       if (bpipe) {
649          while (fgets(line, sizeof(line), bpipe->rfd)) {
650             Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line);
651          }
652          status = close_bpipe(bpipe);
653       } else {
654          status = errno;
655       }
656       if (status != 0) {
657          berrno be;
658          Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
659               alert, be.strerror(status));
660       }
661
662       Dmsg1(400, "alert status=%d\n", status);
663       free_pool_memory(alert);
664    }
665    unlock_device(dev);
666    free_dcr(dcr);
667    jcr->dcr = NULL;
668    pthread_cond_broadcast(&wait_device_release);
669    return ok;
670 }