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