]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/MonitorStore: always O_TRUNC when writing states
authorSage Weil <sage@inktank.com>
Mon, 16 Jul 2012 03:30:34 +0000 (20:30 -0700)
committerSage Weil <sage@inktank.com>
Mon, 16 Jul 2012 04:38:29 +0000 (21:38 -0700)
It is possible for a .new file to already exist, potentially with a
larger size.  This would happen if:

 - we were proposing a different value
 - we crashed (or were stopped) before it got renamed into place
 - after restarting, a different value was proposed and accepted.

This isn't so unlikely for the log state machine, where we're
aggregating random messages.  O_TRUNC ensure we avoid getting the tail
end of some previous junk.

I observed #2593 and found that a logm state value had a larger size on
one mon (after slurping) than the others, pointing to put_bl_sn_map().

While we are at it, O_TRUNC put_int() too; the same type of bug is
possible there, too.

Fixes: #2593
Signed-off-by: Sage Weil <sage@inktank.com>
src/mon/MonitorStore.cc

index ea4ac17cee85d238510bee55ac07f799fda3646a..16e5c38492045a7959adb389e2b8c4fc497707a4 100644 (file)
@@ -174,7 +174,7 @@ void MonitorStore::put_int(version_t val, const char *a, const char *b)
   char tfn[1024];
   snprintf(tfn, sizeof(tfn), "%s.new", fn);
 
-  int fd = TEMP_FAILURE_RETRY(::open(tfn, O_WRONLY|O_CREAT, 0600));
+  int fd = TEMP_FAILURE_RETRY(::open(tfn, O_WRONLY|O_CREAT|O_TRUNC, 0600));
   if (fd < 0) {
     int err = errno;
     derr << "MonitorStore::put_int: failed to open '" << tfn << "': "
@@ -379,7 +379,7 @@ int MonitorStore::put_bl_sn_map(const char *a,
     snprintf(fn, sizeof(fn), "%s/%llu", dfn, (long long unsigned)p->first);
     snprintf(tfn, sizeof(tfn), "%s.new", fn);
 
-    int fd = ::open(tfn, O_WRONLY|O_CREAT, 0600);
+    int fd = ::open(tfn, O_WRONLY|O_CREAT|O_TRUNC, 0600);
     if (fd < 0) {
       int err = -errno;
       derr << "failed to open " << tfn << ": " << cpp_strerror(err) << dendl;