Adds a C++ utility for filling a hard drive via block device

This commit is contained in:
zontreck 2025-02-02 15:07:57 -07:00
parent 03e2cd1bc6
commit 1bf7da7479
5 changed files with 198 additions and 0 deletions

1
Jenkinsfile vendored
View file

@ -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()
}
}

View file

@ -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)

92
cpp/filldisk.c Normal file
View file

@ -0,0 +1,92 @@
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#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 <device>\n", argv[0]);
return EXIT_FAILURE;
}
fill_device(argv[1]);
return EXIT_SUCCESS;
}

96
cpp/filldisk.cpp Normal file
View file

@ -0,0 +1,96 @@
#include <iostream>
#include <vector>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
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<float>(total_written) / total_size;
if (percent > 1.0)
percent = 1.0;
int filled = static_cast<int>(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<unsigned char> 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] << " <device>\n";
return EXIT_FAILURE;
}
fill_device(argv[1]);
return EXIT_SUCCESS;
}

View file

@ -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}"