X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Faskdir.c;h=4080802edbf1f9bc7c73c4c72ed356dffd1c8af9;hb=85319cb5b8d9b163972aa8deb764e440824dc72a;hp=926e0db90c03d6f89ed8eae54cc1f730c0cc58a3;hpb=48091ff92c6a2bbc0e78722ffe596fb162b642d0;p=bacula%2Fbacula diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index 926e0db90c..4080802edb 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -54,12 +54,12 @@ static char OK_media[] = "1000 OK VolName=%127s VolJobs=%u VolFiles=%u" static char OK_create[] = "1000 OK CreateJobMedia\n"; /* Forward referenced functions */ -static int wait_for_sysop(JCR *jcr, DEVICE *dev); +static int wait_for_sysop(DCR *dcr); /* * Send current JobStatus to Director */ -int dir_send_job_status(JCR *jcr) +bool dir_send_job_status(JCR *jcr) { return bnet_fsend(jcr->dir_bsock, Job_status, jcr->Job, jcr->JobStatus); } @@ -70,13 +70,13 @@ int dir_send_job_status(JCR *jcr) * and * dir_find_next_appendable_volume() * - * Returns: 1 on success and vol info in jcr->VolCatInfo - * 0 on failure + * Returns: true on success and vol info in jcr->VolCatInfo + * false on failure */ -static int do_get_volume_info(JCR *jcr) +static bool do_get_volume_info(DCR *dcr) { + JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; - DCR *dcr = jcr->dcr; VOLUME_CAT_INFO vol; int n; int InChanger; @@ -85,8 +85,8 @@ static int do_get_volume_info(JCR *jcr) dcr->VolumeName[0] = 0; /* No volume */ if (bnet_recv(dir) <= 0) { Dmsg0(200, "getvolname error bnet_recv\n"); - Mmsg(&jcr->errmsg, _("Network error on bnet_recv in req_vol_info.\n")); - return 0; + Mmsg(jcr->errmsg, _("Network error on bnet_recv in req_vol_info.\n")); + return false; } memset(&vol, 0, sizeof(vol)); Dmsg1(200, "Get vol info=%s\n", dir->msg); @@ -100,8 +100,8 @@ static int do_get_volume_info(JCR *jcr) &InChanger, &vol.VolReadTime, &vol.VolWriteTime); if (n != 17) { Dmsg2(100, "Bad response from Dir fields=%d: %s\n", n, dir->msg); - Mmsg(&jcr->errmsg, _("Error getting Volume info: %s\n"), dir->msg); - return 0; + Mmsg(jcr->errmsg, _("Error getting Volume info: %s\n"), dir->msg); + return false; } vol.InChanger = InChanger; /* bool in structure */ unbash_spaces(vol.VolCatName); @@ -112,22 +112,23 @@ static int do_get_volume_info(JCR *jcr) Dmsg2(200, "do_reqest_vol_info got slot=%d Volume=%s\n", vol.Slot, vol.VolCatName); - return 1; + return true; } /* * Get Volume info for a specific volume from the Director's Database * - * Returns: 1 on success (not Director guarantees that Pool and MediaType - * are correct and VolStatus==Append or - * VolStatus==Recycle) - * 0 on failure + * Returns: true on success (not Director guarantees that Pool and MediaType + * are correct and VolStatus==Append or + * VolStatus==Recycle) + * false on failure * * Volume information returned in jcr */ -int dir_get_volume_info(JCR *jcr, enum get_vol_info_rw writing) +bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) { + JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; bstrncpy(jcr->VolCatInfo.VolCatName, jcr->VolumeName, sizeof(jcr->VolCatInfo.VolCatName)); @@ -135,28 +136,29 @@ int dir_get_volume_info(JCR *jcr, enum get_vol_info_rw writing) bash_spaces(jcr->VolCatInfo.VolCatName); bnet_fsend(dir, Get_Vol_Info, jcr->Job, jcr->VolCatInfo.VolCatName, writing==GET_VOL_INFO_FOR_WRITE?1:0); - return do_get_volume_info(jcr); + return do_get_volume_info(dcr); } /* * Get info on the next appendable volume in the Director's database - * Returns: 1 on success - * 0 on failure + * Returns: true on success + * false on failure * * Volume information returned in jcr * */ -int dir_find_next_appendable_volume(JCR *jcr) +bool dir_find_next_appendable_volume(DCR *dcr) { + JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; JCR *njcr; Dmsg0(200, "dir_find_next_appendable_volume\n"); for (int vol_index=1; vol_index < 3; vol_index++) { bnet_fsend(dir, Find_media, jcr->Job, vol_index); - if (do_get_volume_info(jcr)) { + if (do_get_volume_info(dcr)) { Dmsg2(200, "JobId=%d got possible Vol=%s\n", jcr->JobId, jcr->VolumeName); bool found = false; /* @@ -200,9 +202,11 @@ int dir_find_next_appendable_volume(JCR *jcr) * back to the director. The information comes from the * dev record. */ -int dir_update_volume_info(JCR *jcr, DEVICE *dev, int label) +bool dir_update_volume_info(DCR *dcr, bool label) { + JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; + DEVICE *dev = dcr->dev; time_t LastWritten = time(NULL); char ed1[50], ed2[50], ed3[50], ed4[50]; VOLUME_CAT_INFO *vol = &dev->VolCatInfo; @@ -210,15 +214,11 @@ int dir_update_volume_info(JCR *jcr, DEVICE *dev, int label) if (vol->VolCatName[0] == 0) { Jmsg0(jcr, M_ERROR, 0, _("NULL Volume name. This shouldn't happen!!!\n")); - return 0; + return false; } if (dev_state(dev, ST_READ)) { Jmsg0(jcr, M_ERROR, 0, _("Attempt to update_volume_info in read mode!!!\n")); - return 0; - } - if (!dev_state(dev, ST_LABEL)) { - Jmsg0(jcr, M_ERROR, 0, _("Attempt to update_volume_info on non-labeled Volume!!!\n")); - return 0; + return false; } Dmsg1(100, "Update cat VolFiles=%d\n", dev->file); @@ -242,26 +242,26 @@ int dir_update_volume_info(JCR *jcr, DEVICE *dev, int label) Dmsg1(120, "update_volume_info(): %s", dir->msg); unbash_spaces(vol->VolCatName); - if (!do_get_volume_info(jcr)) { + if (!do_get_volume_info(dcr)) { Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg); - return 0; + return false; } Dmsg1(120, "get_volume_info(): %s", dir->msg); /* Update dev Volume info in case something changed (e.g. expired) */ memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(dev->VolCatInfo)); - return 1; + return true; } /* * After writing a Volume, create the JobMedia record. */ -int dir_create_jobmedia_record(JCR *jcr) +bool dir_create_jobmedia_record(DCR *dcr) { + JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; - DCR *dcr = jcr->dcr; if (!dcr->WroteVol) { - return 1; /* nothing written to tape */ + return true; /* nothing written to tape */ } dcr->WroteVol = false; @@ -274,23 +274,24 @@ int dir_create_jobmedia_record(JCR *jcr) Dmsg0(190, "create_jobmedia error bnet_recv\n"); Jmsg(jcr, M_ERROR, 0, _("Error creating JobMedia record: ERR=%s\n"), bnet_strerror(dir)); - return 0; + return false; } Dmsg1(120, "Create_jobmedia: %s", dir->msg); if (strcmp(dir->msg, OK_create) != 0) { Dmsg1(130, "Bad response from Dir: %s\n", dir->msg); Jmsg(jcr, M_ERROR, 0, _("Error creating JobMedia record: %s\n"), dir->msg); - return 0; + return false; } - return 1; + return true; } /* * Update File Attribute data */ -int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) +bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { + JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; ser_declare; @@ -315,8 +316,8 @@ int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) * Entered with device blocked. * Leaves with device blocked. * - * Returns: 1 on success (operator issues a mount command) - * 0 on failure + * Returns: true on success (operator issues a mount command) + * false on failure * Note, must create dev->errmsg on error return. * * On success, jcr->VolumeName and jcr->VolCatInfo contain @@ -327,24 +328,26 @@ int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) * actually be mounted. The calling routine must read it and * verify the label. */ -int dir_ask_sysop_to_create_appendable_volume(JCR *jcr, DEVICE *dev) +bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { int stat = 0, jstat; bool unmounted; bool first = true; + DEVICE *dev = dcr->dev; + JCR *jcr = dcr->jcr; - Dmsg0(130, "enter dir_ask_sysop_to_create_appendable_volume\n"); + Dmsg0(200, "enter dir_ask_sysop_to_create_appendable_volume\n"); ASSERT(dev->dev_blocked); for ( ;; ) { if (job_canceled(jcr)) { - Mmsg(&dev->errmsg, + Mmsg(dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device \"%s\".\n"), jcr->Job, jcr->dev_name); Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg); - return 0; + return false; } /* First pass, we *know* there are no appendable volumes, so no need to call */ - if (!first && dir_find_next_appendable_volume(jcr)) { /* get suggested volume */ + if (!first && dir_find_next_appendable_volume(dcr)) { /* get suggested volume */ unmounted = (dev->dev_blocked == BST_UNMOUNTED) || (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); /* @@ -356,8 +359,8 @@ int dir_ask_sysop_to_create_appendable_volume(JCR *jcr, DEVICE *dev) if (!unmounted && ((jcr->VolumeName[0] && !dev_cap(dev, CAP_REM) && dev_cap(dev, CAP_LABEL)) || (jcr->VolumeName[0] && jcr->VolCatInfo.Slot))) { - Dmsg0(100, "Return 1 from mount without wait.\n"); - return 1; + Dmsg0(200, "Return 1 from mount without wait.\n"); + return true; } jstat = JS_WaitMount; if (!dev->poll) { @@ -365,7 +368,7 @@ int dir_ask_sysop_to_create_appendable_volume(JCR *jcr, DEVICE *dev) "Please mount Volume \"%s\" on Storage Device \"%s\" for Job %s\n" "Use \"mount\" command to release Job.\n"), jcr->VolumeName, jcr->dev_name, jcr->Job); - Dmsg3(190, "Mount %s on %s for Job %s\n", + Dmsg3(200, "Mount %s on %s for Job %s\n", jcr->VolumeName, jcr->dev_name, jcr->Job); } } else { @@ -388,7 +391,7 @@ Please use the \"label\" command to create a new Volume for:\n\ jcr->JobStatus = jstat; dir_send_job_status(jcr); - stat = wait_for_sysop(jcr, dev); + stat = wait_for_sysop(dcr); if (dev->poll) { Dmsg1(200, "Poll timeout in create append vol on device %s\n", dev_name(dev)); continue; @@ -396,29 +399,31 @@ Please use the \"label\" command to create a new Volume for:\n\ if (stat == ETIMEDOUT) { if (!double_dev_wait_time(dev)) { - Mmsg(&dev->errmsg, _("Gave up waiting to mount Storage Device \"%s\" for Job %s\n"), + Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device \"%s\" for Job %s\n"), dev_name(dev), jcr->Job); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); - Dmsg1(190, "Gave up waiting on device %s\n", dev_name(dev)); - return 0; /* exceeded maximum waits */ + Dmsg1(200, "Gave up waiting on device %s\n", dev_name(dev)); + return false; /* exceeded maximum waits */ } continue; } if (stat == EINVAL) { - Mmsg2(&dev->errmsg, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), - stat, strerror(stat)); + berrno be; + Mmsg2(dev->errmsg, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), + stat, be.strerror(stat)); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); - return 0; + return false; } if (stat != 0) { + berrno be; Jmsg(jcr, M_WARNING, 0, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), stat, - strerror(stat)); + be.strerror(stat)); } - Dmsg1(190, "Someone woke me for device %s\n", dev_name(dev)); + Dmsg1(200, "Someone woke me for device %s\n", dev_name(dev)); /* If no VolumeName, and cannot get one, try again */ if (jcr->VolumeName[0] == 0 && !job_canceled(jcr) && - !dir_find_next_appendable_volume(jcr)) { + !dir_find_next_appendable_volume(dcr)) { Jmsg(jcr, M_MOUNT, 0, _( "Someone woke me up, but I cannot find any appendable\n\ volumes for Job=%s.\n"), jcr->Job); @@ -439,8 +444,8 @@ volumes for Job=%s.\n"), jcr->Job); } set_jcr_job_status(jcr, JS_Running); dir_send_job_status(jcr); - Dmsg0(130, "leave dir_ask_sysop_to_mount_create_appendable_volume\n"); - return 1; + Dmsg0(200, "leave dir_ask_sysop_to_mount_create_appendable_volume\n"); + return true; } /* @@ -455,88 +460,79 @@ volumes for Job=%s.\n"), jcr->Job); * Note, must create dev->errmsg on error return. * */ -int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev) +bool dir_ask_sysop_to_mount_volume(DCR *dcr) { int stat = 0; - char *msg; + const char *msg; + DEVICE *dev = dcr->dev; + JCR *jcr = dcr->jcr; - Dmsg0(130, "enter dir_ask_sysop_to_mount_volume\n"); + Dmsg0(200, "enter dir_ask_sysop_to_mount_volume\n"); if (!jcr->VolumeName[0]) { - Mmsg0(&dev->errmsg, _("Cannot request another volume: no volume name given.\n")); + Mmsg0(dev->errmsg, _("Cannot request another volume: no volume name given.\n")); return 0; } ASSERT(dev->dev_blocked); for ( ;; ) { if (job_canceled(jcr)) { - Mmsg(&dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device \"%s\".\n"), + Mmsg(dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device \"%s\".\n"), jcr->Job, jcr->dev_name); - return 0; + return false; } -#ifdef needed - /* - * If we have a valid volume name and we are not - * removable media, return now, or if we have a - * Slot for an autochanger, otherwise wait - * for the operator to mount the media. - */ - if ((!dev_cap(dev, CAP_REM) && dev_cap(dev, CAP_LABEL)) || jcr->VolCatInfo.Slot) { - Dmsg0(100, "Return 1 from mount without wait.\n"); - return 1; - } -#endif - if (!dev->poll) { msg = _("Please mount"); Jmsg(jcr, M_MOUNT, 0, _("%s Volume \"%s\" on Storage Device \"%s\" for Job %s\n"), msg, jcr->VolumeName, jcr->dev_name, jcr->Job); - Dmsg3(190, "Mount %s on %s for Job %s\n", + Dmsg3(200, "Mount %s on %s for Job %s\n", jcr->VolumeName, jcr->dev_name, jcr->Job); } jcr->JobStatus = JS_WaitMount; dir_send_job_status(jcr); - stat = wait_for_sysop(jcr, dev); /* wait on device */ + stat = wait_for_sysop(dcr); ; /* wait on device */ if (dev->poll) { Dmsg1(200, "Poll timeout in mount vol on device %s\n", dev_name(dev)); - Dmsg1(200, "Blocked=%d\n", dev->dev_blocked); - return 1; + Dmsg1(200, "Blocked=%s\n", edit_blocked_reason(dev)); + return true; } if (stat == ETIMEDOUT) { if (!double_dev_wait_time(dev)) { - Mmsg(&dev->errmsg, _("Gave up waiting to mount Storage Device \"%s\" for Job %s\n"), + Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device \"%s\" for Job %s\n"), dev_name(dev), jcr->Job); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); - Dmsg1(190, "Gave up waiting on device %s\n", dev_name(dev)); - return 0; /* exceeded maximum waits */ + Dmsg1(200, "Gave up waiting on device %s\n", dev_name(dev)); + return false; /* exceeded maximum waits */ } continue; } if (stat == EINVAL) { - Mmsg2(&dev->errmsg, _("pthread error in mount_volume stat=%d ERR=%s\n"), - stat, strerror(stat)); + berrno be; + Mmsg2(dev->errmsg, _("pthread error in mount_volume stat=%d ERR=%s\n"), + stat, be.strerror(stat)); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); - return 0; + return false; } if (stat != 0) { + berrno be; Jmsg(jcr, M_ERROR, 0, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), stat, - strerror(stat)); + be.strerror(stat)); } - Dmsg1(190, "Someone woke me for device %s\n", dev_name(dev)); + Dmsg1(200, "Someone woke me for device %s\n", dev_name(dev)); break; } set_jcr_job_status(jcr, JS_Running); dir_send_job_status(jcr); - Dmsg0(130, "leave dir_ask_sysop_to_mount_volume\n"); - return 1; + Dmsg0(200, "leave dir_ask_sysop_to_mount_volume\n"); + return true; } /* * Wait for SysOp to mount a tape */ -static int wait_for_sysop(JCR *jcr, DEVICE *dev) +static int wait_for_sysop(DCR *dcr) { struct timeval tv; struct timezone tz; @@ -546,6 +542,8 @@ static int wait_for_sysop(JCR *jcr, DEVICE *dev) int stat = 0; int add_wait; bool unmounted; + DEVICE *dev = dcr->dev; + JCR *jcr = dcr->jcr; P(dev->mutex); unmounted = (dev->dev_blocked == BST_UNMOUNTED) || @@ -562,6 +560,9 @@ static int wait_for_sysop(JCR *jcr, DEVICE *dev) if (me->heartbeat_interval && add_wait > me->heartbeat_interval) { add_wait = me->heartbeat_interval; } + /* If the user did not unmount the tape and we are polling, ensure + * that we poll at the correct interval. + */ if (!unmounted && dev->vol_poll_interval && add_wait > dev->vol_poll_interval) { add_wait = dev->vol_poll_interval; } @@ -577,11 +578,12 @@ static int wait_for_sysop(JCR *jcr, DEVICE *dev) for ( ; !job_canceled(jcr); ) { time_t now, start; - Dmsg3(100, "I'm going to sleep on device %s. HB=%d wait=%d\n", dev_name(dev), + Dmsg3(200, "I'm going to sleep on device %s. HB=%d wait=%d\n", dev_name(dev), (int)me->heartbeat_interval, dev->wait_sec); start = time(NULL); + /* Wait required time */ stat = pthread_cond_timedwait(&dev->wait_next_vol, &dev->mutex, &timeout); - Dmsg1(100, "Wokeup from sleep on device stat=%d\n", stat); + Dmsg1(200, "Wokeup from sleep on device stat=%d\n", stat); now = time(NULL); dev->rem_wait_sec -= (now - start); @@ -592,7 +594,7 @@ static int wait_for_sysop(JCR *jcr, DEVICE *dev) /* send heartbeats */ if (jcr->file_bsock) { bnet_sig(jcr->file_bsock, BNET_HEARTBEAT); - Dmsg0(100, "Send heartbeat to FD.\n"); + Dmsg0(200, "Send heartbeat to FD.\n"); } if (jcr->dir_bsock) { bnet_sig(jcr->dir_bsock, BNET_HEARTBEAT); @@ -611,14 +613,14 @@ static int wait_for_sysop(JCR *jcr, DEVICE *dev) break; /* on error return */ } if (dev->rem_wait_sec <= 0) { /* on exceeding wait time return */ - Dmsg0(100, "Exceed wait time.\n"); + Dmsg0(200, "Exceed wait time.\n"); break; } if (!unmounted && dev->vol_poll_interval && (now - first_start >= dev->vol_poll_interval)) { - Dmsg1(200, "In wait blocked=%d\n", dev->dev_blocked); - dev->poll = true; + Dmsg1(200, "In wait blocked=%s\n", edit_blocked_reason(dev)); + dev->poll = true; /* returning a poll event */ break; } /* @@ -639,7 +641,7 @@ static int wait_for_sysop(JCR *jcr, DEVICE *dev) gettimeofday(&tv, &tz); timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + add_wait; /* additional wait */ - Dmsg1(100, "Additional wait %d sec.\n", add_wait); + Dmsg1(200, "Additional wait %d sec.\n", add_wait); } if (!unmounted) {