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