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