Implemented the creation of backing disks

This commit is contained in:
Alexei KADIR 2024-02-15 13:06:21 +01:00
parent f64f39c9c8
commit e6bc757343
6 changed files with 130 additions and 5 deletions

View File

@ -9,6 +9,8 @@
#include <unistd.h> #include <unistd.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <time.h>
#include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
char* get_backings_path(void) { char* get_backings_path(void) {
@ -182,3 +184,44 @@ char* find_latest_backing(void) {
return latest_backing; return latest_backing;
} }
bool create_backing(const char* disk, const char* description) {
// Create the backing disk name
uint64_t timestamp = (uint64_t)time(NULL);
char* backing_name = NULL;
if (description == NULL || strlen(description) == 0)
backing_name = format("%lu", timestamp);
else
backing_name = format("%lu-%s", timestamp, description);
if (backing_name == NULL) {
log_msg(LOG_ERROR, "Failed to create the backing disk name.");
return false;
}
// Create the backing disk path
char* backings_path = get_backings_path();
if (backings_path == NULL) {
free(backing_name);
return false;
}
char* backing_path = format("%s/%s", backings_path, backing_name);
free(backing_name);
free(backings_path);
if (backing_path == NULL)
return false;
// Copy the disk to the backing disk
if (!copy_file(disk, backing_path, 0755, 0, 0)) {
free(backing_path);
return false;
}
// Free the backing disk path
free(backing_path);
return true;
}

View File

@ -36,7 +36,7 @@ uint64_t get_backing_creation_time(const char* backing);
char* find_latest_backing(void); char* find_latest_backing(void);
/// @brief Creates a new backing disk. /// @brief Creates a new backing disk.
/// @param backing_disk The disk to use as the backing disk. Warning: the disk must be part of the backing disks. /// @param disk The disk to use as the backing disk. Warning: the disk must be part of the backing disks.
/// @param description The description of the backing disk. /// @param description The description of the backing disk.
/// @return true if the backing disk was created, otherwise false. /// @return true if the backing disk was created, otherwise false.
bool create_backing(const char* backing_disk, const char* description); bool create_backing(const char* disk, const char* description);

View File

@ -237,3 +237,20 @@ uint64_t get_available_space(void) {
return statbuf.f_bsize * statbuf.f_bavail; return statbuf.f_bsize * statbuf.f_bavail;
} }
bool reserve_space(uint64_t space) {
// While the available space is not enough, delete the oldest entry
while (get_available_space() < space) {
char* oldest_entry = find_oldest_entry();
if (oldest_entry == NULL)
return false;
bool result = delete_entry(oldest_entry);
free(oldest_entry);
if (!result)
return false;
}
return true;
}

View File

@ -14,8 +14,18 @@
#include <errno.h> #include <errno.h>
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
while (1) { char** backings = list_backings();
char* oldest_entry = find_oldest_entry();
free(oldest_entry); if (backings == NULL) {
fprintf(stderr, "Failed to list the backing disks: %s\n", strerror(errno));
return EXIT_FAILURE;
} }
for (size_t i = 0; backings[i] != NULL; i++)
printf("%s\n", backings[i]);
for (size_t i = 0; backings[i] != NULL; i++)
free(backings[i]);
free(backings);
} }

View File

@ -359,3 +359,49 @@ bool delete_directory(const char* directory, int level) {
return true; return true;
} }
bool copy_file(const char* source, const char* destination, mode_t mode, uid_t uid, gid_t gid) {
// Open the source file
FILE* source_file = fopen(source, "r");
if (source_file == NULL) {
log_msg(LOG_ERROR, "Failed to open file '%s' for reading (%s).", source, strerror(errno));
return false;
}
// Open the destination file
FILE* destination_file = fopen(destination, "w");
if (destination_file == NULL) {
log_msg(LOG_ERROR, "Failed to open file '%s' for writing (%s).", destination, strerror(errno));
fclose(source_file);
return false;
}
// Copy the file
char buffer[4096];
size_t bytes_read;
while ((bytes_read = fread(buffer, 1, sizeof(buffer), source_file)) > 0)
if (fwrite(buffer, 1, bytes_read, destination_file) != bytes_read) {
log_msg(LOG_ERROR, "Failed to write to file '%s' (%s).", destination, strerror(errno));
fclose(source_file);
fclose(destination_file);
return false;
}
// Close the files
fclose(source_file);
fclose(destination_file);
// Change the mode of the destination file
if (chmod(destination, mode) != 0) {
log_msg(LOG_ERROR, "Failed to change the mode of file '%s' (%s).", destination, strerror(errno));
return false;
}
// Change the owner of the destination file
if (chown(destination, uid, gid) != 0) {
log_msg(LOG_ERROR, "Failed to change the owner of file '%s' (%s).", destination, strerror(errno));
return false;
}
return true;
}

View File

@ -47,3 +47,12 @@ bool create_directory(const char* directory, mode_t mode, uid_t uid, gid_t gid);
/// @param level The current level of recursion. This parameter is used internally and should be set to 0. /// @param level The current level of recursion. This parameter is used internally and should be set to 0.
/// @return true if the directory was deleted, otherwise false. /// @return true if the directory was deleted, otherwise false.
bool delete_directory(const char* directory, int level); bool delete_directory(const char* directory, int level);
/// @brief Copies the specified file to the specified destination.
/// @param source The source file to copy.
/// @param destination The destination file.
/// @param mode The mode to use when creating the destination file.
/// @param uid The user ID to use when creating the destination file.
/// @param gid The group ID to use when creating the destination file.
/// @return true if the file was copied, otherwise false.
bool copy_file(const char* source, const char* destination, mode_t mode, uid_t uid, gid_t gid);