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