From 23087966d684619a4c5f90ae970c7deb97980020 Mon Sep 17 00:00:00 2001 From: YZBruh Date: Wed, 13 Aug 2025 09:41:27 +0300 Subject: [PATCH] pmt: start working for 1.1.0, first: add * operator to libpartition_map --- .../cutils/android_reboot.h | 0 .../private/android_filesystem_config.h | 0 src/functions/MemoryTestFunction.cpp | 100 ++++++++++++++++++ .../include/libpartition_map/lib.hpp | 6 ++ srclib/libpartition_map/src/Magic.cpp | 2 +- srclib/libpartition_map/src/PartitionMap.cpp | 8 ++ 6 files changed, 115 insertions(+), 1 deletion(-) rename {srclib/libhelper/include => include}/cutils/android_reboot.h (100%) rename {srclib/libhelper/include => include}/private/android_filesystem_config.h (100%) create mode 100644 src/functions/MemoryTestFunction.cpp diff --git a/srclib/libhelper/include/cutils/android_reboot.h b/include/cutils/android_reboot.h similarity index 100% rename from srclib/libhelper/include/cutils/android_reboot.h rename to include/cutils/android_reboot.h diff --git a/srclib/libhelper/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h similarity index 100% rename from srclib/libhelper/include/private/android_filesystem_config.h rename to include/private/android_filesystem_config.h diff --git a/src/functions/MemoryTestFunction.cpp b/src/functions/MemoryTestFunction.cpp new file mode 100644 index 0000000..6dcc568 --- /dev/null +++ b/src/functions/MemoryTestFunction.cpp @@ -0,0 +1,100 @@ +/* +Copyright 2025 Yağız Zengin + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include "functions.hpp" +#include + +#define MTFUN "memoryTestFunction" + +namespace PartitionManager { + +bool memoryTestFunction::init(CLI::App &_app) { + LOGN(MTFUN, INFO) << "Initializing variables of memory test function." << std::endl; + cmd = _app.add_subcommand("memtest", "Test your write/read speed of device."); + cmd->add_option("testDirectory", testPath, "Path to test directory")->default_val("/data/local/tmp")->check([&](const std::string &val) { + if (val != "/data/local/tmp" && !Helper::directoryIsExists(val)) + return std::string("Couldn't find directory: " + val); + return std::string(); + }); + cmd->add_option("-b,--buffer-size", bufferSize, "Buffer size for reading partition(s) and writing to file(s)")->transform(CLI::AsSizeValue(false))->default_val("4KB"); + cmd->add_option("-s,--file-size", testFileSize, "File size of test file")->transform(CLI::AsSizeValue(false))->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, "Don't read test data from disk")->default_val(false); + + return true; +} + +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; + Helper::garbageCollector collector; + const std::string test = testPath + "/test.bin"; + + LOGN(MTFUN, INFO) << "Generating random data for testing" << std::endl; + auto *buffer = new(std::nothrow) char[bufferSize]; + collector.delAfterProgress(buffer); + srand(time(nullptr)); + for (size_t i = 0; i < bufferSize; i++) buffer[i] = rand() % 256; + + if (!doNotWriteTest) { + const int wfd = Helper::openAndAddToCloseList(test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644); + if (wfd < 0) throw Error("Can't open/create test file: %s", strerror(errno)); + + LOGN(MTFUN, INFO) << "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 double writeTime = std::chrono::duration(endWrite - startWrite).count(); + println("Write speed: %f MB/s", (testFileSize / (1024.0 * 1024.0)) / writeTime); + LOGN(MTFUN, INFO) << "Write test done!" << std::endl; + } + + if (!doNotReadTest) { + const int rfd = Helper::openAndAddToCloseList(test, collector, O_RDONLY | O_SYNC); + if (rfd < 0) throw Error("Can't open test file: %s", strerror(errno)); + + LOGN(MTFUN, INFO) << "Read test started!" << std::endl; + const auto startRead = std::chrono::high_resolution_clock::now(); + while (read(rfd, buffer, bufferSize) > 0) {} + const auto endRead = std::chrono::high_resolution_clock::now(); + + const double read_time = std::chrono::duration(endRead - startRead).count(); + println("Read speed: %f MB/s", (testFileSize / (1024.0 * 1024.0)) / read_time); + LOGN(MTFUN, INFO) << "Read test done!" << std::endl; + } + + Helper::eraseEntry(test); + return true; +} + +bool memoryTestFunction::isUsed() const { return cmd->parsed(); } + +const char *memoryTestFunction::name() const { return MTFUN; } + +} // namespace PartitionManager \ No newline at end of file diff --git a/srclib/libpartition_map/include/libpartition_map/lib.hpp b/srclib/libpartition_map/include/libpartition_map/lib.hpp index 5d9c86e..1252e4e 100644 --- a/srclib/libpartition_map/include/libpartition_map/lib.hpp +++ b/srclib/libpartition_map/include/libpartition_map/lib.hpp @@ -282,6 +282,12 @@ public: * Build map with input path. Implementation of readDirectory(). */ bool operator()(std::string_view path); + + /** + * Get Map_t object reference + */ + Map_t& operator*(); + const Map_t& operator*() const; }; using Error = Helper::Error; diff --git a/srclib/libpartition_map/src/Magic.cpp b/srclib/libpartition_map/src/Magic.cpp index 9f85e63..30823dc 100644 --- a/srclib/libpartition_map/src/Magic.cpp +++ b/srclib/libpartition_map/src/Magic.cpp @@ -89,7 +89,7 @@ bool hasMagic(const uint64_t magic, const ssize_t buf, return false; } - auto *buffer = new uint8_t[buf]; + auto *buffer = new(std::nothrow) uint8_t[buf]; collector.delAfterProgress(buffer); const ssize_t bytesRead = read(fd, buffer, buf); diff --git a/srclib/libpartition_map/src/PartitionMap.cpp b/srclib/libpartition_map/src/PartitionMap.cpp index 0d8b934..7509d67 100644 --- a/srclib/libpartition_map/src/PartitionMap.cpp +++ b/srclib/libpartition_map/src/PartitionMap.cpp @@ -251,5 +251,13 @@ bool basic_partition_map_builder::operator()(const std::string_view path) { return readDirectory(path); } +Map_t& basic_partition_map_builder::operator*() { + return _current_map; +} + +const Map_t& basic_partition_map_builder::operator*() const { + return _current_map; +} + std::string getLibVersion() { MKVERSION("libpartition_map"); } } // namespace PartitionMap