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