]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add SyncOnClose Storage Device directive
authorEric Bollengier <eric@baculasystems.com>
Fri, 29 Mar 2019 15:31:10 +0000 (16:31 +0100)
committerRadosław Korzeniewski <radekk@inteos.pl>
Sat, 14 Dec 2019 14:55:28 +0000 (15:55 +0100)
bacula/src/stored/acquire.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/status.c
bacula/src/stored/stored_conf.c

index d81bf9c4e9e865113185ed3bd1cf8388dfe02cd5..87eac5c38dc1c7852e57a1364bbfcc87c0a76f68 100644 (file)
@@ -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);
       }
index b8367ceb6b23f72e81e1dc2dc9c7528752d23d8d..6da1fc5b415c44f830137b0e2f69dca75b6dab07 100644 (file)
@@ -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;
index 4c776c0807fa3df02f3d2b296a84deadb3cf1fb4..9990a50f3259efd93d285fa010d56ac415d4dba4 100644 (file)
@@ -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);
index 26ff8f098a2e470ef4599cd0ce9d779d6ec00f94..acfd460dc8c77ec2c229ce2c824fcdac980907e9 100644 (file)
@@ -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);
    }
 
index d743231e74d458e836667195919f08731c194dfd..9148292df47837302055f33d9288ec3c66a15511 100644 (file)
@@ -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}
 };