You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by mp...@apache.org on 2016/06/22 22:46:55 UTC
incubator-kudu git commit: Add Env::GetBytesFree() method
Repository: incubator-kudu
Updated Branches:
refs/heads/master 7d5788225 -> d952b70f6
Add Env::GetBytesFree() method
This method returns the number of bytes free on the filesystem
represented by its path argument.
Change-Id: Ica484be987312b275bafdd6e6fa79239ed3ac1ff
Reviewed-on: http://gerrit.cloudera.org:8080/3451
Reviewed-by: Adar Dembo <ad...@cloudera.com>
Tested-by: Mike Percy <mp...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/incubator-kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-kudu/commit/d952b70f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-kudu/tree/d952b70f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-kudu/diff/d952b70f
Branch: refs/heads/master
Commit: d952b70f670247709ede7832d870657eb636143b
Parents: 7d57882
Author: Mike Percy <mp...@apache.org>
Authored: Wed Jun 22 11:11:28 2016 -0700
Committer: Mike Percy <mp...@apache.org>
Committed: Wed Jun 22 22:46:38 2016 +0000
----------------------------------------------------------------------
src/kudu/util/env-test.cc | 24 ++++++++++++++++++++++++
src/kudu/util/env.h | 8 ++++++++
src/kudu/util/env_posix.cc | 26 +++++++++++++++++++++++++-
3 files changed, 57 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/d952b70f/src/kudu/util/env-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/env-test.cc b/src/kudu/util/env-test.cc
index db2e608..4348d74 100644
--- a/src/kudu/util/env-test.cc
+++ b/src/kudu/util/env-test.cc
@@ -750,4 +750,28 @@ TEST_F(TestEnv, TestTempRWFile) {
ASSERT_OK(env_->DeleteFile(path));
}
+TEST_F(TestEnv, TestGetBytesFree) {
+ const string kDataDir = GetTestPath("parent");
+ const string kTestFilePath = JoinPathSegments(kDataDir, "testfile");
+ const int kFileSizeBytes = 256;
+ int64_t orig_bytes_free;
+ int64_t cur_bytes_free;
+ ASSERT_OK(env_->CreateDir(kDataDir));
+
+ // Loop several times in case there are concurrent tests running that are
+ // modifying the filesystem.
+ const int kIters = 100;
+ for (int i = 0; i < kIters; i++) {
+ if (env_->FileExists(kTestFilePath)) {
+ ASSERT_OK(env_->DeleteFile(kTestFilePath));
+ }
+ ASSERT_OK(env_->GetBytesFree(kDataDir, &orig_bytes_free));
+ NO_FATALS(WriteTestFile(env_.get(), kTestFilePath, kFileSizeBytes));
+ ASSERT_OK(env_->GetBytesFree(kDataDir, &cur_bytes_free));
+ if (orig_bytes_free - cur_bytes_free >= kFileSizeBytes) break;
+ }
+ ASSERT_GE(orig_bytes_free - cur_bytes_free, kFileSizeBytes)
+ << "Failed after " << kIters << " attempts";
+}
+
} // namespace kudu
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/d952b70f/src/kudu/util/env.h
----------------------------------------------------------------------
diff --git a/src/kudu/util/env.h b/src/kudu/util/env.h
index 0283f5a..f62f85b 100644
--- a/src/kudu/util/env.h
+++ b/src/kudu/util/env.h
@@ -169,6 +169,11 @@ class Env {
// *block_size. fname must exist but it may be a file or a directory.
virtual Status GetBlockSize(const std::string& fname, uint64_t* block_size) = 0;
+ // Determine the number of bytes free on the filesystem specified by 'path'.
+ // "Free space" accounting on the underlying filesystem may be more coarse
+ // than single bytes.
+ virtual Status GetBytesFree(const std::string& path, int64_t* bytes_free) = 0;
+
// Rename file src to target.
virtual Status RenameFile(const std::string& src,
const std::string& target) = 0;
@@ -583,6 +588,9 @@ class EnvWrapper : public Env {
Status GetBlockSize(const std::string& f, uint64_t* s) OVERRIDE {
return target_->GetBlockSize(f, s);
}
+ Status GetBytesFree(const std::string& path, int64_t* bytes_free) OVERRIDE {
+ return target_->GetBytesFree(path, bytes_free);
+ }
Status RenameFile(const std::string& s, const std::string& t) OVERRIDE {
return target_->RenameFile(s, t);
}
http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/d952b70f/src/kudu/util/env_posix.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/env_posix.cc b/src/kudu/util/env_posix.cc
index c0137c1..465e7aa 100644
--- a/src/kudu/util/env_posix.cc
+++ b/src/kudu/util/env_posix.cc
@@ -14,6 +14,7 @@
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <sys/statvfs.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/uio.h>
@@ -910,6 +911,29 @@ class PosixEnv : public Env {
return s;
}
+ // Local convenience function for safely running statvfs().
+ static Status StatVfs(const string& path, struct statvfs* buf) {
+ ThreadRestrictions::AssertIOAllowed();
+ int ret;
+ RETRY_ON_EINTR(ret, statvfs(path.c_str(), buf));
+ if (ret == -1) {
+ return IOError(Substitute("statvfs: $0", path), errno);
+ }
+ return Status::OK();
+ }
+
+ virtual Status GetBytesFree(const string& path, int64_t* bytes_free) OVERRIDE {
+ TRACE_EVENT1("io", "PosixEnv::GetBytesFree", "path", path);
+ struct statvfs buf;
+ RETURN_NOT_OK(StatVfs(path, &buf));
+ if (geteuid() == 0) {
+ *bytes_free = buf.f_frsize * buf.f_bfree;
+ } else {
+ *bytes_free = buf.f_frsize * buf.f_bavail;
+ }
+ return Status::OK();
+ }
+
virtual Status RenameFile(const std::string& src, const std::string& target) OVERRIDE {
TRACE_EVENT2("io", "PosixEnv::RenameFile", "src", src, "dst", target);
ThreadRestrictions::AssertIOAllowed();
@@ -997,7 +1021,7 @@ class PosixEnv : public Env {
#if defined(__linux__)
int rc = readlink("/proc/self/exe", buf.get(), size);
if (rc == -1) {
- return Status::IOError("Unable to determine own executable path", "", errno);
+ return IOError("Unable to determine own executable path", errno);
} else if (rc >= size) {
// The buffer wasn't large enough
size *= 2;