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