Implemented the creation of backing disks
This commit is contained in:
parent
f64f39c9c8
commit
e6bc757343
@ -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;
|
||||||
|
}
|
||||||
|
@ -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);
|
17
src/entry.c
17
src/entry.c
@ -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;
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
46
src/utils.c
46
src/utils.c
@ -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;
|
||||||
|
}
|
||||||
|
@ -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);
|
Loading…
Reference in New Issue
Block a user