]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/reserve.c
kes Implement cleaner orphan buffer dumping with buf address.
[bacula/bacula] / bacula / src / stored / reserve.c
1 /*
2  *   Drive reservation functions for Storage Daemon
3  *
4  *   Kern Sibbald, MM
5  *
6  *   Split from job.c and acquire.c June 2005
7  *
8  *   Version $Id$
9  *
10  */
11 /*
12    Bacula® - The Network Backup Solution
13
14    Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
15
16    The main author of Bacula is Kern Sibbald, with contributions from
17    many others, a complete list can be found in the file AUTHORS.
18    This program is Free Software; you can redistribute it and/or
19    modify it under the terms of version two of the GNU General Public
20    License as published by the Free Software Foundation plus additions
21    that are listed in the file LICENSE.
22
23    This program is distributed in the hope that it will be useful, but
24    WITHOUT ANY WARRANTY; without even the implied warranty of
25    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26    General Public License for more details.
27
28    You should have received a copy of the GNU General Public License
29    along with this program; if not, write to the Free Software
30    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31    02110-1301, USA.
32
33    Bacula® is a registered trademark of John Walker.
34    The licensor of Bacula is the Free Software Foundation Europe
35    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
36    Switzerland, email:ftf@fsfeurope.org.
37 */
38
39 #include "bacula.h"
40 #include "stored.h"
41
42 static dlist *vol_list = NULL;
43 static pthread_mutex_t vol_list_lock = PTHREAD_MUTEX_INITIALIZER;
44
45 /* Forward referenced functions */
46 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
47 static int reserve_device(RCTX &rctx);
48 static bool reserve_device_for_read(DCR *dcr);
49 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
50 static bool use_storage_cmd(JCR *jcr);
51 static void queue_reserve_message(JCR *jcr);
52
53 /* Requests from the Director daemon */
54 static char use_storage[]  = "use storage=%127s media_type=%127s "
55    "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
56 static char use_device[]  = "use device=%127s\n";
57
58 /* Responses sent to Director daemon */
59 static char OK_device[] = "3000 OK use device device=%s\n";
60 static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
61 static char BAD_use[]   = "3913 Bad use command: %s\n";
62
63 bool use_cmd(JCR *jcr) 
64 {
65    /*
66     * Get the device, media, and pool information
67     */
68    if (!use_storage_cmd(jcr)) {
69       set_jcr_job_status(jcr, JS_ErrorTerminated);
70       memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
71       return false;
72    }
73    return true;
74 }
75
76 static int my_compare(void *item1, void *item2)
77 {
78    return strcmp(((VOLRES *)item1)->vol_name, ((VOLRES *)item2)->vol_name);
79 }
80
81 static brwlock_t reservation_lock;
82
83 void init_reservations_lock()
84 {
85    int errstat;
86    if ((errstat=rwl_init(&reservation_lock)) != 0) {
87       berrno be;
88       Emsg1(M_ABORT, 0, _("Unable to initialize reservation lock. ERR=%s\n"),
89             be.strerror(errstat));
90    }
91
92 }
93
94 void term_reservations_lock()
95 {
96    rwl_destroy(&reservation_lock);
97 }
98
99 /* This applies to a drive and to Volumes */
100 void lock_reservations()
101 {
102    int errstat;
103    if ((errstat=rwl_writelock(&reservation_lock)) != 0) {
104       berrno be;
105       Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
106            errstat, be.strerror(errstat));
107    }
108 }
109
110 void unlock_reservations()
111 {
112    int errstat;
113    if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
114       berrno be;
115       Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
116            errstat, be.strerror(errstat));
117    }
118 }
119
120
121 /*
122  * Put a new Volume entry in the Volume list. This
123  *  effectively reserves the volume so that it will
124  *  not be mounted again.
125  *
126  *  Return: VOLRES entry on success
127  *          NULL if the Volume is already in the list
128  */
129 VOLRES *new_volume(DCR *dcr, const char *VolumeName)
130 {
131    VOLRES *vol, *nvol;
132
133    Dmsg1(400, "new_volume %s\n", VolumeName);
134    /* 
135     * We lock the reservations system here to ensure
136     *  when adding a new volume that no newly scheduled
137     *  job can reserve it.
138     */
139    lock_reservations();
140    P(vol_list_lock);
141    if (dcr->dev) {
142 again:
143       foreach_dlist(vol, vol_list) {
144          if (vol && vol->dev == dcr->dev) {
145             vol_list->remove(vol);
146             if (vol->vol_name) {
147                free(vol->vol_name);
148             }
149             free(vol);
150             goto again;
151          }
152       }
153    }
154    vol = (VOLRES *)malloc(sizeof(VOLRES));
155    memset(vol, 0, sizeof(VOLRES));
156    vol->vol_name = bstrdup(VolumeName);
157    vol->dev = dcr->dev;
158    vol->dcr = dcr;
159    Dmsg2(100, "New Vol=%s dev=%s\n", VolumeName, dcr->dev->print_name());
160    nvol = (VOLRES *)vol_list->binary_insert(vol, my_compare);
161    if (nvol != vol) {
162       free(vol->vol_name);
163       free(vol);
164       vol = NULL;
165       if (dcr->dev) {
166          DEVICE *dev = nvol->dev;
167          if (!dev->is_busy()) {
168             Dmsg3(100, "Swap vol=%s from dev=%s to %s\n", VolumeName,
169                dev->print_name(), dcr->dev->print_name());
170             nvol->dev = dcr->dev;
171             dev->VolHdr.VolumeName[0] = 0;
172          } else {
173             Dmsg3(100, "!!!! could not swap vol=%s from dev=%s to %s\n", VolumeName,
174                dev->print_name(), dcr->dev->print_name());
175          }
176       }
177    }
178    V(vol_list_lock);
179    unlock_reservations();
180    return vol;
181 }
182
183 /*
184  * Search for a Volume name in the Volume list.
185  *
186  *  Returns: VOLRES entry on success
187  *           NULL if the Volume is not in the list
188  */
189 VOLRES *find_volume(const char *VolumeName)
190 {
191    VOLRES vol, *fvol;
192    /* Do not lock reservations here */
193    P(vol_list_lock);
194    vol.vol_name = bstrdup(VolumeName);
195    fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
196    free(vol.vol_name);
197    V(vol_list_lock);
198    return fvol;
199 }
200
201 /*  
202  * Free a Volume from the Volume list
203  *
204  *  Returns: true if the Volume found and removed from the list
205  *           false if the Volume is not in the list
206  */
207 bool free_volume(DEVICE *dev)
208 {
209    VOLRES vol, *fvol;
210
211    P(vol_list_lock);
212    if (dev->VolHdr.VolumeName[0] == 0) {
213       Dmsg1(100, "free_volume: no vol on dev %s\n", dev->print_name());
214       /*
215        * Our device has no VolumeName listed, but
216        *  search the list for any Volume attached to
217        *  this device and remove it.
218        */
219       foreach_dlist(fvol, vol_list) {
220          if (fvol && fvol->dev == dev) {
221             vol_list->remove(fvol);
222             if (fvol->vol_name) {
223                Dmsg2(100, "free_volume %s dev=%s\n", fvol->vol_name, dev->print_name());
224                free(fvol->vol_name);
225             }
226             free(fvol);
227             break;
228          }
229       }
230       goto bail_out;
231    }
232    Dmsg1(400, "free_volume %s\n", dev->VolHdr.VolumeName);
233    vol.vol_name = bstrdup(dev->VolHdr.VolumeName);
234    fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
235    if (fvol) {
236       vol_list->remove(fvol);
237       Dmsg2(100, "free_volume %s dev=%s\n", fvol->vol_name, dev->print_name());
238       free(fvol->vol_name);
239       free(fvol);
240    }
241    free(vol.vol_name);
242    dev->VolHdr.VolumeName[0] = 0;
243 bail_out:
244    V(vol_list_lock);
245    return fvol != NULL;
246 }
247
248 /* Free volume reserved by this dcr but not attached to a dev */
249 void free_unused_volume(DCR *dcr)
250 {
251    VOLRES *vol;
252
253    P(vol_list_lock);
254    for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
255       if (vol->dcr == dcr && (vol->dev == NULL || 
256           strcmp(vol->vol_name, vol->dev->VolHdr.VolumeName) != 0)) {
257          vol_list->remove(vol);
258          Dmsg1(100, "free_unused_volume %s\n", vol->vol_name);
259          free(vol->vol_name);
260          free(vol);
261          break;
262       }
263    }
264    V(vol_list_lock);
265 }
266
267 /*
268  * List Volumes -- this should be moved to status.c
269  */
270 void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg)
271 {
272    VOLRES *vol;
273    char *msg;
274    int len;
275
276    msg = (char *)get_pool_memory(PM_MESSAGE);
277
278    P(vol_list_lock);
279    for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
280       if (vol->dev) {
281          len = Mmsg(msg, "%s on device %s\n", vol->vol_name, vol->dev->print_name());
282          sendit(msg, len, arg);
283       } else {
284          len = Mmsg(msg, "%s\n", vol->vol_name);
285          sendit(msg, len, arg);
286       }
287    }
288    V(vol_list_lock);
289
290    free_pool_memory(msg);
291 }
292       
293 /* Create the Volume list */
294 void create_volume_list()
295 {
296    VOLRES *dummy = NULL;
297    if (vol_list == NULL) {
298       vol_list = New(dlist(dummy, &dummy->link));
299    }
300 }
301
302 /* Release all Volumes from the list */
303 void free_volume_list()
304 {
305    VOLRES *vol;
306    if (!vol_list) {
307       return;
308    }
309    P(vol_list_lock);
310    for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
311       Dmsg3(100, "Unreleased Volume=%s dcr=0x%x dev=0x%x\n", vol->vol_name,
312          vol->dcr, vol->dev);
313    }
314    delete vol_list;
315    vol_list = NULL;
316    V(vol_list_lock);
317 }
318
319 bool is_volume_in_use(DCR *dcr)
320 {
321    VOLRES *vol = find_volume(dcr->VolumeName);
322    if (!vol) {
323       Dmsg1(100, "Vol=%s not in use.\n", dcr->VolumeName);
324       return false;                   /* vol not in list */
325    }
326    if (!vol->dev) {                   /* vol not attached to device */
327       Dmsg1(100, "Vol=%s has no dev.\n", dcr->VolumeName);
328       return false;
329    }
330    if (dcr->dev == vol->dev) {        /* same device OK */
331       Dmsg1(100, "Vol=%s on same dev.\n", dcr->VolumeName);
332       return false;
333    }
334    if (!vol->dev->is_busy()) {
335       Dmsg2(100, "Vol=%s dev=%s not busy.\n", dcr->VolumeName, vol->dev->print_name());
336       return false;
337    }
338    Dmsg2(100, "Vol=%s used by %s.\n", dcr->VolumeName, vol->dev->print_name());
339    return true;
340 }
341
342
343 /*
344  * We get the following type of information:
345  *
346  * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
347  *  use device=zzz
348  *  use device=aaa
349  *  use device=bbb
350  * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
351  *  use device=bbb
352  *
353  */
354 static bool use_storage_cmd(JCR *jcr)
355 {
356    POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
357    BSOCK *dir = jcr->dir_bsock;
358    int append;
359    bool ok;       
360    int Copy, Stripe;
361    DIRSTORE *store;
362    RCTX rctx;
363    char *msg;
364    alist *msgs;
365    alist *dirstore;
366
367    memset(&rctx, 0, sizeof(RCTX));
368    rctx.jcr = jcr;
369    /*
370     * If there are multiple devices, the director sends us
371     *   use_device for each device that it wants to use.
372     */
373    dirstore = New(alist(10, not_owned_by_alist));
374 // Dmsg2(000, "dirstore=%p JobId=%u\n", dirstore, jcr->JobId);
375    msgs = jcr->reserve_msgs = New(alist(10, not_owned_by_alist));  
376    do {
377       Dmsg1(100, "<dird: %s", dir->msg);
378       ok = sscanf(dir->msg, use_storage, store_name.c_str(), 
379                   media_type.c_str(), pool_name.c_str(), 
380                   pool_type.c_str(), &append, &Copy, &Stripe) == 7;
381       if (!ok) {
382          break;
383       }
384       if (append) {
385          jcr->write_store = dirstore;
386       } else {
387          jcr->read_store = dirstore;
388       }
389       rctx.append = append;
390       unbash_spaces(store_name);
391       unbash_spaces(media_type);
392       unbash_spaces(pool_name);
393       unbash_spaces(pool_type);
394       store = new DIRSTORE;
395       dirstore->append(store);
396       memset(store, 0, sizeof(DIRSTORE));
397       store->device = New(alist(10));
398       bstrncpy(store->name, store_name, sizeof(store->name));
399       bstrncpy(store->media_type, media_type, sizeof(store->media_type));
400       bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
401       bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
402       store->append = append;
403
404       /* Now get all devices */
405       while (bnet_recv(dir) >= 0) {
406          Dmsg1(100, "<dird device: %s", dir->msg);
407          ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
408          if (!ok) {
409             break;
410          }
411          unbash_spaces(dev_name);
412          store->device->append(bstrdup(dev_name.c_str()));
413       }
414    }  while (ok && bnet_recv(dir) >= 0);
415
416 #ifdef DEVELOPER
417    /* This loop is debug code and can be removed */
418    /* ***FIXME**** remove after 1.38 release */
419    char *device_name;
420    foreach_alist(store, dirstore) {
421       Dmsg5(110, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n", 
422          store->name, store->media_type, store->pool_name, 
423          store->pool_type, store->append);
424       foreach_alist(device_name, store->device) {
425          Dmsg1(110, "   Device=%s\n", device_name);
426       }
427    }
428 #endif
429
430    init_jcr_device_wait_timers(jcr);
431    /*                    
432     * At this point, we have a list of all the Director's Storage
433     *  resources indicated for this Job, which include Pool, PoolType,
434     *  storage name, and Media type.     
435     * Then for each of the Storage resources, we have a list of
436     *  device names that were given.
437     *
438     * Wiffle through them and find one that can do the backup.
439     */
440    if (ok) {
441       bool first = true;           /* print wait message once */
442       bool fail = false;
443       rctx.notify_dir = true;
444       lock_reservations();
445       for ( ; !fail && !job_canceled(jcr); ) {
446          while ((msg = (char *)msgs->pop())) {
447             free(msg);
448          }
449          rctx.suitable_device = false;
450          rctx.have_volume = false;
451          rctx.any_drive = false;
452          if (!jcr->PreferMountedVols) {
453             /* Look for unused drives in autochangers */
454             rctx.num_writers = 20000000;   /* start with impossible number */
455             rctx.low_use_drive = NULL;
456             rctx.PreferMountedVols = false;                
457             rctx.exact_match = false;
458             rctx.autochanger_only = true;
459             Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
460                rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
461                rctx.autochanger_only, rctx.any_drive);
462             if ((ok = find_suitable_device_for_job(jcr, rctx))) {
463                break;
464             }
465             /* Look through all drives possibly for low_use drive */
466             if (rctx.low_use_drive) {
467                rctx.try_low_use_drive = true;
468                if ((ok = find_suitable_device_for_job(jcr, rctx))) {
469                   break;
470                }
471                rctx.try_low_use_drive = false;
472             }
473             rctx.autochanger_only = false;
474             Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
475                rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
476                rctx.autochanger_only, rctx.any_drive);
477             if ((ok = find_suitable_device_for_job(jcr, rctx))) {
478                break;
479             }
480          }
481          /* Look for an exact match all drives */
482          rctx.PreferMountedVols = true;
483          rctx.exact_match = true;
484          rctx.autochanger_only = false;
485          Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
486             rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
487             rctx.autochanger_only, rctx.any_drive);
488          if ((ok = find_suitable_device_for_job(jcr, rctx))) {
489             break;
490          }
491          /* Look for any mounted drive */
492          rctx.exact_match = false;
493          Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
494             rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
495             rctx.autochanger_only, rctx.any_drive);
496          if ((ok = find_suitable_device_for_job(jcr, rctx))) {
497             break;
498          }
499          /* Try any drive */
500          rctx.any_drive = true;
501          Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
502             rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
503             rctx.autochanger_only, rctx.any_drive);
504          if ((ok = find_suitable_device_for_job(jcr, rctx))) {
505             break;
506          }
507          /* Keep reservations locked *except* during wait_for_device() */
508          unlock_reservations();
509          if (!rctx.suitable_device || !wait_for_device(jcr, first)) {
510             Dmsg0(100, "Fail. !suitable_device || !wait_for_device\n");
511             fail = true;
512          }   
513          lock_reservations();
514          first = false;
515          bnet_sig(dir, BNET_HEARTBEAT);  /* Inform Dir that we are alive */
516       }
517       unlock_reservations();
518       if (!ok) {
519          /*
520           * If we get here, there are no suitable devices available, which
521           *  means nothing configured.  If a device is suitable but busy
522           *  with another Volume, we will not come here.
523           */
524          unbash_spaces(dir->msg);
525          pm_strcpy(jcr->errmsg, dir->msg);
526          Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
527          Jmsg(jcr, M_FATAL, 0, _("\n"
528             "     Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
529               dev_name.c_str(), media_type.c_str());
530          bnet_fsend(dir, NO_device, dev_name.c_str());
531
532          Dmsg1(100, ">dird: %s", dir->msg);
533       }
534    } else {
535       unbash_spaces(dir->msg);
536       pm_strcpy(jcr->errmsg, dir->msg);
537       Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
538       bnet_fsend(dir, BAD_use, jcr->errmsg);
539       Dmsg1(100, ">dird: %s", dir->msg);
540    }
541
542    release_msgs(jcr);
543    return ok;
544 }
545
546 void release_msgs(JCR *jcr)
547 {
548    alist *msgs = jcr->reserve_msgs;
549    char *msg;
550
551    if (!msgs) {
552       return;
553    }
554    lock_reservations();
555    while ((msg = (char *)msgs->pop())) {
556       free(msg);
557    }
558    delete msgs;
559    jcr->reserve_msgs = NULL;
560    unlock_reservations();
561 }
562
563 /*
564  * Search for a device suitable for this job.
565  */
566 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
567 {
568    bool ok;
569    DIRSTORE *store;
570    char *device_name;
571    alist *dirstore;
572
573    if (rctx.append) {
574       dirstore = jcr->write_store;
575    } else {
576       dirstore = jcr->read_store;
577    }
578    /* 
579     * For each storage device that the user specified, we
580     *  search and see if there is a resource for that device.
581     */
582    Dmsg4(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d\n",
583       rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
584       rctx.autochanger_only);
585    ok = false;
586    foreach_alist(store, dirstore) {
587       rctx.store = store;
588       foreach_alist(device_name, store->device) {
589          int stat;
590          rctx.device_name = device_name;
591          stat = search_res_for_device(rctx); 
592          if (stat == 1) {             /* found available device */
593             Dmsg1(100, "Suitable device found=%s\n", device_name);
594             ok = true;
595             break;
596          } else if (stat == 0) {      /* device busy */
597             Dmsg1(110, "Suitable device found=%s, not used: busy\n", device_name);
598          } else {
599             /* otherwise error */
600             Dmsg0(110, "No suitable device found.\n");
601          }
602       }
603       if (ok) {
604          break;
605       }
606    }
607    return ok;
608 }
609
610 /*
611  * Search for a particular storage device with particular storage
612  *  characteristics (MediaType).
613  */
614 int search_res_for_device(RCTX &rctx) 
615 {
616    AUTOCHANGER *changer;
617    BSOCK *dir = rctx.jcr->dir_bsock;
618    bool ok;
619    int stat;
620
621    Dmsg1(110, "Search res for %s\n", rctx.device_name);
622    /* Look through Autochangers first */
623    foreach_res(changer, R_AUTOCHANGER) {
624       Dmsg1(150, "Try match changer res=%s\n", changer->hdr.name);
625       /* Find resource, and make sure we were able to open it */
626       if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
627          /* Try each device in this AutoChanger */
628          foreach_alist(rctx.device, changer->device) {
629             Dmsg1(110, "Try changer device %s\n", rctx.device->hdr.name);
630             stat = reserve_device(rctx);
631             if (stat != 1) {             /* try another device */
632                continue;
633             }
634             POOL_MEM dev_name;
635             if (rctx.store->append == SD_APPEND) {
636                Dmsg2(100, "Device %s reserved=%d for append.\n", rctx.device->hdr.name,
637                   rctx.jcr->dcr->dev->reserved_device);
638             } else {
639                Dmsg2(100, "Device %s reserved=%d for read.\n", rctx.device->hdr.name,
640                   rctx.jcr->read_dcr->dev->reserved_device);
641             }
642             if (rctx.notify_dir) {
643                pm_strcpy(dev_name, rctx.device->hdr.name);
644                bash_spaces(dev_name);
645                ok = bnet_fsend(dir, OK_device, dev_name.c_str());  /* Return real device name */
646                Dmsg1(100, ">dird changer: %s", dir->msg);
647             } else {
648                ok = true;
649             }
650             return ok ? 1 : -1;
651          }
652       }
653    }
654
655    /* Now if requested look through regular devices */
656    if (!rctx.autochanger_only) {
657       foreach_res(rctx.device, R_DEVICE) {
658          Dmsg1(150, "Try match res=%s\n", rctx.device->hdr.name);
659          /* Find resource, and make sure we were able to open it */
660          if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0) {
661             stat = reserve_device(rctx);
662             if (stat != 1) {
663                return stat;
664             }
665             if (rctx.notify_dir) {
666                bash_spaces(rctx.device_name);
667                ok = bnet_fsend(dir, OK_device, rctx.device_name);
668                Dmsg1(100, ">dird dev: %s", dir->msg);
669             } else {
670                ok = true;
671             }
672             return ok ? 1 : -1;
673          }
674       }
675    }
676    return -1;                    /* nothing found */
677 }
678
679 /*
680  *  Try to reserve a specific device.
681  *
682  *  Returns: 1 -- OK, have DCR
683  *           0 -- must wait
684  *          -1 -- fatal error
685  */
686 static int reserve_device(RCTX &rctx)
687 {
688    bool ok;
689    DCR *dcr;
690    const int name_len = MAX_NAME_LENGTH;
691
692    /* Make sure MediaType is OK */
693    Dmsg2(110, "MediaType device=%s request=%s\n",
694          rctx.device->media_type, rctx.store->media_type);
695    if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
696       return -1;
697    }
698
699    /* Make sure device exists -- i.e. we can stat() it */
700    if (!rctx.device->dev) {
701       rctx.device->dev = init_dev(rctx.jcr, rctx.device);
702    }
703    if (!rctx.device->dev) {
704       if (rctx.device->changer_res) {
705         Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
706            "     Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
707              rctx.device->hdr.name, rctx.device_name);
708       } else {
709          Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
710             "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
711               rctx.device_name);
712       }
713       return -1;  /* no use waiting */
714    }  
715
716    rctx.suitable_device = true;
717    Dmsg2(110, "Try reserve %s JobId=%u\n", rctx.device->hdr.name,
718          rctx.jcr->JobId);
719    dcr = new_dcr(rctx.jcr, rctx.device->dev);
720    if (!dcr) {
721       BSOCK *dir = rctx.jcr->dir_bsock;
722       bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
723       Dmsg1(100, ">dird: %s", dir->msg);
724       return -1;
725    }
726    bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
727    bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
728    bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
729    bstrncpy(dcr->dev_name, rctx.device_name, name_len);
730    if (rctx.store->append == SD_APPEND) {
731       if (rctx.exact_match && !rctx.have_volume) {
732          dcr->any_volume = true;
733          if (dir_find_next_appendable_volume(dcr)) {
734             bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
735             Dmsg2(100, "JobId=%u looking for Volume=%s\n", rctx.jcr->JobId, rctx.VolumeName);
736             rctx.have_volume = true;
737          } else {
738             Dmsg0(100, "No next volume found\n");
739             rctx.VolumeName[0] = 0;
740         }
741       }
742       ok = reserve_device_for_append(dcr, rctx);
743       if (ok) {
744          rctx.jcr->dcr = dcr;
745          Dmsg5(100, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
746                dcr->dev->reserved_device,
747                dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
748       }
749    } else {
750       ok = reserve_device_for_read(dcr);
751       if (ok) {
752          rctx.jcr->read_dcr = dcr;
753          Dmsg5(100, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
754                dcr->dev->reserved_device,
755                dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
756       }
757    }
758    if (!ok) {
759       free_dcr(dcr);
760       Dmsg0(110, "Not OK.\n");
761       return 0;
762    }
763    return 1;
764 }
765
766 /*
767  * We "reserve" the drive by setting the ST_READ bit. No one else
768  *  should touch the drive until that is cleared.
769  *  This allows the DIR to "reserve" the device before actually
770  *  starting the job. 
771  */
772 static bool reserve_device_for_read(DCR *dcr)
773 {
774    DEVICE *dev = dcr->dev;
775    JCR *jcr = dcr->jcr;
776    bool ok = false;
777
778    ASSERT(dcr);
779
780    /* Get locks in correct order */
781    unlock_reservations();
782    P(dev->mutex);
783    lock_reservations();
784
785    if (is_device_unmounted(dev)) {             
786       Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
787       Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
788            jcr->JobId, dev->print_name());
789       queue_reserve_message(jcr);
790       goto bail_out;
791    }
792
793    if (dev->is_busy()) {
794       Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
795          dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
796       Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
797             jcr->JobId, dev->print_name());
798       queue_reserve_message(jcr);
799       goto bail_out;
800    }
801
802    dev->clear_append();
803    dev->set_read();
804    ok = true;
805    dev->reserved_device++;
806    Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device, 
807       dev->print_name(), dev);
808    dcr->reserved_device = true;
809
810 bail_out:
811    V(dev->mutex);
812    return ok;
813 }
814
815
816 /*
817  * We reserve the device for appending by incrementing the 
818  *  reserved_device. We do virtually all the same work that
819  *  is done in acquire_device_for_append(), but we do
820  *  not attempt to mount the device. This routine allows
821  *  the DIR to reserve multiple devices before *really* 
822  *  starting the job. It also permits the SD to refuse 
823  *  certain devices (not up, ...).
824  *
825  * Note, in reserving a device, if the device is for the
826  *  same pool and the same pool type, then it is acceptable.
827  *  The Media Type has already been checked. If we are
828  *  the first tor reserve the device, we put the pool
829  *  name and pool type in the device record.
830  */
831 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
832 {
833    JCR *jcr = dcr->jcr;
834    DEVICE *dev = dcr->dev;
835    bool ok = false;
836
837    ASSERT(dcr);
838
839    /* Get locks in correct order */
840    unlock_reservations();
841    P(dev->mutex);
842    lock_reservations();
843
844    /* If device is being read, we cannot write it */
845    if (dev->can_read()) {
846       Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"), 
847          jcr->JobId, dev->print_name());
848       Dmsg1(110, "%s", jcr->errmsg);
849       queue_reserve_message(jcr);
850       goto bail_out;
851    }
852
853    /* If device is unmounted, we are out of luck */
854    if (is_device_unmounted(dev)) {
855       Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"), 
856          jcr->JobId, dev->print_name());
857       Dmsg1(110, "%s", jcr->errmsg);
858       queue_reserve_message(jcr);
859       goto bail_out;
860    }
861
862    Dmsg1(110, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
863
864    /* Now do detailed tests ... */
865    if (can_reserve_drive(dcr, rctx) != 1) {
866       Dmsg0(110, "can_reserve_drive!=1\n");
867       goto bail_out;
868    }
869
870    dev->reserved_device++;
871    Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device, 
872       dev->print_name(), dev);
873    dcr->reserved_device = true;
874    ok = true;
875
876 bail_out:
877    V(dev->mutex);
878    return ok;
879 }
880
881 /*
882  * Returns: 1 if drive can be reserved
883  *          0 if we should wait
884  *         -1 on error or impossibility
885  */
886 static int can_reserve_drive(DCR *dcr, RCTX &rctx) 
887 {
888    DEVICE *dev = dcr->dev;
889    JCR *jcr = dcr->jcr;
890
891    Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
892          rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
893          rctx.autochanger_only, rctx.any_drive);
894
895    /* setting any_drive overrides PreferMountedVols flag */
896    if (!rctx.any_drive) {
897       /*
898        * When PreferMountedVols is set, we keep track of the 
899        *  drive in use that has the least number of writers, then if
900        *  no unmounted drive is found, we try that drive. This   
901        *  helps spread the load to the least used drives.  
902        */
903       if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
904          Dmsg3(110, "OK dev=%s == low_drive=%s. JobId=%u\n",
905             dev->print_name(), rctx.low_use_drive->print_name(), jcr->JobId);
906          return 1;
907       }
908       /* If he wants a free drive, but this one is busy, no go */
909       if (!rctx.PreferMountedVols && dev->is_busy()) {
910          /* Save least used drive */
911          if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
912             rctx.num_writers = dev->num_writers + dev->reserved_device;
913             rctx.low_use_drive = dev;
914             Dmsg2(110, "set low use drive=%s num_writers=%d\n", dev->print_name(),
915                rctx.num_writers);
916          } else {
917             Dmsg1(110, "not low use num_writers=%d\n", dev->num_writers+ 
918                dev->reserved_device);
919          }
920          Dmsg1(110, "failed: !prefMnt && busy. JobId=%u\n", jcr->JobId);
921          Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"), 
922             jcr->JobId, dev->print_name());
923          queue_reserve_message(jcr);
924          return 0;
925       }
926
927       /* Check for prefer mounted volumes */
928       if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
929          Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"), 
930             jcr->JobId, dev->print_name());
931          queue_reserve_message(jcr);
932          Dmsg1(110, "failed: want mounted -- no vol JobId=%u\n", jcr->JobId);
933          return 0;                 /* No volume mounted */
934       }
935
936       /* Check for exact Volume name match */
937       if (rctx.exact_match && rctx.have_volume &&
938           strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
939          Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"), 
940             jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName, 
941             dev->print_name());
942          queue_reserve_message(jcr);
943          Dmsg2(110, "failed: Not exact match have=%s want=%s\n",
944                dev->VolHdr.VolumeName, rctx.VolumeName);
945          return 0;
946       }
947    }
948
949    /* Check for unused autochanger drive */
950    if (rctx.autochanger_only && dev->num_writers == 0 &&
951        dev->VolHdr.VolumeName[0] == 0) {
952       /* Device is available but not yet reserved, reserve it for us */
953       Dmsg2(100, "OK Res Unused autochanger %s JobId=%u.\n",
954          dev->print_name(), jcr->JobId);
955       bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
956       bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
957       return 1;                       /* reserve drive */
958    }
959
960    /*
961     * Handle the case that there are no writers
962     */
963    if (dev->num_writers == 0) {
964       /* Now check if there are any reservations on the drive */
965       if (dev->reserved_device) {           
966          /* Now check if we want the same Pool and pool type */
967          if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
968              strcmp(dev->pool_type, dcr->pool_type) == 0) {
969             /* OK, compatible device */
970             Dmsg2(100, "OK dev: %s num_writers=0, reserved, pool matches JobId=%u\n",
971                dev->print_name(), jcr->JobId);
972             return 1;
973          } else {
974             /* Drive Pool not suitable for us */
975             Mmsg(jcr->errmsg, _("3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" on drive %s.\n"), 
976                   jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
977             queue_reserve_message(jcr);
978             Dmsg2(110, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
979                dev->pool_name, dcr->pool_name);
980             return 0;                 /* wait */
981          }
982       } else if (dev->can_append()) {
983          /* Device in append mode, check if changing pool */
984          if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
985              strcmp(dev->pool_type, dcr->pool_type) == 0) {
986             Dmsg2(100, "OK dev: %s num_writers=0, can_append, pool matches. JobId=%u\n",
987                dev->print_name(), jcr->JobId);
988             /* OK, compatible device */
989             return 1;
990          } else {
991             /* Changing pool, unload old tape if any in drive */
992             Dmsg0(100, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
993             unload_autochanger(dcr, 0);
994          }
995       }
996       /* Device is available but not yet reserved, reserve it for us */
997       Dmsg2(100, "OK Dev avail reserved %s JobId=%u\n", dev->print_name(),
998          jcr->JobId);
999       bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1000       bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1001       return 1;                       /* reserve drive */
1002    }
1003
1004    /*
1005     * Check if the device is in append mode with writers (i.e.
1006     *  available if pool is the same).
1007     */
1008    if (dev->can_append() || dev->num_writers > 0) {
1009       /* Yes, now check if we want the same Pool and pool type */
1010       if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1011           strcmp(dev->pool_type, dcr->pool_type) == 0) {
1012          Dmsg2(100, "OK dev: %s num_writers>=0, can_append, pool matches. JobId=%u\n",
1013             dev->print_name(), jcr->JobId);
1014          /* OK, compatible device */
1015          return 1;
1016       } else {
1017          /* Drive Pool not suitable for us */
1018          Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"), 
1019                jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
1020          queue_reserve_message(jcr);
1021          Dmsg2(110, "failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
1022             dev->pool_name, dcr->pool_name);
1023          return 0;                    /* wait */
1024       }
1025    } else {
1026       Pmsg0(000, _("Logic error!!!! Should not get here.\n"));
1027       Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1028             jcr->JobId, dev->print_name());
1029       queue_reserve_message(jcr);
1030       Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1031       return -1;                      /* error, should not get here */
1032    }
1033    Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"), 
1034          jcr->JobId, dev->print_name());
1035    queue_reserve_message(jcr);
1036    Dmsg2(110, "failed: No reserve %s JobId=%u\n", dev->print_name(), jcr->JobId);
1037    return 0;
1038 }
1039
1040 /*
1041  * search_lock is already set on entering this routine 
1042  */
1043 static void queue_reserve_message(JCR *jcr)
1044 {
1045    int i;   
1046    alist *msgs = jcr->reserve_msgs;
1047    char *msg;
1048
1049    if (!msgs) {
1050       return;
1051    }
1052    /*
1053     * Look for duplicate message.  If found, do
1054     * not insert
1055     */
1056    for (i=msgs->size()-1; i >= 0; i--) {
1057       msg = (char *)msgs->get(i);
1058       if (!msg) {
1059          return;
1060       }
1061       /* Comparison based on 4 digit message number */
1062       if (strncmp(msg, jcr->errmsg, 4) == 0) {
1063          return;
1064       }
1065    }      
1066    /* Message unique, so insert it */
1067    jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1068 }
1069
1070 /*
1071  * Send any reservation messages queued for this jcr
1072  */
1073 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1074 {
1075    int i;
1076    alist *msgs;
1077    char *msg;
1078
1079    lock_reservations();
1080    msgs = jcr->reserve_msgs;
1081    if (!msgs || msgs->size() == 0) {
1082       unlock_reservations();
1083       return;
1084    }
1085    for (i=msgs->size()-1; i >= 0; i--) {
1086       msg = (char *)msgs->get(i);
1087       if (msg) {
1088          sendit("   ", 3, arg);
1089          sendit(msg, strlen(msg), arg);
1090       } else {
1091          break;
1092       }
1093    }
1094    unlock_reservations();
1095 }