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