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