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