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