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