From 1bf7da747922032a40ecb77f034772b0ffaa6114 Mon Sep 17 00:00:00 2001 From: zontreck Date: Sun, 2 Feb 2025 15:07:57 -0700 Subject: [PATCH] Adds a C++ utility for filling a hard drive via block device --- Jenkinsfile | 1 + cpp/CMakeLists.txt | 7 ++++ cpp/filldisk.c | 92 ++++++++++++++++++++++++++++++++++++++++++++ cpp/filldisk.cpp | 96 ++++++++++++++++++++++++++++++++++++++++++++++ installscript.sh | 2 + 5 files changed, 198 insertions(+) create mode 100644 cpp/filldisk.c create mode 100644 cpp/filldisk.cpp diff --git a/Jenkinsfile b/Jenkinsfile index 5059345..abf860e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -28,6 +28,7 @@ pipeline { archiveArtifacts artifacts: "dart/out/*", fingerprint: true archiveArtifacts artifacts: "cpp/build/vsleep-cpp", fingerprint: true archiveArtifacts artifacts: "cpp/build/pause-cpp", fingerprint: true + archiveArtifacts artifacts: "cpp/build/filldisk-cpp", fingerprint: true cleanWs() } } diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index f96ba32..63cad4b 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -10,3 +10,10 @@ install(TARGETS vsleep-cpp add_executable(pause-cpp pause.cpp) install(TARGETS pause-cpp RUNTIME DESTINATION /usr/bin) + +add_executable(filldisk-cpp filldisk.cpp) +install(TARGETS filldisk-cpp RUNTIME DESTINATION /usr/sbin) + + +add_executable(filldisk filldisk.c) +install(TARGETS filldisk RUNTIME DESTINATION /usr/sbin) diff --git a/cpp/filldisk.c b/cpp/filldisk.c new file mode 100644 index 0000000..c8bd900 --- /dev/null +++ b/cpp/filldisk.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define BLKSZ (100 * 1024 * 1024) // 100MB buffer +#define PATTERN_SIZE 7 // 7-byte repeating pattern +#define BAR_WIDTH 50 // Progress bar width + +// Function to get total size of block device +size_t get_device_size(int fd) { + size_t size = 0; + if (ioctl(fd, BLKGETSIZE64, &size) < 0) { + perror("Failed to get device size"); + exit(EXIT_FAILURE); + } + return size; +} + +// Function to print progress bar +void print_progress(size_t total_written, size_t total_size) { + float percent = (float)total_written / total_size; + if (percent > 1.0) percent = 1.0; + + int filled = (int)(percent * BAR_WIDTH); + printf("\r["); + for (int i = 0; i < BAR_WIDTH; i++) { + printf(i < filled ? "#" : " "); + } + printf("] %lu MB / %lu MB", total_written / (1024 * 1024), total_size / (1024 * 1024)); + fflush(stdout); +} + +void fill_device(const char *device) { + int fd = open(device, O_WRONLY); + if (fd < 0) { + perror("Failed to open device"); + exit(EXIT_FAILURE); + } + + // Get total device size + size_t total_size = get_device_size(fd); + + // Allocate 100MB buffer + unsigned char *buffer = (unsigned char *)malloc(BLKSZ); + if (!buffer) { + perror("Failed to allocate buffer"); + close(fd); + exit(EXIT_FAILURE); + } + + // Define the 7-byte repeating pattern + unsigned char pattern[PATTERN_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; + + // Fill the buffer with the repeating pattern + for (size_t i = 0; i < BLKSZ; i++) { + buffer[i] = pattern[i % PATTERN_SIZE]; + } + + printf("Writing to %s with a 7-byte repeating pattern in 100MB chunks...\n", device); + printf("Total device size: %lu MB\n", total_size / (1024 * 1024)); + + size_t total_written = 0; + while (total_written < total_size) { + ssize_t written = write(fd, buffer, BLKSZ); + if (written < 0) { + perror("\nWrite failed"); + break; + } + total_written += written; + print_progress(total_written, total_size); + } + + printf("\nCompleted. Total written: %lu MB\n", total_written / (1024 * 1024)); + + free(buffer); + close(fd); +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + fill_device(argv[1]); + return EXIT_SUCCESS; +} diff --git a/cpp/filldisk.cpp b/cpp/filldisk.cpp new file mode 100644 index 0000000..2ea0606 --- /dev/null +++ b/cpp/filldisk.cpp @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include +#include + +constexpr size_t BUFFER_SIZE = 100 * 1024 * 1024; // 100MB buffer +constexpr size_t PATTERN_SIZE = 7; // 7-byte repeating pattern +constexpr int BAR_WIDTH = 50; // Progress bar width + +// Function to get total size of block device +size_t get_device_size(int fd) +{ + size_t size = 0; + if (ioctl(fd, BLKGETSIZE64, &size) < 0) + { + perror("Failed to get device size"); + exit(EXIT_FAILURE); + } + return size; +} + +// Function to print progress bar +void print_progress(size_t total_written, size_t total_size) +{ + float percent = static_cast(total_written) / total_size; + if (percent > 1.0) + percent = 1.0; + + int filled = static_cast(percent * BAR_WIDTH); + std::cout << "\r["; + for (int i = 0; i < BAR_WIDTH; i++) + { + std::cout << (i < filled ? '#' : ' '); + } + std::cout << "] " << (total_written / (1024 * 1024)) << " MB / " + << (total_size / (1024 * 1024)) << " MB" << std::flush; +} + +void fill_device(const std::string &device) +{ + int fd = open(device.c_str(), O_WRONLY); + if (fd < 0) + { + perror("Failed to open device"); + exit(EXIT_FAILURE); + } + + // Get total device size + size_t total_size = get_device_size(fd); + + // Allocate 100MB buffer + std::vector buffer(BUFFER_SIZE); + + // Define the 7-byte repeating pattern + unsigned char pattern[PATTERN_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; + + // Fill the buffer with the repeating pattern + for (size_t i = 0; i < BUFFER_SIZE; i++) + { + buffer[i] = pattern[i % PATTERN_SIZE]; + } + + std::cout << "Writing to " << device << " with a 7-byte repeating pattern in 100MB chunks...\n"; + std::cout << "Total device size: " << (total_size / (1024 * 1024)) << " MB\n"; + + size_t total_written = 0; + while (total_written < total_size) + { + ssize_t written = write(fd, buffer.data(), BUFFER_SIZE); + if (written < 0) + { + perror("\nWrite failed"); + break; + } + total_written += written; + print_progress(total_written, total_size); + } + + std::cout << "\nCompleted. Total written: " << (total_written / (1024 * 1024)) << " MB\n"; + + close(fd); +} + +int main(int argc, char *argv[]) +{ + if (argc != 2) + { + std::cerr << "Usage: " << argv[0] << " \n"; + return EXIT_FAILURE; + } + + fill_device(argv[1]); + return EXIT_SUCCESS; +} diff --git a/installscript.sh b/installscript.sh index acc7481..9565014 100644 --- a/installscript.sh +++ b/installscript.sh @@ -73,6 +73,8 @@ download_with_retry "https://ci.zontreck.com/job/Projects/job/Dart/job/AWSParser download_with_retry "https://ci.zontreck.com/job/Projects/job/Dart/job/SimpleHelperTools/job/main/lastSuccessfulBuild/artifact/dart/out/timestamp-linux-x64" "/usr/bin/timestamp" +download_with_retry "https://ci.zontreck.com/job/Projects/job/Dart/job/SimpleHelperTools/job/main/lastSuccessfulBuild/artifact/cpp/build/filldisk-cpp" "/usr/sbin/filldisk" + # Set executable permissions eval "$SUDO_CMD chmod +x /usr/bin/{nbt2snbt,snbt2nbt,pause,mkfsreport,dbikc,vsleep,uuidgen,regedit,awsparser,timestamp}"