From: Eric Bollengier Date: Fri, 29 Mar 2019 15:31:10 +0000 (+0100) Subject: Add SyncOnClose Storage Device directive X-Git-Tag: Release-9.6.0~162 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b46c9f7d08d60be6dc38193c1ea87d3200eeee31;p=thirdparty%2Fbacula.git Add SyncOnClose Storage Device directive --- diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index d81bf9c4e..87eac5c38 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -543,9 +543,13 @@ bool release_device(DCR *dcr) if (dev->num_writers == 0) { /* if not being used */ volume_unused(dcr); /* we obviously are not using the volume */ generate_plugin_event(jcr, bsdEventDeviceClose, dcr); + } else { + /* Other jobs are writing, make sure our data is safely written */ + if (!dev->sync_data(dcr)) { + Jmsg(jcr, M_ERROR, 0, ("%s\n"), dev->errmsg); + } } } - } else { /* * If we reach here, it is most likely because the job @@ -561,6 +565,10 @@ bool release_device(DCR *dcr) /* If no writers, close if file or !CAP_ALWAYS_OPEN */ if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) { generate_plugin_event(jcr, bsdEventDeviceClose, dcr); + /* Sync the data before close() if needed for this device */ + if (!dev->sync_data(dcr)) { + Jmsg(jcr, M_ERROR, 0, ("%s\n"), dev->errmsg); + } if (!dev->close(dcr) && dev->errmsg[0]) { Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); } diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index b8367ceb6..6da1fc5b4 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -317,8 +317,8 @@ bool DEVICE::close(DCR *dcr) if (d_close(m_fd) != 0) { berrno be; dev_errno = errno; - Mmsg2(errmsg, _("Error closing device %s. ERR=%s.\n"), - print_name(), be.bstrerror()); + Mmsg(errmsg, _("Error closing volume \"%s\" device %s. ERR=%s.\n"), + VolHdr.VolumeName, print_name(), be.bstrerror()); ok = false; } break; diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 4c776c080..9990a50f3 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -140,6 +140,7 @@ typedef struct { #define CAP_CHECKLABELS (1<<22) /* Check for ANSI/IBM labels */ #define CAP_BLOCKCHECKSUM (1<<23) /* Create/test block checksum */ #define CAP_LSEEK (1<<24) /* Has lseek function defined i.e. basically File storage */ +#define CAP_SYNCONCLOSE (1<<25) /* Need to call fsync() when releasing/closing the device */ /* Test state */ #define dev_state(dev, st_state) ((dev)->state & (st_state)) @@ -553,6 +554,7 @@ public: virtual bool open_device(DCR *dcr, int omode) = 0; virtual bool open_next_part(DCR *dcr); virtual bool close(DCR *dcr); /* in dev.c */ + virtual bool sync_data(DCR *dcr); /* in dev.c */ virtual void term(DCR *dcr); /* in dev.c */ virtual bool close_part(DCR *dcr); virtual bool reposition(DCR *dcr, uint64_t raddr); diff --git a/bacula/src/stored/status.c b/bacula/src/stored/status.c index 26ff8f098..acfd460dc 100644 --- a/bacula/src/stored/status.c +++ b/bacula/src/stored/status.c @@ -653,7 +653,7 @@ void send_device_status(DEVICE *dev, STATUS_PKT *sp) if (chk_dbglvl(5)) { len = Mmsg(msg, _("Configured device capabilities:\n")); sendit(msg, len, sp); - len = Mmsg(msg, " %sEOF %sBSR %sBSF %sFSR %sFSF %sEOM %sREM %sRACCESS %sAUTOMOUNT %sLABEL %sANONVOLS %sALWAYSOPEN\n", + len = Mmsg(msg, " %sEOF %sBSR %sBSF %sFSR %sFSF %sEOM %sREM %sRACCESS %sAUTOMOUNT %sLABEL %sANONVOLS %sALWAYSOPEN %sSYNCONCLOSE\n", dev->capabilities & CAP_EOF ? "" : "!", dev->capabilities & CAP_BSR ? "" : "!", dev->capabilities & CAP_BSF ? "" : "!", @@ -665,7 +665,8 @@ void send_device_status(DEVICE *dev, STATUS_PKT *sp) dev->capabilities & CAP_AUTOMOUNT ? "" : "!", dev->capabilities & CAP_LABEL ? "" : "!", dev->capabilities & CAP_ANONVOLS ? "" : "!", - dev->capabilities & CAP_ALWAYSOPEN ? "" : "!"); + dev->capabilities & CAP_ALWAYSOPEN ? "" : "!", + dev->capabilities & CAP_SYNCONCLOSE ? "" : "!"); sendit(msg, len, sp); } diff --git a/bacula/src/stored/stored_conf.c b/bacula/src/stored/stored_conf.c index d743231e7..9148292df 100644 --- a/bacula/src/stored/stored_conf.c +++ b/bacula/src/stored/stored_conf.c @@ -168,6 +168,7 @@ static RES_ITEM dev_items[] = { {"FreeSpaceCommand", store_strname,ITEM(res_dev.free_space_command), 0, 0, 0}, {"LabelType", store_label, ITEM(res_dev.label_type), 0, 0, 0}, {"Cloud", store_res, ITEM(res_dev.cloud), R_CLOUD, 0, 0}, + {"SyncOnClose", store_bit, ITEM(res_dev.cap_bits), CAP_SYNCONCLOSE, ITEM_DEFAULT, 0}, {NULL, NULL, {0}, 0, 0, 0} };