]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/reserve.c
Apply patches from bugs #2325 and #2326 to fix FIFO bugs
[bacula/bacula] / bacula / src / stored / reserve.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2017 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *   Drive reservation functions for Storage Daemon
21  *
22  *   Written by Kern Sibbald, MM
23  *
24  *   Split from job.c and acquire.c June 2005
25  *
26  */
27
28 #include "bacula.h"
29 #include "stored.h"
30
31 const int dbglvl = 150;
32
33 static brwlock_t reservation_lock;
34 int reservations_lock_count = 0;
35
36 /* Forward referenced functions */
37 static int  can_reserve_drive(DCR *dcr, RCTX &rctx);
38 static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol);
39 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
40 static bool reserve_device_for_read(DCR *dcr);
41 static bool use_device_cmd(JCR *jcr);
42 static int  reserve_device(RCTX &rctx);
43 static void pop_reserve_messages(JCR *jcr);
44 static void queue_reserve_message(JCR *jcr);
45 static int is_pool_ok(DCR *dcr);
46 //void switch_device(DCR *dcr, DEVICE *dev);
47
48 /* Requests from the Director daemon */
49 static char use_storage[]  = "use storage=%127s media_type=%127s "
50     "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
51 static char use_device[]  = "use device=%127s\n";
52
53 /* Responses sent to Director daemon */
54 static char OK_device[] = "3000 OK use device device=%s\n";
55 static char NO_device[] = "3924 Device \"%s\" not in SD Device"
56      " resources or no matching Media Type or is disabled.\n";
57 static char BAD_use[]   = "3913 Bad use command: %s\n";
58
59 /*
60  * This allows a given thread to recursively call lock_reservations.
61  *   It must, of course, call unlock_... the same number of times.
62  */
63 void init_reservations_lock()
64 {
65    int errstat;
66    if ((errstat=rwl_init(&reservation_lock)) != 0) {
67       berrno be;
68       Emsg1(M_ABORT, 0, _("Unable to initialize reservation lock. ERR=%s\n"),
69             be.bstrerror(errstat));
70    }
71
72    init_vol_list_lock();
73 }
74
75
76 /* This applies to a drive and to Volumes */
77 void _lock_reservations(const char *file, int line)
78 {
79    int errstat;
80    reservations_lock_count++;
81    if ((errstat=rwl_writelock_p(&reservation_lock, file, line)) != 0) {
82       berrno be;
83       Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
84            errstat, be.bstrerror(errstat));
85    }
86 }
87
88 void _unlock_reservations()
89 {
90    int errstat;
91    reservations_lock_count--;
92    if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
93       berrno be;
94       Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
95            errstat, be.bstrerror(errstat));
96    }
97 }
98
99 void term_reservations_lock()
100 {
101    rwl_destroy(&reservation_lock);
102    term_vol_list_lock();
103 }
104
105 void DCR::clear_reserved()
106 {
107    if (m_reserved) {
108       m_reserved = false;
109       dev->dec_reserved();
110       Dmsg3(dbglvl, "Dec reserve=%d writers=%d dev=%s\n", dev->num_reserved(),
111          dev->num_writers,  dev->print_name());
112       if (dev->num_reserved() == 0) {
113          dev->reserved_pool_name[0] = 0;
114       }
115    }
116 }
117
118 void DCR::set_reserved_for_append()
119 {
120    if (dev->num_reserved() == 0) {
121       bstrncpy(dev->reserved_pool_name, pool_name, sizeof(dev->reserved_pool_name));
122       Dmsg1(dbglvl, "Set reserve pool: %s\n", pool_name);
123    }
124    m_reserved = true;
125    dev->set_append_reserve();
126    dev->inc_reserved();
127    Dmsg3(dbglvl, "Inc reserve=%d writers=%d dev=%s\n", dev->num_reserved(),
128       dev->num_writers,  dev->print_name());
129 }
130
131 void DCR::set_reserved_for_read()
132 {
133    /* Called for each volume read, no need to increment each time */
134    if (!m_reserved) {
135       m_reserved = true;
136       dev->set_read_reserve();
137       dev->inc_reserved();
138       Dmsg2(dbglvl, "Inc reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
139    }
140 }
141
142 /*
143  * Remove any reservation from a drive and tell the system
144  *  that the volume is unused at least by us.
145  */
146 void DCR::unreserve_device(bool locked)
147 {
148    if (!locked) {
149       dev->Lock();
150    }
151    if (is_reserved()) {
152       clear_reserved();
153       reserved_volume = false;
154       /* If we set read mode in reserving, remove it */
155       if (dev->can_read()) {
156          remove_read_volume(jcr, this->VolumeName);
157          dev->clear_read();
158       }
159       if (dev->num_writers < 0) {
160          Jmsg1(jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
161          dev->num_writers = 0;
162       }
163       if (dev->num_reserved() == 0 && dev->num_writers == 0) {
164          generate_plugin_event(jcr, bsdEventDeviceClose, this);
165          volume_unused(this);
166       }
167    }
168    if (!locked) {
169       dev->Unlock();
170    }
171 }
172
173 bool use_cmd(JCR *jcr)
174 {
175    /*
176     * Get the device, media, and pool information
177     */
178    if (!use_device_cmd(jcr)) {
179       jcr->setJobStatus(JS_ErrorTerminated);
180       memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
181       return false;
182    }
183    return true;
184 }
185
186 /*
187  * Storage search options
188  */
189 struct store_opts_t {
190    bool PreferMountedVols;
191    bool exact_match;
192    bool autochanger_only;
193    bool try_low_use_drive;
194    bool any_drive;
195 };
196
197 /*   *** Old pre-8.8 algorithm *** not used here
198  *   jcr->PreferMountedVols = true
199  *     MntVol  exact  chgonly lowuse any
200  * 1 * {true,  true,  false,  false, false},
201  * 2 * {true,  false, true,   false, false},
202  * 3 * {true,  false, true,   false, true},
203
204  *   jcr->PreferMountedVols = false
205  *     MntVol  exact  chgonly lowuse any
206  * 4 * {false, false, true,   false, false},
207  * 5 * {false, false, true,   true,  false}, * low instantaneous use *
208  * 6 * {false, false, false,  true,  false},
209  * 7 * {true,  true,  false,  false, false},
210  * 8 * {true,  false, true,   false, false},
211  * 9 * {true,  false, true,   false, true}
212  *** End old pre-8.8 algorithm ***
213  */
214
215 store_opts_t store_opts[] = {
216 /*   jcr->PreferMountedVols = true */
217 /*      MntVol  exact  chgonly lowuse any */
218 /* 1 */ {true,  true,  false,  true,  false}, /* low global use */
219 /* 2 */ {true,  false, true,   true,  false},
220 /* 3 */ {true,  false, true,   false, true},
221 /* 4 */ {true,  true,  false,  true,  false},
222 /* 5 */ {false, true,  false,  false, false},
223 /* 6 */ {false, false, false,  false, false},
224 /* 7 */ {true,  false, false,  false, true},
225
226 /*   jcr->PreferMountedVols = false */
227 /*       MntVol  exact  chgonly lowuse any */
228 /* 8 */  {false, false, true,   true,  false},
229 /* 9 */  {false, false, true,   false, false},
230 /* 10 */ {false, false, false,  true,  false},
231 /* 11 */ {true,  true,  false,  true,  true},
232 /* 12 */ {true,  false, true,   true,  false},
233 /* 13 */ {true,  false, true,   false,  true}
234 };
235
236 static void set_options(RCTX &rctx, int num)
237 {
238    rctx.PreferMountedVols = store_opts[num-1].PreferMountedVols;
239    rctx.exact_match = store_opts[num-1].exact_match;
240    rctx.autochanger_only = store_opts[num-1].autochanger_only;
241    rctx.try_low_use_drive = store_opts[num-1].try_low_use_drive;
242    rctx.any_drive = store_opts[num-1].any_drive;
243    rctx.low_use_drive = NULL;
244 }
245
246 static void prt_options(RCTX &rctx, int num)
247 {
248    Dmsg6(dbglvl, "Inx=%d mntVol=%d exact=%d chgonly=%d low_use=%d any=%d\n",
249       num, rctx.PreferMountedVols, rctx.exact_match, rctx.autochanger_only,
250       rctx.try_low_use_drive, rctx.any_drive);
251 }
252
253
254
255 /*
256  * We get the following type of information:
257  *
258  * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
259  *  use device=zzz
260  *  use device=aaa
261  *  use device=bbb
262  * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
263  *  use device=bbb
264  *
265  */
266 static bool use_device_cmd(JCR *jcr)
267 {
268    POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
269    BSOCK *dir = jcr->dir_bsock;
270    int32_t append;
271    bool ok;
272    int32_t Copy, Stripe;
273    DIRSTORE *store;
274    RCTX rctx;
275    alist *dirstore;
276
277    memset(&rctx, 0, sizeof(RCTX));
278    rctx.jcr = jcr;
279    /*
280     * If there are multiple devices, the director sends us
281     *   use_device for each device that it wants to use.
282     */
283    dirstore = New(alist(10, not_owned_by_alist));
284    jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
285    do {
286       Dmsg1(dbglvl, "<dird: %s", dir->msg);
287       ok = sscanf(dir->msg, use_storage, store_name.c_str(),
288                   media_type.c_str(), pool_name.c_str(),
289                   pool_type.c_str(), &append, &Copy, &Stripe) == 7;
290       if (!ok) {
291          break;
292       }
293       if (append) {
294          jcr->write_store = dirstore;
295       } else {
296          jcr->read_store = dirstore;
297       }
298       rctx.append = append;
299       unbash_spaces(store_name);
300       unbash_spaces(media_type);
301       unbash_spaces(pool_name);
302       unbash_spaces(pool_type);
303       store = new DIRSTORE;
304       dirstore->append(store);
305       memset(store, 0, sizeof(DIRSTORE));
306       store->device = New(alist(10));
307       bstrncpy(store->name, store_name, sizeof(store->name));
308       bstrncpy(store->media_type, media_type, sizeof(store->media_type));
309       bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
310       bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
311       store->append = append;
312
313       /* Now get all devices */
314       while (dir->recv() >= 0) {
315          Dmsg1(dbglvl, "<dird device: %s", dir->msg);
316          ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
317          if (!ok) {
318             break;
319          }
320          unbash_spaces(dev_name);
321          store->device->append(bstrdup(dev_name.c_str()));
322       }
323    }  while (ok && dir->recv() >= 0);
324
325 #ifdef xxxx
326    /* Developers debug code */
327    char *device_name;
328    if (debug_level >= dbglvl) {
329       foreach_alist(store, dirstore) {
330          Dmsg5(dbglvl, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
331             store->name, store->media_type, store->pool_name,
332             store->pool_type, store->append);
333          foreach_alist(device_name, store->device) {
334             Dmsg1(dbglvl, "     Device=%s\n", device_name);
335          }
336       }
337    }
338 #endif
339
340    init_jcr_device_wait_timers(jcr);
341    jcr->dcr = new_dcr(jcr, NULL, NULL, !rctx.append);   /* get a dcr */
342    if (!jcr->dcr) {
343       BSOCK *dir = jcr->dir_bsock;
344       dir->fsend(_("3939 Could not get dcr\n"));
345       Dmsg1(dbglvl, ">dird: %s", dir->msg);
346       ok = false;
347    }
348    /*
349     * At this point, we have a list of all the Director's Storage
350     *  resources indicated for this Job, which include Pool, PoolType,
351     *  storage name, and Media type.
352     * Then for each of the Storage resources, we have a list of
353     *  device names that were given.
354     *
355     * Wiffle through Storage resources sent to us and find one that can do the backup.
356     */
357    if (ok) {
358       int wait_for_device_retries = 0;
359       int repeat = 0;
360       bool fail = false;
361       rctx.notify_dir = true;
362
363       /* Put new dcr in proper location */
364       if (rctx.append) {
365          rctx.jcr->dcr = jcr->dcr;
366       } else {
367          rctx.jcr->read_dcr = jcr->dcr;
368       }
369       lock_reservations();
370       for ( ; !fail && !job_canceled(jcr); ) {
371          int i;
372          pop_reserve_messages(jcr);
373          rctx.suitable_device = false;
374          rctx.have_volume = false;
375          rctx.VolumeName[0] = 0;
376          rctx.any_drive = false;
377          if (jcr->PreferMountedVols) {
378             for (i=1; i<=7; i++) {
379                set_options(rctx, i);
380                prt_options(rctx, i);
381                if ((ok = find_suitable_device_for_job(jcr, rctx))) {
382                   break;
383                }
384             }
385          } else {
386             for (i=8; i<=13; i++) {
387                set_options(rctx, i);
388                prt_options(rctx, i);
389                if ((ok = find_suitable_device_for_job(jcr, rctx))) {
390                   break;
391                }
392             }
393          }
394          if (ok) {
395             break;
396          }
397          /* Keep reservations locked *except* during wait_for_device() */
398          unlock_reservations();
399          /*
400           * The idea of looping on repeat a few times it to ensure
401           * that if there is some subtle timing problem between two
402           * jobs, we will simply try again, and most likely succeed.
403           * This can happen if one job reserves a drive or finishes using
404           * a drive at the same time a second job wants it.
405           */
406          if (repeat++ < 20) {             /* try sleeping 20 times */
407             bmicrosleep(30, 0);           /* wait 30 secs */
408             Dmsg1(dbglvl, "repeat reserve algorithm JobId=%d\n", jcr->JobId);
409          } else if (!rctx.suitable_device || !wait_for_any_device(jcr, wait_for_device_retries)) {
410             Dmsg0(dbglvl, "Fail. !suitable_device || !wait_for_device\n");
411             fail = true;
412          }
413          lock_reservations();
414          dir->signal(BNET_HEARTBEAT);  /* Inform Dir that we are alive */
415       }
416       unlock_reservations();
417
418       if (!ok) {
419          /*
420           * If we get here, there are no suitable devices available, which
421           *  means nothing configured.  If a device is suitable but busy
422           *  with another Volume, we will not come here.
423           */
424          unbash_spaces(dir->msg);
425          pm_strcpy(jcr->errmsg, dir->msg);
426          Jmsg(jcr, M_FATAL, 0, _("Device reservation failed for JobId=%d: %s\n"),
427               jcr->JobId, jcr->errmsg);
428          dir->fsend(NO_device, dev_name.c_str());
429
430          Dmsg1(dbglvl, ">dird: %s", dir->msg);
431       }
432    } else {
433       unbash_spaces(dir->msg);
434       pm_strcpy(jcr->errmsg, dir->msg);
435       Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
436       dir->fsend(BAD_use, jcr->errmsg);
437       Dmsg1(dbglvl, ">dird: %s", dir->msg);
438    }
439
440    release_reserve_messages(jcr);
441    return ok;
442 }
443
444 /*
445  * Search for a device suitable for this job.
446  * Note, this routine sets sets rctx.suitable_device if any
447  *   device exists within the SD.  The device may not be actually
448  *   useable.
449  * It also returns if it finds a useable device.
450  */
451 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
452 {
453    bool ok = false;
454    DIRSTORE *store;
455    char *device_name;
456    alist *dirstore;
457    DCR *dcr = jcr->dcr;
458
459    if (rctx.append) {
460       dirstore = jcr->write_store;
461    } else {
462       dirstore = jcr->read_store;
463    }
464    Dmsg5(dbglvl, "Start find_suit_dev PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
465          rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
466          rctx.autochanger_only, rctx.any_drive);
467
468    /*
469     * If the appropriate conditions of this if are met, namely that
470     *  we are appending and the user wants mounted drive (or we
471     *  force try a mounted drive because they are all busy), we
472     *  start by looking at all the Volumes in the volume list.
473     */
474    if (!is_vol_list_empty() && rctx.append && rctx.PreferMountedVols) {
475       dlist *temp_vol_list;
476       VOLRES *vol = NULL;
477       temp_vol_list = dup_vol_list(jcr);
478
479       /* Look through reserved volumes for one we can use */
480       Dmsg0(dbglvl, "look for vol in vol list\n");
481       foreach_dlist(vol, temp_vol_list) {
482          if (!vol->dev) {
483             Dmsg1(dbglvl, "vol=%s no dev\n", vol->vol_name);
484             continue;
485          }
486          bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName));
487          /* Check with Director if this Volume is OK */
488          if (!dir_get_volume_info(dcr, dcr->VolumeName, GET_VOL_INFO_FOR_WRITE)) {
489             continue;
490          }
491          Dmsg1(dbglvl, "vol=%s OK for this job\n", vol->vol_name);
492          foreach_alist(store, dirstore) {
493             int stat;
494             rctx.store = store;
495             foreach_alist(device_name, store->device) {
496                /* Found a device, try to use it */
497                rctx.device_name = device_name;
498                rctx.device = vol->dev->device;
499                if (vol->dev->read_only) {
500                   continue;
501                }
502                if (vol->dev->is_autochanger()) {
503                   Dmsg1(dbglvl, "vol=%s is in changer\n", vol->vol_name);
504                   if (!is_vol_in_autochanger(rctx, vol) || !vol->dev->autoselect ||
505                      !vol->dev->enabled) {
506                      continue;
507                   }
508                } else if (strcmp(device_name, vol->dev->device->hdr.name) != 0) {
509                   Dmsg2(dbglvl, "device=%s not suitable want %s\n",
510                         vol->dev->device->hdr.name, device_name);
511                   continue;
512                }
513                bstrncpy(rctx.VolumeName, vol->vol_name, sizeof(rctx.VolumeName));
514                rctx.have_volume = true;
515                /* Try reserving this device and volume */
516                Dmsg2(dbglvl, "Try reserve vol=%s on device=%s\n", rctx.VolumeName, device_name);
517                stat = reserve_device(rctx);
518                if (stat == 1) {             /* found available device */
519                   Dmsg1(dbglvl, "Device reserved=%s\n", device_name);
520                   ok = true;
521                } else {
522                   /* Error or no suitable device found */
523                   Dmsg0(dbglvl, "No suitable device found.\n");
524                   rctx.have_volume = false;
525                   rctx.VolumeName[0] = 0;
526                }
527             }
528             if (ok) {
529                break;
530             }
531          } /* end of loop over storages */
532          if (ok) {
533             break;
534          }
535       } /* end for loop over reserved volumes */
536
537       Dmsg0(dbglvl, "lock volumes\n");
538       free_temp_vol_list(temp_vol_list);
539    } /* End test for vol_list, ... */
540    if (ok) {
541       Dmsg1(dbglvl, "OK dev found. Vol=%s from in-use vols list\n", rctx.VolumeName);
542       return true;
543    }
544
545    /*
546     * No reserved volume we can use, so now search for an available device.
547     *
548     * For each storage device that the user specified, we
549     *  search and see if there is a resource for that device.
550     */
551    foreach_alist(store, dirstore) {
552       rctx.store = store;
553       foreach_alist(device_name, store->device) {
554          int stat;
555          rctx.device_name = device_name;
556          stat = search_res_for_device(rctx);
557          if (stat == 1) {             /* found available device */
558             Dmsg1(dbglvl, "available device found=%s\n", device_name);
559             ok = true;
560             break;
561          } else if (stat == 0) {      /* device busy */
562             Dmsg1(dbglvl, "No usable device=%s, busy: not use\n", device_name);
563          } else {
564             /* otherwise error */
565             Dmsg0(dbglvl, "No usable device found.\n");
566          }
567       }
568       if (ok) {
569          break;
570       }
571    }
572    if (ok) {
573       Dmsg1(dbglvl, "OK dev found. Vol=%s\n", rctx.VolumeName);
574    } else {
575       Dmsg0(dbglvl, "Leave find_suit_dev: no dev found.\n");
576    }
577    return ok;
578 }
579
580 /*
581  * Search for a particular storage device with particular storage
582  *  characteristics (MediaType).
583  */
584 int search_res_for_device(RCTX &rctx)
585 {
586    AUTOCHANGER *changer;
587    int stat;
588
589    Dmsg1(dbglvl, "search res for %s\n", rctx.device_name);
590    /* Look through Autochangers first */
591    foreach_res(changer, R_AUTOCHANGER) {
592       Dmsg1(dbglvl, "Try match changer res=%s\n", changer->hdr.name);
593       /* Find resource, and make sure we were able to open it */
594       if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
595          /* Try each device in this AutoChanger */
596          foreach_alist(rctx.device, changer->device) {
597             Dmsg1(dbglvl, "Top try changer device %s\n", rctx.device->hdr.name);
598             if (rctx.store->append && rctx.device->read_only) {
599                continue;
600             }
601             if (!rctx.device->autoselect) {
602                Dmsg1(dbglvl, "Device %s not autoselect skipped.\n",
603                rctx.device->hdr.name);
604                continue;              /* device is not available */
605             }
606             if (rctx.try_low_use_drive) {
607                if (!rctx.low_use_drive) {
608                   rctx.low_use_drive = rctx.device->dev;
609                   Dmsg2(dbglvl, "Set low_use usage=%lld drv=%s\n",
610                      rctx.low_use_drive->usage,
611                      rctx.low_use_drive->print_name());
612                } else if ((rctx.low_use_drive->usage > rctx.device->dev->usage) ||
613                           (rctx.low_use_drive->usage == rctx.device->dev->usage &&
614                            rctx.low_use_drive->num_reserved() > rctx.device->dev->num_reserved())) {
615                   rctx.low_use_drive = rctx.device->dev;
616                   Dmsg2(dbglvl, "Reset low_use usage=%lld drv=%s\n",
617                      rctx.low_use_drive->usage,
618                      rctx.low_use_drive->print_name());
619                } else {
620                   Dmsg2(dbglvl, "Skip low_use usage=%lld drv=%s\n",
621                      rctx.low_use_drive->usage,
622                      rctx.low_use_drive->print_name());
623                }
624             } else {
625                Dmsg2(dbglvl, "try reserve vol=%s on device=%s\n", rctx.VolumeName, rctx.device->hdr.name);
626                stat = reserve_device(rctx);
627                if (stat != 1) {             /* try another device */
628                   continue;
629                }
630                /* Debug code */
631                if (rctx.store->append) {
632                   Dmsg2(dbglvl, "Device %s reserved=%d for append.\n",
633                   rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved());
634                } else {
635                   Dmsg2(dbglvl, "Device %s reserved=%d for read.\n",
636                      rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved());
637                }
638                return stat;
639             }
640          }
641          /* If found a drive try to reserve it */
642          if (rctx.try_low_use_drive && rctx.low_use_drive) {
643             rctx.device = rctx.low_use_drive->device;
644             Dmsg2(dbglvl, "Try reserve vol=%s on device=%s\n", rctx.VolumeName, rctx.device->hdr.name);
645             stat = reserve_device(rctx);
646             if (stat == 1) {
647                /* Debug code */
648                if (rctx.store->append) {
649                   Dmsg3(dbglvl, "JobId=%d device %s reserved=%d for append.\n",
650                      rctx.jcr->JobId, rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved());
651                } else {
652                   Dmsg3(dbglvl, "JobId=%d device %s reserved=%d for read.\n",
653                      rctx.jcr->JobId, rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved());
654                }
655             } else {
656                Dmsg2(dbglvl, "Reserve for %s failed for JobId=%d.\n", 
657                   rctx.store->append ? "append" : "read", rctx.jcr->JobId);
658             }
659             return stat;
660          }
661       }
662    }
663
664    /* Now if requested look through regular devices */
665    if (!rctx.autochanger_only) {
666       foreach_res(rctx.device, R_DEVICE) {
667          Dmsg1(dbglvl, "Try match res=%s\n", rctx.device->hdr.name);
668          /* Find resource, and make sure we were able to open it */
669          if (strcmp(rctx.device_name, rctx.device->hdr.name) == 0) {
670             Dmsg2(dbglvl, "Try reserve vol=%s on device=%s\n", rctx.VolumeName, rctx.device->hdr.name);
671             stat = reserve_device(rctx);
672             if (stat != 1) {             /* try another device */
673                continue;
674             }
675             /* Debug code */
676             if (rctx.store->append) {
677                Dmsg2(dbglvl, "Device %s reserved=%d for append.\n",
678                   rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved());
679             } else {
680                Dmsg2(dbglvl, "Device %s reserved=%d for read.\n",
681                   rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved());
682             }
683             return stat;
684          }
685       }
686    }
687    return -1;                    /* nothing found */
688 }
689
690 /*
691  * Walk through the autochanger resources and check if
692  *  the volume is in one of them.
693  *
694  * Returns:  true  if volume is in device
695  *           false otherwise
696  */
697 static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol)
698 {
699    AUTOCHANGER *changer = vol->dev->device->changer_res;
700
701    /* Find resource, and make sure we were able to open it */
702    if (changer && strcmp(rctx.device_name, changer->hdr.name) == 0) {
703       Dmsg1(dbglvl, "Found changer device %s\n", vol->dev->device->hdr.name);
704       return true;
705    }
706    Dmsg1(dbglvl, "Incorrect changer device %s\n", changer->hdr.name);
707    return false;
708 }
709
710
711 /*
712  *  Try to reserve a specific device.
713  *
714  *  Returns: 1 -- OK, have DCR
715  *           0 -- must wait
716  *          -1 -- fatal error
717  */
718 static int reserve_device(RCTX &rctx)
719 {
720    bool ok;
721    DCR *dcr;
722    const int name_len = MAX_NAME_LENGTH;
723
724    /* Make sure MediaType is OK */
725    Dmsg2(dbglvl, "chk MediaType device=%s request=%s\n",
726          rctx.device->media_type, rctx.store->media_type);
727    if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
728       return -1;
729    }
730
731    /* Make sure device exists -- i.e. we can stat() it */
732    if (!rctx.device->dev) {
733       rctx.device->dev = init_dev(rctx.jcr, rctx.device);
734    }
735    if (!rctx.device->dev) {
736       if (rctx.device->changer_res) {
737         Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
738            "     Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
739              rctx.device->hdr.name, rctx.device_name);
740       } else {
741          Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
742             "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
743               rctx.device_name);
744       }
745       return -1;  /* no use waiting */
746    } else if (!rctx.device->dev->enabled) {
747       Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
748            "     Device \"%s\" requested by DIR is disabled.\n"),
749               rctx.device_name);
750       return -1;  /* no use waiting */
751    }
752
753    rctx.suitable_device = true;
754    Dmsg1(dbglvl, "try reserve %s\n", rctx.device->hdr.name);
755    if (rctx.store->append) {
756       dcr = new_dcr(rctx.jcr, rctx.jcr->dcr, rctx.device->dev, SD_APPEND);
757    } else {
758       dcr = new_dcr(rctx.jcr, rctx.jcr->read_dcr, rctx.device->dev, SD_READ);
759    }
760    if (!dcr) {
761       BSOCK *dir = rctx.jcr->dir_bsock;
762       dir->fsend(_("3926 Could not get dcr for device: %s\n"), rctx.device_name);
763       Dmsg1(dbglvl, ">dird: %s", dir->msg);
764       return -1;
765    }
766    bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
767    bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
768    bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
769    bstrncpy(dcr->dev_name, rctx.device_name, name_len);
770    if (rctx.store->append) {
771       Dmsg2(dbglvl, "call reserve for append: have_vol=%d vol=%s\n", rctx.have_volume, rctx.VolumeName);
772       ok = reserve_device_for_append(dcr, rctx);
773       if (!ok) {
774          goto bail_out;
775       }
776       rctx.jcr->dcr = dcr;
777       Dmsg5(dbglvl, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
778                dcr->dev->num_reserved(),
779                dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
780       Dmsg4(dbglvl, "Vol=%s num_writers=%d, reserved=%d have_vol=%d\n",
781          rctx.VolumeName, dcr->dev->num_writers, dcr->dev->num_reserved(),
782          rctx.have_volume);
783       if (rctx.have_volume) {
784          Dmsg0(dbglvl, "Call reserve_volume for append.\n");
785          if (reserve_volume(dcr, rctx.VolumeName)) {
786             Dmsg1(dbglvl, "Reserved vol=%s\n", rctx.VolumeName);
787          } else {
788             Dmsg1(dbglvl, "Could not reserve vol=%s\n", rctx.VolumeName);
789             goto bail_out;
790          }
791       } else {
792          dcr->any_volume = true;
793          Dmsg0(dbglvl, "no vol, call find_next_appendable_vol.\n");
794          if (dir_find_next_appendable_volume(dcr)) {
795             bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
796             rctx.have_volume = true;
797             Dmsg1(dbglvl, "looking for Volume=%s\n", rctx.VolumeName);
798             if (!dcr->can_i_use_volume() || !is_pool_ok(dcr)) {
799                rctx.have_volume = false;
800                rctx.VolumeName[0] = 0;
801                dcr->unreserve_device(false);
802                goto bail_out;
803             }
804          } else {
805             dcr->dev->clear_wait();
806             Dmsg0(dbglvl, "No next volume found\n");
807             rctx.have_volume = false;
808             rctx.VolumeName[0] = 0;
809             /*
810              * If there is at least one volume that is valid and in use,
811              *   but we get here, check if we are running with prefers
812              *   non-mounted drives.  In that case, we have selected a
813              *   non-used drive and our one and only volume is mounted
814              *   elsewhere, so we bail out and retry using that drive.
815              */
816             if (dcr->found_in_use() && !rctx.PreferMountedVols) {
817                rctx.PreferMountedVols = true;
818                if (dcr->VolumeName[0]) {
819                   dcr->unreserve_device(false);
820                }
821                goto bail_out;
822             }
823             /*
824              * Note. Under some circumstances, the Director can hand us
825              *  a Volume name that is not the same as the one on the current
826              *  drive, and in that case, the call above to find the next
827              *  volume will fail because in attempting to reserve the Volume
828              *  the code will realize that we already have a tape mounted,
829              *  and it will fail.  This *should* only happen if there are
830              *  writers, thus the following test.  In that case, we simply
831              *  bail out, and continue waiting, rather than plunging on
832              *  and hoping that the operator can resolve the problem.
833              */
834             if (dcr->dev->num_writers != 0) {
835                if (dcr->VolumeName[0]) {
836                   dcr->unreserve_device(false);
837                }
838                goto bail_out;
839             }
840          }
841       }
842    } else {
843       ok = reserve_device_for_read(dcr);
844       if (ok) {
845          rctx.jcr->read_dcr = dcr;
846          Dmsg5(dbglvl, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
847                dcr->dev->num_reserved(),
848                dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
849       }
850    }
851    if (!ok) {
852       goto bail_out;
853    }
854
855    if (rctx.notify_dir) {
856       POOL_MEM dev_name;
857       BSOCK *dir = rctx.jcr->dir_bsock;
858       pm_strcpy(dev_name, rctx.device->hdr.name);
859       bash_spaces(dev_name);
860       ok = dir->fsend(OK_device, dev_name.c_str());  /* Return real device name */
861       Dmsg1(dbglvl, ">dird: %s", dir->msg);
862       if (!ok) {
863          dcr->unreserve_device(false);
864       }
865    } else {
866       ok = true;
867    }
868    return ok ? 1 : -1;
869
870 bail_out:
871    rctx.have_volume = false;
872    rctx.VolumeName[0] = 0;
873    Dmsg0(dbglvl, "Not OK.\n");
874    return 0;
875 }
876
877
878 /*
879  * We reserve the device for appending by incrementing
880  *  num_reserved(). We do virtually all the same work that
881  *  is done in acquire_device_for_append(), but we do
882  *  not attempt to mount the device. This routine allows
883  *  the DIR to reserve multiple devices before *really*
884  *  starting the job. It also permits the SD to refuse
885  *  certain devices (not up, ...).
886  *
887  * Note, in reserving a device, if the device is for the
888  *  same pool and the same pool type, then it is acceptable.
889  *  The Media Type has already been checked. If we are
890  *  the first to reserve the device, we put the pool
891  *  name and pool type in the device record.
892  */
893 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
894 {
895    JCR *jcr = dcr->jcr;
896    DEVICE *dev = dcr->dev;
897    bool ok = false;
898
899    ASSERT2(dcr, "No dcr in reserve_device_for_append!");
900    if (job_canceled(jcr)) {
901       return false;
902    }
903
904    dev->Lock();
905
906    /* If device is being read or reserved for read, we cannot write it */
907    if (dev->can_read() || dev->is_reserved_for_read()) {
908       Mmsg(jcr->errmsg, _("3603 JobId=%u %s device %s is busy reading.\n"),
909          jcr->JobId, dev->print_type(), dev->print_name());
910       queue_reserve_message(jcr);
911       Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
912       goto bail_out;
913    }
914
915    /* If device is unmounted, we are out of luck */
916    if (dev->is_device_unmounted()) {
917       Mmsg(jcr->errmsg, _("3604 JobId=%u %s device %s is BLOCKED due to user unmount.\n"),
918          jcr->JobId, dev->print_type(), dev->print_name());
919       queue_reserve_message(jcr);
920       Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
921       goto bail_out;
922    }
923
924    Dmsg2(dbglvl, "reserve_append %s device is %s\n", dev->print_type(), dev->print_name());
925
926    /* Now do detailed tests ... */
927    if (can_reserve_drive(dcr, rctx) != 1) {
928       Dmsg0(dbglvl, "can_reserve_drive!=1\n");
929       goto bail_out;
930    }
931
932    /* Note: on failure this returns jcr->errmsg properly edited */
933    if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) {
934       queue_reserve_message(jcr);
935       goto bail_out;
936    }
937    dcr->set_reserved_for_append();
938    ok = true;
939
940 bail_out:
941    dev->Unlock();
942    return ok;
943 }
944
945 /*
946  * We "reserve" the drive by setting the ST_READ bit. No one else
947  *  should touch the drive until that is cleared.
948  *  This allows the DIR to "reserve" the device before actually
949  *  starting the job.
950  */
951 static bool reserve_device_for_read(DCR *dcr)
952 {
953    DEVICE *dev = dcr->dev;
954    JCR *jcr = dcr->jcr;
955    bool ok = false;
956
957    ASSERT2(dcr, "No dcr in reserve_device_for_read!");
958    if (job_canceled(jcr)) {
959       return false;
960    }
961
962    dev->Lock();
963
964    if (dev->is_device_unmounted()) {
965       Mmsg(jcr->errmsg, _("3601 JobId=%u %s device %s is BLOCKED due to user unmount.\n"),
966            jcr->JobId, dev->print_type(), dev->print_name());
967       queue_reserve_message(jcr);
968       Dmsg1(dbglvl, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
969       goto bail_out;
970    }
971
972    if (dev->is_busy()) {
973       Mmsg(jcr->errmsg, _("3602 JobId=%u %s device %s is busy (already reading/writing)."
974             " read=%d, writers=%d reserved=%d\n"),
975             jcr->JobId, dev->print_type(), dev->print_name(),
976             dev->state & ST_READ?1:0, dev->num_writers, dev->num_reserved());
977       queue_reserve_message(jcr);
978       Dmsg4(dbglvl, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n",
979          dev->print_name(),
980          dev->state & ST_READ?1:0, dev->num_writers, dev->num_reserved());
981       goto bail_out;
982    }
983
984    /* Note: on failure this returns jcr->errmsg properly edited */
985    if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) {
986       queue_reserve_message(jcr);
987       goto bail_out;
988    }
989    dev->clear_append();
990    dcr->set_reserved_for_read();
991    ok = true;
992
993 bail_out:
994    dev->Unlock();
995    return ok;
996 }
997
998 static bool is_max_jobs_ok(DCR *dcr)
999 {
1000    DEVICE *dev = dcr->dev;
1001    JCR *jcr = dcr->jcr;
1002
1003    Dmsg6(dbglvl, "MaxJobs=%d VolCatJobs=%d writers=%d reserves=%d Status=%s Vol=%s\n",
1004          dcr->VolCatInfo.VolCatMaxJobs,
1005          dcr->VolCatInfo.VolCatJobs,
1006          dev->num_writers, dev->num_reserved(),
1007          dcr->VolCatInfo.VolCatStatus,
1008          dcr->VolumeName);
1009    /* Limit max concurrent jobs on this drive */
1010    if (dev->max_concurrent_jobs > 0 && (int)dev->max_concurrent_jobs <=
1011               (dev->num_writers + dev->num_reserved())) {
1012       /* Max Concurrent Jobs depassed or already reserved */
1013       Mmsg(jcr->errmsg, _("3609 JobId=%u Max concurrent jobs=%d exceeded on %s device %s.\n"),
1014             (uint32_t)jcr->JobId, dev->max_concurrent_jobs,
1015              dev->print_type(), dev->print_name());
1016       queue_reserve_message(jcr);
1017       Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
1018       return false;
1019    }
1020    if (strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0) {
1021       return true;
1022    }
1023    if (!dev->allow_maxbytes_concurrency(dcr)) {
1024       queue_reserve_message(jcr);
1025       Dmsg1(dbglvl, "reserve dev failed: %s", jcr->errmsg);
1026       return false;                /* wait */
1027    }
1028       
1029    if (dcr->VolCatInfo.VolCatMaxJobs > 0 && (int)dcr->VolCatInfo.VolCatMaxJobs <=
1030         (dev->num_writers + dev->num_reserved())) {
1031       /* Max Job Vols depassed or already reserved */
1032       Mmsg(jcr->errmsg, _("3611 JobId=%u Volume max jobs=%d exceeded on %s device %s.\n"),
1033             (uint32_t)jcr->JobId, dcr->VolCatInfo.VolCatMaxJobs,
1034             dev->print_type(), dev->print_name());
1035       queue_reserve_message(jcr);
1036       Dmsg1(dbglvl, "reserve dev failed: %s", jcr->errmsg);
1037       return false;                /* wait */
1038    }
1039    return true;
1040 }
1041
1042
1043 static int is_pool_ok(DCR *dcr)
1044 {
1045    DEVICE *dev = dcr->dev;
1046    JCR *jcr = dcr->jcr;
1047
1048    if (dev->num_writers >= 0) {
1049       /* Now check if we want the same Pool and pool type */
1050       if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1051           strcmp(dev->pool_type, dcr->pool_type) == 0) {
1052          /* OK, compatible device */
1053          Dmsg1(dbglvl, "OK dev: %s pool matches\n", dev->print_name());
1054          return 1;
1055       }
1056    } else if (dev->num_reserved() > 0) {
1057       if (strcmp(dev->reserved_pool_name, dcr->pool_name) == 0) {
1058          /* OK, compatible device */
1059          Dmsg1(dbglvl, "OK dev: %s pool matches\n", dev->print_name());
1060          return 1;
1061       }
1062    }
1063    /* Drive Pool not suitable for us */
1064    Mmsg(jcr->errmsg, _(
1065 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on %s device %s.\n"),
1066          (uint32_t)jcr->JobId, dcr->pool_name, dev->pool_name,
1067           dev->num_reserved(), dev->print_type(), dev->print_name());
1068    Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
1069    queue_reserve_message(jcr);
1070    return 0;
1071 }
1072
1073 /*
1074  * Returns: 1 if drive can be reserved
1075  *          0 if we should wait
1076  *         -1 on error or impossibility
1077  */
1078 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
1079 {
1080    DEVICE *dev = dcr->dev;
1081    JCR *jcr = dcr->jcr;
1082
1083    Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1084          rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1085          rctx.autochanger_only, rctx.any_drive);
1086
1087    /* Check for max jobs on this Volume */
1088    if (!is_max_jobs_ok(dcr)) {
1089       return 0;
1090    }
1091
1092    /* setting any_drive overrides PreferMountedVols flag */
1093    if (!rctx.any_drive) {
1094       /*
1095        * When PreferMountedVols is set, we keep track of the
1096        *  drive in use that has the least number of writers, then if
1097        *  no unmounted drive is found, we try that drive. This
1098        *  helps spread the load to the least used drives.
1099        */
1100       if (rctx.try_low_use_drive && dev == rctx.low_use_drive &&
1101          is_pool_ok(dcr)) {
1102          Dmsg2(dbglvl, "OK dev=%s == low_drive=%s.\n",
1103             dev->print_name(), rctx.low_use_drive->print_name());
1104          bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1105          bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1106          return 1;
1107       }
1108       /* If he wants a free drive, but this one is busy, no go */
1109       if (!rctx.PreferMountedVols && dev->is_busy()) {
1110          Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but %s device %s is busy.\n"),
1111             jcr->JobId, dev->print_type(), dev->print_name());
1112          queue_reserve_message(jcr);
1113          Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
1114          return 0;
1115       }
1116
1117       /* Check for prefer mounted volumes */
1118       if (rctx.PreferMountedVols && !dev->vol && dev->is_tape()) {
1119          Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but %s device %s has no Volume.\n"),
1120             jcr->JobId, dev->print_type(), dev->print_name());
1121          queue_reserve_message(jcr);
1122          Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
1123          return 0;                 /* No volume mounted */
1124       }
1125
1126       /* Check for exact Volume name match */
1127       /* ***FIXME*** for Disk, we can accept any volume that goes with this
1128        *    drive.
1129        */
1130       if (rctx.exact_match && rctx.have_volume) {
1131          bool ok;
1132          Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1133                rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1134                rctx.autochanger_only, rctx.any_drive);
1135          Dmsg4(dbglvl, "have_vol=%d have=%s resvol=%s want=%s\n",
1136                   rctx.have_volume, dev->VolHdr.VolumeName,
1137                   dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1138          ok = strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) == 0 ||
1139                  (dev->vol && strcmp(dev->vol->vol_name, rctx.VolumeName) == 0);
1140          if (!ok) {
1141             Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on %s device %s.\n"),
1142                jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
1143                dev->print_type(), dev->print_name());
1144             queue_reserve_message(jcr);
1145             Dmsg3(dbglvl, "not OK: dev have=%s resvol=%s want=%s\n",
1146                   dev->VolHdr.VolumeName, dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1147             return 0;
1148          }
1149          if (!dcr->can_i_use_volume()) {
1150             return 0;              /* fail if volume on another drive */
1151          }
1152       }
1153    }
1154
1155    /* Check for unused autochanger drive */
1156    if (rctx.autochanger_only && !dev->is_busy() &&
1157        dev->VolHdr.VolumeName[0] == 0 && is_pool_ok(dcr)) {
1158       /* Device is available but not yet reserved, reserve it for us */
1159       Dmsg1(dbglvl, "OK Res Unused autochanger %s.\n", dev->print_name());
1160       bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1161       bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1162       return 1;                       /* reserve drive */
1163    }
1164
1165    /*
1166     * Handle the case that there are no writers
1167     */
1168    if (dev->num_writers == 0) {
1169       /* Now check if there are any reservations on the drive */
1170       if (dev->num_reserved()) {
1171          return is_pool_ok(dcr);
1172       } else if (dev->can_append()) {
1173          if (is_pool_ok(dcr)) {
1174             return 1;
1175          } else {
1176             /* Changing pool, unload old tape if any in drive */
1177             Dmsg0(dbglvl, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
1178             /* ***FIXME*** use set_unload() */
1179             unload_autochanger(dcr, -1);
1180          }
1181       }
1182       /* Device is available but not yet reserved, reserve it for us */
1183       Dmsg1(dbglvl, "OK Dev avail reserved %s\n", dev->print_name());
1184       bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1185       bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1186       return 1;                       /* reserve drive */
1187    }
1188
1189    /*
1190     * Check if the device is in append mode with writers (i.e.
1191     *  available if pool is the same).
1192     */
1193    if (dev->can_append() || dev->num_writers > 0 || dev->num_reserved() > 0) {
1194       return is_pool_ok(dcr);
1195    } else {
1196       Pmsg1(000, _("Logic error!!!! JobId=%u Should not get here.\n"), (int)jcr->JobId);
1197       Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! %s device %s Should not get here.\n"),
1198             jcr->JobId, dev->print_type(), dev->print_name());
1199       queue_reserve_message(jcr);
1200       Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1201       return -1;                      /* error, should not get here */
1202    }
1203    Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve %s device %s.\n"),
1204          jcr->JobId, dev->print_type(), dev->print_name());
1205    queue_reserve_message(jcr);
1206    Dmsg1(dbglvl, "Failed: No reserve %s\n", dev->print_name());
1207    return 0;
1208 }
1209
1210
1211 /*
1212  * Queue a reservation error or failure message for this jcr
1213  */
1214 static void queue_reserve_message(JCR *jcr)
1215 {
1216    int i;
1217    alist *msgs;
1218    char *msg;
1219
1220    jcr->lock();
1221
1222    msgs = jcr->reserve_msgs;
1223    if (!msgs) {
1224       goto bail_out;
1225    }
1226    /*
1227     * Look for duplicate message.  If found, do
1228     * not insert
1229     */
1230    for (i=msgs->size()-1; i >= 0; i--) {
1231       msg = (char *)msgs->get(i);
1232       if (!msg) {
1233          goto bail_out;
1234       }
1235       /* Comparison based on 4 digit message number */
1236       if (strncmp(msg, jcr->errmsg, 4) == 0) {
1237          goto bail_out;
1238       }
1239    }
1240    /* Message unique, so insert it */
1241    jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1242
1243 bail_out:
1244    jcr->unlock();
1245 }
1246
1247 /*
1248  * Send any reservation messages queued for this jcr
1249  */
1250 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1251 {
1252    int i;
1253    alist *msgs;
1254    char *msg;
1255
1256    jcr->lock();
1257    msgs = jcr->reserve_msgs;
1258    if (!msgs || msgs->size() == 0) {
1259       goto bail_out;
1260    }
1261    for (i=msgs->size()-1; i >= 0; i--) {
1262       msg = (char *)msgs->get(i);
1263       if (msg) {
1264          sendit("   ", 3, arg);
1265          sendit(msg, strlen(msg), arg);
1266       } else {
1267          break;
1268       }
1269    }
1270
1271 bail_out:
1272    jcr->unlock();
1273 }
1274
1275 /*
1276  * Pop and release any reservations messages
1277  */
1278 static void pop_reserve_messages(JCR *jcr)
1279 {
1280    alist *msgs;
1281    char *msg;
1282
1283    jcr->lock();
1284    msgs = jcr->reserve_msgs;
1285    if (!msgs) {
1286       goto bail_out;
1287    }
1288    while ((msg = (char *)msgs->pop())) {
1289       free(msg);
1290    }
1291 bail_out:
1292    jcr->unlock();
1293 }
1294
1295 /*
1296  * Also called from acquire.c
1297  */
1298 void release_reserve_messages(JCR *jcr)
1299 {
1300    pop_reserve_messages(jcr);
1301    jcr->lock();
1302    if (!jcr->reserve_msgs) {
1303       goto bail_out;
1304    }
1305    delete jcr->reserve_msgs;
1306    jcr->reserve_msgs = NULL;
1307
1308 bail_out:
1309    jcr->unlock();
1310 }