X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Faskdir.c;h=685b74f43ddddde73983fb83ae9a1c8f24dac611;hb=217e5ed47147cd420ed0799a96868a561bfd6b57;hp=e28c7b3bfaecd3958aaea7f3a749864d18d80e7c;hpb=f861cd59cdef107600fb317a92ab4cca01aef74e;p=bacula%2Fbacula diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index e28c7b3bfa..685b74f43d 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -1,22 +1,14 @@ -/* - * Subroutines to handle Catalog reqests sent to the Director - * Reqests/commands from the Director are handled in dircmd.c - * - * Kern Sibbald, December 2000 - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2007 Free Software Foundation Europe e.V. + Copyright (C) 2000-2008 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. This program is Free Software; you can redistribute it and/or modify it under the terms of version two of the GNU General Public - License as published by the Free Software Foundation plus additions - that are listed in the file LICENSE. + License as published by the Free Software Foundation and included + in the file LICENSE. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -28,11 +20,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Bacula® is a registered trademark of John Walker. + Bacula® is a registered trademark of Kern Sibbald. The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Subroutines to handle Catalog reqests sent to the Director + * Reqests/commands from the Director are handled in dircmd.c + * + * Kern Sibbald, December 2000 + * + * Version $Id$ + */ #include "bacula.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ @@ -42,7 +42,7 @@ static char Find_media[] = "CatReq Job=%s FindMedia=%d pool_name=%s media_type static char Get_Vol_Info[] = "CatReq Job=%s GetVolInfo VolName=%s write=%d\n"; static char Update_media[] = "CatReq Job=%s UpdateMedia VolName=%s" " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%s VolMounts=%u" - " VolErrors=%u VolWrites=%u MaxVolBytes=%s EndTime=%d VolStatus=%s" + " VolErrors=%u VolWrites=%u MaxVolBytes=%s EndTime=%s VolStatus=%s" " Slot=%d relabel=%d InChanger=%d VolReadTime=%s VolWriteTime=%s" " VolFirstWritten=%s VolParts=%u\n"; static char Create_job_media[] = "CatReq Job=%s CreateJobMedia" @@ -98,7 +98,7 @@ bool dir_update_device(JCR *jcr, DEVICE *dev) } else { pm_strcpy(ChangerName, "*"); } - ok =bnet_fsend(dir, Device_update, + ok = dir->fsend(Device_update, jcr->Job, dev_name.c_str(), dev->can_append()!=0, @@ -125,7 +125,7 @@ bool dir_update_changer(JCR *jcr, AUTOCHANGER *changer) pm_strcpy(MediaType, device->media_type); bash_spaces(MediaType); /* This is mostly to indicate that we are here */ - ok = bnet_fsend(dir, Device_update, + ok = dir->fsend(Device_update, jcr->Job, dev_name.c_str(), /* Changer name */ 0, 0, 0, /* append, read, num_writers */ @@ -148,7 +148,7 @@ bool dir_update_changer(JCR *jcr, AUTOCHANGER *changer) */ bool dir_send_job_status(JCR *jcr) { - return bnet_fsend(jcr->dir_bsock, Job_status, jcr->Job, jcr->JobStatus); + return jcr->dir_bsock->fsend(Job_status, jcr->Job, jcr->JobStatus); } /* @@ -173,7 +173,7 @@ static bool do_get_volume_info(DCR *dcr) int n; int32_t InChanger; - if (bnet_recv(dir) <= 0) { + if (dir->recv() <= 0) { Dmsg0(200, "getvolname error bnet_recv\n"); Mmsg(jcr->errmsg, _("Network error on bnet_recv in req_vol_info.\n")); return false; @@ -191,7 +191,8 @@ static bool do_get_volume_info(DCR *dcr) &vol.EndFile, &vol.EndBlock, &vol.VolCatParts, &vol.LabelType, &vol.VolMediaId); if (n != 22) { - Dmsg2(100, "Bad response from Dir fields=%d: %s", n, dir->msg); + Dmsg3(100, "Bad response from Dir fields=%d, len=%d: %s", + n, dir->msglen, dir->msg); Mmsg(jcr->errmsg, _("Error getting Volume info: %s"), dir->msg); return false; } @@ -224,9 +225,9 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) P(vol_info_mutex); bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName)); bash_spaces(dcr->VolCatInfo.VolCatName); - bnet_fsend(dir, Get_Vol_Info, jcr->Job, dcr->VolCatInfo.VolCatName, + dir->fsend(Get_Vol_Info, jcr->Job, dcr->VolCatInfo.VolCatName, writing==GET_VOL_INFO_FOR_WRITE?1:0); - Dmsg1(100, ">dird: %s", dir->msg); + Dmsg1(100, ">dird %s", dir->msg); unbash_spaces(dcr->VolCatInfo.VolCatName); bool ok = do_get_volume_info(dcr); V(vol_info_mutex); @@ -237,8 +238,12 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) /* * Get info on the next appendable volume in the Director's database - * Returns: true on success - * false on failure + * + * Returns: true on success dcr->VolumeName is volume + * reserve_volume() called on Volume name + * false on failure dcr->VolumeName[0] == 0 + * also sets dcr->found_in_use if at least one + * in use volume was found. * * Volume information returned in dcr * @@ -247,50 +252,64 @@ bool dir_find_next_appendable_volume(DCR *dcr) { JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; - bool found = false; + bool rtn; + char lastVolume[MAX_NAME_LENGTH]; + + Dmsg2(200, "dir_find_next_appendable_volume: reserved=%d Vol=%s\n", + dcr->is_reserved(), dcr->VolumeName); - Dmsg0(200, "dir_find_next_appendable_volume\n"); /* * Try the twenty oldest or most available volumes. Note, * the most available could already be mounted on another * drive, so we continue looking for a not in use Volume. */ - lock_reservations(); + lock_volumes(); P(vol_info_mutex); + dcr->clear_found_in_use(); + lastVolume[0] = 0; for (int vol_index=1; vol_index < 20; vol_index++) { bash_spaces(dcr->media_type); bash_spaces(dcr->pool_name); - bnet_fsend(dir, Find_media, jcr->Job, vol_index, dcr->pool_name, dcr->media_type); + dir->fsend(Find_media, jcr->Job, vol_index, dcr->pool_name, dcr->media_type); unbash_spaces(dcr->media_type); unbash_spaces(dcr->pool_name); - Dmsg1(100, ">dird: %s", dir->msg); - bool ok = do_get_volume_info(dcr); - if (ok) { - if (dcr->any_volume || !is_volume_in_use(dcr)) { - found = true; + Dmsg1(100, ">dird %s", dir->msg); + if (do_get_volume_info(dcr)) { + /* Give up if we get the same volume name twice */ + if (lastVolume[0] && strcmp(lastVolume, dcr->VolumeName) == 0) { + Dmsg1(100, "Got same vol = %s\n", lastVolume); break; + } + bstrncpy(lastVolume, dcr->VolumeName, sizeof(lastVolume)); + if (dcr->can_i_use_volume()) { + Dmsg1(100, "Call reserve_volume. Vol=%s\n", dcr->VolumeName); + if (reserve_volume(dcr, dcr->VolumeName) == NULL) { + Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName, + dcr->dev->print_name()); + continue; + } + Dmsg1(100, "dir_find_next_appendable_volume return true. vol=%s\n", + dcr->VolumeName); + rtn = true; + goto get_out; } else { Dmsg1(100, "Volume %s is in use.\n", dcr->VolumeName); + /* If volume is not usable, it is in use by someone else */ + dcr->set_found_in_use(); continue; } - } else { - Dmsg2(100, "No vol. index %d return false. dev=%s\n", vol_index, - dcr->dev->print_name()); - found = false; - break; } + Dmsg2(100, "No vol. index %d return false. dev=%s\n", vol_index, + dcr->dev->print_name()); + break; } - if (found) { - Dmsg0(400, "dir_find_next_appendable_volume return true\n"); - new_volume(dcr, dcr->VolumeName); /* reserve volume */ - V(vol_info_mutex); - unlock_reservations(); - return true; - } + rtn = false; dcr->VolumeName[0] = 0; + +get_out: V(vol_info_mutex); - unlock_reservations(); - return false; + unlock_volumes(); + return rtn; } @@ -299,14 +318,13 @@ bool dir_find_next_appendable_volume(DCR *dcr) * back to the director. The information comes from the * dev record. */ -bool dir_update_volume_info(DCR *dcr, bool label) +bool dir_update_volume_info(DCR *dcr, bool label, bool update_LastWritten) { JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; DEVICE *dev = dcr->dev; - time_t LastWritten = time(NULL); VOLUME_CAT_INFO *vol = &dev->VolCatInfo; - char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50]; + char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50]; int InChanger; bool ok = false; POOL_MEM VolumeName; @@ -329,21 +347,25 @@ bool dir_update_volume_info(DCR *dcr, bool label) if (label) { bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus)); } +// if (update_LastWritten) { + vol->VolLastWritten = time(NULL); +// } pm_strcpy(VolumeName, vol->VolCatName); bash_spaces(VolumeName); InChanger = vol->InChanger; - bnet_fsend(dir, Update_media, jcr->Job, + dir->fsend(Update_media, jcr->Job, VolumeName.c_str(), vol->VolCatJobs, vol->VolCatFiles, vol->VolCatBlocks, edit_uint64(vol->VolCatBytes, ed1), vol->VolCatMounts, vol->VolCatErrors, vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2), - LastWritten, vol->VolCatStatus, vol->Slot, label, + edit_uint64(vol->VolLastWritten, ed6), + vol->VolCatStatus, vol->Slot, label, InChanger, /* bool in structure */ edit_int64(vol->VolReadTime, ed3), edit_int64(vol->VolWriteTime, ed4), edit_uint64(vol->VolFirstWritten, ed5), vol->VolCatParts); - Dmsg1(100, ">dird: %s", dir->msg); + Dmsg1(100, ">dird %s", dir->msg); /* Do not lock device here because it may be locked from label */ if (!do_get_volume_info(dcr)) { @@ -352,7 +374,7 @@ bool dir_update_volume_info(DCR *dcr, bool label) vol->VolCatName, jcr->errmsg); goto bail_out; } - Dmsg1(420, "get_volume_info(): %s", dir->msg); + Dmsg1(420, "get_volume_info() %s", dir->msg); /* Update dev Volume info in case something changed (e.g. expired) */ dev->VolCatInfo = dcr->VolCatInfo; ok = true; @@ -381,20 +403,20 @@ bool dir_create_jobmedia_record(DCR *dcr) } dcr->WroteVol = false; - bnet_fsend(dir, Create_job_media, jcr->Job, + dir->fsend(Create_job_media, jcr->Job, dcr->VolFirstIndex, dcr->VolLastIndex, dcr->StartFile, dcr->EndFile, dcr->StartBlock, dcr->EndBlock, dcr->Copy, dcr->Stripe, - edit_uint64(dcr->dev->VolCatInfo.VolMediaId, ed1)); - Dmsg1(100, ">dird: %s", dir->msg); - if (bnet_recv(dir) <= 0) { + edit_uint64(dcr->VolMediaId, ed1)); + Dmsg1(100, ">dird %s", dir->msg); + if (dir->recv() <= 0) { Dmsg0(190, "create_jobmedia error bnet_recv\n"); Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: ERR=%s\n"), - bnet_strerror(dir)); + dir->bstrerror()); return false; } - Dmsg1(100, "msg); + Dmsg1(100, "msg); if (strcmp(dir->msg, OK_create) != 0) { Dmsg1(130, "Bad response from Dir: %s\n", dir->msg); Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: %s\n"), dir->msg); @@ -417,9 +439,10 @@ bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) return true; #endif - dir->msglen = sprintf(dir->msg, FileAttributes, jcr->Job); - dir->msg = check_pool_memory_size(dir->msg, dir->msglen + - sizeof(DEV_RECORD) + rec->data_len); + dir->msg = check_pool_memory_size(dir->msg, sizeof(FileAttributes) + + MAX_NAME_LENGTH + sizeof(DEV_RECORD) + rec->data_len + 1); + dir->msglen = bsnprintf(dir->msg, sizeof(FileAttributes) + + MAX_NAME_LENGTH + 1, FileAttributes, jcr->Job); ser_begin(dir->msg + dir->msglen, 0); ser_uint32(rec->VolSessionId); ser_uint32(rec->VolSessionTime); @@ -428,8 +451,8 @@ bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) ser_uint32(rec->data_len); ser_bytes(rec->data, rec->data_len); dir->msglen = ser_length(dir->msg); - Dmsg1(1800, ">dird: %s\n", dir->msg); /* Attributes */ - return bnet_send(dir); + Dmsg1(1800, ">dird %s\n", dir->msg); /* Attributes */ + return dir->send(); } @@ -459,7 +482,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) bool got_vol = false; Dmsg0(400, "enter dir_ask_sysop_to_create_appendable_volume\n"); - ASSERT(dev->dev_blocked); + ASSERT(dev->blocked()); for ( ;; ) { if (job_canceled(jcr)) { Mmsg(dev->errmsg, @@ -468,23 +491,23 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg); return false; } - P(dev->mutex); got_vol = dir_find_next_appendable_volume(dcr); /* get suggested volume */ - V(dev->mutex); if (got_vol) { - return true; + goto get_out; } else { if (stat == W_TIMEOUT || stat == W_MOUNT) { - Jmsg(jcr, M_MOUNT, 0, _( + Mmsg(dev->errmsg, _( "Job %s waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" -" Media type: %s\n" -" Pool: %s\n"), +" Pool: %s\n" +" Media type: %s\n"), jcr->Job, dev->print_name(), - dcr->media_type, - dcr->pool_name); + dcr->pool_name, + dcr->media_type); + Jmsg(jcr, M_MOUNT, 0, "%s", dev->errmsg); + Dmsg1(100, "%s", dev->errmsg); } } @@ -516,6 +539,8 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) } Dmsg1(100, "Someone woke me for device %s\n", dev->print_name()); } + +get_out: set_jcr_job_status(jcr, JS_Running); dir_send_job_status(jcr); Dmsg0(100, "leave dir_ask_sysop_to_mount_create_appendable_volume\n"); @@ -534,7 +559,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) * Note, must create dev->errmsg on error return. * */ -bool dir_ask_sysop_to_mount_volume(DCR *dcr) +bool dir_ask_sysop_to_mount_volume(DCR *dcr, int mode) { int stat = W_TIMEOUT; DEVICE *dev = dcr->dev; @@ -545,7 +570,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr) Mmsg0(dev->errmsg, _("Cannot request another volume: no volume name given.\n")); return false; } - ASSERT(dev->dev_blocked); + ASSERT(dev->blocked()); for ( ;; ) { if (job_canceled(jcr)) { Mmsg(dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device %s.\n"), @@ -563,8 +588,26 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr) * Otherwise skip it. */ if (!dev->poll && (stat == W_TIMEOUT || stat == W_MOUNT)) { - Jmsg(jcr, M_MOUNT, 0, _("Please mount Volume \"%s\" on Storage Device %s for Job %s\n"), - dcr->VolumeName, dev->print_name(), jcr->Job); + char *msg; + if (mode == ST_APPEND) { + msg = _("Please mount Volume \"%s\" or label a new one for:\n" + " Job: %s\n" + " Storage: %s\n" + " Pool: %s\n" + " Media type: %s\n"); + } else { + msg = _("Please mount Volume \"%s\" for:\n" + " Job: %s\n" + " Storage: %s\n" + " Pool: %s\n" + " Media type: %s\n"); + } + Jmsg(jcr, M_MOUNT, 0, msg, + dcr->VolumeName, + jcr->Job, + dev->print_name(), + dcr->pool_name, + dcr->media_type); Dmsg3(400, "Mount \"%s\" on device \"%s\" for Job %s\n", dcr->VolumeName, dev->print_name(), jcr->Job); } @@ -577,7 +620,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr) if (dev->poll) { Dmsg1(400, "Poll timeout in mount vol on device %s\n", dev->print_name()); Dmsg1(400, "Blocked=%s\n", dev->print_blocked()); - return true; + goto get_out; } if (stat == W_TIMEOUT) { @@ -599,6 +642,8 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr) Dmsg1(400, "Someone woke me for device %s\n", dev->print_name()); break; } + +get_out: set_jcr_job_status(jcr, JS_Running); dir_send_job_status(jcr); Dmsg0(400, "leave dir_ask_sysop_to_mount_volume\n");