]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/acquire.c
- Implement first cut of 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, _("Read 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, _("Read 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    dev->unblock();
418    return NULL;
419 }
420
421 /*
422  * This job is done, so release the device. From a Unix standpoint,
423  *  the device remains open.
424  *
425  */
426 bool release_device(DCR *dcr)
427 {
428    JCR *jcr = dcr->jcr;
429    DEVICE *dev = dcr->dev;
430    bool ok = true;
431
432    lock_device(dev);
433    Dmsg1(100, "release_device device is %s\n", dev->is_tape()?"tape":"disk");
434
435    /* if device is reserved, job never started, so release the reserve here */
436    if (dcr->reserved_device) {
437       dev->reserved_device--;
438       Dmsg1(100, "Dec reserve=%d\n", dev->reserved_device);
439       dcr->reserved_device = false;
440    }
441
442    if (dev->can_read()) {
443       dev->clear_read();              /* clear read bit */
444
445       /******FIXME**** send read volume usage statistics to director */
446
447    } else if (dev->num_writers > 0) {
448       /* 
449        * Note if WEOT is set, we are at the end of the tape
450        *   and may not be positioned correctly, so the
451        *   job_media_record and update_vol_info have already been
452        *   done, which means we skip them here.
453        */
454       dev->num_writers--;
455       Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
456       if (dev->is_labeled()) {
457          Dmsg0(100, "dir_create_jobmedia_record. Release\n");
458          if (!dev->at_weot() && !dir_create_jobmedia_record(dcr)) {
459             Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
460                dcr->VolCatInfo.VolCatName, jcr->Job);
461          }
462          /* If no more writers, write an EOF */
463          if (!dev->num_writers && dev->can_write()) {
464             weof_dev(dev, 1);
465             write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
466          }
467          if (!dev->at_weot()) {
468             dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
469             dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs */
470             /* Note! do volume update before close, which zaps VolCatInfo */
471             Dmsg0(100, "dir_update_vol_info. Release0\n");
472             dir_update_volume_info(dcr, false); /* send Volume info to Director */
473          }
474       }
475
476    } else {
477       /*                
478        * If we reach here, it is most likely because the job
479        *   has failed, since the device is not in read mode and
480        *   there are no writers. It was probably reserved.
481        */
482    }
483
484    /* If no writers, close if file or !CAP_ALWAYS_OPEN */
485    if (dev->num_writers == 0 && (!dev->is_tape() || !dev_cap(dev, CAP_ALWAYSOPEN))) {
486       dev->close();
487    }
488
489    /* Fire off Alert command and include any output */
490    if (!job_canceled(jcr) && dcr->device->alert_command) {
491       POOLMEM *alert;
492       int status = 1;
493       BPIPE *bpipe;
494       char line[MAXSTRING];
495       alert = get_pool_memory(PM_FNAME);
496       alert = edit_device_codes(dcr, alert, dcr->device->alert_command, "");
497       bpipe = open_bpipe(alert, 0, "r");
498       if (bpipe) {
499          while (fgets(line, sizeof(line), bpipe->rfd)) {
500             Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line);
501          }
502          status = close_bpipe(bpipe);
503       } else {
504          status = errno;
505       }
506       if (status != 0) {
507          berrno be;
508          Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
509               alert, be.strerror(status));
510       }
511
512       Dmsg1(400, "alert status=%d\n", status);
513       free_pool_memory(alert);
514    }
515    unlock_device(dev);
516    if (jcr->read_dcr == dcr) {
517       jcr->read_dcr = NULL;
518    }
519    if (jcr->dcr == dcr) {
520       jcr->dcr = NULL;
521    }
522    free_dcr(dcr);
523    return ok;
524 }