]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/reserve.c
kes Implement regression that explicitly tests swapping a Volume
[bacula/bacula] / bacula / src / stored / reserve.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *   Drive reservation functions for Storage Daemon
30  *
31  *   Kern Sibbald, MM
32  *
33  *   Split from job.c and acquire.c June 2005
34  *
35  *   Version $Id$
36  *
37  */
38
39 #include "bacula.h"
40 #include "stored.h"
41
42 #define jid() ((int)get_jobid_from_tid())
43
44 const int dbglvl =  50;
45
46 static dlist *vol_list = NULL;
47 static brwlock_t reservation_lock;
48 static brwlock_t vol_list_lock;
49
50 /* Forward referenced functions */
51 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
52 static int reserve_device(RCTX &rctx);
53 static bool reserve_device_for_read(DCR *dcr);
54 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
55 static bool use_storage_cmd(JCR *jcr);
56 static void queue_reserve_message(JCR *jcr);
57 static void pop_reserve_messages(JCR *jcr);
58 //void switch_device(DCR *dcr, DEVICE *dev);
59
60 /* Requests from the Director daemon */
61 static char use_storage[]  = "use storage=%127s media_type=%127s "
62    "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
63 static char use_device[]  = "use device=%127s\n";
64
65 /* Responses sent to Director daemon */
66 static char OK_device[] = "3000 OK use device device=%s\n";
67 static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
68 static char BAD_use[]   = "3913 Bad use command: %s\n";
69
70 bool use_cmd(JCR *jcr) 
71 {
72    /*
73     * Get the device, media, and pool information
74     */
75    if (!use_storage_cmd(jcr)) {
76       set_jcr_job_status(jcr, JS_ErrorTerminated);
77       memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
78       return false;
79    }
80    return true;
81 }
82
83 static int my_compare(void *item1, void *item2)
84 {
85    return strcmp(((VOLRES *)item1)->vol_name, ((VOLRES *)item2)->vol_name);
86 }
87
88 /*
89  * This allows a given thread to recursively call lock_reservations.
90  *   It must, of course, call unlock_... the same number of times.
91  */
92 void init_reservations_lock()
93 {
94    int errstat;
95    if ((errstat=rwl_init(&reservation_lock)) != 0) {
96       berrno be;
97       Emsg1(M_ABORT, 0, _("Unable to initialize reservation lock. ERR=%s\n"),
98             be.bstrerror(errstat));
99    }
100
101    if ((errstat=rwl_init(&vol_list_lock)) != 0) {
102       berrno be;
103       Emsg1(M_ABORT, 0, _("Unable to initialize volume list lock. ERR=%s\n"),
104             be.bstrerror(errstat));
105    }
106 }
107
108 void term_reservations_lock()
109 {
110    rwl_destroy(&reservation_lock);
111    rwl_destroy(&vol_list_lock);
112 }
113
114 int reservations_lock_count = 0;
115
116 /* This applies to a drive and to Volumes */
117 void _lock_reservations()
118 {
119    int errstat;
120    reservations_lock_count++;
121    if ((errstat=rwl_writelock(&reservation_lock)) != 0) {
122       berrno be;
123       Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
124            errstat, be.bstrerror(errstat));
125    }
126 }
127
128 void _unlock_reservations()
129 {
130    int errstat;
131    reservations_lock_count--;
132    if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
133       berrno be;
134       Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
135            errstat, be.bstrerror(errstat));
136    }
137 }
138
139 int vol_list_lock_count = 0;
140
141 /* 
142  * This allows a given thread to recursively call to lock_volumes()
143  */
144 void _lock_volumes()
145 {
146    int errstat;
147    vol_list_lock_count++;
148    if ((errstat=rwl_writelock(&vol_list_lock)) != 0) {
149       berrno be;
150       Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
151            errstat, be.bstrerror(errstat));
152    }
153 }
154
155 void _unlock_volumes()
156 {
157    int errstat;
158    vol_list_lock_count--;
159    if ((errstat=rwl_writeunlock(&vol_list_lock)) != 0) {
160       berrno be;
161       Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
162            errstat, be.bstrerror(errstat));
163    }
164 }
165
166
167 /*
168  * List Volumes -- this should be moved to status.c
169  */
170 enum {
171    debug_lock = true,
172    debug_nolock = false
173 };
174
175 static void debug_list_volumes(const char *imsg)
176 {
177    VOLRES *vol;
178    POOL_MEM msg(PM_MESSAGE);
179
180    lock_volumes();
181    foreach_dlist(vol, vol_list) {
182       if (vol->dev) {
183          Mmsg(msg, "List %s: %s in_use=%d on device %s\n", imsg, 
184               vol->vol_name, vol->is_in_use(), vol->dev->print_name());
185       } else {
186          Mmsg(msg, "List %s: %s in_use=%d no dev\n", imsg, vol->vol_name, 
187               vol->is_in_use());
188       }
189       Dmsg2(dbglvl, "jid=%u %s", jid(), msg.c_str());
190    }
191
192 #ifdef xxx
193    DEVICE *dev = NULL;
194    foreach_dlist(vol, vol_list) {
195       if (vol->dev == dev) {
196          Dmsg0(dbglvl, "Two Volumes on same device.\n");
197          ASSERT(0);
198          dev = vol->dev;
199       }
200    }
201 #endif
202
203    unlock_volumes();
204 }
205
206
207 /*
208  * List Volumes -- this should be moved to status.c
209  */
210 void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg)
211 {
212    VOLRES *vol;
213    POOL_MEM msg(PM_MESSAGE);
214    int len;
215
216    lock_volumes();
217    foreach_dlist(vol, vol_list) {
218       DEVICE *dev = vol->dev;
219       if (dev) {
220          len = Mmsg(msg, "%s on device %s\n", vol->vol_name, dev->print_name());
221          sendit(msg.c_str(), len, arg);
222          len = Mmsg(msg, "    Reader=%d writers=%d devres=%d volinuse=%d\n", 
223             dev->can_read()?1:0, dev->num_writers, dev->num_reserved(),   
224             vol->is_in_use());
225          sendit(msg.c_str(), len, arg);
226       } else {
227          len = Mmsg(msg, "%s no device. volinuse= %d\n", vol->vol_name, 
228             vol->is_in_use());
229          sendit(msg.c_str(), len, arg);
230       }
231    }
232    unlock_volumes();
233 }
234
235 /*
236  * Create a Volume item to put in the Volume list
237  *   Ensure that the device points to it.
238  */
239 static VOLRES *new_vol_item(DCR *dcr, const char *VolumeName)
240 {
241    VOLRES *vol;
242    vol = (VOLRES *)malloc(sizeof(VOLRES));
243    memset(vol, 0, sizeof(VOLRES));
244    vol->vol_name = bstrdup(VolumeName);
245    vol->dev = dcr->dev;
246    Dmsg4(dbglvl, "jid=%u new Vol=%s at %p dev=%s\n", (int)dcr->jcr->JobId,
247          VolumeName, vol->vol_name, vol->dev->print_name());
248    return vol;
249 }
250
251 static void free_vol_item(VOLRES *vol)
252 {
253    DEVICE *dev = NULL;
254
255    free(vol->vol_name);
256    if (vol->dev) {
257       dev = vol->dev;
258    }
259    free(vol);
260    if (dev) {
261       dev->vol = NULL;
262    }
263 }
264
265 /*
266  * Put a new Volume entry in the Volume list. This
267  *  effectively reserves the volume so that it will
268  *  not be mounted again.
269  *
270  * If the device has any current volume associated with it,
271  *  and it is a different Volume, and the device is not busy,
272  *  we release the old Volume item and insert the new one.
273  * 
274  * It is assumed that the device is free and locked so that
275  *  we can change the device structure.
276  *
277  * Some details of the Volume list handling:
278  *
279  *  1. The Volume list entry must be attached to the drive (rather than 
280  *       attached to a job as it currently is. I.e. the drive that "owns" 
281  *       the volume (in use, mounted)
282  *       must point to the volume (still to be maintained in a list).
283  *
284  *  2. The Volume is entered in the list when a drive is reserved.  
285  *
286  *  3. When a drive is in use, the device code must appropriately update the
287  *      volume name as it changes (currently the list is static -- an entry is
288  *      removed when the Volume is no longer reserved, in use or mounted).  
289  *      The new code must keep the same list entry as long as the drive
290  *       has any volume associated with it but the volume name in the list
291  *       must be updated when the drive has a different volume mounted.
292  *
293  *  4. A job that has reserved a volume, can un-reserve the volume, and if the 
294  *      volume is not mounted, and not reserved, and not in use, it will be
295  *      removed from the list.
296  *
297  *  5. If a job wants to reserve a drive with a different Volume from the one on
298  *      the drive, it can re-use the drive for the new Volume.
299  *
300  *  6. If a job wants a Volume that is in a different drive, it can either use the
301  *      other drive or take the volume, only if the other drive is not in use or
302  *      not reserved.
303  *
304  *  One nice aspect of this is that the reserve use count and the writer use count 
305  *  already exist and are correctly programmed and will need no changes -- use 
306  *  counts are always very tricky.
307  *
308  *  The old code had a concept of "reserving" a Volume, but was changed 
309  *  to reserving and using a drive.  A volume is must be attached to (owned by) a 
310  *  drive and can move from drive to drive or be unused given certain specific 
311  *  conditions of the drive.  The key is that the drive must "own" the Volume.  
312  *  The old code had the job (dcr) owning the volume (more or less).  The job was
313  *  to change the insertion and removal of the volumes from the list to be based 
314  *  on the drive rather than the job.  
315  *
316  *  Return: VOLRES entry on success
317  *          NULL volume busy on another drive
318  */
319 VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
320 {
321    VOLRES *vol, *nvol;
322    DEVICE * volatile dev = dcr->dev;
323
324    ASSERT(dev != NULL);
325
326    Dmsg3(dbglvl, "jid=%u enter reserve_volume=%s drive=%s\n", jid(), VolumeName, 
327       dcr->dev->print_name());
328    /* 
329     * We lock the reservations system here to ensure
330     *  when adding a new volume that no newly scheduled
331     *  job can reserve it.
332     */
333    lock_volumes();
334    debug_list_volumes("begin reserve_volume");
335    /* 
336     * First, remove any old volume attached to this device as it
337     *  is no longer used.
338     */
339    if (dev->vol) {
340       vol = dev->vol;
341       Dmsg5(dbglvl, "jid=%u Vol attached=%s, newvol=%s volinuse=%d on %s\n",
342          jid(), vol->vol_name, VolumeName, vol->is_in_use(), dev->print_name());
343       /*
344        * Make sure we don't remove the current volume we are inserting
345        *  because it was probably inserted by another job, or it
346        *  is not being used and is marked as not reserved.
347        */
348       if (strcmp(vol->vol_name, VolumeName) == 0) {
349          Dmsg3(dbglvl, "jid=%u === set reserved vol=%s dev=%s\n", jid(), VolumeName,
350                vol->dev->print_name());
351          vol->set_in_use();             /* retake vol if released previously */
352          dcr->reserved_volume = true;   /* reserved volume */
353          goto get_out;                  /* Volume already on this device */
354       } else {
355          /* Don't release a volume if it was reserved by someone other than us */
356          if (vol->is_in_use() && !dcr->reserved_volume) { 
357             Dmsg2(dbglvl, "jid=%u Cannot free vol=%s. It is reserved.\n", jid(), vol->vol_name);
358             vol = NULL;                  /* vol in use */
359             goto get_out;
360          }
361          Dmsg3(dbglvl, "jid=%u reserve_vol free vol=%s at %p\n", jid(), vol->vol_name, vol->vol_name);
362          free_volume(dev);
363          dev->set_unload();             /* have to unload current volume */
364          debug_list_volumes("reserve_vol free");
365       }
366    }
367
368    /* Create a new Volume entry */
369    nvol = new_vol_item(dcr, VolumeName);
370
371    /*
372     * Now try to insert the new Volume
373     */
374    vol = (VOLRES *)vol_list->binary_insert(nvol, my_compare);
375    if (vol != nvol) {
376       Dmsg3(dbglvl, "jid=%u Found vol=%s dev-same=%d\n", jid(), vol->vol_name, dev==vol->dev);
377       /*
378        * At this point, a Volume with this name already is in the list,
379        *   so we simply release our new Volume entry. Note, this should
380        *   only happen if we are moving the volume from one drive to another.
381        */
382       Dmsg3(dbglvl, "jid=%u reserve_vol free-tmp vol=%s at %p\n", 
383             (int)dcr->jcr->JobId, vol->vol_name, vol->vol_name);
384       /*
385        * Clear dev pointer so that free_vol_item() doesn't 
386        *  take away our volume. 
387        */
388       nvol->dev = NULL;                  /* don't zap dev entry */
389       free_vol_item(nvol);
390
391       /*
392        * Check if we are trying to use the Volume on a different drive
393        *  dev      is our device
394        *  vol->dev is where the Volume we want is
395        */
396       if (dev != vol->dev) {
397          /* Caller wants to switch Volume to another device */
398          if (!vol->dev->is_busy() && !vol->is_swapping()) {
399             int32_t slot;
400             Dmsg4(dbglvl, "==== jid=%u Swap vol=%s from dev=%s to %s\n", jid(),
401                VolumeName, vol->dev->print_name(), dev->print_name());
402             free_volume(dev);            /* free any volume attached to our drive */
403             dcr->dev = vol->dev;         /* temp point to other dev */
404             slot = get_autochanger_loaded_slot(dcr);  /* get slot */
405             dcr->dev = dev;              /* restore dev */
406             vol->set_slot(slot);         /* save slot */
407             vol->dev->set_unload();      /* unload the other drive */
408             vol->set_swapping();         /* swap from other drive */
409             dev->swap_dev = vol->dev;    /* remember to get this vol */
410             dev->set_load();             /* then reload on our drive */
411             vol->dev->vol = NULL;        /* remove volume from other drive */
412             vol->dev = dev;              /* point the Volume at our drive */
413             dev->vol = vol;              /* point our drive at the Volume */
414          } else {
415             Dmsg4(dbglvl, "jid=%u ==== Swap not possible Vol busy vol=%s from dev=%s to %s\n", jid(),
416                VolumeName, vol->dev->print_name(), dev->print_name());
417             vol = NULL;                  /* device busy */
418             goto get_out;
419          }
420       } else {
421          dev->vol = vol;
422       }
423    } else {
424       dev->vol = vol;                    /* point to newly inserted volume */
425    }
426
427 get_out:
428    if (vol) {
429       Dmsg3(dbglvl, "jid=%u === set in_use. vol=%s dev=%s\n", jid(), vol->vol_name,
430             vol->dev->print_name());
431       vol->set_in_use();
432       dcr->reserved_volume = true;
433    }
434    debug_list_volumes("end new volume");
435    unlock_volumes();
436    return vol;
437 }
438
439 /* 
440  * Switch from current device to given device  
441  *   (not yet used) 
442  */
443 #ifdef xxx
444 void switch_device(DCR *dcr, DEVICE *dev)
445 {
446    DCR save_dcr;
447
448    dev->dlock();
449    memcpy(&save_dcr, dcr, sizeof(save_dcr));
450    clean_device(dcr);                  /* clean up the dcr */
451
452    dcr->dev = dev;                     /* get new device pointer */
453    Jmsg(dcr->jcr, M_INFO, 0, _("Device switch. New device %s chosen.\n"),
454       dcr->dev->print_name());
455
456    bstrncpy(dcr->VolumeName, save_dcr.VolumeName, sizeof(dcr->VolumeName));
457    bstrncpy(dcr->media_type, save_dcr.media_type, sizeof(dcr->media_type));
458    dcr->VolCatInfo.Slot = save_dcr.VolCatInfo.Slot;
459    bstrncpy(dcr->pool_name, save_dcr.pool_name, sizeof(dcr->pool_name));
460    bstrncpy(dcr->pool_type, save_dcr.pool_type, sizeof(dcr->pool_type));
461    bstrncpy(dcr->dev_name, dev->dev_name, sizeof(dcr->dev_name));
462
463 // dcr->set_reserved();
464
465    dev->dunlock();
466 }
467 #endif
468
469 /*
470  * Search for a Volume name in the Volume list.
471  *
472  *  Returns: VOLRES entry on success
473  *           NULL if the Volume is not in the list
474  */
475 VOLRES *find_volume(const char *VolumeName) 
476 {
477    VOLRES vol, *fvol;
478    /* Do not lock reservations here */
479    lock_volumes();
480    vol.vol_name = bstrdup(VolumeName);
481    fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
482    free(vol.vol_name);
483    Dmsg3(dbglvl, "jid=%u find_vol=%s found=%d\n", jid(), VolumeName, fvol!=NULL);
484    debug_list_volumes("find_volume");
485    unlock_volumes();
486    return fvol;
487 }
488
489 void DCR::set_reserved()
490 {
491    m_reserved = true;
492    Dmsg2(dbglvl, "Inc reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
493    dev->inc_reserved();
494 }
495
496 void DCR::clear_reserved()
497 {
498    if (m_reserved) {
499       m_reserved = false;
500       dev->dec_reserved();
501       Dmsg2(dbglvl, "Dec reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
502    }
503 }
504
505 /* 
506  * Remove any reservation from a drive and tell the system
507  *  that the volume is unused at least by us.
508  */
509 void DCR::unreserve_device()
510 {
511    lock_volumes();
512    if (is_reserved()) {
513       clear_reserved();
514       reserved_volume = false;
515       /* If we set read mode in reserving, remove it */
516       if (dev->can_read()) {
517          dev->clear_read();
518       }
519       if (dev->num_writers < 0) {
520          Jmsg1(jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
521          dev->num_writers = 0;
522       }
523       if (dev->num_reserved() == 0 && dev->num_writers == 0) {
524          volume_unused(this);
525       }
526    }
527    unlock_volumes();
528 }
529
530 /*  
531  * Free a Volume from the Volume list if it is no longer used
532  *   Note, for tape drives we want to remember where the Volume
533  *   was when last used, so rather than free the volume entry,
534  *   we simply mark it "not reserved" so when the drive is really
535  *   needed for another volume, we can reuse it.
536  *
537  *  Returns: true if the Volume found and "removed" from the list
538  *           false if the Volume is not in the list or is in use
539  */
540 bool volume_unused(DCR *dcr)
541 {
542    DEVICE *dev = dcr->dev;
543
544    if (!dev->vol) {
545       Dmsg2(dbglvl, "jid=%u vol_unused: no vol on %s\n", (int)dcr->jcr->JobId, dev->print_name());
546       debug_list_volumes("null vol cannot unreserve_volume");
547       return false;
548    }
549    if (dev->vol->is_swapping()) {
550       Dmsg1(dbglvl, "vol_unused: vol being swapped on %s\n", dev->print_name());
551       debug_list_volumes("swapping vol cannot unreserve_volume");
552       return false;
553    }
554
555 #ifdef xxx
556    if (dev->is_busy()) {
557       Dmsg2(dbglvl, "jid=%u vol_unused: busy on %s\n", (int)dcr->jcr->JobId, dev->print_name());
558       debug_list_volumes("dev busy cannot unreserve_volume");
559       return false;
560    }
561 #endif
562 #ifdef xxx
563    if (dev->num_writers > 0 || dev->num_reserved() > 0) {
564       ASSERT(0);
565    }
566 #endif
567
568    /*  
569     * If this is a tape, we do not free the volume, rather we wait
570     *  until the autoloader unloads it, or until another tape is
571     *  explicitly read in this drive. This allows the SD to remember
572     *  where the tapes are or last were.
573     */
574    Dmsg5(dbglvl, "jid=%u === set not reserved vol=%s num_writers=%d dev_reserved=%d dev=%s\n",
575       jid(), dev->vol->vol_name, dev->num_writers, dev->num_reserved(), dev->print_name());
576    dev->vol->clear_in_use();
577    if (dev->is_tape() || dev->is_autochanger()) {
578       return true;
579    } else {
580       /*
581        * Note, this frees the volume reservation entry, but the 
582        *   file descriptor remains open with the OS.
583        */
584       return free_volume(dev);
585    }
586 }
587
588 /*
589  * Unconditionally release the volume entry
590  */
591 bool free_volume(DEVICE *dev)
592 {
593    VOLRES *vol;
594
595    if (dev->vol == NULL) {
596       Dmsg2(dbglvl, "jid=%u No vol on dev %s\n", jid(), dev->print_name());
597       return false;
598    }
599    lock_volumes();
600    vol = dev->vol;
601    /* Don't free a volume while it is being swapped */
602    if (!vol->is_swapping()) {
603       dev->vol = NULL;
604       vol_list->remove(vol);
605       Dmsg3(dbglvl, "jid=%u === free_volume %s dev=%s\n", jid(), vol->vol_name, dev->print_name());
606       free_vol_item(vol);
607       debug_list_volumes("free_volume");
608    }
609    unlock_volumes();
610    return true;
611 }
612
613       
614 /* Create the Volume list */
615 void create_volume_list()
616 {
617    VOLRES *vol = NULL;
618    if (vol_list == NULL) {
619       vol_list = New(dlist(vol, &vol->link));
620    }
621 }
622
623 /* Release all Volumes from the list */
624 void free_volume_list()
625 {
626    VOLRES *vol;
627    if (!vol_list) {
628       return;
629    }
630    lock_volumes();
631    foreach_dlist(vol, vol_list) {
632       if (vol->dev) {
633          Dmsg3(dbglvl, "jid=%u free vol_list Volume=%s dev=%s\n", jid(),
634                vol->vol_name, vol->dev->print_name());
635       } else {
636          Dmsg3(dbglvl, "jid=%u free vol_list Volume=%s dev=%p\n", jid(), 
637                vol->vol_name, vol->dev);
638       }
639       free(vol->vol_name);
640       vol->vol_name = NULL;
641    }
642    delete vol_list;
643    vol_list = NULL;
644    unlock_volumes();
645 }
646
647 bool DCR::can_i_use_volume()
648 {
649    bool rtn = true;
650    VOLRES *vol;
651
652    lock_volumes();
653    vol = find_volume(VolumeName);
654    if (!vol) {
655       Dmsg2(dbglvl, "jid=%u Vol=%s not in use.\n", jid(), VolumeName);
656       goto get_out;                   /* vol not in list */
657    }
658    ASSERT(vol->dev != NULL);
659
660    if (dev == vol->dev) {        /* same device OK */
661       Dmsg2(dbglvl, "jid=%u Vol=%s on same dev.\n", jid(), VolumeName);
662       goto get_out;
663    } else {
664       Dmsg4(dbglvl, "jid=%u Vol=%s on %s we have %s\n", jid(), VolumeName,
665             vol->dev->print_name(), dev->print_name());
666    }
667    /* ***FIXME*** check this ... */
668    if (!vol->dev->is_busy()) {
669       Dmsg3(dbglvl, "jid=%u Vol=%s dev=%s not busy.\n", jid(), VolumeName, vol->dev->print_name());
670       goto get_out;
671    } else {
672       Dmsg3(dbglvl, "jid=%u Vol=%s dev=%s busy.\n", jid(), VolumeName, vol->dev->print_name());
673    }
674    Dmsg3(dbglvl, "jid=%u Vol=%s in use by %s.\n", jid(), VolumeName, vol->dev->print_name());
675    rtn = false;
676
677 get_out:
678    unlock_volumes();
679    return rtn;
680
681 }
682
683
684 /*
685  * We get the following type of information:
686  *
687  * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
688  *  use device=zzz
689  *  use device=aaa
690  *  use device=bbb
691  * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
692  *  use device=bbb
693  *
694  */
695 static bool use_storage_cmd(JCR *jcr)
696 {
697    POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
698    BSOCK *dir = jcr->dir_bsock;
699    int append;
700    bool ok;       
701    int Copy, Stripe;
702    DIRSTORE *store;
703    RCTX rctx;
704    alist *dirstore;
705
706    memset(&rctx, 0, sizeof(RCTX));
707    rctx.jcr = jcr;
708    /*
709     * If there are multiple devices, the director sends us
710     *   use_device for each device that it wants to use.
711     */
712    dirstore = New(alist(10, not_owned_by_alist));
713    jcr->reserve_msgs = New(alist(10, not_owned_by_alist));  
714    do {
715       Dmsg2(dbglvl, "jid=%u <dird: %s", jid(), dir->msg);
716       ok = sscanf(dir->msg, use_storage, store_name.c_str(), 
717                   media_type.c_str(), pool_name.c_str(), 
718                   pool_type.c_str(), &append, &Copy, &Stripe) == 7;
719       if (!ok) {
720          break;
721       }
722       if (append) {
723          jcr->write_store = dirstore;
724       } else {
725          jcr->read_store = dirstore;
726       }
727       rctx.append = append;
728       unbash_spaces(store_name);
729       unbash_spaces(media_type);
730       unbash_spaces(pool_name);
731       unbash_spaces(pool_type);
732       store = new DIRSTORE;
733       dirstore->append(store);
734       memset(store, 0, sizeof(DIRSTORE));
735       store->device = New(alist(10));
736       bstrncpy(store->name, store_name, sizeof(store->name));
737       bstrncpy(store->media_type, media_type, sizeof(store->media_type));
738       bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
739       bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
740       store->append = append;
741
742       /* Now get all devices */
743       while (dir->recv() >= 0) {
744          Dmsg2(dbglvl, "jid=%u <dird device: %s", jid(), dir->msg);
745          ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
746          if (!ok) {
747             break;
748          }
749          unbash_spaces(dev_name);
750          store->device->append(bstrdup(dev_name.c_str()));
751       }
752    }  while (ok && dir->recv() >= 0);
753
754    /* Developer debug code */
755    char *device_name;
756    if (debug_level >= dbglvl) {
757       foreach_alist(store, dirstore) {
758          Dmsg6(dbglvl, "jid=%u Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n", 
759             (int)rctx.jcr->JobId,
760             store->name, store->media_type, store->pool_name, 
761             store->pool_type, store->append);
762          foreach_alist(device_name, store->device) {
763             Dmsg2(dbglvl, "jid=%u     Device=%s\n", jid(), device_name);
764          }
765       }
766    }
767
768    init_jcr_device_wait_timers(jcr);
769    jcr->dcr = new_dcr(jcr, NULL, NULL);         /* get a dcr */
770    if (!jcr->dcr) {
771       BSOCK *dir = jcr->dir_bsock;
772       dir->fsend(_("3939 Could not get dcr\n"));
773       Dmsg1(dbglvl, ">dird: %s", dir->msg);
774       ok = false;
775    }
776    /*                    
777     * At this point, we have a list of all the Director's Storage
778     *  resources indicated for this Job, which include Pool, PoolType,
779     *  storage name, and Media type.     
780     * Then for each of the Storage resources, we have a list of
781     *  device names that were given.
782     *
783     * Wiffle through them and find one that can do the backup.
784     */
785    if (ok) {
786       int wait_for_device_retries = 0;  
787       int repeat = 0;
788       bool fail = false;
789       rctx.notify_dir = true;
790
791       lock_reservations();
792       for ( ; !fail && !job_canceled(jcr); ) {
793          pop_reserve_messages(jcr);
794          rctx.suitable_device = false;
795          rctx.have_volume = false;
796          rctx.VolumeName[0] = 0;
797          rctx.any_drive = false;
798          if (!jcr->PreferMountedVols) {
799             /*
800              * Here we try to find a drive that is not used.
801              * This will maximize the use of available drives.
802              *
803              */
804             rctx.num_writers = 20000000;   /* start with impossible number */
805             rctx.low_use_drive = NULL;
806             rctx.PreferMountedVols = false;                
807             rctx.exact_match = false;
808             rctx.autochanger_only = true;
809             if ((ok = find_suitable_device_for_job(jcr, rctx))) {
810                break;
811             }
812             /* Look through all drives possibly for low_use drive */
813             if (rctx.low_use_drive) {
814                rctx.try_low_use_drive = true;
815                if ((ok = find_suitable_device_for_job(jcr, rctx))) {
816                   break;
817                }
818                rctx.try_low_use_drive = false;
819             }
820             rctx.autochanger_only = false;
821             if ((ok = find_suitable_device_for_job(jcr, rctx))) {
822                break;
823             }
824          }
825          /*
826           * Now we look for a drive that may or may not be in
827           *  use.
828           */
829          /* Look for an exact Volume match all drives */
830          rctx.PreferMountedVols = true;
831          rctx.exact_match = true;
832          rctx.autochanger_only = false;
833          if ((ok = find_suitable_device_for_job(jcr, rctx))) {
834             break;
835          }
836          /* Look for any mounted drive */
837          rctx.exact_match = false;
838          if ((ok = find_suitable_device_for_job(jcr, rctx))) {
839             break;
840          }
841          /* Try any drive */
842          rctx.any_drive = true;
843          if ((ok = find_suitable_device_for_job(jcr, rctx))) {
844             break;
845          }
846          /* Keep reservations locked *except* during wait_for_device() */
847          unlock_reservations();
848          /*     
849           * The idea of looping on repeat a few times it to ensure
850           * that if there is some subtle timing problem between two
851           * jobs, we will simply try again, and most likely succeed.
852           * This can happen if one job reserves a drive or finishes using
853           * a drive at the same time a second job wants it.
854           */
855          if (repeat++ > 1) {              /* try algorithm 3 times */
856             bmicrosleep(30, 0);           /* wait a bit */
857             Dmsg1(dbglvl, "jid=%u repeat reserve algorithm\n", (int)rctx.jcr->JobId);
858          } else if (!rctx.suitable_device || !wait_for_device(jcr, wait_for_device_retries)) {
859             Dmsg1(dbglvl, "jid=%u Fail. !suitable_device || !wait_for_device\n",
860                  (int)rctx.jcr->JobId);
861             fail = true;
862          }   
863          lock_reservations();
864          dir->signal(BNET_HEARTBEAT);  /* Inform Dir that we are alive */
865       }
866       unlock_reservations();
867       if (!ok) {
868          /*
869           * If we get here, there are no suitable devices available, which
870           *  means nothing configured.  If a device is suitable but busy
871           *  with another Volume, we will not come here.
872           */
873          unbash_spaces(dir->msg);
874          pm_strcpy(jcr->errmsg, dir->msg);
875          Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
876          Jmsg(jcr, M_FATAL, 0, _("\n"
877             "     Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
878               dev_name.c_str(), media_type.c_str());
879          dir->fsend(NO_device, dev_name.c_str());
880
881          Dmsg2(dbglvl, "jid=%u >dird: %s", jid(), dir->msg);
882       }
883    } else {
884       unbash_spaces(dir->msg);
885       pm_strcpy(jcr->errmsg, dir->msg);
886       Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
887       dir->fsend(BAD_use, jcr->errmsg);
888       Dmsg2(dbglvl, "jid=%u >dird: %s", jid(), dir->msg);
889    }
890
891    release_reserve_messages(jcr);
892    return ok;
893 }
894
895
896 /*
897  * Walk through the autochanger resources and check if
898  *  the volume is in one of them.
899  * 
900  * Returns:  true  if volume is in device
901  *           false otherwise
902  */
903 static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol)
904 {
905    AUTOCHANGER *changer = vol->dev->device->changer_res;
906
907    /* Find resource, and make sure we were able to open it */
908    if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
909       Dmsg2(dbglvl, "jid=%u Found changer device %s\n", (int)rctx.jcr->JobId, vol->dev->device->hdr.name);
910       return true;
911    }  
912    Dmsg2(dbglvl, "jid=%u Incorrect changer device %s\n", (int)rctx.jcr->JobId, changer->hdr.name);
913    return false;
914 }
915
916 /*
917  * Search for a device suitable for this job.
918  * Note, this routine sets sets rctx.suitable_device if any 
919  *   device exists within the SD.  The device may not be actually
920  *   useable.
921  * It also returns if it finds a useable device.  
922  */
923 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
924 {
925    bool ok = false;
926    DIRSTORE *store;
927    char *device_name;
928    alist *dirstore;
929    DCR *dcr = jcr->dcr;
930
931    if (rctx.append) {
932       dirstore = jcr->write_store;
933    } else {
934       dirstore = jcr->read_store;
935    }
936    Dmsg5(dbglvl, "jid=%u PrefMnt=%d exact=%d suitable=%d chgronly=%d\n",
937       (int)rctx.jcr->JobId,
938       rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
939       rctx.autochanger_only);
940
941    /* 
942     * If the appropriate conditions of this if are met, namely that
943     *  we are appending and the user wants mounted drive (or we
944     *  force try a mounted drive because they are all busy), we
945     *  start by looking at all the Volumes in the volume list.
946     */
947    if (!vol_list->empty() && rctx.append && rctx.PreferMountedVols) {
948       dlist *temp_vol_list, *save_vol_list;
949       VOLRES *vol = NULL;
950       lock_volumes();
951       Dmsg0(dbglvl, "lock volumes\n");                           
952
953       /*  
954        * Create a temporary copy of the volume list.  We do this,
955        *   to avoid having the volume list locked during the
956        *   call to reserve_device(), which would cause a deadlock.
957        * Note, we may want to add an update counter on the vol_list
958        *   so that if it is modified while we are traversing the copy
959        *   we can take note and act accordingly (probably redo the 
960        *   search at least a few times).
961        */
962       Dmsg1(dbglvl, "jid=%u duplicate vol list\n", (int)rctx.jcr->JobId);
963       temp_vol_list = New(dlist(vol, &vol->link));
964       foreach_dlist(vol, vol_list) {
965          VOLRES *nvol;
966          VOLRES *tvol = (VOLRES *)malloc(sizeof(VOLRES));
967          memset(tvol, 0, sizeof(VOLRES));
968          tvol->vol_name = bstrdup(vol->vol_name);
969          tvol->dev = vol->dev;
970          nvol = (VOLRES *)temp_vol_list->binary_insert(tvol, my_compare);
971          if (tvol != nvol) {
972             tvol->dev = NULL;                   /* don't zap dev entry */
973             free_vol_item(tvol);
974             Pmsg0(000, "Logic error. Duplicating vol list hit duplicate.\n");
975             Jmsg(jcr, M_WARNING, 0, "Logic error. Duplicating vol list hit duplicate.\n");
976          }
977       }
978       unlock_volumes();
979
980       /* Look through reserved volumes for one we can use */
981       Dmsg1(dbglvl, "jid=%u look for vol in vol list\n", (int)rctx.jcr->JobId);
982       foreach_dlist(vol, temp_vol_list) {
983          if (!vol->dev) {
984             Dmsg2(dbglvl, "jid=%u vol=%s no dev\n", (int)rctx.jcr->JobId, vol->vol_name);
985             continue;
986          }
987          /* Check with Director if this Volume is OK */
988          bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName));
989          if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
990             continue;
991          }
992
993          Dmsg2(dbglvl, "jid=%u vol=%s OK for this job\n", (int)rctx.jcr->JobId, vol->vol_name);
994          foreach_alist(store, dirstore) {
995             int stat;
996             rctx.store = store;
997             foreach_alist(device_name, store->device) {
998                /* Found a device, try to use it */
999                rctx.device_name = device_name;
1000                rctx.device = vol->dev->device;
1001
1002                if (vol->dev->is_autochanger()) {
1003                   Dmsg2(dbglvl, "jid=%u vol=%s is in changer\n", (int)rctx.jcr->JobId, 
1004                         vol->vol_name);
1005                   if (!is_vol_in_autochanger(rctx, vol)) {
1006                      continue;
1007                   }
1008                } else if (strcmp(device_name, vol->dev->device->hdr.name) != 0) {
1009                   Dmsg3(dbglvl, "jid=%u device=%s not suitable want %s\n", (int)rctx.jcr->JobId, 
1010                         vol->dev->device->hdr.name, device_name);
1011                   continue;
1012                }
1013
1014                bstrncpy(rctx.VolumeName, vol->vol_name, sizeof(rctx.VolumeName));
1015                rctx.have_volume = true;
1016                /* Try reserving this device and volume */
1017                Dmsg3(dbglvl, "jid=%u try vol=%s on device=%s\n", (int)rctx.jcr->JobId, 
1018                      rctx.VolumeName, device_name);
1019                stat = reserve_device(rctx);
1020                if (stat == 1) {             /* found available device */
1021                   Dmsg2(dbglvl, "jid=%u Suitable device found=%s\n", (int)rctx.jcr->JobId, 
1022                         device_name);
1023                   ok = true;
1024                   break;
1025                } else if (stat == 0) {      /* device busy */
1026                   Dmsg2(dbglvl, "jid=%u Suitable device=%s, busy: not use\n", 
1027                         (int)rctx.jcr->JobId, device_name);
1028                } else {
1029                   /* otherwise error */
1030                   Dmsg1(dbglvl, "jid=%u No suitable device found.\n", (int)rctx.jcr->JobId);
1031                }
1032                rctx.have_volume = false;
1033                rctx.VolumeName[0] = 0;
1034             }
1035             if (ok) {
1036                break;
1037             }
1038          }
1039          if (ok) {
1040             break;
1041          }
1042       } /* end for loop over reserved volumes */
1043
1044       Dmsg1(dbglvl, "%u lock volumes\n", jid());
1045       lock_volumes();
1046       save_vol_list = vol_list;
1047       vol_list = temp_vol_list;
1048       free_volume_list();                  /* release temp_vol_list */
1049       vol_list = save_vol_list;
1050       Dmsg1(dbglvl, "jid=%u deleted temp vol list\n", (int)rctx.jcr->JobId);
1051       Dmsg1(dbglvl, "jid=%u unlock volumes\n", (int)rctx.jcr->JobId);
1052       unlock_volumes();
1053    }
1054    if (ok) {
1055       Dmsg2(dbglvl, "jid=%u got vol %s from in-use vols list\n", (int)rctx.jcr->JobId,
1056             rctx.VolumeName);
1057       return true;
1058    }
1059
1060    /* 
1061     * No reserved volume we can use, so now search for an available device.  
1062     *
1063     * For each storage device that the user specified, we
1064     *  search and see if there is a resource for that device.
1065     */
1066    foreach_alist(store, dirstore) {
1067       rctx.store = store;
1068       foreach_alist(device_name, store->device) {
1069          int stat;
1070          rctx.device_name = device_name;
1071          stat = search_res_for_device(rctx); 
1072          if (stat == 1) {             /* found available device */
1073             Dmsg2(dbglvl, "jid=%u available device found=%s\n", (int)rctx.jcr->JobId,device_name);
1074             ok = true;
1075             break;
1076          } else if (stat == 0) {      /* device busy */
1077             Dmsg2(dbglvl, "jid=%u No usable device=%s, busy: not use\n", (int)rctx.jcr->JobId,device_name);
1078          } else {
1079             /* otherwise error */
1080             Dmsg1(dbglvl, "jid=%u No usable device found.\n", (int)rctx.jcr->JobId);
1081          }
1082       }
1083       if (ok) {
1084          break;
1085       }
1086    }
1087    if (ok) {
1088       Dmsg1(dbglvl, "OK dev found. Vol=%s\n", rctx.VolumeName);
1089    } else {
1090       Dmsg0(dbglvl, "Leave find_suit_dev: no dev found.\n");
1091    }
1092    return ok;
1093 }
1094
1095 /*
1096  * Search for a particular storage device with particular storage
1097  *  characteristics (MediaType).
1098  */
1099 int search_res_for_device(RCTX &rctx) 
1100 {
1101    AUTOCHANGER *changer;
1102    int stat;
1103
1104    Dmsg2(dbglvl, "jid=%u search res for %s\n", (int)rctx.jcr->JobId, rctx.device_name);
1105    /* Look through Autochangers first */
1106    foreach_res(changer, R_AUTOCHANGER) {
1107       Dmsg2(dbglvl, "jid=%u Try match changer res=%s\n", (int)rctx.jcr->JobId, changer->hdr.name);
1108       /* Find resource, and make sure we were able to open it */
1109       if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
1110          /* Try each device in this AutoChanger */
1111          foreach_alist(rctx.device, changer->device) {
1112             Dmsg2(dbglvl, "jid=%u Try changer device %s\n", (int)rctx.jcr->JobId, 
1113                   rctx.device->hdr.name);
1114             stat = reserve_device(rctx);
1115             if (stat != 1) {             /* try another device */
1116                continue;
1117             }
1118             /* Debug code */
1119             if (rctx.store->append == SD_APPEND) {
1120                Dmsg3(dbglvl, "jid=%u Device %s reserved=%d for append.\n", 
1121                   (int)rctx.jcr->JobId, rctx.device->hdr.name,
1122                   rctx.jcr->dcr->dev->num_reserved());
1123             } else {
1124                Dmsg3(dbglvl, "jid=%u Device %s reserved=%d for read.\n", 
1125                   (int)rctx.jcr->JobId, rctx.device->hdr.name,
1126                   rctx.jcr->read_dcr->dev->num_reserved());
1127             }
1128             return stat;
1129          }
1130       }
1131    }
1132
1133    /* Now if requested look through regular devices */
1134    if (!rctx.autochanger_only) {
1135       foreach_res(rctx.device, R_DEVICE) {
1136          Dmsg2(dbglvl, "jid=%u Try match res=%s\n", (int)rctx.jcr->JobId, rctx.device->hdr.name);
1137          /* Find resource, and make sure we were able to open it */
1138          if (strcmp(rctx.device_name, rctx.device->hdr.name) == 0) {
1139             stat = reserve_device(rctx);
1140             if (stat != 1) {             /* try another device */
1141                continue;
1142             }
1143             /* Debug code */
1144             if (rctx.store->append == SD_APPEND) {
1145                Dmsg3(dbglvl, "jid=%u Device %s reserved=%d for append.\n", 
1146                   (int)rctx.jcr->JobId, rctx.device->hdr.name,
1147                   rctx.jcr->dcr->dev->num_reserved());
1148             } else {
1149                Dmsg3(dbglvl, "jid=%u Device %s reserved=%d for read.\n", 
1150                   (int)rctx.jcr->JobId, rctx.device->hdr.name,
1151                   rctx.jcr->read_dcr->dev->num_reserved());
1152             }
1153             return stat;
1154          }
1155       }
1156    }
1157    return -1;                    /* nothing found */
1158 }
1159
1160 /*
1161  *  Try to reserve a specific device.
1162  *
1163  *  Returns: 1 -- OK, have DCR
1164  *           0 -- must wait
1165  *          -1 -- fatal error
1166  */
1167 static int reserve_device(RCTX &rctx)
1168 {
1169    bool ok;
1170    DCR *dcr;
1171    const int name_len = MAX_NAME_LENGTH;
1172
1173    /* Make sure MediaType is OK */
1174    Dmsg3(dbglvl, "jid=%u chk MediaType device=%s request=%s\n",
1175          (int)rctx.jcr->JobId,
1176          rctx.device->media_type, rctx.store->media_type);
1177    if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
1178       return -1;
1179    }
1180
1181    /* Make sure device exists -- i.e. we can stat() it */
1182    if (!rctx.device->dev) {
1183       rctx.device->dev = init_dev(rctx.jcr, rctx.device);
1184    }
1185    if (!rctx.device->dev) {
1186       if (rctx.device->changer_res) {
1187         Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
1188            "     Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
1189              rctx.device->hdr.name, rctx.device_name);
1190       } else {
1191          Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
1192             "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
1193               rctx.device_name);
1194       }
1195       return -1;  /* no use waiting */
1196    }  
1197
1198    rctx.suitable_device = true;
1199    Dmsg1(dbglvl, "try reserve %s\n", rctx.device->hdr.name);
1200    rctx.jcr->dcr = dcr = new_dcr(rctx.jcr, rctx.jcr->dcr, rctx.device->dev);
1201    if (!dcr) {
1202       BSOCK *dir = rctx.jcr->dir_bsock;
1203       dir->fsend(_("3926 Could not get dcr for device: %s\n"), rctx.device_name);
1204       Dmsg1(dbglvl, ">dird: %s", dir->msg);
1205       return -1;
1206    }
1207    bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
1208    bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
1209    bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
1210    bstrncpy(dcr->dev_name, rctx.device_name, name_len);
1211    if (rctx.store->append == SD_APPEND) {
1212       Dmsg3(dbglvl, "jid=%u have_vol=%d vol=%s\n", (int)rctx.jcr->JobId,
1213           rctx.have_volume, rctx.VolumeName);                                   
1214       ok = reserve_device_for_append(dcr, rctx);
1215       if (!ok) {
1216          goto bail_out;
1217       }
1218
1219       rctx.jcr->dcr = dcr;
1220       Dmsg6(dbglvl, "jid=%u Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
1221                (int)rctx.jcr->JobId,
1222                dcr->dev->num_reserved(),
1223                dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
1224       if (rctx.have_volume) {
1225          if (reserve_volume(dcr, rctx.VolumeName)) {
1226             Dmsg2(dbglvl, "jid=%u Reserved vol=%s\n", jid(), rctx.VolumeName);
1227          } else {
1228             Dmsg2(dbglvl, "jid=%u Could not reserve vol=%s\n", jid(), rctx.VolumeName);
1229             goto bail_out;
1230          }
1231       } else {
1232          dcr->any_volume = true;
1233          if (dir_find_next_appendable_volume(dcr)) {
1234             bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
1235             Dmsg2(dbglvl, "jid=%u looking for Volume=%s\n", (int)rctx.jcr->JobId, rctx.VolumeName);
1236             rctx.have_volume = true;
1237          } else {
1238             Dmsg1(dbglvl, "jid=%u No next volume found\n", (int)rctx.jcr->JobId);
1239             rctx.have_volume = false;
1240             rctx.VolumeName[0] = 0;
1241             /*
1242              * If there is at least one volume that is valid and in use,
1243              *   but we get here, check if we are running with prefers
1244              *   non-mounted drives.  In that case, we have selected a
1245              *   non-used drive and our one and only volume is mounted
1246              *   elsewhere, so we bail out and retry using that drive.
1247              */
1248             if (dcr->found_in_use() && !rctx.PreferMountedVols) {
1249                rctx.PreferMountedVols = true;
1250                if (dcr->VolumeName[0]) {
1251                   dcr->unreserve_device();
1252                }
1253                goto bail_out;
1254             }
1255             /*
1256              * Note. Under some circumstances, the Director can hand us
1257              *  a Volume name that is not the same as the one on the current
1258              *  drive, and in that case, the call above to find the next
1259              *  volume will fail because in attempting to reserve the Volume
1260              *  the code will realize that we already have a tape mounted,
1261              *  and it will fail.  This *should* only happen if there are 
1262              *  writers, thus the following test.  In that case, we simply
1263              *  bail out, and continue waiting, rather than plunging on
1264              *  and hoping that the operator can resolve the problem. 
1265              */
1266             if (dcr->dev->num_writers != 0) {
1267                if (dcr->VolumeName[0]) {
1268                   dcr->unreserve_device();
1269                }
1270                goto bail_out;
1271             }
1272          }
1273       }
1274    } else {
1275       ok = reserve_device_for_read(dcr);
1276       if (ok) {
1277          rctx.jcr->read_dcr = dcr;
1278          Dmsg6(dbglvl, "jid=%u Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
1279                (int)rctx.jcr->JobId,
1280                dcr->dev->num_reserved(),
1281                dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
1282       }
1283    }
1284    if (!ok) {
1285       goto bail_out;
1286    }
1287
1288    if (rctx.notify_dir) {
1289       POOL_MEM dev_name;
1290       BSOCK *dir = rctx.jcr->dir_bsock;
1291       pm_strcpy(dev_name, rctx.device->hdr.name);
1292       bash_spaces(dev_name);
1293       ok = dir->fsend(OK_device, dev_name.c_str());  /* Return real device name */
1294       Dmsg2(dbglvl, "jid=%u >dird changer: %s", jid(), dir->msg);
1295    } else {
1296       ok = true;
1297    }
1298    return ok ? 1 : -1;
1299
1300 bail_out:
1301    rctx.have_volume = false;
1302    Dmsg1(dbglvl, "jid=%u Not OK.\n", (int)rctx.jcr->JobId);
1303    rctx.VolumeName[0] = 0;
1304    return 0;
1305 }
1306
1307 /*
1308  * We "reserve" the drive by setting the ST_READ bit. No one else
1309  *  should touch the drive until that is cleared.
1310  *  This allows the DIR to "reserve" the device before actually
1311  *  starting the job. 
1312  */
1313 static bool reserve_device_for_read(DCR *dcr)
1314 {
1315    DEVICE *dev = dcr->dev;
1316    JCR *jcr = dcr->jcr;
1317    bool ok = false;
1318
1319    ASSERT(dcr);
1320
1321    dev->dlock();  
1322
1323    if (is_device_unmounted(dev)) {             
1324       Dmsg2(dbglvl, "jid=%u Device %s is BLOCKED due to user unmount.\n", 
1325          (int)jcr->JobId, dev->print_name());
1326       Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
1327            jcr->JobId, dev->print_name());
1328       queue_reserve_message(jcr);
1329       goto bail_out;
1330    }
1331
1332    if (dev->is_busy()) {
1333       Dmsg5(dbglvl, "jid=%u Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", 
1334          (int)jcr->JobId, dev->print_name(),
1335          dev->state & ST_READ?1:0, dev->num_writers, dev->num_reserved());
1336       Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
1337             jcr->JobId, dev->print_name());
1338       queue_reserve_message(jcr);
1339       goto bail_out;
1340    }
1341
1342    dev->clear_append();
1343    dev->set_read();
1344    ok = true;
1345    dcr->set_reserved();
1346
1347 bail_out:
1348    dev->dunlock();
1349    return ok;
1350 }
1351
1352
1353 /*
1354  * We reserve the device for appending by incrementing
1355  *  num_reserved(). We do virtually all the same work that
1356  *  is done in acquire_device_for_append(), but we do
1357  *  not attempt to mount the device. This routine allows
1358  *  the DIR to reserve multiple devices before *really* 
1359  *  starting the job. It also permits the SD to refuse 
1360  *  certain devices (not up, ...).
1361  *
1362  * Note, in reserving a device, if the device is for the
1363  *  same pool and the same pool type, then it is acceptable.
1364  *  The Media Type has already been checked. If we are
1365  *  the first tor reserve the device, we put the pool
1366  *  name and pool type in the device record.
1367  */
1368 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
1369 {
1370    JCR *jcr = dcr->jcr;
1371    DEVICE *dev = dcr->dev;
1372    bool ok = false;
1373
1374    ASSERT(dcr);
1375
1376    dev->dlock();
1377
1378    /* If device is being read, we cannot write it */
1379    if (dev->can_read()) {
1380       Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"), 
1381          jcr->JobId, dev->print_name());
1382       Dmsg2(dbglvl, "jid=%u %s", jid(), jcr->errmsg);
1383       queue_reserve_message(jcr);
1384       goto bail_out;
1385    }
1386
1387    /* If device is unmounted, we are out of luck */
1388    if (is_device_unmounted(dev)) {
1389       Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"), 
1390          jcr->JobId, dev->print_name());
1391       Dmsg2(dbglvl, "jid=%u %s", jid(), jcr->errmsg);
1392       queue_reserve_message(jcr);
1393       goto bail_out;
1394    }
1395
1396    Dmsg2(dbglvl, "jid=%u reserve_append device is %s\n", jid(), dev->print_name());
1397
1398    /* Now do detailed tests ... */
1399    if (can_reserve_drive(dcr, rctx) != 1) {
1400       Dmsg1(dbglvl, "jid=%u can_reserve_drive!=1\n", (int)jcr->JobId);
1401       goto bail_out;
1402    }
1403
1404    dcr->set_reserved();
1405    ok = true;
1406
1407 bail_out:
1408    dev->dunlock();
1409    return ok;
1410 }
1411
1412 static int is_pool_ok(DCR *dcr)
1413 {
1414    DEVICE *dev = dcr->dev;
1415    JCR *jcr = dcr->jcr;
1416
1417    /* Now check if we want the same Pool and pool type */
1418    if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1419        strcmp(dev->pool_type, dcr->pool_type) == 0) {
1420       /* OK, compatible device */
1421       Dmsg1(dbglvl, "OK dev: %s num_writers=0, reserved, pool matches\n", dev->print_name());
1422       return 1;
1423    } else {
1424       /* Drive Pool not suitable for us */
1425       Mmsg(jcr->errmsg, _(
1426 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"), 
1427             (uint32_t)jcr->JobId, dcr->pool_name, dev->pool_name,
1428             dev->num_reserved(), dev->print_name());
1429       queue_reserve_message(jcr);
1430       Dmsg2(dbglvl, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
1431          dev->pool_name, dcr->pool_name);
1432    }
1433    return 0;
1434 }
1435
1436 static bool is_max_jobs_ok(DCR *dcr) 
1437 {
1438    DEVICE *dev = dcr->dev;
1439    JCR *jcr = dcr->jcr;
1440
1441    Dmsg5(dbglvl, "MaxJobs=%d Jobs=%d reserves=%d Status=%s Vol=%s\n",
1442          dcr->VolCatInfo.VolCatMaxJobs,
1443          dcr->VolCatInfo.VolCatJobs, dev->num_reserved(),
1444          dcr->VolCatInfo.VolCatStatus,
1445          dcr->VolumeName);
1446    if (strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0) {
1447       return true;
1448    }
1449    if (dcr->VolCatInfo.VolCatMaxJobs > 0 && dcr->VolCatInfo.VolCatMaxJobs <=
1450         (dcr->VolCatInfo.VolCatJobs + dev->num_reserved())) {
1451       /* Max Job Vols depassed or already reserved */
1452       Mmsg(jcr->errmsg, _("3610 JobId=%u Volume max jobs exceeded on drive %s.\n"), 
1453             (uint32_t)jcr->JobId, dev->print_name());
1454       queue_reserve_message(jcr);
1455       Dmsg1(dbglvl, "reserve dev failed: %s", jcr->errmsg);
1456       return false;                /* wait */
1457    }
1458    return true;
1459 }
1460
1461 /*
1462  * Returns: 1 if drive can be reserved
1463  *          0 if we should wait
1464  *         -1 on error or impossibility
1465  */
1466 static int can_reserve_drive(DCR *dcr, RCTX &rctx) 
1467 {
1468    DEVICE *dev = dcr->dev;
1469    JCR *jcr = dcr->jcr;
1470
1471    Dmsg6(dbglvl, "jid=%u PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1472          (int)jcr->JobId,
1473          rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1474          rctx.autochanger_only, rctx.any_drive);
1475
1476    /* Check for max jobs on this Volume */
1477    if (!is_max_jobs_ok(dcr)) {
1478       return 0;
1479    }
1480
1481    /* setting any_drive overrides PreferMountedVols flag */
1482    if (!rctx.any_drive) {
1483       /*
1484        * When PreferMountedVols is set, we keep track of the 
1485        *  drive in use that has the least number of writers, then if
1486        *  no unmounted drive is found, we try that drive. This   
1487        *  helps spread the load to the least used drives.  
1488        */
1489       if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
1490          Dmsg3(dbglvl, "jid=%u OK dev=%s == low_drive=%s.\n",
1491             jcr->JobId, dev->print_name(), rctx.low_use_drive->print_name());
1492          return 1;
1493       }
1494       /* If he wants a free drive, but this one is busy, no go */
1495       if (!rctx.PreferMountedVols && dev->is_busy()) {
1496          /* Save least used drive */
1497          if ((dev->num_writers + dev->num_reserved()) < rctx.num_writers) {
1498             rctx.num_writers = dev->num_writers + dev->num_reserved();
1499             rctx.low_use_drive = dev;
1500             Dmsg3(dbglvl, "jid=%u set low use drive=%s num_writers=%d\n", 
1501                (int)jcr->JobId, dev->print_name(), rctx.num_writers);
1502          } else {
1503             Dmsg2(dbglvl, "jid=%u not low use num_writers=%d\n", 
1504                (int)jcr->JobId, dev->num_writers+dev->num_reserved());
1505          }
1506          Dmsg1(dbglvl, "jid=%u failed: !prefMnt && busy.\n", jcr->JobId);
1507          Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"), 
1508             jcr->JobId, dev->print_name());
1509          queue_reserve_message(jcr);
1510          return 0;
1511       }
1512
1513       /* Check for prefer mounted volumes */
1514       if (rctx.PreferMountedVols && !dev->vol && dev->is_tape()) {
1515          Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"), 
1516             jcr->JobId, dev->print_name());
1517          queue_reserve_message(jcr);
1518          Dmsg1(dbglvl, "jid=%u failed: want mounted -- no vol\n", (uint32_t)jcr->JobId);
1519          return 0;                 /* No volume mounted */
1520       }
1521
1522       /* Check for exact Volume name match */
1523       /* ***FIXME*** for Disk, we can accept any volume that goes with this
1524        *    drive.
1525        */
1526       if (rctx.exact_match && rctx.have_volume) {
1527          bool ok;
1528          Dmsg6(dbglvl, "jid=%u PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1529                (int)jcr->JobId,
1530                rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1531                rctx.autochanger_only, rctx.any_drive);
1532          Dmsg5(dbglvl, "jid=%u have_vol=%d have=%s resvol=%s want=%s\n",
1533                   (int)jcr->JobId, rctx.have_volume, dev->VolHdr.VolumeName, 
1534                   dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1535          ok = strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) == 0 ||
1536                  (dev->vol && strcmp(dev->vol->vol_name, rctx.VolumeName) == 0);
1537          if (!ok) {
1538             Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"), 
1539                jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName, 
1540                dev->print_name());
1541             queue_reserve_message(jcr);
1542             Dmsg4(dbglvl, "jid=%u not OK: dev have=%s resvol=%s want=%s\n", (int)jcr->JobId,
1543                   dev->VolHdr.VolumeName, dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1544             return 0;
1545          }
1546          if (!dcr->can_i_use_volume()) {
1547             return 0;              /* fail if volume on another drive */
1548          }
1549       }
1550    }
1551
1552    /* Check for unused autochanger drive */
1553    if (rctx.autochanger_only && !dev->is_busy() &&
1554        dev->VolHdr.VolumeName[0] == 0) {
1555       /* Device is available but not yet reserved, reserve it for us */
1556       Dmsg2(dbglvl, "jid=%u OK Res Unused autochanger %s.\n",
1557          jcr->JobId, dev->print_name());
1558       bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1559       bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1560       return 1;                       /* reserve drive */
1561    }
1562
1563    /*
1564     * Handle the case that there are no writers
1565     */
1566    if (dev->num_writers == 0) {
1567       /* Now check if there are any reservations on the drive */
1568       if (dev->num_reserved()) {           
1569          return is_pool_ok(dcr);
1570       } else if (dev->can_append()) {
1571          if (is_pool_ok(dcr)) {
1572             return 1; 
1573          } else {
1574             /* Changing pool, unload old tape if any in drive */
1575             Dmsg1(dbglvl, "jid=%u OK dev: num_writers=0, not reserved, pool change, unload changer\n", (int)jcr->JobId);
1576             /* ***FIXME*** use set_unload() */
1577             unload_autochanger(dcr, 0);
1578          }
1579       }
1580       /* Device is available but not yet reserved, reserve it for us */
1581       Dmsg2(dbglvl, "jid=%u OK Dev avail reserved %s\n", (int)jcr->JobId, dev->print_name());
1582       bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1583       bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1584       return 1;                       /* reserve drive */
1585    }
1586
1587    /*
1588     * Check if the device is in append mode with writers (i.e.
1589     *  available if pool is the same).
1590     */
1591    if (dev->can_append() || dev->num_writers > 0) {
1592       return is_pool_ok(dcr);
1593    } else {
1594       Pmsg1(000, _("Logic error!!!! JobId=%u Should not get here.\n"), (int)jcr->JobId);
1595       Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1596             jcr->JobId, dev->print_name());
1597       queue_reserve_message(jcr);
1598       Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1599       return -1;                      /* error, should not get here */
1600    }
1601    Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"), 
1602          jcr->JobId, dev->print_name());
1603    queue_reserve_message(jcr);
1604    Dmsg2(dbglvl, "jid=%u failed: No reserve %s\n", jcr->JobId, dev->print_name());
1605    return 0;
1606 }
1607
1608
1609
1610
1611 /*
1612  * Queue a reservation error or failure message for this jcr
1613  */
1614 static void queue_reserve_message(JCR *jcr)
1615 {
1616    int i;   
1617    alist *msgs;
1618    char *msg;
1619
1620    jcr->lock();
1621
1622    msgs = jcr->reserve_msgs;
1623    if (!msgs) {
1624       goto bail_out;
1625    }
1626    /*
1627     * Look for duplicate message.  If found, do
1628     * not insert
1629     */
1630    for (i=msgs->size()-1; i >= 0; i--) {
1631       msg = (char *)msgs->get(i);
1632       if (!msg) {
1633          goto bail_out;
1634       }
1635       /* Comparison based on 4 digit message number */
1636       if (strncmp(msg, jcr->errmsg, 4) == 0) {
1637          goto bail_out;
1638       }
1639    }      
1640    /* Message unique, so insert it */
1641    jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1642
1643 bail_out:
1644    jcr->unlock();
1645 }
1646
1647 /*
1648  * Send any reservation messages queued for this jcr
1649  */
1650 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1651 {
1652    int i;
1653    alist *msgs;
1654    char *msg;
1655
1656    jcr->lock();
1657    msgs = jcr->reserve_msgs;
1658    if (!msgs || msgs->size() == 0) {
1659       goto bail_out;
1660    }
1661    for (i=msgs->size()-1; i >= 0; i--) {
1662       msg = (char *)msgs->get(i);
1663       if (msg) {
1664          sendit("   ", 3, arg);
1665          sendit(msg, strlen(msg), arg);
1666       } else {
1667          break;
1668       }
1669    }
1670
1671 bail_out:
1672    jcr->unlock();
1673 }
1674
1675 /*
1676  * Pop and release any reservations messages
1677  */
1678 static void pop_reserve_messages(JCR *jcr)
1679 {
1680    alist *msgs;
1681    char *msg;
1682
1683    jcr->lock();
1684    msgs = jcr->reserve_msgs;
1685    if (!msgs) {
1686       goto bail_out;
1687    }
1688    while ((msg = (char *)msgs->pop())) {
1689       free(msg);
1690    }
1691 bail_out:
1692    jcr->unlock();
1693 }
1694
1695 /*
1696  * Also called from acquire.c 
1697  */
1698 void release_reserve_messages(JCR *jcr)
1699 {
1700    pop_reserve_messages(jcr);
1701    jcr->lock();
1702    if (!jcr->reserve_msgs) {
1703       goto bail_out;
1704    }
1705    delete jcr->reserve_msgs;
1706    jcr->reserve_msgs = NULL;
1707
1708 bail_out:
1709    jcr->unlock();
1710 }