X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Freserve.c;h=a7763839bf1a6bf084c6218d80821635e9b15a35;hb=22a5d43f2bf48e4d5c056dc17bd7cff90d84290e;hp=41c5797d4b02dbc9f6e59b388f46ddd02d0bf7ff;hpb=fe3cc7407f557f6881075dd6e546fef71a5afdee;p=bacula%2Fbacula diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index 41c5797d4b..a7763839bf 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -242,7 +242,7 @@ void free_unused_volume(DCR *dcr) if (vol->dcr == dcr && (vol->dev == NULL || strcmp(vol->vol_name, vol->dev->VolHdr.VolumeName) != 0)) { vol_list->remove(vol); - Dmsg1(100, "free_unused_olume %s\n", vol->vol_name); + Dmsg1(100, "free_unused_volume %s\n", vol->vol_name); free(vol->vol_name); free(vol); break; @@ -254,18 +254,27 @@ void free_unused_volume(DCR *dcr) /* * List Volumes -- this should be moved to status.c */ -void list_volumes(BSOCK *user) +void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg) { VOLRES *vol; + char *msg; + int len; + + msg = (char *)get_pool_memory(PM_MESSAGE); + P(vol_list_lock); for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) { if (vol->dev) { - bnet_fsend(user, "%s on device %s\n", vol->vol_name, vol->dev->print_name()); + len = Mmsg(msg, "%s on device %s\n", vol->vol_name, vol->dev->print_name()); + sendit(msg, len, arg); } else { - bnet_fsend(user, "%s\n", vol->vol_name); + len = Mmsg(msg, "%s\n", vol->vol_name); + sendit(msg, len, arg); } } V(vol_list_lock); + + free_pool_memory(msg); } /* Create the Volume list */ @@ -340,6 +349,7 @@ static bool use_storage_cmd(JCR *jcr) RCTX rctx; char *msg; alist *msgs; + alist *dirstore; memset(&rctx, 0, sizeof(RCTX)); rctx.jcr = jcr; @@ -347,7 +357,8 @@ static bool use_storage_cmd(JCR *jcr) * If there are multiple devices, the director sends us * use_device for each device that it wants to use. */ - jcr->dirstore = New(alist(10, not_owned_by_alist)); + dirstore = New(alist(10, not_owned_by_alist)); +// Dmsg2(000, "dirstore=%p JobId=%u\n", dirstore, jcr->JobId); msgs = jcr->reserve_msgs = New(alist(10, not_owned_by_alist)); do { Dmsg1(100, "msg); @@ -357,12 +368,18 @@ static bool use_storage_cmd(JCR *jcr) if (!ok) { break; } + if (append) { + jcr->write_store = dirstore; + } else { + jcr->read_store = dirstore; + } + rctx.append = append; unbash_spaces(store_name); unbash_spaces(media_type); unbash_spaces(pool_name); unbash_spaces(pool_type); store = new DIRSTORE; - jcr->dirstore->append(store); + dirstore->append(store); memset(store, 0, sizeof(DIRSTORE)); store->device = New(alist(10)); bstrncpy(store->name, store_name, sizeof(store->name)); @@ -387,7 +404,7 @@ static bool use_storage_cmd(JCR *jcr) /* This loop is debug code and can be removed */ /* ***FIXME**** remove after 1.38 release */ char *device_name; - foreach_alist(store, jcr->dirstore) { + foreach_alist(store, dirstore) { Dmsg5(110, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n", store->name, store->media_type, store->pool_name, store->pool_type, store->append); @@ -409,9 +426,10 @@ static bool use_storage_cmd(JCR *jcr) */ if (ok) { bool first = true; /* print wait message once */ + bool fail = false; rctx.notify_dir = true; - for ( ; !job_canceled(jcr); ) { - lock_reservations(); /* only one thread at a time */ + lock_reservations(); + for ( ; !fail && !job_canceled(jcr); ) { while ((msg = (char *)msgs->pop())) { free(msg); } @@ -473,48 +491,41 @@ static bool use_storage_cmd(JCR *jcr) if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } - /* Unlock before possible wait */ + /* Keep reservations locked *except* during wait_for_device() */ unlock_reservations(); if (!rctx.suitable_device || !wait_for_device(jcr, first)) { Dmsg0(100, "Fail. !suitable_device || !wait_for_device\n"); - break; /* Get out, failure ... */ + fail = true; } + lock_reservations(); first = false; bnet_sig(dir, BNET_HEARTBEAT); /* Inform Dir that we are alive */ } - /* Note if !ok then search_lock is already cleared */ - if (ok) { - unlock_reservations(); - goto all_done; - } - - /* - * If we get here, there are no suitable devices available, which - * means nothing configured. If a device is suitable but busy - * with another Volume, we will not come here. - */ - if (verbose) { + unlock_reservations(); + if (!ok) { + /* + * If we get here, there are no suitable devices available, which + * means nothing configured. If a device is suitable but busy + * with another Volume, we will not come here. + */ unbash_spaces(dir->msg); pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg); - } - Jmsg(jcr, M_FATAL, 0, _("\n" - " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"), - dev_name.c_str(), media_type.c_str()); - bnet_fsend(dir, NO_device, dev_name.c_str()); + Jmsg(jcr, M_FATAL, 0, _("\n" + " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"), + dev_name.c_str(), media_type.c_str()); + bnet_fsend(dir, NO_device, dev_name.c_str()); - Dmsg1(100, ">dird: %s", dir->msg); + Dmsg1(100, ">dird: %s", dir->msg); + } } else { unbash_spaces(dir->msg); pm_strcpy(jcr->errmsg, dir->msg); - if (verbose) { - Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg); - } + Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg); bnet_fsend(dir, BAD_use, jcr->errmsg); Dmsg1(100, ">dird: %s", dir->msg); } -all_done: release_msgs(jcr); return ok; } @@ -544,7 +555,13 @@ bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx) bool ok; DIRSTORE *store; char *device_name; + alist *dirstore; + if (rctx.append) { + dirstore = jcr->write_store; + } else { + dirstore = jcr->read_store; + } /* * For each storage device that the user specified, we * search and see if there is a resource for that device. @@ -553,7 +570,7 @@ bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx) rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device, rctx.autochanger_only); ok = false; - foreach_alist(store, jcr->dirstore) { + foreach_alist(store, dirstore) { rctx.store = store; foreach_alist(device_name, store->device) { int stat; @@ -748,7 +765,10 @@ static bool reserve_device_for_read(DCR *dcr) ASSERT(dcr); + /* Get locks in correct order */ + unlock_reservations(); P(dev->mutex); + lock_reservations(); if (is_device_unmounted(dev)) { Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name()); @@ -891,7 +911,7 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx) /* Check for prefer mounted volumes */ if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) { - Mmsg(jcr->errmsg, _("3606 JobId=%u wants mounted, but drive %s has no Volume.\n"), + Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"), jcr->JobId, dev->print_name()); queue_reserve_message(jcr); Dmsg1(110, "failed: want mounted -- no vol JobId=%u\n", jcr->JobId); @@ -980,7 +1000,7 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx) return 1; } else { /* Drive Pool not suitable for us */ - Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" on drive %s.\n"), + Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"), jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name()); queue_reserve_message(jcr); Dmsg2(110, "failed: busy num_writers>0, can_append, pool=%s wanted=%s\n", @@ -1035,7 +1055,7 @@ static void queue_reserve_message(JCR *jcr) /* * Send any reservation messages queued for this jcr */ -void send_drive_reserve_messages(JCR *jcr, BSOCK *user) +void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg) { int i; alist *msgs; @@ -1050,7 +1070,8 @@ void send_drive_reserve_messages(JCR *jcr, BSOCK *user) for (i=msgs->size()-1; i >= 0; i--) { msg = (char *)msgs->get(i); if (msg) { - bnet_fsend(user, " %s", msg); + sendit(" ", 3, arg); + sendit(msg, strlen(msg), arg); } else { break; }