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