From 6f47b7f27436e7513c368378db05d6c7da641917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexe=C3=AF=20KADIR?= Date: Wed, 21 Feb 2024 17:41:12 +0100 Subject: [PATCH] Added syncing and working directory param to execute --- src/backing.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/backing.h | 4 ++++ src/disk.c | 12 ++++++------ src/sandbox.h | 3 +++ src/utils.c | 11 ++++++++++- src/utils.h | 3 ++- 6 files changed, 65 insertions(+), 8 deletions(-) diff --git a/src/backing.c b/src/backing.c index 43faecc..80fac2f 100755 --- a/src/backing.c +++ b/src/backing.c @@ -1,5 +1,6 @@ #include "backing.h" +#include "sandbox.h" #include "container.h" #include "disk.h" @@ -444,3 +445,42 @@ result_t get_backing_info(disk_info_t* _info, const char* backing) { return result; } + +result_t sync_backing_pool(void) { + // Execute /etc/sandbox.d/sync with the backing pool as the working directory + int exit_code; + // char* stdoutbuf; + char* stderrbuf; + + // Get the path of the backing pool + char* pool_path; + result_t result = get_backing_pool_path(&pool_path); + if (result != success()) + return result; + + // Execute the sync script + result = execute(&exit_code, NULL, &stderrbuf, pool_path, "/etc/sandbox.d/sync", NULL); + + free(pool_path); + + // Check for errors during the execution + if (result != success()) + return result; + + // Check the exit code + if (exit_code != 0) { + // Remove all newlines from the stderr buffer + for (char* c = stderrbuf; *c != '\0'; c++) + if (*c == '\n') + *c = ' '; + + result = failure("Failed to synchronize the backing pool (%s).", stderrbuf); + free(stderrbuf); + return result; + } + + // Free the stderr buffer as it is not needed anymore + free(stderrbuf); + + return success(); +} diff --git a/src/backing.h b/src/backing.h index 5d64ca1..332638a 100755 --- a/src/backing.h +++ b/src/backing.h @@ -82,3 +82,7 @@ result_t get_backing_parent(char** _parent, const char* backing); /// @param backing The backing to get information about. /// @return The result of the operation. result_t get_backing_info(disk_info_t* _info, const char* backing); + +/// @brief Executes /etc/sandbox.d/sync to synchronize the backing pool. +/// @return The result of the operation. +result_t sync_backing_pool(void); diff --git a/src/disk.c b/src/disk.c index ea8df80..b6dce3b 100755 --- a/src/disk.c +++ b/src/disk.c @@ -18,7 +18,7 @@ result_t create_root_disk(const char* path, uint64_t size) { // char* stdoutbuf; char* stderrbuf; - result = execute(&exit_code, NULL, &stderrbuf, "qemu-img", "create", "-f", "qcow2", path, size_str, NULL); + result = execute(&exit_code, NULL, &stderrbuf, NULL, "qemu-img", "create", "-f", "qcow2", path, size_str, NULL); // Free the size string as it is no longer needed free(size_str); @@ -51,7 +51,7 @@ result_t create_backed_disk(const char* path, const char* backing_path) { // char* stdoutbuf; char* stderrbuf; - result_t result = execute(&exit_code, NULL, &stderrbuf, "qemu-img", "create", "-f", "qcow2", "-F", "qcow2", "-b", backing_path, path, NULL); + result_t result = execute(&exit_code, NULL, &stderrbuf, NULL, "qemu-img", "create", "-f", "qcow2", "-F", "qcow2", "-b", backing_path, path, NULL); // Check for errors during the execution if (result != success()) @@ -96,9 +96,9 @@ result_t trim_disk(const char* path) { char* stderrbuf; if (info.backing_path == NULL) - result = execute(&exit_code, NULL, &stderrbuf, "qemu-img", "convert", "-f", "qcow2", "-O", "qcow2", path, temp_path, NULL); + result = execute(&exit_code, NULL, &stderrbuf, NULL, "qemu-img", "convert", "-f", "qcow2", "-O", "qcow2", path, temp_path, NULL); else - result = execute(&exit_code, NULL, &stderrbuf, "qemu-img", "convert", "-f", "qcow2", "-F", "qcow2", "-O", "qcow2", "-B", info.backing_path, path, temp_path, NULL); + result = execute(&exit_code, NULL, &stderrbuf, NULL, "qemu-img", "convert", "-f", "qcow2", "-F", "qcow2", "-O", "qcow2", "-B", info.backing_path, path, temp_path, NULL); // Free the disk info free_disk_info(&info); @@ -167,7 +167,7 @@ result_t reback_disk(const char* path, const char* backing_path) { // char* stdoutbuf; char* stderrbuf; - result_t result = execute(&exit_code, NULL, &stderrbuf, "qemu-img", "rebase", "-u", "-f", "qcow2", "-F", "qcow2", "-b", backing_path, path, NULL); + result_t result = execute(&exit_code, NULL, &stderrbuf, NULL, "qemu-img", "rebase", "-u", "-f", "qcow2", "-F", "qcow2", "-b", backing_path, path, NULL); // Check for errors during the execution if (result != success()) @@ -202,7 +202,7 @@ result_t get_disk_info(disk_info_t* _info, const char* path) { char* stdoutbuf; char* stderrbuf; - result_t result = execute(&exit_code, &stdoutbuf, &stderrbuf, "qemu-img", "info", "--output", "json", path, NULL); + result_t result = execute(&exit_code, &stdoutbuf, &stderrbuf, NULL, "qemu-img", "info", "--output", "json", path, NULL); // Check for errors during the execution if (result != success()) diff --git a/src/sandbox.h b/src/sandbox.h index 4b804c1..8347a0e 100755 --- a/src/sandbox.h +++ b/src/sandbox.h @@ -6,6 +6,9 @@ #define SANDBOX_USER "sandbox" #define LIBVIRT_DOMAIN "sandbox" +#define CONFIG_FILE "/etc/sandbox.d/sandbox.conf" +#define SYNC_FILE "/etc/sandbox.d/sync" + typedef struct { const char* name; const bool required; diff --git a/src/utils.c b/src/utils.c index 072e682..826215d 100755 --- a/src/utils.c +++ b/src/utils.c @@ -222,7 +222,7 @@ result_t parse_size(uint64_t* _size, const char* str) { } } -result_t execute(int* _exit_code, char** _stdoutbuf, char** _stderrbuf, const char* executable, ...) { +result_t execute(int* _exit_code, char** _stdoutbuf, char** _stderrbuf, const char* working_directory, const char* executable, ...) { // Initialize the output parameters if (_exit_code != NULL) *_exit_code = 0; @@ -325,6 +325,15 @@ result_t execute(int* _exit_code, char** _stdoutbuf, char** _stderrbuf, const ch close(stdout_pipe[1]); close(stderr_pipe[1]); + // Change the working directory of the child process + if (working_directory != NULL) { + errno = 0; + if (chdir(working_directory) < 0) { + fprintf(stderr, "Failed to change the working directory of the child process (%s).\n", strerror(errno)); + exit(EXIT_FAILURE); + } + } + // Execute the child process errno = 0; execvp(executable, argv); diff --git a/src/utils.h b/src/utils.h index be0a28a..2334c5a 100755 --- a/src/utils.h +++ b/src/utils.h @@ -85,10 +85,11 @@ result_t parse_size(uint64_t* _size, const char* str); /// @param _exit_code The exit code pointer to store the resulting exit code in. /// @param _stdoutbuf The standard output string pointer to store the resulting string in. The caller is responsible for freeing the string. This parameter can be NULL if the standard output is not needed. /// @param _stderrbuf The standard error string pointer to store the resulting string in. The caller is responsible for freeing the string. This parameter can be NULL if the standard error is not needed. +/// @param working_directory The working directory to execute the command in. If this parameter is NULL, the command will be executed in the current working directory. /// @param executable The command to execute. /// @param ... The arguments to pass to the command. The last argument must be NULL. No need to pass the executable as the first argument. /// @return The result of the operation. -result_t execute(int* _exit_code, char** _stdoutbuf, char** _stderrbuf, const char* executable, ...); +result_t execute(int* _exit_code, char** _stdoutbuf, char** _stderrbuf, const char* working_directory, const char* executable, ...); // @brief Reads the given file descriptor, and stores the resulting string in the given string pointer. The string can contain null characters. // @param _str The string pointer to store the resulting string in. The caller is responsible for freeing the string.