]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/vol_mgr.c
Apply Marcin's fix for 6th week of the month
[bacula/bacula] / bacula / src / stored / vol_mgr.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2016 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *   Volume management functions for Storage Daemon
21  *
22  *   Kern Sibbald, MM
23  *
24  *   Split from reserve.c October 2008
25  *
26  */
27
28 #include "bacula.h"
29 #include "stored.h"
30
31 const int dbglvl =  150;
32
33 static dlist *vol_list = NULL;
34 static brwlock_t vol_list_lock;
35 static dlist *read_vol_list = NULL;
36 static bthread_mutex_t read_vol_lock = BTHREAD_MUTEX_PRIORITY(PRIO_SD_READ_VOL_LIST);
37
38 /* Forward referenced functions */
39 static void free_vol_item(VOLRES *vol);
40 static VOLRES *new_vol_item(DCR *dcr, const char *VolumeName);
41 static void debug_list_volumes(const char *imsg);
42
43 /*
44  * For append volumes the key is the VolumeName.
45  */
46 static int name_compare(void *item1, void *item2)
47 {
48    return strcmp(((VOLRES *)item1)->vol_name, ((VOLRES *)item2)->vol_name);
49 }
50
51 /*
52  * For read volumes the key is JobId, VolumeName.
53  */
54 static int read_compare(void *item1, void *item2)
55 {
56    VOLRES *vol1 = (VOLRES *)item1;
57    VOLRES *vol2 = (VOLRES *)item2;
58
59    if (vol1->get_jobid() == vol2->get_jobid()) {
60       return strcmp(vol1->vol_name, vol2->vol_name);
61    }
62    if (vol1->get_jobid() < vol2->get_jobid()) {
63       return -1;
64    }
65    return 1;
66 }
67
68 bool is_vol_list_empty()
69 {
70    return vol_list->empty();
71 }
72
73 int vol_list_lock_count = 0;
74
75 /*
76  *  Initialized the main volume list. Note, we are using a recursive lock.
77  */
78 void init_vol_list_lock()
79 {
80    int errstat;
81    if ((errstat=rwl_init(&vol_list_lock, PRIO_SD_VOL_LIST)) != 0) {
82       berrno be;
83       Emsg1(M_ABORT, 0, _("Unable to initialize volume list lock. ERR=%s\n"),
84             be.bstrerror(errstat));
85    }
86 }
87
88 void term_vol_list_lock()
89 {
90    rwl_destroy(&vol_list_lock);
91 }
92
93 /*
94  * This allows a given thread to recursively call to lock_volumes()
95  */
96 void _lock_volumes(const char *file, int line)
97 {
98    int errstat;
99    vol_list_lock_count++;
100    if ((errstat=rwl_writelock_p(&vol_list_lock, file, line)) != 0) {
101       berrno be;
102       Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
103            errstat, be.bstrerror(errstat));
104    }
105 }
106
107 void _unlock_volumes()
108 {
109    int errstat;
110    vol_list_lock_count--;
111    if ((errstat=rwl_writeunlock(&vol_list_lock)) != 0) {
112       berrno be;
113       Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
114            errstat, be.bstrerror(errstat));
115    }
116 }
117
118 #define lock_read_volumes() lock_read_volumes_p(__FILE__, __LINE__)
119 static void lock_read_volumes_p(const char *file="**Unknown", int line=0)
120 {
121    bthread_mutex_lock_p(&read_vol_lock, file, line);
122 }
123
124 static void unlock_read_volumes()
125 {
126    bthread_mutex_unlock(&read_vol_lock);
127 }
128
129 /*
130  * Add a volume to the read list.
131  * Note, we use VOLRES because it simplifies the code
132  *   even though, the only part of VOLRES that we need is
133  *   the volume name.  The same volume may be in the list
134  *   multiple times, but each one is distinguished by the
135  *   JobId.  We use JobId, VolumeName as the key.
136  * We can get called multiple times for the same volume because
137  *   when parsing the bsr, the volume name appears multiple times.
138  */
139 void add_read_volume(JCR *jcr, const char *VolumeName)
140 {
141    VOLRES *nvol, *vol;
142
143    nvol = new_vol_item(NULL, VolumeName);
144    nvol->set_jobid(jcr->JobId);
145    nvol->set_reading();
146    lock_read_volumes();
147    vol = (VOLRES *)read_vol_list->binary_insert(nvol, read_compare);
148    if (vol != nvol) {
149       free_vol_item(nvol);
150       Dmsg2(dbglvl, "read_vol=%s JobId=%d already in list.\n", VolumeName, jcr->JobId);
151    } else {
152       Dmsg2(dbglvl, "add read_vol=%s JobId=%d\n", VolumeName, jcr->JobId);
153    }
154    unlock_read_volumes();
155 }
156
157 /*
158  * Check if volume name is in the read list.
159  */
160 bool is_read_volume(JCR *jcr, const char *VolumeName)
161 {
162    VOLRES vol, *fvol;
163    lock_read_volumes();
164    vol.vol_name = bstrdup(VolumeName);
165    fvol = (VOLRES *)read_vol_list->binary_search(&vol, name_compare);
166    free(vol.vol_name);
167    unlock_read_volumes();
168    return fvol != NULL;
169 }
170
171 /*
172  * Remove a given volume name from the read list.
173  */
174 void remove_read_volume(JCR *jcr, const char *VolumeName)
175 {
176    VOLRES vol, *fvol;
177    lock_read_volumes();
178    vol.vol_name = bstrdup(VolumeName);
179    vol.set_jobid(jcr->JobId);
180    fvol = (VOLRES *)read_vol_list->binary_search(&vol, read_compare);
181    free(vol.vol_name);
182    if (fvol) {
183       Dmsg3(dbglvl, "remove_read_vol=%s JobId=%d found=%d\n", VolumeName, jcr->JobId, fvol!=NULL);
184    }
185    if (fvol) {
186       read_vol_list->remove(fvol);
187       free_vol_item(fvol);
188    }
189    unlock_read_volumes();
190 // pthread_cond_broadcast(&wait_next_vol);
191 }
192
193 /*
194  * List Volumes -- this should be moved to status.c
195  */
196 enum {
197    debug_lock = true,
198    debug_nolock = false
199 };
200
201 static void debug_list_volumes(const char *imsg)
202 {
203    VOLRES *vol;
204    POOL_MEM msg(PM_MESSAGE);
205
206    if (debug_level < dbglvl) {
207       return;
208    }
209
210    foreach_vol(vol) {
211       if (vol->dev) {
212          Mmsg(msg, "List %s: %s in_use=%d swap=%d slot=%d on %s device %s\n", imsg,
213               vol->vol_name, vol->is_in_use(), vol->is_swapping(),
214               vol->get_slot(),
215               vol->dev->print_type(), vol->dev->print_name());
216       } else {
217          Mmsg(msg, "List %s: %s in_use=%d swap=%d slot=%d no dev\n", imsg, vol->vol_name,
218               vol->is_in_use(), vol->is_swapping(), vol->get_slot());
219       }
220       Dmsg1(dbglvl, "%s", msg.c_str());
221    }
222    endeach_vol(vol);
223 }
224
225
226 /*
227  * List Volumes -- this should be moved to status.c
228  */
229 void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg)
230 {
231    VOLRES *vol;
232    POOL_MEM msg(PM_MESSAGE);
233    int len;
234
235    foreach_vol(vol) {
236       DEVICE *dev = vol->dev;
237       if (dev) {
238          len = Mmsg(msg, "Reserved volume: %s on %s device %s\n", vol->vol_name,
239                   dev->print_type(), dev->print_name());
240          sendit(msg.c_str(), len, arg);
241          len = Mmsg(msg, "    Reader=%d writers=%d reserves=%d volinuse=%d\n",
242             dev->can_read()?1:0, dev->num_writers, dev->num_reserved(),
243             vol->is_in_use());
244          sendit(msg.c_str(), len, arg);
245       } else {
246          len = Mmsg(msg, "Volume %s no device. volinuse=%d\n", vol->vol_name,
247             vol->is_in_use());
248          sendit(msg.c_str(), len, arg);
249       }
250    }
251    endeach_vol(vol);
252
253    lock_read_volumes();
254    foreach_dlist(vol, read_vol_list) {
255       DEVICE *dev = vol->dev;
256       if (dev) {
257          len = Mmsg(msg, "Read volume: %s on %s device %s\n", vol->vol_name,
258                   dev->print_type(), dev->print_name());
259          sendit(msg.c_str(), len, arg);
260          len = Mmsg(msg, "    Reader=%d writers=%d reserves=%d volinuse=%d JobId=%d\n",
261             dev->can_read()?1:0, dev->num_writers, dev->num_reserved(),
262             vol->is_in_use(), vol->get_jobid());
263          sendit(msg.c_str(), len, arg);
264       } else {
265          len = Mmsg(msg, "Volume: %s no device. volinuse=%d\n", vol->vol_name,
266             vol->is_in_use());
267          sendit(msg.c_str(), len, arg);
268       }
269    }
270    unlock_read_volumes();
271 }
272
273 /*
274  * Create a Volume item to put in the Volume list
275  *   Ensure that the device points to it.
276  */
277 static VOLRES *new_vol_item(DCR *dcr, const char *VolumeName)
278 {
279    VOLRES *vol;
280    vol = (VOLRES *)malloc(sizeof(VOLRES));
281    memset(vol, 0, sizeof(VOLRES));
282    vol->vol_name = bstrdup(VolumeName);
283    if (dcr) {
284       vol->dev = dcr->dev;
285       Dmsg4(dbglvl, "new Vol=%s slot=%d at %p dev=%s\n",
286             VolumeName, vol->get_slot(), vol->vol_name, vol->dev->print_name());
287    }
288    vol->init_mutex();
289    vol->inc_use_count();
290    return vol;
291 }
292
293 static void free_vol_item(VOLRES *vol)
294 {
295    DEVICE *dev = NULL;
296
297    vol->dec_use_count();
298    vol->vLock();
299    if (vol->use_count() > 0) {
300       vol->vUnlock();
301       return;
302    }
303    vol->vUnlock();
304    free(vol->vol_name);
305    if (vol->dev) {
306       dev = vol->dev;
307    }
308    vol->destroy_mutex();
309    free(vol);
310    if (dev) {
311       dev->vol = NULL;
312    }
313 }
314
315 /*
316  * Put a new Volume entry in the Volume list. This
317  *  effectively reserves the volume so that it will
318  *  not be mounted again.
319  *
320  * If the device has any current volume associated with it,
321  *  and it is a different Volume, and the device is not busy,
322  *  we release the old Volume item and insert the new one.
323  *
324  * It is assumed that the device is free and locked so that
325  *  we can change the device structure.
326  *
327  * Some details of the Volume list handling:
328  *
329  *  1. The Volume list entry is attached to the drive (rather than
330  *       attached to a job as it was previously. I.e. the drive that "owns"
331  *       the volume (in use, mounted)
332  *       must point to the volume (still to be maintained in a list).
333  *
334  *  2. The Volume is entered in the list when a drive is reserved.
335  *
336  *  3. When a drive is in use, the device code must appropriately update the
337  *       volume name as it changes.
338   *      This code keeps the same list entry as long as the drive
339  *       has any volume associated with it but the volume name in the list
340  *       must be updated when the drive has a different volume mounted.
341  *
342  *  4. A job that has reserved a volume, can un-reserve the volume, and if the
343  *      volume is not mounted, and not reserved, and not in use, it will be
344  *      removed from the list.
345  *
346  *  5. If a job wants to reserve a drive with a different Volume from the one on
347  *      the drive, it can re-use the drive for the new Volume.
348
349  *  6. If a job wants a Volume that is in a different drive, it can either use the
350  *      other drive or take the volume, only if the other drive is not in use or
351  *      not reserved.
352  *
353  *  One nice aspect of this is that the reserve use count and the writer use count
354  *  already exist and are correctly programmed and will need no changes -- use
355  *  counts are always very tricky.
356  *
357  *  The old code had a concept of "reserving" a Volume, but was changed
358  *  to reserving and using a drive.  A volume is must be attached to (owned by) a
359  *  drive and can move from drive to drive or be unused given certain specific
360  *  conditions of the drive.  The key is that the drive must "own" the Volume.
361  *
362  *  Return: VOLRES entry on success
363  *          NULL volume busy on another drive
364  *               jcr->errmsg has details
365  */
366 VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
367 {
368    VOLRES *vol, *nvol;
369    DEVICE * volatile dev = dcr->dev;
370    JCR *jcr = dcr->jcr;
371
372    jcr->errmsg[0] = 0;
373    if (job_canceled(dcr->jcr)) {
374       Mmsg1(jcr->errmsg, _("Could not reserve volume \"%s\", because job canceled.\n"),
375          dev->VolHdr.VolumeName);
376       return NULL;
377    }
378    ASSERT2(dev != NULL, "No device in reserve_volume!");
379
380    Dmsg2(dbglvl, "enter reserve_volume=%s drive=%s\n", VolumeName,
381       dcr->dev->print_name());
382
383    /* If acquiring to write, don't accept a Volume in read list */
384    if (dcr->is_writing() && is_read_volume(dcr->jcr, VolumeName)) {
385       Mmsg1(jcr->errmsg, _("Could not reserve volume \"%s\" for append, because it will be read.\n"),
386          dev->VolHdr.VolumeName);
387       return NULL;
388    }
389
390    /*
391     * We lock the reservations system here to ensure
392     *  when adding a new volume that no newly scheduled
393     *  job can reserve it.
394     */
395    lock_volumes();
396    debug_list_volumes("begin reserve_volume");
397    /*
398     * First, remove any old volume attached to this device as it
399     *  is no longer used.
400     */
401    if (dev->vol) {
402       vol = dev->vol;
403       Dmsg4(dbglvl, "Vol attached=%s, newvol=%s volinuse=%d on %s\n",
404          vol->vol_name, VolumeName, vol->is_in_use(), dev->print_name());
405       /*
406        * Make sure we don't remove the current volume we are inserting
407        *  because it was probably inserted by another job, or it
408        *  is not being used and is marked as not reserved.
409        */
410       if (strcmp(vol->vol_name, VolumeName) == 0) {
411          Dmsg3(dbglvl, "set reserved vol=%s slot=%d dev=%s\n", VolumeName,
412                vol->get_slot(), vol->dev->print_name());
413          goto get_out;                  /* Volume already on this device */
414       } else {
415          /* Don't release a volume if it was reserved by someone other than us */
416          if (vol->is_in_use() && !dcr->reserved_volume) {
417             Dmsg2(dbglvl, "Set wait(). Cannot free vol=%s for %s. It is reserved.\n", vol->vol_name, VolumeName);
418             Mmsg1(dcr->jcr->errmsg, _("Cannot free Volume \"%s\", because it is reserved by someone else.\n"),
419                vol->vol_name);
420             dev->set_wait();
421             vol = NULL;                  /* vol in use */
422             goto get_out;
423          }
424          Dmsg2(dbglvl, "reserve_vol free vol=%s at %p\n", vol->vol_name, vol->vol_name);
425          /* If old Volume is still mounted, must unload it */
426          if (strcmp(vol->vol_name, dev->VolHdr.VolumeName) == 0) {
427             Dmsg2(50, "set_unload vol=%s slot=%d\n", vol->vol_name, vol->get_slot());
428             dev->set_unload();          /* have to unload current volume */
429          }
430          free_volume(dev);              /* Release old volume entry */
431          debug_list_volumes("reserve_vol free");
432       }
433    }
434
435    /* Create a new Volume entry */
436    nvol = new_vol_item(dcr, VolumeName);
437
438    /*
439     * Handle request for read volume for file
440     *  device, for which we assume we can open multiple
441     *  devices to read the Volume.
442     *
443     * Note: when doing multiple simultaneous reads
444     *  of the same volume, the volume names are not
445     *  inserted into the write volume list.
446     */
447    if (dcr->is_reading() && dev->is_file()) {
448       nvol->set_jobid(dcr->jcr->JobId);
449       nvol->set_reading();
450       vol = nvol;
451       dev->vol = vol;
452       goto get_out;
453    } else {
454       vol = (VOLRES *)vol_list->binary_insert(nvol, name_compare);
455    }
456
457    /*
458     * This part handles any write volumes or read volumes that
459     *  cannot be simultaneously on multiple devices.
460     */
461    if (vol != nvol) {
462       /*
463        * At this point, a Volume with this name already is in the list,
464        *   so we simply release our new Volume entry. Note, this should
465        *   only happen if we are moving the volume from one drive to another.
466        */
467       Dmsg2(dbglvl, "Found vol=%s dev-same=%d\n", vol->vol_name, dev==vol->dev);
468       Dmsg2(dbglvl, "reserve_vol free-tmp vol=%s at %p\n",
469             vol->vol_name, vol->vol_name);
470       /*
471        * Clear dev pointer so that free_vol_item() doesn't
472        *  take away our volume.
473        */
474       nvol->dev = NULL;                  /* don't zap dev entry */
475       free_vol_item(nvol);
476
477       if (vol->dev) {
478          Dmsg2(dbglvl, "dev=%s vol->dev=%s\n", dev->print_name(), vol->dev->print_name());
479       }
480
481       /*
482        * Check if we are trying to use the Volume on a different drive
483        *  dev      is our device
484        *  vol->dev is where the Volume we want is
485        */
486       if (dev != vol->dev) {
487          /* Caller wants to switch Volume to another device */
488          if (!vol->dev->is_busy() && !vol->is_swapping()) {
489             int32_t slot;
490             Dmsg3(dbglvl, "==== Swap vol=%s from dev=%s to %s\n",
491                VolumeName, vol->dev->print_name(), dev->print_name());
492             free_volume(dev);            /* free any volume attached to our drive */
493             Dmsg3(50, "set_unload vol=%s slot=%d dev=%s\n", vol->vol_name,
494                vol->get_slot(), dev->print_name());
495             dev->set_unload();           /* Unload any volume that is on our drive */
496             dcr->set_dev(vol->dev);      /* temp point to other dev */
497             slot = get_autochanger_loaded_slot(dcr);  /* get slot on other drive */
498             dcr->set_dev(dev);           /* restore dev */
499             vol->set_slot(slot);         /* save slot */
500             vol->dev->set_unload();      /* unload the other drive */
501             vol->set_swapping();         /* swap from other drive */
502             dev->swap_dev = vol->dev;    /* remember to get this vol */
503             dev->set_load();             /* then reload on our drive */
504             vol->dev->vol = NULL;        /* remove volume from other drive */
505             vol->dev = dev;              /* point the Volume at our drive */
506             dev->vol = vol;              /* point our drive at the Volume */
507          } else {
508             if (dev) {
509                Jmsg8(jcr, M_WARNING, 0, "Need volume for %s from other drive, "
510                   "but swap not possible. Status: reader=%d writers=%d "
511                   "reserves=%d swap=%d vol=%s from dev=%s to %s\n",
512                   dcr->is_writing()?"write":"read",
513                   vol->dev->can_read(), vol->dev->num_writers,
514                   vol->dev->num_reserved(), vol->is_swapping(),
515                   VolumeName, vol->dev->print_name(), dev->print_name());
516             }
517             if (vol->is_swapping()) {
518                DEVICE *swapdev = dev->swap_dev;
519                if (vol && dev && swapdev) {
520                   Mmsg3(jcr->errmsg, _("Volume %s is busy swapping from %s to %s\n"),
521                      NPRT(vol->vol_name), dev->print_name(), swapdev->print_name());
522                } else {
523                   Mmsg1(jcr->errmsg, _("Volume %s is busy swapping.\n"),
524                      NPRT(vol->vol_name));
525                }
526             } else if (vol->dev) {
527                Mmsg2(jcr->errmsg, _("%s device %s is busy.\n"),
528                   vol->dev->print_type(), vol->dev->print_name());
529             } else {
530                Mmsg1(jcr->errmsg, _("Volume %s is busy swapping.\n"),
531                   NPRT(vol->vol_name));
532             }
533             debug_list_volumes("failed swap");
534             vol = NULL;                  /* device busy */
535             goto get_out;
536          }
537       } else {
538          dev->vol = vol;
539       }
540    } else {
541       dev->vol = vol;                    /* point to newly inserted volume */
542    }
543
544 get_out:
545    if (vol) {
546       Dmsg2(dbglvl, "set in_use. vol=%s dev=%s\n", vol->vol_name,
547             vol->dev->print_name());
548       vol->set_in_use();
549       dcr->reserved_volume = true;
550       bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName));
551    }
552    debug_list_volumes("end new volume");
553    unlock_volumes();
554    return vol;
555 }
556
557 /*
558  * Start walk of vol chain
559  * The proper way to walk the vol chain is:
560  *    VOLRES *vol;
561  *    foreach_vol(vol) {
562  *      ...
563  *    }
564  *    endeach_vol(vol);
565  *
566  *  It is possible to leave out the endeach_vol(vol), but
567  *   in that case, the last vol referenced must be explicitly
568  *   released with:
569  *
570  *    free_vol_item(vol);
571  *
572  */
573 VOLRES *vol_walk_start()
574 {
575    VOLRES *vol;
576    lock_volumes();
577    vol = (VOLRES *)vol_list->first();
578    if (vol) {
579       vol->inc_use_count();
580       Dmsg2(dbglvl, "Inc walk_start use_count=%d volname=%s\n",
581             vol->use_count(), vol->vol_name);
582    }
583    unlock_volumes();
584    return vol;
585 }
586
587 /*
588  * Get next vol from chain, and release current one
589  */
590 VOLRES *vol_walk_next(VOLRES *prev_vol)
591 {
592    VOLRES *vol;
593
594    lock_volumes();
595    vol = (VOLRES *)vol_list->next(prev_vol);
596    if (vol) {
597       vol->inc_use_count();
598       Dmsg2(dbglvl, "Inc walk_next use_count=%d volname=%s\n",
599             vol->use_count(), vol->vol_name);
600    }
601    if (prev_vol) {
602       free_vol_item(prev_vol);
603    }
604    unlock_volumes();
605    return vol;
606 }
607
608 /*
609  * Release last vol referenced
610  */
611 void vol_walk_end(VOLRES *vol)
612 {
613    if (vol) {
614       lock_volumes();
615       Dmsg2(dbglvl, "Free walk_end use_count=%d volname=%s\n",
616             vol->use_count(), vol->vol_name);
617       free_vol_item(vol);
618       unlock_volumes();
619    }
620 }
621
622 /*
623  * Search for a Volume name in the Volume list.
624  *
625  *  Returns: VOLRES entry on success
626  *           NULL if the Volume is not in the list
627  */
628 static VOLRES *find_volume(const char *VolumeName)
629 {
630    VOLRES vol, *fvol;
631
632    if (vol_list->empty()) {
633       return NULL;
634    }
635    /* Do not lock reservations here */
636    lock_volumes();
637    vol.vol_name = bstrdup(VolumeName);
638    fvol = (VOLRES *)vol_list->binary_search(&vol, name_compare);
639    free(vol.vol_name);
640    Dmsg2(dbglvl, "find_vol=%s found=%d\n", VolumeName, fvol!=NULL);
641    debug_list_volumes("find_volume");
642    unlock_volumes();
643    return fvol;
644 }
645
646 /*
647  * Search for a Volume name in the read Volume list.
648  *
649  *  Returns: VOLRES entry on success
650  *           NULL if the Volume is not in the list
651  */
652 static VOLRES *find_read_volume(const char *VolumeName)
653 {
654    VOLRES vol, *fvol;
655
656    if (read_vol_list->empty()) {
657       Dmsg0(dbglvl, "find_read_vol: read_vol_list empty.\n");
658       return NULL;
659    }
660    /* Do not lock reservations here */
661    lock_read_volumes();
662    vol.vol_name = bstrdup(VolumeName);
663    /* Note, we do want a simple name_compare on volume name only here */
664    fvol = (VOLRES *)read_vol_list->binary_search(&vol, name_compare);
665    free(vol.vol_name);
666    Dmsg2(dbglvl, "find_read_vol=%s found=%d\n", VolumeName, fvol!=NULL);
667    unlock_read_volumes();
668    return fvol;
669 }
670
671
672 /*
673  * Free a Volume from the Volume list if it is no longer used
674  *   Note, for tape drives we want to remember where the Volume
675  *   was when last used, so rather than free the volume entry,
676  *   we simply mark it "not reserved" so when the drive is really
677  *   needed for another volume, we can reuse it.
678  *
679  *  Returns: true if the Volume found and "removed" from the list
680  *           false if the Volume is not in the list or is in use
681  */
682 bool volume_unused(DCR *dcr)
683 {
684    DEVICE *dev = dcr->dev;
685
686    if (!dev->vol) {
687       Dmsg1(dbglvl, "vol_unused: no vol on %s\n", dev->print_name());
688       debug_list_volumes("null vol cannot unreserve_volume");
689       return false;
690    }
691
692    Dmsg2(dbglvl, "Clear in_use vol=%s slot=%d\n", dev->vol->vol_name,
693          dev->vol->get_slot());
694    dev->vol->clear_in_use();
695
696    if (dev->vol->is_swapping()) {
697       Dmsg1(dbglvl, "vol_unused: vol being swapped on %s\n", dev->print_name());
698       debug_list_volumes("swapping vol cannot free_volume");
699       return false;
700    }
701
702    /*
703     * If this is a tape, we do not free the volume, rather we wait
704     *  until the autoloader unloads it, or until another tape is
705     *  explicitly read in this drive. This allows the SD to remember
706     *  where the tapes are or last were.
707     */
708    Dmsg5(dbglvl, "set not reserved vol=%s slot=%d writers=%d reserves=%d dev=%s\n",
709       dev->vol->vol_name, dev->vol->get_slot(), dev->num_writers,
710       dev->num_reserved(), dev->print_name());
711    if (dev->is_tape() || dev->is_autochanger()) {
712       return true;
713    } else {
714       /*
715        * Note, this frees the volume reservation entry, but the
716        *   file descriptor remains open with the OS.
717        */
718       return free_volume(dev);
719    }
720 }
721
722 /*
723  * Unconditionally release the volume entry
724  * Note: read volumes are not in the list, so
725  *   do not attempt to remove them.
726  */
727 bool free_volume(DEVICE *dev)
728 {
729    VOLRES *vol;
730
731    lock_volumes();
732    vol = dev->vol;
733    if (vol == NULL) {
734       Dmsg1(dbglvl, "No vol on dev %s\n", dev->print_name());
735       unlock_volumes();
736       return false;
737    }
738    /* Don't free a volume while it is being swapped */
739    if (!vol->is_swapping()) {
740       Dmsg2(dbglvl, "Clear in_use vol=%s slot=%d\n", vol->vol_name, vol->get_slot());
741       dev->vol = NULL;
742       if (vol->is_writing()) {
743          vol_list->remove(vol);
744       }
745       Dmsg3(dbglvl, "Remove volume %s slot=%d dev=%s\n", vol->vol_name,
746          vol->get_slot(), dev->print_name());
747       free_vol_item(vol);
748       debug_list_volumes("free_volume");
749    } else {
750       Dmsg1(dbglvl, "=== Cannot clear. Swapping vol=%s\n", vol->vol_name);
751    }
752    unlock_volumes();
753    return true;
754 }
755
756
757 /* Create the Volume list */
758 void create_volume_lists()
759 {
760    VOLRES *vol = NULL;
761    if (vol_list == NULL) {
762       vol_list = New(dlist(vol, &vol->link));
763    }
764    if (read_vol_list == NULL) {
765       read_vol_list = New(dlist(vol, &vol->link));
766    }
767 }
768
769 /*
770  * Free normal append volumes list
771  */
772 static void free_volume_list()
773 {
774    VOLRES *vol;
775    if (vol_list) {
776       lock_volumes();
777       foreach_dlist(vol, vol_list) {
778          if (vol->dev) {
779             Dmsg2(dbglvl, "free vol_list Volume=%s dev=%s\n", vol->vol_name, vol->dev->print_name());
780          } else {
781             Dmsg1(dbglvl, "free vol_list Volume=%s No dev\n", vol->vol_name);
782          }
783          free(vol->vol_name);
784          vol->vol_name = NULL;
785          vol->destroy_mutex();
786       }
787       delete vol_list;
788       vol_list = NULL;
789       unlock_volumes();
790    }
791 }
792
793 /* Release all Volumes from the list */
794 void free_volume_lists()
795 {
796    VOLRES *vol;
797
798    free_volume_list();           /* normal append list */
799
800    if (read_vol_list) {
801       lock_read_volumes();
802       foreach_dlist(vol, read_vol_list) {
803          if (vol->dev) {
804             Dmsg2(dbglvl, "free read_vol_list Volume=%s dev=%s\n", vol->vol_name, vol->dev->print_name());
805          } else {
806             Dmsg1(dbglvl, "free read_vol_list Volume=%s No dev\n", vol->vol_name);
807          }
808          free(vol->vol_name);
809          vol->vol_name = NULL;
810          vol->destroy_mutex();
811       }
812       delete read_vol_list;
813       read_vol_list = NULL;
814       unlock_read_volumes();
815    }
816 }
817
818 /*
819  * Determine if caller can write on volume.
820  *  If not, return reason in jcr->errmsg
821  */
822 bool DCR::can_i_write_volume()
823 {
824    VOLRES *vol;
825
826    vol = find_read_volume(VolumeName);
827    if (vol) {
828       Mmsg(jcr->errmsg, "Found in read list; cannot write vol=%s\n", VolumeName);
829       Dmsg1(100, "Found in read list; cannot write vol=%s\n", VolumeName);
830       return false;
831    }
832    return can_i_use_volume();
833 }
834
835 /*
836  * Determine if caller can read or write volume.
837  *  If not, return reason in jcr->errmsg
838  */
839 bool DCR::can_i_use_volume()
840 {
841    bool rtn = true;
842    VOLRES *vol;
843
844    if (job_canceled(jcr)) {
845       Mmsg(jcr->errmsg, "Job is canceled\n");
846       return false;
847    }
848    lock_volumes();
849    vol = find_volume(VolumeName);
850    if (!vol) {
851       Dmsg1(dbglvl, "Vol=%s not in use.\n", VolumeName);
852       goto get_out;                   /* vol not in list */
853    }
854    ASSERT2(vol->dev != NULL, "No device in can_i_use_volume!");
855
856    if (dev == vol->dev) {        /* same device OK */
857       Dmsg1(dbglvl, "Vol=%s on same dev.\n", VolumeName);
858       goto get_out;
859    } else {
860       Dmsg3(dbglvl, "Vol=%s on %s we have %s\n", VolumeName,
861             vol->dev->print_name(), dev->print_name());
862    }
863    /* ***FIXME*** check this ... */
864    if (!vol->dev->is_busy()) {
865       Dmsg2(dbglvl, "Vol=%s dev=%s not busy.\n", VolumeName, vol->dev->print_name());
866       goto get_out;
867    } else {
868       Dmsg2(dbglvl, "Vol=%s dev=%s busy.\n", VolumeName, vol->dev->print_name());
869    }
870    Mmsg(jcr->errmsg, "Volume=%s in use on another device %s.\n", VolumeName, vol->dev->print_name());
871    Dmsg2(dbglvl, "Volume=%s in use on another device %s.\n", VolumeName, vol->dev->print_name());
872    rtn = false;
873
874 get_out:
875    unlock_volumes();
876    return rtn;
877
878 }
879
880 /*
881  * Create a temporary copy of the volume list.  We do this,
882  *   to avoid having the volume list locked during the
883  *   call to reserve_device(), which would cause a deadlock.
884  * Note, we may want to add an update counter on the vol_list
885  *   so that if it is modified while we are traversing the copy
886  *   we can take note and act accordingly (probably redo the
887  *   search at least a few times).
888  */
889 dlist *dup_vol_list(JCR *jcr)
890 {
891    dlist *temp_vol_list;
892    VOLRES *vol = NULL;
893
894    Dmsg0(dbglvl, "lock volumes\n");
895
896    Dmsg0(dbglvl, "duplicate vol list\n");
897    temp_vol_list = New(dlist(vol, &vol->link));
898    foreach_vol(vol) {
899       VOLRES *nvol;
900       VOLRES *tvol = (VOLRES *)malloc(sizeof(VOLRES));
901       memset(tvol, 0, sizeof(VOLRES));
902       tvol->vol_name = bstrdup(vol->vol_name);
903       tvol->dev = vol->dev;
904       tvol->init_mutex();
905       tvol->inc_use_count();
906       nvol = (VOLRES *)temp_vol_list->binary_insert(tvol, name_compare);
907       if (tvol != nvol) {
908          tvol->dev = NULL;                   /* don't zap dev entry */
909          free_vol_item(tvol);
910          Pmsg0(000, "Logic error. Duplicating vol list hit duplicate.\n");
911          Jmsg(jcr, M_WARNING, 0, "Logic error. Duplicating vol list hit duplicate.\n");
912       }
913    }
914    endeach_vol(vol);
915    Dmsg0(dbglvl, "unlock volumes\n");
916    return temp_vol_list;
917 }
918
919 /*
920  * Free the specified temp list.
921  */
922 void free_temp_vol_list(dlist *temp_vol_list)
923 {
924    dlist *save_vol_list;
925
926    lock_volumes();
927    save_vol_list = vol_list;
928    vol_list = temp_vol_list;
929    free_volume_list();                  /* release temp_vol_list */
930    vol_list = save_vol_list;
931    Dmsg0(dbglvl, "deleted temp vol list\n");
932    Dmsg0(dbglvl, "unlock volumes\n");
933    unlock_volumes();
934    debug_list_volumes("after free temp table");
935 }