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