]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/device.c
f92081f16d927f6a7367750f2bf0e3a8da0e73be
[bacula/bacula] / bacula / src / stored / device.c
1 /*
2  *
3  *  Higher Level Device routines. 
4  *  Knows about Bacula tape labels and such  
5  *
6  *  NOTE! In general, subroutines that have the word
7  *        "device" in the name do locking.  Subroutines
8  *        that have the word "dev" in the name do not
9  *        do locking.  Thus if xxx_device() calls
10  *        yyy_dev(), all is OK, but if xxx_device()
11  *        calls yyy_device(), everything will hang.
12  *        Obviously, no zzz_dev() is allowed to call
13  *        a www_device() or everything falls apart. 
14  *
15  * Concerning the routines lock_device() and block_device()
16  *  see the end of this module for details.  In general,
17  *  blocking a device leaves it in a state where all threads
18  *  other than the current thread block when they attempt to 
19  *  lock the device. They remain suspended (blocked) until the device
20  *  is unblocked. So, a device is blocked during an operation
21  *  that takes a long time (initialization, mounting a new
22  *  volume, ...) locking a device is done for an operation
23  *  that takes a short time such as writing data to the   
24  *  device.
25  *
26  *
27  *   Kern Sibbald, MM, MMI
28  *                            
29  */
30 /*
31    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
32
33    This program is free software; you can redistribute it and/or
34    modify it under the terms of the GNU General Public License as
35    published by the Free Software Foundation; either version 2 of
36    the License, or (at your option) any later version.
37
38    This program is distributed in the hope that it will be useful,
39    but WITHOUT ANY WARRANTY; without even the implied warranty of
40    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41    General Public License for more details.
42
43    You should have received a copy of the GNU General Public
44    License along with this program; if not, write to the Free
45    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
46    MA 02111-1307, USA.
47
48  */
49
50 #include "bacula.h"                   /* pull in global headers */
51 #include "stored.h"                   /* pull in Storage Deamon headers */
52
53 /* Forward referenced functions */
54 static int ready_dev_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
55 static int mount_next_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *label_blk);
56
57 extern char my_name[];
58 extern int debug_level;
59
60
61 /********************************************************************* 
62  * Acquire device for reading.  We permit (for the moment)
63  *  only one reader.  We read the Volume label from the block and
64  *  leave the block pointers just after the label.
65  *
66  *  Returns: 0 if failed for any reason
67  *           1 if successful
68  */
69 int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
70 {
71    int stat;
72
73    lock_device(dev);
74    if (dev->state & ST_READ || dev->num_writers > 0) {
75       Jmsg(jcr, M_FATAL, 0, _("Device %s is busy.\n"), dev_name(dev));
76       unlock_device(dev);
77       return 0;
78    }
79    dev->state &= ~ST_LABEL;           /* force reread of label */
80    block_device(dev, BST_DOING_ACQUIRE);
81    unlock_device(dev);
82    stat = ready_dev_for_read(jcr, dev, block);  
83    P(dev->mutex); 
84    unblock_device(dev);
85    V(dev->mutex);
86    return stat;
87 }
88
89 /*
90  * Acquire device for writing. We permit multiple writers.
91  *  If this is the first one, we read the label.
92  *
93  *  Returns: 0 if failed for any reason
94  *           1 if successful
95  */
96 int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
97 {
98
99    lock_device(dev);
100    Dmsg1(90, "acquire_append device is %s\n", dev_is_tape(dev)?"tape":"disk");
101    if (!(dev->state & ST_APPEND)) {
102       if (dev->state & ST_READ) {
103          Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev));
104          unlock_device(dev);
105          return 0;
106       } 
107       ASSERT(dev->num_writers == 0);
108       block_device(dev, BST_DOING_ACQUIRE);
109       unlock_device(dev);
110       if (!ready_dev_for_append(jcr, dev, block)) {
111          Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
112             dev_name(dev));
113          P(dev->mutex);
114          unblock_device(dev);
115          V(dev->mutex);
116          return 0;
117       }
118       P(dev->mutex);
119       dev->VolCatInfo.VolCatJobs++;         /* increment number of jobs on this media */
120       dev->num_writers = 1;
121       if (jcr->NumVolumes == 0) {
122          jcr->NumVolumes = 1;
123       }
124       unblock_device(dev);
125       V(dev->mutex);
126       return 1;
127    } else { 
128       /* 
129        * Device already in append mode   
130        *
131        * Check if we have the right Volume mounted   
132        *  OK if AnonVols and volume info OK
133        *  OK if next volume matches current volume
134        *  otherwise mount desired volume obtained from
135        *    dir_find_next_appendable_volume
136        */
137       strcpy(jcr->VolumeName, dev->VolHdr.VolName);
138       if (((dev->capabilities & CAP_ANONVOLS) &&
139             !dir_get_volume_info(jcr)) ||
140           (!dir_find_next_appendable_volume(jcr) || 
141             strcmp(dev->VolHdr.VolName, jcr->VolumeName) != 0)) { /* wrong tape mounted */
142          if (dev->num_writers != 0) {
143             Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing with another Volume.\n"), dev_name(dev));
144             unlock_device(dev);
145             return 0;
146          }
147          /* Wrong tape currently mounted */  
148          block_device(dev, BST_DOING_ACQUIRE);
149          unlock_device(dev);
150          if (!mount_next_volume(jcr, dev, block)) {
151             Jmsg(jcr, M_FATAL, 0, _("Unable to mount desired volume.\n"));
152             P(dev->mutex);
153             unblock_device(dev);
154             V(dev->mutex);
155             return 0;
156          }
157          P(dev->mutex);
158          unblock_device(dev);
159       }
160    }
161    dev->VolCatInfo.VolCatJobs++;            /* increment number of jobs on this media */
162    dev->num_writers++;
163    if (dev->num_writers > 1) {
164       Dmsg2(0, "Hey!!!! There are %d writers on device %s\n", dev->num_writers,
165          dev_name(dev));
166    }
167    if (jcr->NumVolumes == 0) {
168       jcr->NumVolumes = 1;
169    }
170    unlock_device(dev);
171    return 1;                          /* got it */
172 }
173
174 /*
175  * This job is done, so release the device. From a Unix standpoint,
176  *  the device remains open.
177  *
178  */
179 int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
180 {
181    P(dev->mutex);
182    Dmsg1(90, "release_device device is %s\n", dev_is_tape(dev)?"tape":"disk");
183    if (dev->state & ST_READ) {
184       dev->state &= ~ST_READ;         /* clear read bit */
185       if (!dev_is_tape(dev)) {
186          close_dev(dev);
187       }
188       /******FIXME**** send read volume info to director */
189
190    } else if (dev->num_writers > 0) {
191       dev->num_writers--;
192       Dmsg1(90, "There are %d writers in release_device\n", dev->num_writers);
193       if (dev->num_writers == 0) {
194          weof_dev(dev, 1);
195          dev->VolCatInfo.VolCatFiles++;             /* increment number of files */
196          /* Note! do volume update before close, which zaps VolCatInfo */
197          dir_update_volume_info(jcr, &dev->VolCatInfo);   /* send Volume info to Director */
198          if (!dev_is_tape(dev)) {
199             close_dev(dev);
200          } else {
201             Dmsg0(90, "Device is tape leave open in release_device\n");
202          }
203       } else {
204          dir_update_volume_info(jcr, &dev->VolCatInfo);   /* send Volume info to Director */
205       }
206    } else {
207       Emsg1(M_ERROR, 0, _("BAD ERROR: release_device %s not in use.\n"), dev_name(dev));
208    }
209    V(dev->mutex);
210    return 1;
211 }
212
213
214
215 /*
216  * We rewind the current volume, which we no longer want, and
217  *  ask the user (console) to mount the next volume.
218  *
219  *  Continue trying until we get it, and we call
220  *  ready_dev_for_append() so that we can write on it.
221  *
222  * This routine retuns a 0 only if it is REALLY
223  *  impossible to get the requested Volume.
224  */
225 static int mount_next_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *label_blk)
226 {
227    Dmsg0(90, "Enter mount_next_volume()\n");
228
229    /* 
230     * First erase all memory of the current volume   
231     */
232    dev->block_num = 0;
233    dev->file = 0;
234    dev->LastBlockNumWritten = 0;
235    memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo));
236    memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
237
238    /* Keep trying until we get something good mounted */
239    for ( ;; ) {
240       if (job_cancelled(jcr)) {
241          Mmsg0(&dev->errmsg, "Job cancelled.\n");
242          return 0;
243       }
244
245       if (dev->state & ST_OPENED && !rewind_dev(dev)) {
246          Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"), 
247                dev_name(dev), strerror_dev(dev));
248       }
249
250       /*
251        * Ask to mount and wait if necessary   
252        */
253       if (!dir_ask_sysop_to_mount_next_volume(jcr, dev)) {
254          Jmsg(jcr, M_FATAL, 0, _("Unable to mount next Volume on device %s\n"),
255             dev_name(dev));
256          return 0;
257       }
258
259       /* 
260        * Ready output device for writing
261        */
262       Dmsg1(120, "just before ready_dev_for_append dev=%x\n", dev);
263       if (!ready_dev_for_append(jcr, dev, label_blk)) {
264          continue;
265       }
266       dev->VolCatInfo.VolCatMounts++;
267       jcr->VolFirstFile = 0;
268       break;                       /* Got new volume, continue */
269    }
270    return 1;
271 }
272
273
274 /*
275  * This routine ensures that the device is ready for
276  * writing. We start from the assumption that there
277  * may not be a tape mounted. 
278  *
279  * If the device is a file, we create the output
280  * file. If it is a tape, we check the volume name
281  * and move the tape to the end of data.
282  *
283  * It assumes that the device is not already in use!
284  *
285  *  Returns 0 on failure
286  *  Returns 1 on success
287  */
288 static int ready_dev_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
289 {
290    int mounted = 0;
291
292    Dmsg0(100, "Enter ready_dev_for_append\n");
293
294    dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
295
296
297    for ( ;; ) {
298       if (job_cancelled(jcr)) {
299          Mmsg(&dev->errmsg, "Job %s cancelled.\n", jcr->Job);
300          return 0;
301       }
302
303       /* 
304        * Ask Director for Volume Info (Name, attributes) to use.         
305        */
306       if (!dir_find_next_appendable_volume(jcr)) {
307          if (!dir_ask_sysop_to_mount_next_volume(jcr, dev)) {
308             Jmsg1(jcr, M_ERROR, 0, _("Unable to mount desired Volume for device %s.\n"),
309                dev_name(dev));
310             return 0;              /* error return */
311          }
312       }
313       Dmsg1(200, "want vol=%s\n", jcr->VolumeName);
314
315       /* Open device */
316       for ( ; !(dev->state & ST_OPENED); ) {
317           if (open_dev(dev, jcr->VolCatInfo.VolCatName, READ_WRITE) < 0) {
318              if (dev->dev_errno == EAGAIN || dev->dev_errno == EBUSY) {
319                 sleep(30);
320              }
321              Jmsg2(jcr, M_ERROR, 0, _("Unable to open device %s. ERR=%s\n"), 
322                 dev_name(dev), strerror_dev(dev));
323              return 0;
324           }
325       }
326
327       /*
328        * Now make sure we have the right tape mounted
329        */
330       switch (read_dev_volume_label(jcr, dev, block)) {
331          case VOL_OK:
332             Dmsg1(200, "Vol OK name=%s\n", jcr->VolumeName);
333             memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo));
334             break;                    /* got it */
335          case VOL_NAME_ERROR:
336             /* Check if we can accept this as an anonymous volume */
337             strcpy(jcr->VolumeName, dev->VolHdr.VolName);
338             if (!dev->capabilities & CAP_ANONVOLS ||
339                 !dir_get_volume_info(jcr)) {
340                goto mount_next_vol;
341             }
342             Dmsg1(200, "want new name=%s\n", jcr->VolumeName);
343             memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo));
344             break;
345
346          case VOL_NO_LABEL:
347          case VOL_IO_ERROR:
348             /* If permitted, create a label */
349             if (dev->capabilities & CAP_LABEL) {
350                Dmsg0(90, "Create volume label\n");
351                if (!write_volume_label_to_dev(jcr, (DEVRES *)dev->device, jcr->VolumeName,
352                       jcr->pool_name)) {
353                   return 0;
354                }
355                Jmsg(jcr, M_INFO, 0, _("Created Volume label %s on device %s.\n"),
356                   jcr->VolumeName, dev_name(dev));
357                mounted = 1;
358                continue;              /* read label we just wrote */
359             } 
360             /* NOTE! Fall-through wanted. */
361          default:
362 mount_next_vol:
363             /* Send error message generated by read_dev_volume_label() */
364             Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);                         
365             rewind_dev(dev);
366             if (!dir_ask_sysop_to_mount_next_volume(jcr, dev)) {
367                Jmsg1(jcr, M_ERROR, 0, _("Unable to mount desired Volume for device %s.\n"),
368                   dev_name(dev));
369                return 0;              /* error return */
370             }
371             mounted = 1;
372             continue;                 /* try reading again */
373       }
374       break;
375    }
376    if (mounted) {
377       dev->VolCatInfo.VolCatMounts++;
378    }
379
380    /* 
381     * See if we have a fresh tape or tape with data.
382     *
383     * Note, if the LabelType is PRE_LABEL, it was labeled
384     *  but never written. If so, rewrite the label but set as
385     *  VOL_LABEL.  We rewind and return the label (reconstructed)
386     *  in the block so that in the case of a new tape, data can
387     *  be appended just after the block label.  If we are writing
388     *  an second volume, the calling routine will write the label
389     *  before writing the overflow block.
390     */
391    if (dev->VolHdr.LabelType == PRE_LABEL) {      /* fresh tape */
392       Dmsg1(90, "ready_for_append found freshly labeled volume. dev=%x\n", dev);
393       dev->VolHdr.LabelType = VOL_LABEL; /* set Volume label */
394       write_volume_label_to_block(jcr, dev, block);
395       /*
396        * Write the block now to ensure we have write permission.
397        *  It is better to find out now rather than later.
398        */
399       dev->VolCatInfo.VolCatBytes = 0;
400       if (!rewind_dev(dev)) {
401          Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"), 
402                dev_name(dev), strerror_dev(dev));
403       }
404       if (!write_block_to_dev(dev, block)) {
405          Jmsg2(jcr, M_ERROR, 0, _("Unable to write device %s. ERR=%s\n"),
406             dev_name(dev), strerror_dev(dev));
407          return 0;
408       }
409       if (!rewind_dev(dev)) {
410          Jmsg2(jcr, M_ERROR, 0, _("Unable to rewind device %s. ERR=%s\n"),
411             dev_name(dev), strerror_dev(dev));
412          return 0;
413       }
414       /* Recreate a correct volume label and return it in the block */
415       write_volume_label_to_block(jcr, dev, block);
416       dev->VolCatInfo.VolCatJobs = 1;
417       dev->VolCatInfo.VolCatFiles = 1;
418       dev->VolCatInfo.VolCatMounts = 1;
419       dev->VolCatInfo.VolCatErrors = 0;
420       dev->VolCatInfo.VolCatWrites = 1;
421       dev->VolCatInfo.VolCatBlocks = 1;
422       dir_update_volume_info(jcr, &dev->VolCatInfo);
423       Jmsg(jcr, M_INFO, 0, _("Wrote label to prelabeled Volume %s on device %s\n"),
424          jcr->VolumeName, dev_name(dev));
425
426    } else {
427       /* OK, at this point, we have a valid Bacula label, but
428        * we need to position to the end of the volume.
429        */
430       Dmsg0(20, "Device previously written, moving to end of data\n");
431       Jmsg(jcr, M_INFO, 0, _("Volume %s previously written, moving to end of data.\n"),
432          jcr->VolumeName);
433       if (!eod_dev(dev)) {
434          Jmsg(jcr, M_ERROR, 0, _("Unable to position to end of data %s. ERR=%s\n"),
435             dev_name(dev), strerror_dev(dev));
436          Jmsg(jcr, M_INFO, 0, _("Marking Volume %s in Error in Catalog.\n"),
437             jcr->VolumeName);
438          strcpy(dev->VolCatInfo.VolCatStatus, "Error");
439          dir_update_volume_info(jcr, &dev->VolCatInfo);
440          return 0;
441       }
442       /* *****FIXME**** we might do some checking for files too */
443       if (dev_is_tape(dev)) {
444          Jmsg(jcr, M_INFO, 0, _("Ready to write at EOM File=%d\n"), dev_file(dev));
445          if (dev->VolCatInfo.VolCatFiles != dev_file(dev) + 1) {
446             /* ****FIXME**** this should refuse to write on tape */
447             Jmsg(jcr, M_INFO, 0, _("Hey! Num files mismatch! Catalog Files=%d\n"), dev->VolCatInfo.VolCatFiles);
448          }
449       }
450       /* Return an empty block */
451       empty_block(block);             /* we used it for reading so set for write */
452    }
453    dev->state |= ST_APPEND;
454    Dmsg0(100, "Normal return from read_dev_for_append\n");
455    return 1; 
456 }
457
458 /*
459  * This routine ensures that the device is ready for
460  * reading. If it is a file, it opens it.
461  * If it is a tape, it checks the volume name 
462  *
463  *  Returns 0 on failure
464  *  Returns 1 on success
465  */
466 int ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
467 {
468    if (!(dev->state & ST_OPENED)) {
469        Dmsg1(20, "bstored: open vol=%s\n", jcr->VolumeName);
470        if (open_dev(dev, jcr->VolumeName, READ_ONLY) < 0) {
471           Jmsg(jcr, M_FATAL, 0, _("Open device %s volume %s failed, ERR=%s\n"), 
472               dev_name(dev), jcr->VolumeName, strerror_dev(dev));
473           return 0;
474        }
475        Dmsg1(29, "open_dev %s OK\n", dev_name(dev));
476    }
477
478    for (;;) {
479       if (job_cancelled(jcr)) {
480          Mmsg0(&dev->errmsg, _("Job cancelled.\n"));
481          return 0;
482       }
483       if (!rewind_dev(dev)) {
484          Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"), 
485                dev_name(dev), strerror_dev(dev));
486       }
487       switch (read_dev_volume_label(jcr, dev, block)) {
488          case VOL_OK:
489             break;                    /* got it */
490          default:
491             /* Send error message generated by read_dev_volume_label() */
492             Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);                         
493             if (!rewind_dev(dev)) {
494                Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"), 
495                      dev_name(dev), strerror_dev(dev));
496             }
497             if (!dir_ask_sysop_to_mount_volume(jcr, dev)) {
498                return 0;              /* error return */
499             }
500             continue;                 /* try reading again */
501       }
502       break;
503    }
504
505    dev->state |= ST_READ;
506    return 1; 
507 }
508
509 /*
510  * This is the dreaded moment. We either have an end of
511  * medium condition or worse, and error condition.
512  * Attempt to "recover" by obtaining a new Volume.
513  *
514  * We enter with device locked, and 
515  *     exit with device locked.
516  *
517  * Note, we are called only from one place in block.c
518  *
519  *  Returns: 1 on success
520  *           0 on failure
521  */
522 int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
523 {
524    uint32_t stat = 0;                   
525    char PrevVolName[MAX_NAME_LENGTH];
526    DEV_BLOCK *label_blk;
527    char b1[30], b2[30];
528    time_t wait_time;
529
530    wait_time = time(NULL);
531    status_dev(dev, &stat);
532    if (stat & MT_EOD) {
533       Dmsg0(90, "======= Got EOD ========\n");
534
535       block_device(dev, BST_DOING_ACQUIRE);
536
537       strcpy(dev->VolCatInfo.VolCatStatus, "Full");
538       Dmsg0(90, "Call update_vol_info\n");
539       if (!dir_update_volume_info(jcr, &dev->VolCatInfo)) {    /* send Volume info to Director */
540          Jmsg(jcr, M_ERROR, 0, _("Could not update Volume info Volume=%s Job=%s\n"),
541             dev->VolCatInfo.VolCatName, jcr->Job);
542          return 0;                    /* device locked */
543       }
544       Dmsg0(90, "Back from update_vol_info\n");
545
546       strcpy(PrevVolName, dev->VolCatInfo.VolCatName);
547       strcpy(dev->VolHdr.PrevVolName, PrevVolName);
548
549       label_blk = new_block(dev);
550
551       /* Inform User about end of media */
552       Jmsg(jcr, M_INFO, 0, _("End of media on Volume %s Bytes=%s Blocks=%s.\n"), 
553            PrevVolName, edit_uint_with_commas(dev->VolCatInfo.VolCatBytes, b1),
554            edit_uint_with_commas(dev->VolCatInfo.VolCatBlocks, b2));
555
556       if (!dev_is_tape(dev)) {           /* If file, */
557          close_dev(dev);                 /* yes, close it */
558       }
559
560       /* Unlock, but leave BLOCKED */
561       unlock_device(dev);
562       if (!mount_next_volume(jcr, dev, label_blk)) {
563          P(dev->mutex);
564          unblock_device(dev);
565          return 0;                    /* device locked */
566       }
567
568       P(dev->mutex);                  /* lock again */
569
570       Jmsg(jcr, M_INFO, 0, _("New volume %s mounted on device %s\n"),
571          jcr->VolumeName, dev_name(dev));
572
573       /* 
574        * If this is a new tape, the label_blk will contain the
575        *  label, so write it now. If this is a previously
576        *  used tape, mount_next_volume() will return an
577        *  empty label_blk, and nothing will be written.
578        */
579       Dmsg0(90, "write label block to dev\n");
580       if (!write_block_to_dev(dev, label_blk)) {
581          Dmsg1(0, "write_block_to_device Volume label failed. ERR=%s",
582            strerror_dev(dev));
583          free_block(label_blk);
584          unblock_device(dev);
585          return 0;                    /* device locked */
586       }
587
588       /* Write overflow block to tape */
589       Dmsg0(90, "Write overflow block to dev\n");
590       if (!write_block_to_dev(dev, block)) {
591          Dmsg1(0, "write_block_to_device overflow block failed. ERR=%s",
592            strerror_dev(dev));
593          free_block(label_blk);
594          unblock_device(dev);
595          return 0;                    /* device locked */
596       }
597
598       jcr->NumVolumes++;
599       Dmsg0(90, "Wake up any waiting threads.\n");
600       free_block(label_blk);
601       unblock_device(dev);
602       jcr->run_time += time(NULL) - wait_time; /* correct run time */
603       return 1;                                /* device locked */
604    }
605    free_block(label_blk);
606    return 0;                          /* device locked */
607 }
608
609
610 /*
611  *   Open the device. Expect dev to already be initialized.  
612  *
613  *   This routine is used only when the Storage daemon starts 
614  *   and always_open is set, and in the stand-alone utility
615  *   routines such as bextract.
616  *
617  *   Note, opening of a normal file is deferred to later so
618  *    that we can get the filename; the device_name for
619  *    a file is the directory only. 
620  *
621  *   Retuns: 0 on failure
622  *           1 on success
623  */
624 int open_device(DEVICE *dev)
625 {
626    Dmsg0(20, "start open_output_device()\n");
627    if (!dev) {
628       return 0;
629    }
630
631    lock_device(dev);
632
633    /* Defer opening files */
634    if (!dev_is_tape(dev)) {
635       Dmsg0(29, "Device is file, deferring open.\n");
636       unlock_device(dev);
637       return 1;
638    }
639
640    if (!(dev->state & ST_OPENED)) {
641       Dmsg0(29, "Opening device.\n");
642       if (open_dev(dev, NULL, READ_WRITE) < 0) {
643          Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
644          unlock_device(dev);
645          return 0;
646       }
647    }
648    Dmsg1(29, "open_dev %s OK\n", dev_name(dev));
649
650    unlock_device(dev);
651    return 1;
652 }
653
654
655 /* 
656  * When dev_blocked is set, all threads EXCEPT thread with id no_wait_id
657  * must wait. The no_wait_id thread is out obtaining a new volume
658  * and preparing the label.
659  */
660 void lock_device(DEVICE *dev)
661 {
662    int stat;
663
664    Dmsg1(90, "lock %d\n", dev->dev_blocked);
665    P(dev->mutex);
666    if (dev->dev_blocked && !pthread_equal(dev->no_wait_id, pthread_self())) {
667       dev->num_waiting++;             /* indicate that I am waiting */
668       while (dev->dev_blocked) {
669          if ((stat = pthread_cond_wait(&dev->wait, &dev->mutex)) != 0) {
670             V(dev->mutex);
671             Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
672                strerror(stat));
673          }
674       }
675       dev->num_waiting--;             /* no longer waiting */
676    }
677 }
678
679 void unlock_device(DEVICE *dev) 
680 {
681    Dmsg0(90, "unlock\n");
682    V(dev->mutex);
683 }
684
685 /* 
686  * Block all other threads from using the device
687  *  Device must already be locked.  After this call,
688  *  the device is blocked to any thread calling lock_device(),
689  *  but the device is not locked (i.e. no P on device).  Also,
690  *  the current thread can do slip through the lock_device()
691  *  calls without blocking.
692  */
693 void block_device(DEVICE *dev, int state)
694 {
695    Dmsg1(90, "block set %d\n", state);
696    ASSERT(dev->dev_blocked == BST_NOT_BLOCKED);
697    dev->dev_blocked = state;          /* make other threads wait */
698    dev->no_wait_id = pthread_self();  /* allow us to continue */
699 }
700
701 /*
702  * Unblock the device, and wake up anyone who went to sleep.
703  */
704 void unblock_device(DEVICE *dev)
705 {
706    Dmsg1(90, "unblock %d\n", dev->dev_blocked);
707    ASSERT(dev->dev_blocked);
708    dev->dev_blocked = BST_NOT_BLOCKED;
709    if (dev->num_waiting > 0) {
710       pthread_cond_broadcast(&dev->wait); /* wake them up */
711    }
712 }