From 50214f14890aeacf111813aa2749005efdb1ff9a Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Tue, 8 Jan 2008 21:35:22 +0000 Subject: [PATCH] kes Undo recent reservations changes ... will apply them later when they work better. kes Fix bsnprintf for float point numbers. I broke recently when parameterizing some variables. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6259 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/patches/2.2.7-fpformat.patch | 120 ++++++++++++++++++++++++++++ bacula/src/dird/backup.c | 8 +- bacula/src/lib/bsnprintf.c | 37 +++++---- bacula/src/stored/acquire.c | 4 +- bacula/src/stored/block.c | 1 - bacula/src/stored/btape.c | 1 - bacula/src/stored/dircmd.c | 2 - bacula/src/stored/label.c | 3 - bacula/src/stored/read_record.c | 1 - bacula/src/stored/reserve.c | 44 ++++------ bacula/technotes-2.3 | 8 ++ 11 files changed, 170 insertions(+), 59 deletions(-) create mode 100644 bacula/patches/2.2.7-fpformat.patch diff --git a/bacula/patches/2.2.7-fpformat.patch b/bacula/patches/2.2.7-fpformat.patch new file mode 100644 index 0000000000..c022627abd --- /dev/null +++ b/bacula/patches/2.2.7-fpformat.patch @@ -0,0 +1,120 @@ + + This patch fixes a float point editing bug introduced in 2.2.7 (I think) + causing the rate fields to be formated incorrectly (actually trunctated). + This fixes bug #1036. + + Apply it to version 2.2.7 with: + + cd + patch -p0 <2.2.7-fpformat.patch + ./configure + make + ... + make install + + +Index: src/lib/bsnprintf.c +=================================================================== +--- src/lib/bsnprintf.c (revision 6183) ++++ src/lib/bsnprintf.c (working copy) +@@ -16,7 +16,7 @@ + /* + Bacula® - The Network Backup Solution + +- Copyright (C) 2005-2007 Free Software Foundation Europe e.V. ++ Copyright (C) 2005-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. +@@ -566,11 +566,11 @@ + return result; + } + +-static long round(LDOUBLE value) ++static int64_t round(LDOUBLE value) + { +- long intpart; ++ int64_t intpart; + +- intpart = (long)value; ++ intpart = (int64_t)value; + value = value - intpart; + if (value >= 0.5) + intpart++; +@@ -584,8 +584,8 @@ + int signvalue = 0; + LDOUBLE ufvalue; + #ifndef HAVE_FCVT +- char iconvert[25]; +- char fconvert[25]; ++ char iconvert[311]; ++ char fconvert[311]; + #else + char iconvert[311]; + char fconvert[311]; +@@ -602,6 +602,7 @@ + int caps = 0; + int64_t intpart; + int64_t fracpart; ++ const char *cvt_str; + + /* + * AIX manpage says the default is 0, but Solaris says the default +@@ -625,7 +626,7 @@ + #endif + + #ifndef HAVE_FCVT +- intpart = (long)ufvalue; ++ intpart = (int64_t)ufvalue; + + /* + * Sorry, we only support 9 digits past the decimal because of our +@@ -645,28 +646,30 @@ + } + + #ifdef DEBUG_SNPRINTF +- printf("fmtfp: %g %d.%d min=%d max=%d\n", ++ printf("fmtfp: %g %lld.%lld min=%d max=%d\n", + (double)fvalue, intpart, fracpart, min, max); + #endif + + /* Convert integer part */ ++ cvt_str = caps ? "0123456789ABCDEF" : "0123456789abcdef"; + do { +- iconvert[iplace++] = +- (caps ? "0123456789ABCDEF" : "0123456789abcdef")[intpart % 10]; ++ iconvert[iplace++] = cvt_str[(int)(intpart % 10)]; + intpart = (intpart / 10); +- } while (intpart && (iplace < (int)sizeof(iplace))); +- if (iplace == (int)sizeof(iplace)) { ++ } while (intpart && (iplace < (int)sizeof(iconvert))); ++ ++ if (iplace == (int)sizeof(fconvert)) { + iplace--; + } + iconvert[iplace] = 0; + + /* Convert fractional part */ ++ cvt_str = caps ? "0123456789ABCDEF" : "0123456789abcdef"; + do { +- fconvert[fplace++] = +- (caps ? "0123456789ABCDEF" : "0123456789abcdef")[fracpart % 10]; ++ fconvert[fplace++] = cvt_str[fracpart % 10]; + fracpart = (fracpart / 10); +- } while (fracpart && (fplace < (int)sizeof(fplace))); +- if (fplace == (int)sizeof(fplace)) { ++ } while (fracpart && (fplace < (int)sizeof(fconvert))); ++ ++ if (fplace == (int)sizeof(fconvert)) { + fplace--; + } + fconvert[fplace] = 0; +@@ -825,7 +828,7 @@ + NULL + }; + double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, +- 0.9996, 1.996, 4.136, 6442452944.1234, 0 ++ 0.9996, 1.996, 4.136, 6442452944.1234, 0, 23365.5 + }; + #endif + char *int_fmt[] = { diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index 7f33e80317..6d7c43d172 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -1,7 +1,7 @@ /* 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. @@ -423,7 +423,7 @@ void backup_cleanup(JCR *jcr, int TermCode) if (RunTime <= 0) { kbps = 0; } else { - kbps = (double)jcr->jr.JobBytes / (1000 * RunTime); + kbps = ((double)jcr->jr.JobBytes) / (1000.0 * (double)RunTime); } if (!db_get_job_volume_names(jcr, jcr->db, jcr->jr.JobId, &jcr->VolumeName)) { /* @@ -445,7 +445,7 @@ void backup_cleanup(JCR *jcr, int TermCode) if (compression < 0.5) { bstrncpy(compress, "None", sizeof(compress)); } else { - bsnprintf(compress, sizeof(compress), "%.1f %%", (float)compression); + bsnprintf(compress, sizeof(compress), "%.1f %%", compression); } } jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg)); @@ -504,7 +504,7 @@ void backup_cleanup(JCR *jcr, int TermCode) edit_uint64_with_suffix(jcr->jr.JobBytes, ec4), edit_uint64_with_commas(jcr->SDJobBytes, ec5), edit_uint64_with_suffix(jcr->SDJobBytes, ec6), - (float)kbps, + kbps, compress, jcr->VSS?"yes":"no", jcr->Encrypt?"yes":"no", diff --git a/bacula/src/lib/bsnprintf.c b/bacula/src/lib/bsnprintf.c index 4800c3e60a..cbb6966ce5 100644 --- a/bacula/src/lib/bsnprintf.c +++ b/bacula/src/lib/bsnprintf.c @@ -16,7 +16,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2005-2007 Free Software Foundation Europe e.V. + Copyright (C) 2005-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. @@ -566,11 +566,11 @@ static LDOUBLE pow10(int exp) return result; } -static long round(LDOUBLE value) +static int64_t round(LDOUBLE value) { - long intpart; + int64_t intpart; - intpart = (long)value; + intpart = (int64_t)value; value = value - intpart; if (value >= 0.5) intpart++; @@ -584,8 +584,8 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, int signvalue = 0; LDOUBLE ufvalue; #ifndef HAVE_FCVT - char iconvert[25]; - char fconvert[25]; + char iconvert[311]; + char fconvert[311]; #else char iconvert[311]; char fconvert[311]; @@ -602,6 +602,7 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, int caps = 0; int64_t intpart; int64_t fracpart; + const char *cvt_str; /* * AIX manpage says the default is 0, but Solaris says the default @@ -625,7 +626,7 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, #endif #ifndef HAVE_FCVT - intpart = (long)ufvalue; + intpart = (int64_t)ufvalue; /* * Sorry, we only support 9 digits past the decimal because of our @@ -645,28 +646,30 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, } #ifdef DEBUG_SNPRINTF - printf("fmtfp: %g %d.%d min=%d max=%d\n", + printf("fmtfp: %g %lld.%lld min=%d max=%d\n", (double)fvalue, intpart, fracpart, min, max); #endif /* Convert integer part */ + cvt_str = caps ? "0123456789ABCDEF" : "0123456789abcdef"; do { - iconvert[iplace++] = - (caps ? "0123456789ABCDEF" : "0123456789abcdef")[intpart % 10]; + iconvert[iplace++] = cvt_str[(int)(intpart % 10)]; intpart = (intpart / 10); - } while (intpart && (iplace < (int)sizeof(iplace))); - if (iplace == (int)sizeof(iplace)) { + } while (intpart && (iplace < (int)sizeof(iconvert))); + + if (iplace == (int)sizeof(fconvert)) { iplace--; } iconvert[iplace] = 0; /* Convert fractional part */ + cvt_str = caps ? "0123456789ABCDEF" : "0123456789abcdef"; do { - fconvert[fplace++] = - (caps ? "0123456789ABCDEF" : "0123456789abcdef")[fracpart % 10]; + fconvert[fplace++] = cvt_str[fracpart % 10]; fracpart = (fracpart / 10); - } while (fracpart && (fplace < (int)sizeof(fplace))); - if (fplace == (int)sizeof(fplace)) { + } while (fracpart && (fplace < (int)sizeof(fconvert))); + + if (fplace == (int)sizeof(fconvert)) { fplace--; } fconvert[fplace] = 0; @@ -825,7 +828,7 @@ int main(void) NULL }; double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, - 0.9996, 1.996, 4.136, 6442452944.1234, 0 + 0.9996, 1.996, 4.136, 6442452944.1234, 0, 23365.5 }; #endif char *int_fmt[] = { diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index a0dcf4ced2..83741679d0 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -324,7 +324,7 @@ DCR *acquire_device_for_append(DCR *dcr) init_device_wait_timers(dcr); dev->dblock(BST_DOING_ACQUIRE); - Dmsg1(190, "acquire_append device is %s\n", dev->is_tape()?"tape": + Dmsg1(100, "acquire_append device is %s\n", dev->is_tape()?"tape": (dev->is_dvd()?"DVD":"disk")); /* @@ -506,7 +506,6 @@ bool release_device(DCR *dcr) dev->clear_read(); /* clear read bit */ Dmsg0(100, "dir_update_vol_info. Release0\n"); dir_update_volume_info(dcr, false, false); /* send Volume info to Director */ - volume_unused(dcr); } else if (dev->num_writers > 0) { /* @@ -527,7 +526,6 @@ bool release_device(DCR *dcr) if (!dev->num_writers && dev->can_write() && dev->block_num > 0) { dev->weof(1); write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName); - volume_unused(dcr); } if (!dev->at_weot()) { dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */ diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index fc530139a2..b9cbbfa36a 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -772,7 +772,6 @@ static bool terminate_writing_volume(DCR *dcr) } bail_out: - volume_unused(dcr); /* mark volume unused */ dev->set_ateot(); /* no more writing this tape */ Dmsg1(50, "*** Leave terminate_writing_volume -- %s\n", ok?"OK":"ERROR"); return ok; diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 3cd7be3095..d966a881f0 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -2732,7 +2732,6 @@ static bool my_mount_next_read_volume(DCR *dcr) Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName, quickie_count); - volume_unused(dcr); /* mark volume no longer needed */ if (LastBlock != block->BlockNumber) { VolBytes += block->block_len; } diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 1529367f08..9901774a71 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -512,7 +512,6 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, } bail_out: - volume_unused(dcr); /* no longer using */ if (!dev->is_open()) { dev->clear_volhdr(); } @@ -549,7 +548,6 @@ static bool read_label(DCR *dcr) ok = false; break; } - volume_unused(dcr); give_back_device_lock(dev, &hold); return ok; } diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 68fe6f1b52..b1f8ee0cdf 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -257,7 +257,6 @@ int read_dev_volume_label(DCR *dcr) return VOL_OK; bail_out: - volume_unused(dcr); /* mark volume "released" */ empty_block(block); dev->rewind(dcr); Dmsg1(150, "return %d\n", stat); @@ -317,7 +316,6 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, empty_block(dcr->block); if (relabel) { - volume_unused(dcr); /* mark current volume unused */ /* Truncate device */ if (!dev->truncate(dcr)) { goto bail_out; @@ -454,7 +452,6 @@ bool rewrite_volume_label(DCR *dcr, bool recycle) return false; } if (recycle) { - volume_unused(dcr); /* mark volume unused */ if (!dev->truncate(dcr)) { Jmsg2(jcr, M_FATAL, 0, _("Truncate error on device %s: ERR=%s\n"), dev->print_name(), dev->print_errmsg()); diff --git a/bacula/src/stored/read_record.c b/bacula/src/stored/read_record.c index 4190d11848..6be9c15d5c 100644 --- a/bacula/src/stored/read_record.c +++ b/bacula/src/stored/read_record.c @@ -82,7 +82,6 @@ bool read_records(DCR *dcr, DEV_RECORD *trec = new_record(); Jmsg(jcr, M_INFO, 0, _("End of Volume at file %u on device %s, Volume \"%s\"\n"), dev->file, dev->print_name(), dcr->VolumeName); - volume_unused(dcr); /* mark volume unused */ if (!mount_cb(dcr)) { Jmsg(jcr, M_INFO, 0, _("End of all volumes.\n")); ok = false; /* Stop everything */ diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index e3269d33c0..9c7960e684 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -177,10 +177,10 @@ static void debug_list_volumes(const char *imsg) lock_volumes(); foreach_dlist(vol, vol_list) { if (vol->dev) { - Mmsg(msg, "List from %s: %s at %p on device %s\n", imsg, - vol->vol_name, vol->vol_name, vol->dev->print_name()); + Mmsg(msg, "List %s: %s rel=%d on device %s\n", imsg, + vol->vol_name, vol->released, vol->dev->print_name()); } else { - Mmsg(msg, "List from %s: %s at %p no dev\n", imsg, vol->vol_name, vol->vol_name); + Mmsg(msg, "List %s: %s rel=%d no dev\n", imsg, vol->vol_name, vol->released); } Dmsg1(dbglvl, "%s", msg.c_str()); } @@ -337,15 +337,8 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) */ if (strcmp(vol->vol_name, VolumeName) == 0) { Dmsg1(dbglvl, "=== OK, vol=%s on device. set not released.\n", VolumeName); - vol->released = false; /* retake vol if released previously */ goto get_out; /* Volume already on this device */ } else { - /* Don't release a volume if it is in use */ - if (!vol->released) { - Dmsg1(dbglvl, "Cannot free vol=%s. It is not released.\n", vol->vol_name); - vol = NULL; /* vol in use */ - goto get_out; - } Dmsg2(dbglvl, "reserve_vol free vol=%s at %p\n", vol->vol_name, vol->vol_name); unload_autochanger(dcr, -1); /* unload the volume */ free_volume(dev); @@ -478,10 +471,9 @@ void unreserve_device(DCR *dcr) Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers); dev->num_writers = 0; } - if (dev->reserved_device == 0 && dev->num_writers == 0) { - volume_unused(dcr); - } } + + volume_unused(dcr); } /* @@ -504,13 +496,11 @@ bool volume_unused(DCR *dcr) return false; } -#ifdef xxx if (dev->is_busy()) { Dmsg1(dbglvl, "vol_unused: busy on %s\n", dev->print_name()); debug_list_volumes("dev busy cannot unreserve_volume"); return false; } -#endif #ifdef xxx if (dev->num_writers > 0 || dev->reserved_device > 0) { ASSERT(0); @@ -523,8 +513,8 @@ bool volume_unused(DCR *dcr) * explicitly read in this drive. This allows the SD to remember * where the tapes are or last were. */ - Dmsg2(dbglvl, "=== mark released. num_writers=%d reserved=%d\n", - dev->num_writers, dev->reserved_device); + Dmsg3(dbglvl, "=== mark released vol=%s num_writers=%d reserved=%d\n", + dev->vol->vol_name, dev->num_writers, dev->reserved_device); dev->vol->released = true; if (dev->is_tape() || dev->is_autochanger()) { return true; @@ -972,6 +962,7 @@ bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx) Dmsg0(dbglvl, "No suitable device found.\n"); } rctx.have_volume = false; + rctx.VolumeName[0] = 0; } if (ok) { break; @@ -1149,21 +1140,17 @@ static int reserve_device(RCTX &rctx) Dmsg5(dbglvl, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n", dcr->dev->reserved_device, dcr->dev_name, dcr->media_type, dcr->pool_name, ok); - Dmsg2(dbglvl, "num_writers=%d, have_vol=%d\n", dcr->dev->num_writers, - rctx.have_volume); - if (rctx.have_volume && !reserve_volume(dcr, rctx.VolumeName)) { - goto bail_out; - } else { + Dmsg3(dbglvl, "Vol=%s num_writers=%d, have_vol=%d\n", + rctx.VolumeName, dcr->dev->num_writers, rctx.have_volume); + if (!rctx.have_volume) { dcr->any_volume = true; Dmsg0(dbglvl, "no vol, call find_next_appendable_vol.\n"); if (dir_find_next_appendable_volume(dcr)) { bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName)); - Dmsg1(dbglvl, "looking for Volume=%s\n", rctx.VolumeName); rctx.have_volume = true; + Dmsg1(dbglvl, "looking for Volume=%s\n", rctx.VolumeName); } else { Dmsg0(dbglvl, "No next volume found\n"); - rctx.have_volume = false; - rctx.VolumeName[0] = 0; /* * If there is at least one volume that is valid and in use, * but we get here, check if we are running with prefers @@ -1174,7 +1161,7 @@ static int reserve_device(RCTX &rctx) if (dcr->volume_in_use && !rctx.PreferMountedVols) { rctx.PreferMountedVols = true; if (dcr->VolumeName[0]) { - unreserve_device(dcr); + volume_unused(dcr); } goto bail_out; } @@ -1191,10 +1178,12 @@ static int reserve_device(RCTX &rctx) */ if (dcr->dev->num_writers != 0) { if (dcr->VolumeName[0]) { - unreserve_device(dcr); + volume_unused(dcr); } goto bail_out; } + rctx.have_volume = false; + rctx.VolumeName[0] = 0; } } } else { @@ -1224,6 +1213,7 @@ static int reserve_device(RCTX &rctx) bail_out: rctx.have_volume = false; + rctx.VolumeName[0] = 0; // free_dcr(dcr); Dmsg0(dbglvl, "Not OK.\n"); return 0; diff --git a/bacula/technotes-2.3 b/bacula/technotes-2.3 index 366a13fd94..abff2d0aef 100644 --- a/bacula/technotes-2.3 +++ b/bacula/technotes-2.3 @@ -1,6 +1,11 @@ Technical notes on version 2.3 General: +08Jan08 +kes Undo recent reservations changes ... will apply them later + when they work better. +kes Fix bsnprintf for float point numbers. I broke recently when + parameterizing some variables. 06Jan08 ebl Fixes #1034 which cause mysql to hang the connection after 8h ebl Change default statistics target of filename.name and path.path @@ -14,6 +19,9 @@ kes A few more tweaks to new reservation code. Make sure to clear kes Fix reserve_volume() so it doesn't release a volume in use (i.e. a volume entry not marked released). This should be the last part needed to fix bug #1018. +03Jan08 +kes Move Heartbeat documentation from Job to Director resource. + This fixes bug #1033. 02Jan08 kes Fix existing switch drive SD code to call autochanger to release any old volume. This must be done to keep the autochanger from -- 2.39.5