--- /dev/null
+
+ 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 <bacula-source>
+ patch -p0 <2.2.7-fpformat.patch
+ ./configure <your-options>
+ 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[] = {
/*
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.
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)) {
/*
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));
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",
/*
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.
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++;
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];
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
#endif
#ifndef HAVE_FCVT
- intpart = (long)ufvalue;
+ intpart = (int64_t)ufvalue;
/*
* Sorry, we only support 9 digits past the decimal because of our
}
#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;
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[] = {
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"));
/*
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) {
/*
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 */
}
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;
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;
}
}
bail_out:
- volume_unused(dcr); /* no longer using */
if (!dev->is_open()) {
dev->clear_volhdr();
}
ok = false;
break;
}
- volume_unused(dcr);
give_back_device_lock(dev, &hold);
return ok;
}
return VOL_OK;
bail_out:
- volume_unused(dcr); /* mark volume "released" */
empty_block(block);
dev->rewind(dcr);
Dmsg1(150, "return %d\n", stat);
empty_block(dcr->block);
if (relabel) {
- volume_unused(dcr); /* mark current volume unused */
/* Truncate device */
if (!dev->truncate(dcr)) {
goto bail_out;
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());
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 */
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());
}
*/
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);
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);
}
/*
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);
* 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;
Dmsg0(dbglvl, "No suitable device found.\n");
}
rctx.have_volume = false;
+ rctx.VolumeName[0] = 0;
}
if (ok) {
break;
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
if (dcr->volume_in_use && !rctx.PreferMountedVols) {
rctx.PreferMountedVols = true;
if (dcr->VolumeName[0]) {
- unreserve_device(dcr);
+ volume_unused(dcr);
}
goto bail_out;
}
*/
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 {
bail_out:
rctx.have_volume = false;
+ rctx.VolumeName[0] = 0;
// free_dcr(dcr);
Dmsg0(dbglvl, "Not OK.\n");
return 0;
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
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