]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/acquire.c
728e7cc37892428e1289f03e6c93ed9bcf1b19c1
[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-2006 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 amended 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 /* Forward referenced functions */
27 static void attach_dcr_to_dev(DCR *dcr);
28
29
30 /*********************************************************************
31  * Acquire device for reading. 
32  *  The drive should have previously been reserved by calling 
33  *  reserve_device_for_read(). We read the Volume label from the block and
34  *  leave the block pointers just after the label.
35  *
36  *  Returns: NULL if failed for any reason
37  *           dcr  if successful
38  */
39 bool acquire_device_for_read(DCR *dcr)
40 {
41    DEVICE *dev = dcr->dev;
42    JCR *jcr = dcr->jcr;
43    bool ok = false;
44    bool tape_previously_mounted;
45    bool tape_initially_mounted;
46    VOL_LIST *vol;
47    bool try_autochanger = true;
48    int i;
49    int vol_label_status;
50    int retry = 0;
51    
52    Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
53    dev->block(BST_DOING_ACQUIRE);
54
55    if (dev->num_writers > 0) {
56       Jmsg2(jcr, M_FATAL, 0, _("Num_writers=%d not zero. Job %d canceled.\n"), 
57          dev->num_writers, jcr->JobId);
58       goto get_out;
59    }
60
61    /* Find next Volume, if any */
62    vol = jcr->VolList;
63    if (!vol) {
64       Jmsg(jcr, M_FATAL, 0, _("No volumes specified. Job %d canceled.\n"), jcr->JobId);
65       goto get_out;
66    }
67    jcr->CurVolume++;
68    for (i=1; i<jcr->CurVolume; i++) {
69       vol = vol->next;
70    }
71    if (!vol) {
72       goto get_out;                   /* should not happen */   
73    }
74    bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
75    bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
76    dcr->VolCatInfo.Slot = vol->Slot;
77     
78    /*
79     * If the MediaType requested for this volume is not the
80     *  same as the current drive, we attempt to find the same
81     *  device that was used to write the orginal volume.  If
82     *  found, we switch to using that device.
83     */
84    Dmsg2(100, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
85    if (dcr->media_type[0] && strcmp(dcr->media_type, dev->device->media_type) != 0) {
86       RCTX rctx;
87       DIRSTORE *store;
88       int stat;
89       DCR *dcr_save = jcr->dcr;
90
91       lock_reservations();
92       jcr->dcr = NULL;
93       memset(&rctx, 0, sizeof(RCTX));
94       rctx.jcr = jcr;
95       jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
96       rctx.any_drive = true;
97       rctx.device_name = vol->device;
98       store = new DIRSTORE;
99       memset(store, 0, sizeof(DIRSTORE));
100       store->name[0] = 0; /* No dir name */
101       bstrncpy(store->media_type, vol->MediaType, sizeof(store->media_type));
102       bstrncpy(store->pool_name, dcr->pool_name, sizeof(store->pool_name));
103       bstrncpy(store->pool_type, dcr->pool_type, sizeof(store->pool_type));
104       store->append = false;
105       rctx.store = store;
106       
107       /*
108        * Note, if search_for_device() succeeds, we get a new_dcr,
109        *  which we do not use except for the dev info.
110        */
111       stat = search_res_for_device(rctx);
112       release_msgs(jcr);              /* release queued messages */
113       unlock_reservations();
114       if (stat == 1) {
115          DCR *new_dcr = jcr->read_dcr;
116          dev->unblock();
117          detach_dcr_from_dev(dcr);    /* release old device */
118          /* Copy important info from the new dcr */
119          dev = dcr->dev = new_dcr->dev; 
120          jcr->read_dcr = dcr; 
121          dcr->device = new_dcr->device;
122          dcr->max_job_spool_size = dcr->device->max_job_spool_size;
123          attach_dcr_to_dev(dcr);
124          new_dcr->VolumeName[0] = 0;
125          free_dcr(new_dcr);
126          dev->block(BST_DOING_ACQUIRE); 
127          Jmsg(jcr, M_INFO, 0, _("Media Type change.  New device %s chosen.\n"),
128             dev->print_name());
129          bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
130          bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
131          dcr->VolCatInfo.Slot = vol->Slot;
132          bstrncpy(dcr->pool_name, store->pool_name, sizeof(dcr->pool_name));
133          bstrncpy(dcr->pool_type, store->pool_type, sizeof(dcr->pool_type));
134       } else if (stat == 0) {   /* device busy */
135          Dmsg1(000, "Device %s is busy.\n", vol->device);
136       } else {
137          /* error */
138          Jmsg1(jcr, M_FATAL, 0, _("No suitable device found to read Volume \"%s\"\n"),
139             vol->VolumeName);
140          jcr->dcr = dcr_save;
141          goto get_out;
142       }
143       jcr->dcr = dcr_save;
144    }
145
146
147    init_device_wait_timers(dcr);
148
149    tape_previously_mounted = dev->can_read() || dev->can_append() ||
150                              dev->is_labeled();
151    tape_initially_mounted = tape_previously_mounted;
152
153
154    /* Volume info is always needed because of VolParts */
155    Dmsg0(200, "dir_get_volume_info\n");
156    if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
157       Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
158    }
159    
160    for ( ;; ) {
161       /* If not polling limit retries */
162       if (!dev->poll && retry++ > 10) {
163          break;
164       }
165       dev->clear_labeled();              /* force reread of label */
166       if (job_canceled(jcr)) {
167          Mmsg1(dev->errmsg, _("Job %d canceled.\n"), jcr->JobId);
168          goto get_out;                /* error return */
169       }
170
171       autoload_device(dcr, 0, NULL);
172
173       /*
174        * This code ensures that the device is ready for
175        * reading. If it is a file, it opens it.
176        * If it is a tape, it checks the volume name
177        */
178       Dmsg1(100, "bstored: open vol=%s\n", dcr->VolumeName);
179       if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
180         Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
181               dev->print_name(), dcr->VolumeName, dev->bstrerror());
182          goto default_path;
183       }
184       Dmsg1(100, "opened dev %s OK\n", dev->print_name());
185       
186       /* Read Volume Label */
187       
188       Dmsg0(200, "calling read-vol-label\n");
189       vol_label_status = read_dev_volume_label(dcr);
190       switch (vol_label_status) {
191       case VOL_OK:
192          ok = true;
193          memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
194          break;                    /* got it */
195       case VOL_IO_ERROR:
196          /*
197           * Send error message generated by read_dev_volume_label()
198           *  only we really had a tape mounted. This supresses superfluous
199           *  error messages when nothing is mounted.
200           */
201          if (tape_previously_mounted) {
202             Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
203          }
204          goto default_path;
205       case VOL_NAME_ERROR:
206          if (tape_initially_mounted) {
207             tape_initially_mounted = false;
208             goto default_path;
209          }
210          /* If polling and got a previous bad name, ignore it */
211          if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) {
212             goto default_path;
213          } else {
214              bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName));
215          }
216          /* Fall through */
217       default:
218          Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
219 default_path:
220          tape_previously_mounted = true;
221          
222          /*
223           * If the device requires mount, close it, so the device can be ejected.
224           */
225          if (dev->requires_mount()) {
226             dev->close();
227          }
228          
229          /* Call autochanger only once unless ask_sysop called */
230          if (try_autochanger) {
231             int stat;
232             Dmsg2(200, "calling autoload Vol=%s Slot=%d\n",
233                dcr->VolumeName, dcr->VolCatInfo.Slot);
234             stat = autoload_device(dcr, 0, NULL);
235             if (stat > 0) {
236                try_autochanger = false;
237                continue;              /* try reading volume mounted */
238             }
239          }
240          
241          /* Mount a specific volume and no other */
242          Dmsg0(200, "calling dir_ask_sysop\n");
243          if (!dir_ask_sysop_to_mount_volume(dcr)) {
244             goto get_out;             /* error return */
245          }
246          try_autochanger = true;      /* permit using autochanger again */
247          continue;                    /* try reading again */
248       } /* end switch */
249       break;
250    } /* end for loop */
251    if (!ok) {
252       Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"),
253             dev->print_name());
254       goto get_out;
255    }
256
257    dev->clear_append();
258    dev->set_read();
259    set_jcr_job_status(jcr, JS_Running);
260    dir_send_job_status(jcr);
261    Jmsg(jcr, M_INFO, 0, _("Ready to read from volume \"%s\" on device %s.\n"),
262       dcr->VolumeName, dev->print_name());
263
264 get_out:
265    P(dev->mutex);
266    if (dcr->reserved_device) {
267       dev->reserved_device--;
268       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
269       dcr->reserved_device = false;
270    }
271    V(dev->mutex);
272    dev->unblock();
273    Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
274    return ok;
275 }
276
277
278 /*
279  * Acquire device for writing. We permit multiple writers.
280  *  If this is the first one, we read the label.
281  *
282  *  Returns: NULL if failed for any reason
283  *           dcr if successful.
284  *   Note, normally reserve_device_for_append() is called
285  *   before this routine.
286  */
287 DCR *acquire_device_for_append(DCR *dcr)
288 {
289    bool release = false;
290    bool recycle = false;
291    bool do_mount = false;
292    DEVICE *dev = dcr->dev;
293    JCR *jcr = dcr->jcr;
294
295    init_device_wait_timers(dcr);
296
297    dev->block(BST_DOING_ACQUIRE);
298    Dmsg1(190, "acquire_append device is %s\n", dev->is_tape()?"tape":
299         (dev->is_dvd()?"DVD":"disk"));
300
301    /*
302     * With the reservation system, this should not happen
303     */
304    if (dev->can_read()) {
305       Jmsg1(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev->print_name());
306       Dmsg1(200, "Device %s is busy reading.\n", dev->print_name());
307       goto get_out;
308    }
309
310    if (dev->can_append()) {
311       Dmsg0(190, "device already in append.\n");
312       /*
313        * Device already in append mode
314        *
315        * Check if we have the right Volume mounted
316        *   OK if current volume info OK
317        *   OK if next volume matches current volume
318        *   otherwise mount desired volume obtained from
319        *    dir_find_next_appendable_volume
320        *  dev->VolHdr.VolumeName is what is in the drive
321        *  dcr->VolumeName is what we pass into the routines, or
322        *    get back from the subroutines.
323        */
324       bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
325       if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
326           !(dir_find_next_appendable_volume(dcr) &&
327             strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
328          Dmsg2(190, "Wrong tape mounted: %s. wants:%s\n", dev->VolHdr.VolumeName,
329             dcr->VolumeName);
330          /* Release volume reserved by dir_find_next_appendable_volume() */
331          if (dcr->VolumeName[0]) {
332             free_unused_volume(dcr);
333          }
334          if (dev->num_writers != 0) {
335             Jmsg3(jcr, M_FATAL, 0, _("Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n"), 
336                  dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
337             Dmsg3(200, "Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n",  
338                  dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
339             goto get_out;
340          }
341          /* Wrong tape mounted, release it, then fall through to get correct one */
342          Dmsg0(190, "Wrong tape mounted, release and try mount.\n");
343          release = true;
344          do_mount = true;
345       } else {
346          /*
347           * At this point, the correct tape is already mounted, so
348           *   we do not need to do mount_next_write_volume(), unless
349           *   we need to recycle the tape.
350           */
351           recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
352           Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle);
353           if (recycle && dev->num_writers != 0) {
354              Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
355                   " on device %s because it is in use by another job.\n"),
356                   dev->VolHdr.VolumeName, dev->print_name());
357              goto get_out;
358           }
359           if (dev->num_writers == 0) {
360              memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
361           }
362       }
363    } else {
364       /* Not already in append mode, so mount the device */
365       Dmsg0(190, "Not in append mode, try mount.\n");
366       ASSERT(dev->num_writers == 0);
367       do_mount = true;
368    }
369
370    if (do_mount || recycle) {
371       Dmsg0(190, "Do mount_next_write_vol\n");
372       bool mounted = mount_next_write_volume(dcr, release);
373       if (!mounted) {
374          if (!job_canceled(jcr)) {
375             /* Reduce "noise" -- don't print if job canceled */
376             Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
377                dev->print_name());
378             Dmsg1(200, "Could not ready device %s for append.\n", 
379                dev->print_name());
380          }
381          goto get_out;
382       }
383       Dmsg2(190, "Output pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num);
384    }
385
386    dev->num_writers++;                /* we are now a writer */
387    if (jcr->NumVolumes == 0) {
388       jcr->NumVolumes = 1;
389    }
390    P(dev->mutex);
391    if (dcr->reserved_device) {
392       dev->reserved_device--;
393       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
394       dcr->reserved_device = false;
395    }
396    V(dev->mutex);
397    dev->unblock();
398    return dcr;
399
400 /*
401  * Error return
402  */
403 get_out:
404    P(dev->mutex);
405    if (dcr->reserved_device) {
406       dev->reserved_device--;
407       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
408       dcr->reserved_device = false;
409    }
410    V(dev->mutex);
411    dev->unblock();
412    return NULL;
413 }
414
415
416 /*
417  * This job is done, so release the device. From a Unix standpoint,
418  *  the device remains open.
419  *
420  */
421 bool release_device(DCR *dcr)
422 {
423    JCR *jcr = dcr->jcr;
424    DEVICE *dev = dcr->dev;
425    bool ok = true;
426
427    lock_device(dev);
428    Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape()?"tape":"disk");
429
430    /* if device is reserved, job never started, so release the reserve here */
431    if (dcr->reserved_device) {
432       dev->reserved_device--;
433       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
434       dcr->reserved_device = false;
435    }
436
437    if (dev->can_read()) {
438       dev->clear_read();              /* clear read bit */
439
440       /******FIXME**** send read volume usage statistics to director */
441
442    } else if (dev->num_writers > 0) {
443       /* 
444        * Note if WEOT is set, we are at the end of the tape
445        *   and may not be positioned correctly, so the
446        *   job_media_record and update_vol_info have already been
447        *   done, which means we skip them here.
448        */
449       dev->num_writers--;
450       Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
451       if (dev->is_labeled()) {
452          Dmsg0(100, "dir_create_jobmedia_record. Release\n");
453          if (!dev->at_weot() && !dir_create_jobmedia_record(dcr)) {
454             Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
455                dcr->VolCatInfo.VolCatName, jcr->Job);
456          }
457          /* If no more writers, write an EOF */
458          if (!dev->num_writers && dev->can_write()) {
459             dev->weof(1);
460             write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
461          }
462          if (!dev->at_weot()) {
463             dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
464             dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs */
465             /* Note! do volume update before close, which zaps VolCatInfo */
466             Dmsg0(100, "dir_update_vol_info. Release0\n");
467             dir_update_volume_info(dcr, false); /* send Volume info to Director */
468          }
469       }
470
471    } else {
472       /*                
473        * If we reach here, it is most likely because the job
474        *   has failed, since the device is not in read mode and
475        *   there are no writers. It was probably reserved.
476        */
477    }
478
479    /* If no writers, close if file or !CAP_ALWAYS_OPEN */
480    if (dev->num_writers == 0 && (!dev->is_tape() || !dev_cap(dev, CAP_ALWAYSOPEN))) {
481       dvd_remove_empty_part(dcr);        /* get rid of any empty spool part */
482       dev->close();
483    }
484
485    /* Fire off Alert command and include any output */
486    if (!job_canceled(jcr) && dcr->device->alert_command) {
487       POOLMEM *alert;
488       int status = 1;
489       BPIPE *bpipe;
490       char line[MAXSTRING];
491       alert = get_pool_memory(PM_FNAME);
492       alert = edit_device_codes(dcr, alert, dcr->device->alert_command, "");
493       bpipe = open_bpipe(alert, 0, "r");
494       if (bpipe) {
495          while (fgets(line, sizeof(line), bpipe->rfd)) {
496             Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line);
497          }
498          status = close_bpipe(bpipe);
499       } else {
500          status = errno;
501       }
502       if (status != 0) {
503          berrno be;
504          Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
505               alert, be.strerror(status));
506       }
507
508       Dmsg1(400, "alert status=%d\n", status);
509       free_pool_memory(alert);
510    }
511    unlock_device(dev);
512    if (jcr->read_dcr == dcr) {
513       jcr->read_dcr = NULL;
514    }
515    if (jcr->dcr == dcr) {
516       jcr->dcr = NULL;
517    }
518    free_dcr(dcr);
519    return ok;
520 }
521
522 /*
523  * Create a new Device Control Record and attach
524  *   it to the device (if this is a real job).
525  */
526 DCR *new_dcr(JCR *jcr, DEVICE *dev)
527 {
528    DCR *dcr = (DCR *)malloc(sizeof(DCR));
529    memset(dcr, 0, sizeof(DCR));
530    dcr->jcr = jcr;
531    if (dev) {
532       dcr->dev = dev;
533       dcr->device = dev->device;
534       dcr->block = new_block(dev);
535       dcr->rec = new_record();
536       dcr->max_job_spool_size = dev->device->max_job_spool_size;
537       attach_dcr_to_dev(dcr);
538    }
539    dcr->spool_fd = -1;
540    return dcr;
541 }
542
543 /*
544  * Search the dcrs list for the given dcr. If it is found,
545  *  as it should be, then remove it. Also zap the jcr pointer
546  *  to the dcr if it is the same one.
547  */
548 #ifdef needed
549 static void remove_dcr_from_dcrs(DCR *dcr)
550 {
551    JCR *jcr = dcr->jcr;
552    if (jcr->dcrs) {
553       int i = 0;
554       DCR *ldcr;
555       int num = jcr->dcrs->size();
556       for (i=0; i < num; i++) {
557          ldcr = (DCR *)jcr->dcrs->get(i);
558          if (ldcr == dcr) {
559             jcr->dcrs->remove(i);
560             if (jcr->dcr == dcr) {
561                jcr->dcr = NULL;
562             }
563          }
564       }
565    }
566 }
567 #endif
568
569 static void attach_dcr_to_dev(DCR *dcr)
570 {
571    DEVICE *dev = dcr->dev;
572    JCR *jcr = dcr->jcr;
573
574    if (!dcr->attached_to_dev && dev->is_open() && jcr && jcr->JobType != JT_SYSTEM) {
575       dev->attached_dcrs->append(dcr);  /* attach dcr to device */
576       dcr->attached_to_dev = true;
577    }
578 }
579
580 void detach_dcr_from_dev(DCR *dcr)
581 {
582    DEVICE *dev = dcr->dev;
583
584    if (dcr->reserved_device) {
585       dcr->reserved_device = false;
586       lock_device(dev);
587       dev->reserved_device--;
588       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
589       dcr->reserved_device = false;
590       /* If we set read mode in reserving, remove it */
591       if (dev->can_read()) {
592          dev->clear_read();
593       }
594       if (dev->num_writers < 0) {
595          Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
596          dev->num_writers = 0;
597       }
598       unlock_device(dev);
599    }
600
601    /* Detach this dcr only if attached */
602    if (dcr->attached_to_dev) {
603       dcr->dev->attached_dcrs->remove(dcr);  /* detach dcr from device */
604       dcr->attached_to_dev = false;
605 //    remove_dcr_from_dcrs(dcr);      /* remove dcr from jcr list */
606    }
607    free_unused_volume(dcr);           /* free unused vols attached to this dcr */
608    pthread_cond_broadcast(&dcr->dev->wait_next_vol);
609    pthread_cond_broadcast(&wait_device_release);
610 }
611
612 /*
613  * Free up all aspects of the given dcr -- i.e. dechain it,
614  *  release allocated memory, zap pointers, ...
615  */
616 void free_dcr(DCR *dcr)
617 {
618
619    detach_dcr_from_dev(dcr);
620
621    if (dcr->block) {
622       free_block(dcr->block);
623    }
624    if (dcr->rec) {
625       free_record(dcr->rec);
626    }
627    if (dcr->jcr) {
628       dcr->jcr->dcr = NULL;
629    }
630    free(dcr);
631 }