diff --git a/src/backing.c b/src/backing.c deleted file mode 100644 index 29240e6..0000000 --- a/src/backing.c +++ /dev/null @@ -1,163 +0,0 @@ -#include "backing.h" - -#include "utils.h" - -#include -#include -#include -#include -#include -#include - -bool is_valid_backing_name(const char* name) { - if (name == NULL) - return false; - - size_t len = strlen(name); - if (len == 0) - return false; - - for (size_t i = 0; i < len; i++) - if (name[i] == '/') - return false; - - if (name[0] < '0' || name[0] > '9') - return false; - - return true; -} - -char* get_backing_path(const char* name) { - if (name == NULL) - return NULL; - - return format("%s/%s", "/var/lib/sandbox/backings", name); // TODO: Use a setting for the backings directory -} - -bool backing_exists(const char* name) { - if (name == NULL) - return false; - - char* path = get_backing_path(name); - if (path == NULL) - return false; - - // Check if the backing exists - struct stat st; - if (stat(path, &st) != 0) { - free(path); - return false; - } - - // Free the path, as it is no longer needed - free(path); - - if (!S_ISREG(st.st_mode)) - return false; - - return true; -} - -char** list_backings(void) { - // Open the backings directory - DIR* dir = opendir("/var/lib/sandbox/backings"); // TODO: Use a setting for the backings directory - if (dir == NULL) - return NULL; - - // Count the number of backings - size_t count = 0; - struct dirent* entry; - while ((entry = readdir(dir)) != NULL) { - if (is_valid_backing_name(entry->d_name)) - count++; - } - - // Allocate the array - char** backings = calloc(count + 1, sizeof(char*)); - if (backings == NULL) { - closedir(dir); - return NULL; - } - - // Reset the directory stream - rewinddir(dir); - - // Fill the array - size_t i = 0; - while ((entry = readdir(dir)) != NULL) { - if (is_valid_backing_name(entry->d_name)) { - backings[i] = strdup(entry->d_name); - if (backings[i] == NULL) { - closedir(dir); - - for (size_t j = 0; j < i; j++) - free(backings[j]); - free(backings); - - return NULL; - } - i++; - } - } - - // Close the directory - closedir(dir); - - // Terminate the array - backings[count] = NULL; - - return backings; -} - -time_t get_backing_ctime(const char* name) { - // As the name starts with the ctime, we can just convert the first part of the name to a time_t - size_t len = strlen(name); - size_t ctime_len = 0; - for (size_t i = 0; i < len; i++) { - if (name[i] < '0' || name[i] > '9') - break; - - ctime_len++; - } - - char* ctime_str = strndup(name, ctime_len); - if (ctime_str == NULL) - return 0; - - time_t ctime = (time_t)strtoull(ctime_str, NULL, 10); - - free(ctime_str); - - return ctime; -} - -char* get_latest_backing(void) { - // Get the backings - char** backings = list_backings(); - if (backings == NULL) - return NULL; - - // Find the latest backing - time_t latest_ctime = 0; - char* latest_backing = NULL; - - for (size_t i = 0; backings[i] != NULL; i++) { - time_t ctime = get_backing_ctime(backings[i]); - - if (ctime >= latest_ctime) { - latest_ctime = ctime; - latest_backing = backings[i]; - } - } - - // Duplicate the latest backing - if (latest_backing != NULL) - latest_backing = strdup(latest_backing); - - // Free the backings - for (size_t i = 0; backings[i] != NULL; i++) - free(backings[i]); - free(backings); - - return latest_backing; -} \ No newline at end of file diff --git a/src/backing.h b/src/backing.h index a8863d2..73dbaa2 100644 --- a/src/backing.h +++ b/src/backing.h @@ -1,41 +1,6 @@ #pragma once -#include "sandbox.h" - #include #include -#include -/// @brief Returns whether the given name is a valid backing name. Backing names are valid if they start with a number (used as the ctime). -/// @param name The name to check. -/// @return Whether the name is valid or not. -bool is_valid_backing_name(const char* name); - -/// @brief Returns the backing path for the given name. -/// @param name The name of the backing. Note: This function does not check if the name is valid. -/// @return The backing path. -char* get_backing_path(const char* name); - -/// @brief Returns the backing path for the given name. -/// @param name The name of the backing. Note: This function does not check if the name is valid. -/// @return The backing path. -bool backing_exists(const char* name); - -/// @brief Returns an array of all the backing names, terminated by a NULL pointer. -/// @return An array of all the backing names. Note: The array must be freed by the caller, including every string in the array. -char** list_backings(void); - -/// @brief Returns the ctime of the backing with the given name. -/// @param name The name of the backing. -/// @return The ctime of the backing. -time_t get_backing_ctime(const char* name); - -/// @brief Returns the latest backing's name. -/// @return The latest backing's name. -char* get_latest_backing(void); - -/// @brief Creates a new backing with the given name from the given source disk. -/// @param name The name of the new backing. -/// @param source_disk The source disk to create the backing from. Note: If the source disk has a backing file, it must be a existing sandbox backing disk. -/// @return Whether the backing was created successfully or not. -bool create_backing(const char* name, const char* source_disk); +#define BACKING_POOL "/var/lib/sandbox/backings" diff --git a/src/disk.c b/src/disk.c index ca1acfa..ece9114 100644 --- a/src/disk.c +++ b/src/disk.c @@ -16,26 +16,26 @@ bool create_empty_disk(const char* path, uint64_t size) { // Convert the size to a string char* size_str = format("%lu", size); if (size_str == NULL) { - logmsg(LOG_ERROR, "Failed to allocate memory for the size string."); + log_message(LOG_ERROR, "Failed to allocate memory for the size string."); return false; } // Create the disk - int ret = exec(NULL, &errb, "qemu-img", "create", "-f", "qcow2", path, size_str, NULL); + int ret = execute(NULL, &errb, "qemu-img", "create", "-f", "qcow2", path, size_str, NULL); free(size_str); // Check for errors if (ret != 0) { if (errb == NULL) - logmsg(LOG_ERROR, "Failed to create disk %s.", path); + log_message(LOG_ERROR, "Failed to create disk %s.", path); else { size_t length = strlen(errb); for (size_t i = 0; i < length; i++) if (errb[i] == '\n') errb[i] = ' '; - logmsg(LOG_ERROR, "Failed to create disk %s (%s).", path, errb); + log_message(LOG_ERROR, "Failed to create disk %s (%s).", path, errb); } return false; @@ -48,19 +48,19 @@ bool create_backed_disk(const char* path, const char* backing_disk) { char* errb = NULL; // Create the disk - int ret = exec(NULL, &errb, "qemu-img", "create", "-f", "qcow2", "-F", "qcow2", "-b", backing_disk, path, NULL); + int ret = execute(NULL, &errb, "qemu-img", "create", "-f", "qcow2", "-F", "qcow2", "-b", backing_disk, path, NULL); // Check for errors if (ret != 0) { if (errb == NULL) - logmsg(LOG_ERROR, "Failed to create disk %s.", path); + log_message(LOG_ERROR, "Failed to create disk %s.", path); else { size_t length = strlen(errb); for (size_t i = 0; i < length; i++) if (errb[i] == '\n') errb[i] = ' '; - logmsg(LOG_ERROR, "Failed to create disk %s (%s).", path, errb); + log_message(LOG_ERROR, "Failed to create disk %s (%s).", path, errb); } return false; @@ -72,7 +72,7 @@ bool create_backed_disk(const char* path, const char* backing_disk) { bool trim_disk(const char* path) { char* tmp_path = format("%s.tmp", path); if (tmp_path == NULL) { - logmsg(LOG_ERROR, "Failed to allocate memory for the temporary disk path."); + log_message(LOG_ERROR, "Failed to allocate memory for the temporary disk path."); return false; } @@ -90,18 +90,18 @@ bool trim_disk(const char* path) { if (info.backing_file != NULL) { char* backing_str = format("backing_file=%s", info.backing_file); if (backing_str == NULL) { - logmsg(LOG_ERROR, "Failed to allocate memory for the backing file string."); + log_message(LOG_ERROR, "Failed to allocate memory for the backing file string."); free_disk_info(&info); free(tmp_path); return false; } - ret = exec(NULL, &errb, "qemu-img", "convert", "-f", "qcow2", "-F", "qcow2", "-O", "qcow2", "-o", backing_str, path, tmp_path, NULL); + ret = execute(NULL, &errb, "qemu-img", "convert", "-f", "qcow2", "-F", "qcow2", "-O", "qcow2", "-o", backing_str, path, tmp_path, NULL); free(backing_str); } else - ret = exec(NULL, &errb, "qemu-img", "convert", "-f", "qcow2", "-O", "qcow2", path, tmp_path, NULL); + ret = execute(NULL, &errb, "qemu-img", "convert", "-f", "qcow2", "-O", "qcow2", path, tmp_path, NULL); // Free the disk info as we don't need it anymore free_disk_info(&info); @@ -109,14 +109,14 @@ bool trim_disk(const char* path) { // Check for errors if (ret != 0) { if (errb == NULL) - logmsg(LOG_ERROR, "Failed to trim disk %s.", path); + log_message(LOG_ERROR, "Failed to trim disk %s.", path); else { size_t length = strlen(errb); for (size_t i = 0; i < length; i++) if (errb[i] == '\n') errb[i] = ' '; - logmsg(LOG_ERROR, "Failed to trim disk %s (%s).", path, errb); + log_message(LOG_ERROR, "Failed to trim disk %s (%s).", path, errb); } unlink(tmp_path); @@ -127,7 +127,7 @@ bool trim_disk(const char* path) { // Replace the original disk with the trimmed disk if (rename(tmp_path, path) != 0) { - logmsg(LOG_ERROR, "Failed to replace disk %s with the trimmed disk (%s).", path, strerror(errno)); + log_message(LOG_ERROR, "Failed to replace disk %s with the trimmed disk (%s).", path, strerror(errno)); unlink(tmp_path); @@ -143,19 +143,19 @@ bool rebase_disk(const char* path, const char* backing_disk) { char* errb = NULL; // Rebase the disk - int ret = exec(NULL, &errb, "qemu-img", "rebase", "-u", "-F", "qcow2", "-b", backing_disk, path, NULL); + int ret = execute(NULL, &errb, "qemu-img", "rebase", "-u", "-F", "qcow2", "-b", backing_disk, path, NULL); // Check for errors if (ret != 0) { if (errb == NULL) - logmsg(LOG_ERROR, "Failed to rebase disk %s.", path); + log_message(LOG_ERROR, "Failed to rebase disk %s.", path); else { size_t length = strlen(errb); for (size_t i = 0; i < length; i++) if (errb[i] == '\n') errb[i] = ' '; - logmsg(LOG_ERROR, "Failed to rebase disk %s (%s).", path, errb); + log_message(LOG_ERROR, "Failed to rebase disk %s (%s).", path, errb); } return false; @@ -168,18 +168,18 @@ bool get_disk_info(const char* path, DiskInfo* info) { char* outb = NULL; char* errb = NULL; - int ret = exec(&outb, &errb, "qemu-img", "info", "--output=json", path, NULL); + int ret = execute(&outb, &errb, "qemu-img", "info", "--output=json", path, NULL); if (ret != 0) { if (errb == NULL) - logmsg(LOG_ERROR, "Failed to get information about disk %s.", path); + log_message(LOG_ERROR, "Failed to get information about disk %s.", path); else { size_t length = strlen(errb); for (size_t i = 0; i < length; i++) if (errb[i] == '\n') errb[i] = ' '; - logmsg(LOG_ERROR, "Failed to get information about disk %s (%s).", path, errb); + log_message(LOG_ERROR, "Failed to get information about disk %s (%s).", path, errb); } free(outb); @@ -195,29 +195,32 @@ bool get_disk_info(const char* path, DiskInfo* info) { free(outb); if (root == NULL) { - logmsg(LOG_ERROR, "Failed to parse the JSON output from qemu-img."); + log_message(LOG_ERROR, "Failed to parse the JSON output from qemu-img."); return false; } + // Get the virtual size json_object* virtual_size = json_object_object_get(root, "virtual-size"); if (virtual_size == NULL) info->virtual_size = 0; else info->virtual_size = json_object_get_int64(virtual_size); + // Get the actual size json_object* actual_size = json_object_object_get(root, "actual-size"); if (actual_size == NULL) info->actual_size = 0; else info->actual_size = json_object_get_int64(actual_size); + // Get the backing file json_object* backing_file = json_object_object_get(root, "backing-filename"); if (backing_file == NULL) info->backing_file = NULL; else { info->backing_file = strdup(json_object_get_string(backing_file)); if (info->backing_file == NULL) { - logmsg(LOG_ERROR, "Failed to allocate memory for the backing file path."); + log_message(LOG_ERROR, "Failed to allocate memory for the backing file path."); json_object_put(root); return false; diff --git a/src/disk.h b/src/disk.h index 8bffe32..eea3c81 100644 --- a/src/disk.h +++ b/src/disk.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include typedef struct DiskInfo { uint64_t virtual_size; diff --git a/src/entry.h b/src/entry.h index 1fce9ea..4c43558 100644 --- a/src/entry.h +++ b/src/entry.h @@ -2,26 +2,5 @@ #include #include -#include -bool is_valid_entry_name(const char* name); - -char* get_entry_path(const char* name); - -bool entry_exists(const char* name); - -char* get_entry_disk_path(const char* name); - -char** list_entries(void); - -time_t get_entry_mtime(const char* name); - -char* find_oldest_entry(void); - -bool create_entry(const char* name); - -bool delete_entry(const char* name); - -uint64_t get_available_size(void); - -void reserve_space(uint64_t size); \ No newline at end of file +#define ENTRY_POOL "/var/lib/sandbox/entries" diff --git a/src/sandbox.c b/src/sandbox.c index 6ca111b..e6b1cdd 100644 --- a/src/sandbox.c +++ b/src/sandbox.c @@ -2,26 +2,10 @@ #include "utils.h" -#include "backing.h" - #include #include #include int main(int argc, char* argv[]) { - char** backings = list_backings(); - - if (backings == NULL) { - logmsg(LOG_ERROR, "Failed to list backings."); - return 1; - } - - for (size_t i = 0; backings[i] != NULL; i++) { - printf("%s\n", backings[i]); - free(backings[i]); - } - - free(backings); - return 0; } \ No newline at end of file diff --git a/src/sandbox.h b/src/sandbox.h index 8dd27c5..6358d2f 100644 --- a/src/sandbox.h +++ b/src/sandbox.h @@ -1,3 +1,3 @@ #pragma once -int main(int argc, char* argv[]); \ No newline at end of file +int main(int argc, char* argv[]); diff --git a/src/utils.c b/src/utils.c index e2e2083..27950f4 100644 --- a/src/utils.c +++ b/src/utils.c @@ -8,8 +8,11 @@ #include #include #include +#include #include #include +#include +#include char* format(const char* fmt, ...) { va_list args; @@ -26,7 +29,7 @@ char* format(const char* fmt, ...) { // Allocate a buffer for the formatted string char* buffer = calloc(length, sizeof(char)); if (buffer == NULL) { - logmsg(LOG_ERROR, "Failed to allocate memory for the formatted string."); + log_message(LOG_ERROR, "Failed to allocate memory for the formatted string."); return NULL; } @@ -40,7 +43,7 @@ char* format(const char* fmt, ...) { return buffer; } -void logmsg(LogLevel level, const char* fmt, ...) { +void log_message(LogLevel level, const char* fmt, ...) { va_list args; va_start(args, fmt); @@ -90,7 +93,7 @@ void logmsg(LogLevel level, const char* fmt, ...) { va_end(args); } -int exec(char** outb, char** errb, const char* file, ...) { +int execute(char** outb, char** errb, const char* file, ...) { // Count the number of arguments int argc = 1; // The first argument is the file name @@ -105,7 +108,7 @@ int exec(char** outb, char** errb, const char* file, ...) { // Allocate an array for the arguments char** argv = calloc(argc + 1, sizeof(char*)); if (argv == NULL) { - logmsg(LOG_ERROR, "Failed to allocate memory for the arguments array."); + log_message(LOG_ERROR, "Failed to allocate memory for the arguments array."); return -1; } @@ -114,7 +117,7 @@ int exec(char** outb, char** errb, const char* file, ...) { argv[0] = strdup(file); if (argv[0] == NULL) { - logmsg(LOG_ERROR, "Failed to allocate memory for the file name."); + log_message(LOG_ERROR, "Failed to allocate memory for the file name."); free(argv); va_end(args); @@ -125,7 +128,7 @@ int exec(char** outb, char** errb, const char* file, ...) { for (int i = 1; i < argc; i++) { argv[i] = strdup(va_arg(args, const char*)); if (argv[i] == NULL) { - logmsg(LOG_ERROR, "Failed to allocate memory for the argument %d.", i); + log_message(LOG_ERROR, "Failed to allocate memory for the argument %d.", i); for (int j = 0; j < i; j++) free(argv[j]); @@ -144,7 +147,7 @@ int exec(char** outb, char** errb, const char* file, ...) { // Create a pipe for the standard output int outp[2]; if (pipe(outp) != 0) { - logmsg(LOG_ERROR, "Failed to create a pipe for the standard output."); + log_message(LOG_ERROR, "Failed to create a pipe for the standard output."); for (int i = 0; i < argc; i++) free(argv[i]); @@ -156,7 +159,7 @@ int exec(char** outb, char** errb, const char* file, ...) { // Create a pipe for the standard error int errp[2]; if (pipe(errp) != 0) { - logmsg(LOG_ERROR, "Failed to create a pipe for the standard error."); + log_message(LOG_ERROR, "Failed to create a pipe for the standard error."); close(outp[0]); close(outp[1]); @@ -172,7 +175,7 @@ int exec(char** outb, char** errb, const char* file, ...) { pid_t pid = fork(); if (pid == -1) { - logmsg(LOG_ERROR, "Failed to fork the process (%s).", strerror(errno)); + log_message(LOG_ERROR, "Failed to fork the process (%s).", strerror(errno)); close(outp[0]); close(outp[1]); @@ -244,7 +247,7 @@ char* read_file(int fd) { while ((n = read(fd, buffer, sizeof(buffer))) > 0) { char* new_data = realloc(data, length + n + 1); if (new_data == NULL) { - logmsg(LOG_ERROR, "Failed to allocate memory for the file data."); + log_message(LOG_ERROR, "Failed to allocate memory for the file data."); free(data); @@ -262,7 +265,7 @@ char* read_file(int fd) { // Check for read errors if (n < 0) { - logmsg(LOG_ERROR, "Failed to read the file (%s).", strerror(errno)); + log_message(LOG_ERROR, "Failed to read the file (%s).", strerror(errno)); free(data); @@ -276,14 +279,14 @@ bool copy_file(const char* src, const char* dst, mode_t mode) { // Open the source file int src_fd = open(src, O_RDONLY); if (src_fd == -1) { - logmsg(LOG_ERROR, "Failed to open the source file %s (%s).", src, strerror(errno)); + log_message(LOG_ERROR, "Failed to open the source file %s (%s).", src, strerror(errno)); return false; } // Open the destination file int dst_fd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, mode); if (dst_fd == -1) { - logmsg(LOG_ERROR, "Failed to open the destination file %s (%s).", dst, strerror(errno)); + log_message(LOG_ERROR, "Failed to open the destination file %s (%s).", dst, strerror(errno)); close(src_fd); @@ -296,7 +299,7 @@ bool copy_file(const char* src, const char* dst, mode_t mode) { while ((n = read(src_fd, buffer, sizeof(buffer))) > 0) { if (write(dst_fd, buffer, n) != n) { - logmsg(LOG_ERROR, "Failed to write to the destination file %s (%s).", dst, strerror(errno)); + log_message(LOG_ERROR, "Failed to write to the destination file %s (%s).", dst, strerror(errno)); close(src_fd); close(dst_fd); @@ -307,7 +310,7 @@ bool copy_file(const char* src, const char* dst, mode_t mode) { // Check for read errors if (n < 0) { - logmsg(LOG_ERROR, "Failed to read the source file %s (%s).", src, strerror(errno)); + log_message(LOG_ERROR, "Failed to read the source file %s (%s).", src, strerror(errno)); close(src_fd); close(dst_fd); diff --git a/src/utils.h b/src/utils.h index 3c3cf28..2349b31 100644 --- a/src/utils.h +++ b/src/utils.h @@ -13,10 +13,10 @@ typedef enum { char* format(const char* fmt, ...); -void logmsg(LogLevel level, const char* fmt, ...); +void log_message(LogLevel level, const char* fmt, ...); -int exec(char** outb, char** errb, const char* file, ...); +int execute(char** outb, char** errb, const char* file, ...); char* read_file(int fd); -bool copy_file(const char* src, const char* dst, mode_t mode); \ No newline at end of file +bool copy_file(const char* src, const char* dst, mode_t mode);