]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/reserve.c
- Remove temp file created in mtx-changer script.
[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-2005 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 ammended 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    alist *errors;
52    JCR *jcr;
53    char *device_name;
54    DIRSTORE *store;
55    DEVRES   *device;
56    bool PreferMountedVols;
57 };
58
59 static dlist *vol_list = NULL;
60 static pthread_mutex_t vol_list_lock = PTHREAD_MUTEX_INITIALIZER;
61
62 /* Forward referenced functions */
63 static int can_reserve_drive(DCR *dcr, bool PerferMountedVols);
64 static int search_res_for_device(RCTX &rctx);
65 static int reserve_device(RCTX &rctx);
66 static bool reserve_device_for_read(DCR *dcr);
67 static bool reserve_device_for_append(DCR *dcr, bool PreferMountedVols);
68 static bool use_storage_cmd(JCR *jcr);
69 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx);
70
71 /* Requests from the Director daemon */
72 static char use_storage[]  = "use storage=%127s media_type=%127s "
73    "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
74 static char use_device[]  = "use device=%127s\n";
75
76 /* Responses sent to Director daemon */
77 static char OK_device[] = "3000 OK use device device=%s\n";
78 static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
79 static char BAD_use[]   = "3913 Bad use command: %s\n";
80
81 bool use_cmd(JCR *jcr) 
82 {
83    /*
84     * Get the device, media, and pool information
85     */
86    if (!use_storage_cmd(jcr)) {
87       set_jcr_job_status(jcr, JS_ErrorTerminated);
88       memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
89       return false;
90    }
91    return true;
92 }
93
94 static int my_compare(void *item1, void *item2)
95 {
96    return strcmp(((VOLRES *)item1)->vol_name, ((VOLRES *)item2)->vol_name);
97 }
98
99
100 /*
101  * Put a new Volume entry in the Volume list. This
102  *  effectively reserves the volume so that it will
103  *  not be mounted again.
104  *
105  *  Return: VOLRES entry on success
106  *          NULL if the Volume is already in the list
107  */
108 VOLRES *new_volume(DCR *dcr, const char *VolumeName)
109 {
110    VOLRES *vol, *nvol;
111    vol = (VOLRES *)malloc(sizeof(VOLRES));
112    memset(vol, 0, sizeof(VOLRES));
113    vol->vol_name = bstrdup(VolumeName);
114    vol->dev = dcr->dev;
115    vol->dcr = dcr;
116    P(vol_list_lock);
117    nvol = (VOLRES *)vol_list->binary_insert(vol, my_compare);
118    V(vol_list_lock);
119    if (nvol != vol) {
120       free(vol->vol_name);
121       free(vol);
122       if (dcr->dev) {
123          nvol->dev = dcr->dev;
124       }
125       return NULL;
126    }
127    return vol;
128 }
129
130 /*
131  * Search for a Volume name in the Volume list.
132  *
133  *  Returns: VOLRES entry on success
134  *           NULL if the Volume is not in the list
135  */
136 VOLRES *find_volume(const char *VolumeName)
137 {
138    VOLRES vol, *fvol;
139    vol.vol_name = bstrdup(VolumeName);
140    P(vol_list_lock);
141    fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
142    V(vol_list_lock);
143    free(vol.vol_name);
144    return fvol;
145 }
146
147 /*  
148  * Free a Volume from the Volume list
149  *
150  *  Returns: true if the Volume found and removed from the list
151  *           false if the Volume is not in the list
152  */
153 bool free_volume(DEVICE *dev)
154 {
155    VOLRES vol, *fvol;
156
157    if (dev->VolHdr.VolumeName[0] == 0) {
158       return false;
159    }
160    vol.vol_name = bstrdup(dev->VolHdr.VolumeName);
161    P(vol_list_lock);
162    fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
163    if (fvol) {
164       vol_list->remove(fvol);
165       free(fvol->vol_name);
166       free(fvol);
167    }
168    V(vol_list_lock);
169    free(vol.vol_name);
170    dev->VolHdr.VolumeName[0] = 0;
171    return fvol != NULL;
172 }
173
174 /* Free volume reserved by this dcr but not attached to a dev */
175 void free_unused_volume(DCR *dcr)
176 {
177    VOLRES *vol;
178    P(vol_list_lock);
179    for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
180       if (vol->dcr == dcr && (vol->dev == NULL || 
181           strcmp(vol->vol_name, vol->dev->VolHdr.VolumeName) != 0)) {
182          vol_list->remove(vol);
183          free(vol->vol_name);
184          free(vol);
185          break;
186       }
187    }
188    V(vol_list_lock);
189 }
190
191 /*
192  * List Volumes -- this should be moved to status.c
193  */
194 void list_volumes(BSOCK *user)  
195 {
196    VOLRES *vol;
197    for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
198       bnet_fsend(user, "%s\n", vol->vol_name);
199    }
200 }
201       
202 /* Create the Volume list */
203 void create_volume_list()
204 {
205    VOLRES *dummy;
206    if (vol_list == NULL) {
207       vol_list = New(dlist(dummy, &dummy->link));
208    }
209 }
210
211 /* Release all Volumes from the list */
212 void free_volume_list()
213 {
214    VOLRES *vol;
215    if (!vol_list) {
216       return;
217    }
218    for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
219       Dmsg3(000, "Unreleased Volume=%s dcr=0x%x dev=0x%x\n", vol->vol_name,
220          vol->dcr, vol->dev);
221    }
222    delete vol_list;
223    vol_list = NULL;
224 }
225
226 bool is_volume_in_use(const char *VolumeName) 
227 {
228    VOLRES *vol = find_volume(VolumeName);
229    if (!vol) {
230       return false;                   /* vol not in list */
231    }
232    if (!vol->dev) {                   /* vol not attached to device */
233       return false;
234    }
235    if (!vol->dev->is_busy()) {
236       return false;
237    }
238    return true;
239 }
240
241
242 static bool use_storage_cmd(JCR *jcr)
243 {
244    POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
245    BSOCK *dir = jcr->dir_bsock;
246    int append;
247    bool ok;       
248    int Copy, Stripe;
249    DIRSTORE *store;
250    RCTX rctx;
251    rctx.jcr = jcr;
252 #ifdef implemented
253    char *error;
254 #endif
255
256    /*
257     * If there are multiple devices, the director sends us
258     *   use_device for each device that it wants to use.
259     */
260    Dmsg1(100, "<dird: %s", dir->msg);
261    jcr->dirstore = New(alist(10, not_owned_by_alist));
262    do {
263       ok = sscanf(dir->msg, use_storage, store_name.c_str(), 
264                   media_type.c_str(), pool_name.c_str(), 
265                   pool_type.c_str(), &append, &Copy, &Stripe) == 7;
266       if (!ok) {
267          break;
268       }
269       unbash_spaces(store_name);
270       unbash_spaces(media_type);
271       unbash_spaces(pool_name);
272       unbash_spaces(pool_type);
273       store = new DIRSTORE;
274       jcr->dirstore->append(store);
275       memset(store, 0, sizeof(DIRSTORE));
276       store->device = New(alist(10));
277       bstrncpy(store->name, store_name, sizeof(store->name));
278       bstrncpy(store->media_type, media_type, sizeof(store->media_type));
279       bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
280       bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
281       store->append = append;
282
283       /* Now get all devices */
284       while (bnet_recv(dir) >= 0) {
285          ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
286          if (!ok) {
287             break;
288          }
289          unbash_spaces(dev_name);
290          store->device->append(bstrdup(dev_name.c_str()));
291       }
292    }  while (ok && bnet_recv(dir) >= 0);
293
294 #ifdef DEVELOPER
295    /* This loop is debug code and can be removed */
296    /* ***FIXME**** remove after 1.38 release */
297    char *device_name;
298    foreach_alist(store, jcr->dirstore) {
299       Dmsg4(100, "Storage=%s media_type=%s pool=%s pool_type=%s\n", 
300          store->name, store->media_type, store->pool_name, 
301          store->pool_type);
302       foreach_alist(device_name, store->device) {
303          Dmsg1(100, "   Device=%s\n", device_name);
304       }
305    }
306 #endif
307
308    /*                    
309     * At this point, we have a list of all the Director's Storage
310     *  resources indicated for this Job, which include Pool, PoolType,
311     *  storage name, and Media type.     
312     * Then for each of the Storage resources, we have a list of
313     *  device names that were given.
314     *
315     * Wiffle through them and find one that can do the backup.
316     */
317    if (ok) {
318       /*
319        * Make up to two passes. The first with PreferMountedVols possibly
320        *   set to true.  In that case, we look only for an available 
321        *   drive with something mounted. If that fails, then we
322        *   do a second pass with PerferMountedVols set false.
323        */
324       rctx.PreferMountedVols = jcr->PreferMountedVols;
325       ok = find_suitable_device_for_job(jcr, rctx);
326       if (ok) {
327          goto done;
328       }
329       if (rctx.PreferMountedVols) {
330          rctx.PreferMountedVols = false;
331          ok = find_suitable_device_for_job(jcr, rctx);
332          if (ok) {
333             goto done;
334          }
335       }
336       if (verbose) {
337          unbash_spaces(dir->msg);
338          pm_strcpy(jcr->errmsg, dir->msg);
339          Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
340       }
341       Jmsg(jcr, M_FATAL, 0, _("\n"
342          "     Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
343            dev_name.c_str(), media_type.c_str());
344       bnet_fsend(dir, NO_device, dev_name.c_str());
345 #ifdef implemented
346       for (error=(char*)rctx->errors.first(); error;
347            error=(char*)rctx->errors.next()) {
348          Jmsg(jcr, M_INFO, 0, "%s", error);
349       }
350 #endif
351       Dmsg1(100, ">dird: %s\n", dir->msg);
352    } else {
353       unbash_spaces(dir->msg);
354       pm_strcpy(jcr->errmsg, dir->msg);
355       if (verbose) {
356          Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
357       }
358       bnet_fsend(dir, BAD_use, jcr->errmsg);
359       Dmsg1(100, ">dird: %s\n", dir->msg);
360    }
361
362 done:
363    foreach_alist(store, jcr->dirstore) {
364       delete store->device;
365       delete store;
366    }
367    delete jcr->dirstore;
368 #ifdef implemented
369    for (error=(char*)rctx->errors.first(); error;
370         error=(char*)rctx->errors.next()) {
371       free(error);
372    }
373 #endif
374    return ok;
375 }
376
377
378 /*
379  * Search for a device suitable for this job.
380  */
381 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
382 {
383    bool first = true;
384    bool ok = false;
385    DCR *dcr = NULL;
386    DIRSTORE *store;
387    char *device_name;
388
389    init_jcr_device_wait_timers(jcr);
390    for ( ;; ) {
391       int need_wait = false;
392       foreach_alist(store, jcr->dirstore) {
393          rctx.store = store;
394          foreach_alist(device_name, store->device) {
395             int stat;
396             rctx.device_name = device_name;
397             stat = search_res_for_device(rctx); 
398             if (stat == 1) {             /* found available device */
399                dcr = jcr->dcr;
400                ok = true;
401                break;
402             } else if (stat == 0) {      /* device busy */
403                need_wait = true;
404             }
405             /* otherwise error */
406 //             rctx->errors.push(bstrdup(jcr->errmsg));
407          }
408       }
409       /*
410        * If there is some device for which we can wait, then
411        *  wait and try again until the wait time expires
412        */
413       if (!need_wait || !wait_for_device(jcr, first)) {
414          break;
415       }
416       first = false;
417 #ifdef implemented
418       for (error=(char*)rctx->errors.first(); error;
419            error=(char*)rctx->errors.next()) {
420          free(error);
421       }
422 #endif
423    }
424    if (!ok && dcr) {
425       free_dcr(dcr);
426    }
427
428    return ok;
429 }
430
431 /*
432  * Search for a particular storage device with particular storage
433  *  characteristics (MediaType).
434  */
435 static int search_res_for_device(RCTX &rctx) 
436 {
437    AUTOCHANGER *changer;
438    BSOCK *dir = rctx.jcr->dir_bsock;
439    bool ok;
440    int stat;
441
442    Dmsg1(100, "Search res for %s\n", rctx.device_name);
443    foreach_res(rctx.device, R_DEVICE) {
444       Dmsg1(100, "Try res=%s\n", rctx.device->hdr.name);
445       /* Find resource, and make sure we were able to open it */
446       if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0 &&
447           strcmp(rctx.device->media_type, rctx.store->media_type) == 0) {
448          stat = reserve_device(rctx);
449          if (stat != 1) {
450             return stat;
451          }
452          Dmsg1(220, "Got: %s", dir->msg);
453          bash_spaces(rctx.device_name);
454          ok = bnet_fsend(dir, OK_device, rctx.device_name);
455          Dmsg1(100, ">dird: %s\n", dir->msg);
456          return ok ? 1 : -1;
457       }
458    }
459    foreach_res(changer, R_AUTOCHANGER) {
460       Dmsg1(100, "Try changer res=%s\n", changer->hdr.name);
461       /* Find resource, and make sure we were able to open it */
462       if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
463          /* Try each device in this AutoChanger */
464          foreach_alist(rctx.device, changer->device) {
465             Dmsg1(100, "Try changer device %s\n", rctx.device->hdr.name);
466             stat = reserve_device(rctx);
467             if (stat == -1) {            /* hard error */
468                return -1;
469             }
470             if (stat == 0) {             /* must wait, try next one */
471                continue;
472             }
473             POOL_MEM dev_name;
474             Dmsg1(100, "Device %s opened.\n", rctx.device_name);
475             pm_strcpy(dev_name, rctx.device->hdr.name);
476             bash_spaces(dev_name);
477             ok = bnet_fsend(dir, OK_device, dev_name.c_str());  /* Return real device name */
478             Dmsg1(100, ">dird: %s\n", dir->msg);
479             return ok ? 1 : -1;
480          }
481       }
482    }
483    return 0;                    /* nothing found */
484 }
485
486 /*
487  *  Try to reserve a specific device.
488  *
489  *  Returns: 1 -- OK, have DCR
490  *           0 -- must wait
491  *          -1 -- fatal error
492  */
493 static int reserve_device(RCTX &rctx)
494 {
495    bool ok;
496    DCR *dcr;
497    const int name_len = MAX_NAME_LENGTH;
498    if (!rctx.device->dev) {
499       rctx.device->dev = init_dev(rctx.jcr, rctx.device);
500    }
501    if (!rctx.device->dev) {
502       if (rctx.device->changer_res) {
503         Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
504            "     Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
505              rctx.device->hdr.name, rctx.device_name);
506       } else {
507          Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
508             "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
509               rctx.device_name);
510       }
511       return -1;  /* no use waiting */
512    }  
513    Dmsg1(100, "Found device %s\n", rctx.device->hdr.name);
514    dcr = new_dcr(rctx.jcr, rctx.device->dev);
515    if (!dcr) {
516       BSOCK *dir = rctx.jcr->dir_bsock;
517       bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
518       Dmsg1(100, ">dird: %s\n", dir->msg);
519       return -1;
520    }
521    rctx.jcr->dcr = dcr;
522    bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
523    bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
524    bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
525    bstrncpy(dcr->dev_name, rctx.device_name, name_len);
526    if (rctx.store->append == SD_APPEND) {
527       ok = reserve_device_for_append(dcr, rctx.PreferMountedVols);
528       Dmsg3(200, "dev_name=%s mediatype=%s ok=%d\n", dcr->dev_name, dcr->media_type, ok);
529    } else {
530       ok = reserve_device_for_read(dcr);
531    }
532    if (!ok) {
533       free_dcr(rctx.jcr->dcr);
534       return 0;
535    }
536    return 1;
537 }
538
539 /*
540  * We "reserve" the drive by setting the ST_READ bit. No one else
541  *  should touch the drive until that is cleared.
542  *  This allows the DIR to "reserve" the device before actually
543  *  starting the job. 
544  */
545 static bool reserve_device_for_read(DCR *dcr)
546 {
547    DEVICE *dev = dcr->dev;
548    JCR *jcr = dcr->jcr;
549    bool ok = false;
550
551    ASSERT(dcr);
552
553    dev->block(BST_DOING_ACQUIRE);
554
555    if (is_device_unmounted(dev)) {             
556       Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
557       Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"),
558            dev->print_name());
559       goto bail_out;
560    }
561
562    if (dev->is_busy()) {
563       Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
564          dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
565       Mmsg1(jcr->errmsg, _("Device %s is busy.\n"),
566             dev->print_name());
567       goto bail_out;
568    }
569
570    dev->clear_append();
571    dev->set_read();
572    ok = true;
573
574 bail_out:
575    dev->unblock();
576    return ok;
577 }
578
579
580 /*
581  * We reserve the device for appending by incrementing the 
582  *  reserved_device. We do virtually all the same work that
583  *  is done in acquire_device_for_append(), but we do
584  *  not attempt to mount the device. This routine allows
585  *  the DIR to reserve multiple devices before *really* 
586  *  starting the job. It also permits the SD to refuse 
587  *  certain devices (not up, ...).
588  *
589  * Note, in reserving a device, if the device is for the
590  *  same pool and the same pool type, then it is acceptable.
591  *  The Media Type has already been checked. If we are
592  *  the first tor reserve the device, we put the pool
593  *  name and pool type in the device record.
594  */
595 static bool reserve_device_for_append(DCR *dcr, bool PreferMountedVols) 
596 {
597    JCR *jcr = dcr->jcr;
598    DEVICE *dev = dcr->dev;
599    bool ok = false;
600
601    ASSERT(dcr);
602
603    dev->block(BST_DOING_ACQUIRE);
604
605    if (dev->can_read()) {
606       Mmsg1(jcr->errmsg, _("Device %s is busy reading.\n"), dev->print_name());
607       Dmsg1(100, "%s", jcr->errmsg);
608       goto bail_out;
609    }
610
611    if (is_device_unmounted(dev)) {
612       Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"), dev->print_name());
613       Dmsg1(100, "%s", jcr->errmsg);
614       goto bail_out;
615    }
616
617    Dmsg1(190, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
618
619    if (can_reserve_drive(dcr, PreferMountedVols) != 1) {
620       Mmsg1(jcr->errmsg, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
621       Dmsg1(100, "%s", jcr->errmsg);
622       goto bail_out;
623    }
624
625    dev->reserved_device++;
626    Dmsg1(200, "Inc reserve=%d\n", dev->reserved_device);
627    dcr->reserved_device = true;
628    ok = true;
629
630 bail_out:
631    dev->unblock();
632    return ok;
633 }
634
635 /*
636  * Returns: 1 if drive can be reserved
637  *          0 if we should wait
638  *         -1 on error
639  */
640 static int can_reserve_drive(DCR *dcr, bool PreferMountedVols) 
641 {
642    DEVICE *dev = dcr->dev;
643    JCR *jcr = dcr->jcr;
644
645    if (PreferMountedVols && !dev->VolHdr.VolumeName[0] &&
646        dev->is_tape() && !dev->is_autochanger()) {
647       return 0;                 /* No volume mounted */
648    }
649
650    /*
651     * Handle the case that the drive is not yet in append mode
652     */
653    if (!dev->can_append() && dev->num_writers == 0) {
654       /* Now check if there are any reservations on the drive */
655       if (dev->reserved_device) {           
656          /* Yes, now check if we want the same Pool and pool type */
657          if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
658              strcmp(dev->pool_type, dcr->pool_type) == 0) {
659             /* OK, compatible device */
660          } else {
661             /* Drive not suitable for us */
662             return 0;                 /* wait */
663          }
664       } else {
665          /* Device is available but not yet reserved, reserve it for us */
666          bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
667          bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
668       }
669       return 1;                       /* reserve drive */
670    }
671
672    /*
673     * Check if device in append mode with no writers (i.e. available)
674     */
675    if (dev->can_append() && dev->num_writers == 0) {
676       /* Device is available but not yet reserved, reserve it for us */
677       bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
678       bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
679       return 1;
680    }
681    /*
682     * Check if the device is in append mode with writers (i.e.
683     *  available if pool is the same).
684     */
685    if (dev->can_append() || dev->num_writers > 0) {
686       Dmsg0(190, "device already in append.\n");
687       /* Yes, now check if we want the same Pool and pool type */
688       if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
689           strcmp(dev->pool_type, dcr->pool_type) == 0) {
690          /* OK, compatible device */
691          return 1;
692       } else {
693          /* Drive not suitable for us */
694          Jmsg(jcr, M_WARNING, 0, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
695          return 0;                    /* wait */
696       }
697    } else {
698       Pmsg0(000, "Logic error!!!! Should not get here.\n");
699       Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
700       return -1;                      /* error, should not get here */
701    }
702
703    return 0;
704 }