Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

is_hdd: update for linux only #4293

Merged
merged 1 commit into from
Sep 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/blockchain_db/lmdb/db_lmdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1200,8 +1200,12 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
throw DB_ERROR("Database could not be opened");
}

if (tools::is_hdd(filename.c_str()))
MCLOG_RED(el::Level::Warning, "global", "The blockchain is on a rotating drive: this will be very slow, use a SSD if possible");
boost::optional<bool> is_hdd_result = tools::is_hdd(filename.c_str());
if (is_hdd_result)
{
if (is_hdd_result.value())
MCLOG_RED(el::Level::Warning, "global", "The blockchain is on a rotating drive: this will be very slow, use a SSD if possible");
}

m_folder = filename;

Expand Down
86 changes: 36 additions & 50 deletions src/common/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@
#include <string>
#endif

//tools::is_hdd
#ifdef __GLIBC__
#include <sstream>
#include <sys/sysmacros.h>
#include <fstream>
#endif

#include "unbound.h"

#include "include_base_utils.h"
Expand Down Expand Up @@ -733,62 +740,41 @@ std::string get_nix_version_display_string()
#endif
}

bool is_hdd(const char *path)
boost::optional<bool> is_hdd(const char *file_path)
{
#ifdef __GLIBC__
std::string device = "";
struct stat st, dst;
if (stat(path, &st) < 0)
return 0;

DIR *dir = opendir("/dev/block");
if (!dir)
return 0;
struct dirent *de;
while ((de = readdir(dir)))
{
if (strcmp(de->d_name, ".") && strcmp(de->d_name, ".."))
struct stat st;
std::string prefix;
if(stat(file_path, &st) == 0)
{
std::ostringstream s;
s << "/sys/dev/block/" << major(st.st_dev) << ":" << minor(st.st_dev);
prefix = s.str();
}
else
{
return boost::none;
}
std::string attr_path = prefix + "/queue/rotational";
std::ifstream f(attr_path, std::ios_base::in);
if(not f.is_open())
{
attr_path = prefix + "/../queue/rotational";
f.open(attr_path, std::ios_base::in);
if(not f.is_open())
{
std::string dev_path = std::string("/dev/block/") + de->d_name;
char resolved[PATH_MAX];
if (realpath(dev_path.c_str(), resolved) && !strncmp(resolved, "/dev/", 5))
{
if (stat(resolved, &dst) == 0)
{
if (dst.st_rdev == st.st_dev)
{
// take out trailing digits (eg, sda1 -> sda)
char *ptr = resolved;
while (*ptr)
++ptr;
while (ptr > resolved && isdigit(*--ptr))
*ptr = 0;
device = resolved + 5;
break;
}
}
}
return boost::none;
}
}
closedir(dir);

if (device.empty())
return 0;

std::string sys_path = "/sys/block/" + device + "/queue/rotational";
FILE *f = fopen(sys_path.c_str(), "r");
if (!f)
return false;
char s[8];
char *ptr = fgets(s, sizeof(s), f);
fclose(f);
if (!ptr)
return 0;
s[sizeof(s) - 1] = 0;
int n = atoi(s); // returns 0 on parse error
return n == 1;
unsigned short val = 0xdead;
f >> val;
if(not f.fail())
{
return (val == 1);
}
return boost::none;
#else
return 0;
return boost::none;
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion src/common/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ namespace tools
bool sha256sum(const uint8_t *data, size_t len, crypto::hash &hash);
bool sha256sum(const std::string &filename, crypto::hash &hash);

bool is_hdd(const char *path);
boost::optional<bool> is_hdd(const char *path);

boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str);

Expand Down
3 changes: 2 additions & 1 deletion tests/unit_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ set(unit_tests_sources
output_selection.cpp
vercmp.cpp
ringdb.cpp
wipeable_string.cpp)
wipeable_string.cpp
is_hdd.cpp)

set(unit_tests_headers
unit_tests_utils.h)
Expand Down
17 changes: 17 additions & 0 deletions tests/unit_tests/is_hdd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "common/util.h"
#include <string>
#include <gtest/gtest.h>

#if defined(__GLIBC__)
TEST(is_hdd, linux_os_root)
{
std::string path = "/";
EXPECT_TRUE(tools::is_hdd(path.c_str()));
}
#else
TEST(is_hdd, unknown_os)
{
std::string path = "";
EXPECT_FALSE(tools::is_hdd(path.c_str()));
}
#endif