pmt: fix memory leaks, and improve info function
- Removed --no-write-test argument of memory test function - Fixed memory leak of memory test function - Improved info function with using nlohmann/json header-only library - Some other improvents
This commit is contained in:
@@ -31,3 +31,4 @@ Detailed usage instructions and option references can be found in the [USAGE.md]
|
|||||||
## Credits
|
## Credits
|
||||||
- [CLI11: Command line parser for C++11](https://github.com/CLIUtils/CLI11)
|
- [CLI11: Command line parser for C++11](https://github.com/CLIUtils/CLI11)
|
||||||
- [PicoSHA2: A header-file-only, SHA256 hash generator in C++](https://github.com/okdshin/PicoSHA2)
|
- [PicoSHA2: A header-file-only, SHA256 hash generator in C++](https://github.com/okdshin/PicoSHA2)
|
||||||
|
- [nlohmann/json: JSON for Modern C++](https://github.com/nlohmann/json)
|
||||||
|
|||||||
21
include/LICENSE.nlohmann
Normal file
21
include/LICENSE.nlohmann
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2013-2025 Niels Lohmann
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
25526
include/nlohmann/json.hpp
Normal file
25526
include/nlohmann/json.hpp
Normal file
File diff suppressed because it is too large
Load Diff
187
include/nlohmann/json_fwd.hpp
Normal file
187
include/nlohmann/json_fwd.hpp
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
|
||||||
|
#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
|
||||||
|
|
||||||
|
#include <cstdint> // int64_t, uint64_t
|
||||||
|
#include <map> // map
|
||||||
|
#include <memory> // allocator
|
||||||
|
#include <string> // string
|
||||||
|
#include <vector> // vector
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/abi_macros.hpp>
|
||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This file contains all macro definitions affecting or depending on the ABI
|
||||||
|
|
||||||
|
#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
|
||||||
|
#if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
|
||||||
|
#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0
|
||||||
|
#warning "Already included a different version of the library!"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
|
||||||
|
#define NLOHMANN_JSON_VERSION_MINOR 12 // NOLINT(modernize-macro-to-enum)
|
||||||
|
#define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum)
|
||||||
|
|
||||||
|
#ifndef JSON_DIAGNOSTICS
|
||||||
|
#define JSON_DIAGNOSTICS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JSON_DIAGNOSTIC_POSITIONS
|
||||||
|
#define JSON_DIAGNOSTIC_POSITIONS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
|
||||||
|
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if JSON_DIAGNOSTICS
|
||||||
|
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
|
||||||
|
#else
|
||||||
|
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if JSON_DIAGNOSTIC_POSITIONS
|
||||||
|
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp
|
||||||
|
#else
|
||||||
|
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
|
||||||
|
#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
|
||||||
|
#else
|
||||||
|
#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
||||||
|
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Construct the namespace ABI tags component
|
||||||
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) json_abi ## a ## b ## c
|
||||||
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c) \
|
||||||
|
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c)
|
||||||
|
|
||||||
|
#define NLOHMANN_JSON_ABI_TAGS \
|
||||||
|
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
||||||
|
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
|
||||||
|
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \
|
||||||
|
NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS)
|
||||||
|
|
||||||
|
// Construct the namespace version component
|
||||||
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
||||||
|
_v ## major ## _ ## minor ## _ ## patch
|
||||||
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
|
||||||
|
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
|
||||||
|
|
||||||
|
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
||||||
|
#define NLOHMANN_JSON_NAMESPACE_VERSION
|
||||||
|
#else
|
||||||
|
#define NLOHMANN_JSON_NAMESPACE_VERSION \
|
||||||
|
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
|
||||||
|
NLOHMANN_JSON_VERSION_MINOR, \
|
||||||
|
NLOHMANN_JSON_VERSION_PATCH)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Combine namespace components
|
||||||
|
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
|
||||||
|
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
|
||||||
|
NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
|
||||||
|
|
||||||
|
#ifndef NLOHMANN_JSON_NAMESPACE
|
||||||
|
#define NLOHMANN_JSON_NAMESPACE \
|
||||||
|
nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
|
||||||
|
NLOHMANN_JSON_ABI_TAGS, \
|
||||||
|
NLOHMANN_JSON_NAMESPACE_VERSION)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
|
||||||
|
namespace nlohmann \
|
||||||
|
{ \
|
||||||
|
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
|
||||||
|
NLOHMANN_JSON_ABI_TAGS, \
|
||||||
|
NLOHMANN_JSON_NAMESPACE_VERSION) \
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
#define NLOHMANN_JSON_NAMESPACE_END \
|
||||||
|
} /* namespace (inline namespace) NOLINT(readability/namespace) */ \
|
||||||
|
} // namespace nlohmann
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief namespace for Niels Lohmann
|
||||||
|
@see https://github.com/nlohmann
|
||||||
|
@since version 1.0.0
|
||||||
|
*/
|
||||||
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief default JSONSerializer template argument
|
||||||
|
|
||||||
|
This serializer ignores the template arguments and uses ADL
|
||||||
|
([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
|
||||||
|
for serialization.
|
||||||
|
*/
|
||||||
|
template<typename T = void, typename SFINAE = void>
|
||||||
|
struct adl_serializer;
|
||||||
|
|
||||||
|
/// a class to store JSON values
|
||||||
|
/// @sa https://json.nlohmann.me/api/basic_json/
|
||||||
|
template<template<typename U, typename V, typename... Args> class ObjectType =
|
||||||
|
std::map,
|
||||||
|
template<typename U, typename... Args> class ArrayType = std::vector,
|
||||||
|
class StringType = std::string, class BooleanType = bool,
|
||||||
|
class NumberIntegerType = std::int64_t,
|
||||||
|
class NumberUnsignedType = std::uint64_t,
|
||||||
|
class NumberFloatType = double,
|
||||||
|
template<typename U> class AllocatorType = std::allocator,
|
||||||
|
template<typename T, typename SFINAE = void> class JSONSerializer =
|
||||||
|
adl_serializer,
|
||||||
|
class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
|
||||||
|
class CustomBaseClass = void>
|
||||||
|
class basic_json;
|
||||||
|
|
||||||
|
/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
|
||||||
|
/// @sa https://json.nlohmann.me/api/json_pointer/
|
||||||
|
template<typename RefStringType>
|
||||||
|
class json_pointer;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief default specialization
|
||||||
|
@sa https://json.nlohmann.me/api/json/
|
||||||
|
*/
|
||||||
|
using json = basic_json<>;
|
||||||
|
|
||||||
|
/// @brief a minimal map-like container that preserves insertion order
|
||||||
|
/// @sa https://json.nlohmann.me/api/ordered_map/
|
||||||
|
template<class Key, class T, class IgnoredLess, class Allocator>
|
||||||
|
struct ordered_map;
|
||||||
|
|
||||||
|
/// @brief specialization that maintains the insertion order of object keys
|
||||||
|
/// @sa https://json.nlohmann.me/api/ordered_json/
|
||||||
|
using ordered_json = basic_json<nlohmann::ordered_map>;
|
||||||
|
|
||||||
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
|
||||||
@@ -119,9 +119,9 @@ int Main(int argc, char **argv) {
|
|||||||
"(--search-path)");
|
"(--search-path)");
|
||||||
|
|
||||||
if (!Helper::hasSuperUser()) {
|
if (!Helper::hasSuperUser()) {
|
||||||
if (!((FuncManager.isUsed("rebootFunction") ||
|
if (!((FuncManager.isUsed("rebootFunction") &&
|
||||||
FuncManager.isUsed("memoryTestFunction")) &&
|
Helper::hasAdbPermissions()) ||
|
||||||
Helper::hasAdbPermissions()))
|
FuncManager.isUsed("memoryTestFunction")))
|
||||||
throw Error(
|
throw Error(
|
||||||
"Partition Manager Tool is requires super-user privileges!\n");
|
"Partition Manager Tool is requires super-user privileges!\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Copyright 2025 Yağız Zengin
|
|||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#define IFUN "infoFunction"
|
#define IFUN "infoFunction"
|
||||||
|
|
||||||
@@ -39,14 +39,17 @@ bool infoFunction::init(CLI::App &_app) {
|
|||||||
"be written separately")
|
"be written separately")
|
||||||
->default_val(false);
|
->default_val(false);
|
||||||
cmd->add_option("--json-partition-name", jNamePartition,
|
cmd->add_option("--json-partition-name", jNamePartition,
|
||||||
"Speficy partition name element for JSON body")
|
"Specify partition name element for JSON body")
|
||||||
->default_val("name");
|
->default_val("name");
|
||||||
cmd->add_option("--json-size-name", jNameSize,
|
cmd->add_option("--json-size-name", jNameSize,
|
||||||
"Speficy size element name for JSON body")
|
"Specify size element name for JSON body")
|
||||||
->default_val("size");
|
->default_val("size");
|
||||||
cmd->add_option("--json-logical-name", jNameLogical,
|
cmd->add_option("--json-logical-name", jNameLogical,
|
||||||
"Speficy logical element name for JSON body")
|
"Specify logical element name for JSON body")
|
||||||
->default_val("isLogical");
|
->default_val("isLogical");
|
||||||
|
cmd->add_option("--json-indent-size", jIndentSize,
|
||||||
|
"Set JSON indent size for printing to screen")
|
||||||
|
->default_val(2);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,6 +66,7 @@ bool infoFunction::run() {
|
|||||||
partitions.push_back(name);
|
partitions.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PartitionMap::Partition_t> jParts;
|
||||||
for (const auto &partition : partitions) {
|
for (const auto &partition : partitions) {
|
||||||
if (!Variables->PartMap->hasPartition(partition))
|
if (!Variables->PartMap->hasPartition(partition))
|
||||||
throw Error("Couldn't find partition: %s", partition.data());
|
throw Error("Couldn't find partition: %s", partition.data());
|
||||||
@@ -79,14 +83,9 @@ bool infoFunction::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (jsonFormat)
|
if (jsonFormat)
|
||||||
#ifdef __LP64__
|
jParts.push_back({partition,
|
||||||
println("{\"%s\": \"%s\", \"%s\": %lu, \"%s\": %s}",
|
{Variables->PartMap->sizeOf(partition),
|
||||||
#else
|
Variables->PartMap->isLogical(partition)}});
|
||||||
println("{\"%s\": \"%s\", \"%s\": %llu, \"%s\": %s}",
|
|
||||||
#endif
|
|
||||||
jNamePartition.data(), partition.data(), jNameSize.data(),
|
|
||||||
Variables->PartMap->sizeOf(partition), jNameLogical.data(),
|
|
||||||
Variables->PartMap->isLogical(partition) ? "true" : "false");
|
|
||||||
else
|
else
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
println("partition=%s size=%lu isLogical=%s",
|
println("partition=%s size=%lu isLogical=%s",
|
||||||
@@ -97,6 +96,18 @@ bool infoFunction::run() {
|
|||||||
Variables->PartMap->isLogical(partition) ? "true" : "false");
|
Variables->PartMap->isLogical(partition) ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (jsonFormat) {
|
||||||
|
nlohmann::json j;
|
||||||
|
j["partitions"] = nlohmann::json::array();
|
||||||
|
for (const auto &[name, props] : jParts) {
|
||||||
|
j["partitions"].push_back({{jNamePartition, name},
|
||||||
|
{jNameSize, props.size},
|
||||||
|
{jNameLogical, props.isLogical}});
|
||||||
|
}
|
||||||
|
|
||||||
|
println("%s", j.dump(jIndentSize).data());
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,17 +34,21 @@ bool memoryTestFunction::init(CLI::App &_app) {
|
|||||||
cmd->add_option("testDirectory", testPath, "Path to test directory")
|
cmd->add_option("testDirectory", testPath, "Path to test directory")
|
||||||
->default_val("/data/local/tmp")
|
->default_val("/data/local/tmp")
|
||||||
->check([&](const std::string &val) {
|
->check([&](const std::string &val) {
|
||||||
|
if (val.find("/sdcard") != std::string::npos ||
|
||||||
|
val.find("/storage") != std::string::npos)
|
||||||
|
return std::string(
|
||||||
|
"Sequential read tests on FUSE-mounted paths do not give correct "
|
||||||
|
"results, so its use is prohibited (by pmt)!");
|
||||||
|
|
||||||
if (val != "/data/local/tmp" && !Helper::directoryIsExists(val))
|
if (val != "/data/local/tmp" && !Helper::directoryIsExists(val))
|
||||||
return std::string("Couldn't find directory: " + val +
|
return std::string("Couldn't find directory: " + val +
|
||||||
", no root? Try executing in ADB shell.");
|
", no root? Try executing in ADB shell.");
|
||||||
|
|
||||||
return std::string();
|
return std::string();
|
||||||
});
|
});
|
||||||
cmd->add_option("-s,--file-size", testFileSize, "File size of test file")
|
cmd->add_option("-s,--file-size", testFileSize, "File size of test file")
|
||||||
->transform(CLI::AsSizeValue(false))
|
->transform(CLI::AsSizeValue(false))
|
||||||
->default_val("1GB");
|
->default_val("1GB");
|
||||||
cmd->add_flag("--no-write-test", doNotWriteTest,
|
|
||||||
"Don't write test data to disk")
|
|
||||||
->default_val(false);
|
|
||||||
cmd->add_flag("--no-read-test", doNotReadTest,
|
cmd->add_flag("--no-read-test", doNotReadTest,
|
||||||
"Don't read test data from disk")
|
"Don't read test data from disk")
|
||||||
->default_val(false);
|
->default_val(false);
|
||||||
@@ -53,13 +57,9 @@ bool memoryTestFunction::init(CLI::App &_app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool memoryTestFunction::run() {
|
bool memoryTestFunction::run() {
|
||||||
if (doNotReadTest && doNotWriteTest)
|
|
||||||
throw Error("There must be at least one test transaction, but all of them "
|
|
||||||
"are blocked");
|
|
||||||
|
|
||||||
LOGN(MTFUN, INFO) << "Starting memory test on " << testPath << std::endl;
|
LOGN(MTFUN, INFO) << "Starting memory test on " << testPath << std::endl;
|
||||||
Helper::garbageCollector collector;
|
Helper::garbageCollector collector;
|
||||||
const std::string test = testPath + "/test.bin";
|
const std::string test = Helper::pathJoin(testPath, "test.bin");
|
||||||
|
|
||||||
LOGN(MTFUN, INFO) << "Generating random data for testing" << std::endl;
|
LOGN(MTFUN, INFO) << "Generating random data for testing" << std::endl;
|
||||||
auto *buffer = new (std::nothrow) char[bufferSize];
|
auto *buffer = new (std::nothrow) char[bufferSize];
|
||||||
@@ -72,25 +72,24 @@ bool memoryTestFunction::run() {
|
|||||||
|
|
||||||
collector.delFileAfterProgress(test);
|
collector.delFileAfterProgress(test);
|
||||||
|
|
||||||
if (!doNotWriteTest) {
|
const int wfd = Helper::openAndAddToCloseList(
|
||||||
const int wfd = Helper::openAndAddToCloseList(
|
test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644);
|
||||||
test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644);
|
if (wfd < 0)
|
||||||
if (wfd < 0)
|
throw Error("Can't open/create test file: %s\n", strerror(errno));
|
||||||
throw Error("Can't open/create test file: %s", strerror(errno));
|
|
||||||
|
LOGN(MTFUN, INFO) << "Sequential write test started!" << std::endl;
|
||||||
|
const auto startWrite = std::chrono::high_resolution_clock::now();
|
||||||
|
ssize_t bytesWritten = 0;
|
||||||
|
while (bytesWritten < testFileSize) {
|
||||||
|
const ssize_t ret = write(wfd, buffer, bufferSize);
|
||||||
|
if (ret < 0) throw Error("Can't write to test file: %s\n", strerror(errno));
|
||||||
|
bytesWritten += ret;
|
||||||
|
|
||||||
LOGN(MTFUN, INFO) << "Sequential write test started!" << std::endl;
|
|
||||||
const auto startWrite = std::chrono::high_resolution_clock::now();
|
|
||||||
ssize_t bytesWritten = 0;
|
|
||||||
while (bytesWritten < testFileSize) {
|
|
||||||
const ssize_t ret = write(wfd, buffer, bufferSize);
|
|
||||||
if (ret < 0) throw Error("Can't write to test file: %s", strerror(errno));
|
|
||||||
bytesWritten += ret;
|
|
||||||
}
|
|
||||||
const auto endWrite = std::chrono::high_resolution_clock::now();
|
const auto endWrite = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
const double writeTime =
|
const double writeTime =
|
||||||
std::chrono::duration<double>(endWrite - startWrite).count();
|
std::chrono::duration<double>(endWrite - startWrite).count();
|
||||||
println("Sequential write speed: %f MB/s",
|
println("Sequential write speed: %3.f MB/s",
|
||||||
(static_cast<double>(testFileSize) / (1024.0 * 1024.0)) /
|
(static_cast<double>(testFileSize) / (1024.0 * 1024.0)) /
|
||||||
writeTime);
|
writeTime);
|
||||||
LOGN(MTFUN, INFO) << "Sequential write test done!" << std::endl;
|
LOGN(MTFUN, INFO) << "Sequential write test done!" << std::endl;
|
||||||
@@ -99,10 +98,11 @@ bool memoryTestFunction::run() {
|
|||||||
if (!doNotReadTest) {
|
if (!doNotReadTest) {
|
||||||
auto *rawBuffer = new char[bufferSize + 4096];
|
auto *rawBuffer = new char[bufferSize + 4096];
|
||||||
collector.delAfterProgress(rawBuffer);
|
collector.delAfterProgress(rawBuffer);
|
||||||
auto *bufferRead = reinterpret_cast<char*>((reinterpret_cast<uintptr_t>(rawBuffer) + 4096 - 1) & ~(4096 - 1));
|
auto *bufferRead = reinterpret_cast<char *>(
|
||||||
|
(reinterpret_cast<uintptr_t>(rawBuffer) + 4096 - 1) & ~(4096 - 1));
|
||||||
const int rfd =
|
const int rfd =
|
||||||
Helper::openAndAddToCloseList(test, collector, O_RDONLY | O_DIRECT);
|
Helper::openAndAddToCloseList(test, collector, O_RDONLY | O_DIRECT);
|
||||||
if (rfd < 0) throw Error("Can't open test file: %s", strerror(errno));
|
if (rfd < 0) throw Error("Can't open test file: %s\n", strerror(errno));
|
||||||
|
|
||||||
LOGN(MTFUN, INFO) << "Sequential read test started!" << std::endl;
|
LOGN(MTFUN, INFO) << "Sequential read test started!" << std::endl;
|
||||||
const auto startRead = std::chrono::high_resolution_clock::now();
|
const auto startRead = std::chrono::high_resolution_clock::now();
|
||||||
@@ -115,9 +115,8 @@ bool memoryTestFunction::run() {
|
|||||||
|
|
||||||
const double read_time =
|
const double read_time =
|
||||||
std::chrono::duration<double>(endRead - startRead).count();
|
std::chrono::duration<double>(endRead - startRead).count();
|
||||||
println("Sequential read speed: %f MB/s",
|
println("Sequential read speed: %3.f MB/s",
|
||||||
(static_cast<double>(total) / (1024.0 * 1024.0)) /
|
(static_cast<double>(total) / (1024.0 * 1024.0)) / read_time);
|
||||||
read_time);
|
|
||||||
LOGN(MTFUN, INFO) << "Sequential read test done!" << std::endl;
|
LOGN(MTFUN, INFO) << "Sequential read test done!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ class infoFunction final : public FunctionBase {
|
|||||||
private:
|
private:
|
||||||
std::vector<std::string> partitions;
|
std::vector<std::string> partitions;
|
||||||
std::string jNamePartition, jNameSize, jNameLogical;
|
std::string jNamePartition, jNameSize, jNameLogical;
|
||||||
|
int jIndentSize = 2;
|
||||||
bool jsonFormat = false;
|
bool jsonFormat = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -175,7 +176,7 @@ class memoryTestFunction final : public FunctionBase {
|
|||||||
private:
|
private:
|
||||||
uint64_t bufferSize = MB(4), /* bufferSizeRandom = KB(4),*/ testFileSize = 0;
|
uint64_t bufferSize = MB(4), /* bufferSizeRandom = KB(4),*/ testFileSize = 0;
|
||||||
std::string testPath;
|
std::string testPath;
|
||||||
bool doNotWriteTest = false, doNotReadTest = false;
|
bool doNotReadTest = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CLI::App *cmd = nullptr;
|
CLI::App *cmd = nullptr;
|
||||||
|
|||||||
@@ -81,14 +81,14 @@ private:
|
|||||||
std::vector<uint8_t *> _ptrs_u;
|
std::vector<uint8_t *> _ptrs_u;
|
||||||
std::vector<FILE *> _fps;
|
std::vector<FILE *> _fps;
|
||||||
std::vector<int> _fds;
|
std::vector<int> _fds;
|
||||||
std::vector<std::string_view> _files;
|
std::vector<std::string> _files;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~garbageCollector();
|
~garbageCollector();
|
||||||
|
|
||||||
void delAfterProgress(char *&_ptr);
|
void delAfterProgress(char *&_ptr);
|
||||||
void delAfterProgress(uint8_t *&_ptr);
|
void delAfterProgress(uint8_t *&_ptr);
|
||||||
void delFileAfterProgress(std::string_view path);
|
void delFileAfterProgress(const std::string& path);
|
||||||
void closeAfterProgress(FILE *&_fp);
|
void closeAfterProgress(FILE *&_fp);
|
||||||
void closeAfterProgress(int _fd);
|
void closeAfterProgress(int _fd);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ garbageCollector::~garbageCollector() {
|
|||||||
close(fd);
|
close(fd);
|
||||||
for (const auto &fp : _fps)
|
for (const auto &fp : _fps)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
for (const auto &file: _files)
|
for (const auto &file : _files)
|
||||||
eraseEntry(file);
|
eraseEntry(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ void garbageCollector::delAfterProgress(char *&_ptr) {
|
|||||||
void garbageCollector::delAfterProgress(uint8_t *&_ptr) {
|
void garbageCollector::delAfterProgress(uint8_t *&_ptr) {
|
||||||
_ptrs_u.push_back(_ptr);
|
_ptrs_u.push_back(_ptr);
|
||||||
}
|
}
|
||||||
void garbageCollector::delFileAfterProgress(const std::string_view path) {
|
void garbageCollector::delFileAfterProgress(const std::string &path) {
|
||||||
_files.push_back(path);
|
_files.push_back(path);
|
||||||
}
|
}
|
||||||
void garbageCollector::closeAfterProgress(const int _fd) {
|
void garbageCollector::closeAfterProgress(const int _fd) {
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ public:
|
|||||||
[[nodiscard]] constant_iterator cend() const;
|
[[nodiscard]] constant_iterator cend() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using Partition_t = _entry;
|
||||||
using Map_t = basic_partition_map;
|
using Map_t = basic_partition_map;
|
||||||
|
|
||||||
class basic_partition_map_builder final {
|
class basic_partition_map_builder final {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ bool basic_partition_map_builder::_is_real_block_dir(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Map_t basic_partition_map_builder::_build_map(std::string_view path,
|
Map_t basic_partition_map_builder::_build_map(std::string_view path,
|
||||||
bool logical) {
|
const bool logical) {
|
||||||
Map_t map;
|
Map_t map;
|
||||||
std::vector<std::filesystem::directory_entry> entries{
|
std::vector<std::filesystem::directory_entry> entries{
|
||||||
std::filesystem::directory_iterator(path),
|
std::filesystem::directory_iterator(path),
|
||||||
|
|||||||
Reference in New Issue
Block a user