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