Added add_backing

This commit is contained in:
Alexei KADIR 2024-02-19 18:18:18 +01:00
parent b77418f0ec
commit 3c773a8dc2
6 changed files with 321 additions and 2 deletions

View File

@ -9,6 +9,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <libgen.h>
#include <sys/stat.h> #include <sys/stat.h>
result_t check_backing_identifier(const char* backing) { result_t check_backing_identifier(const char* backing) {
@ -69,10 +70,16 @@ result_t check_backing_exists(const char* backing) {
} }
result_t get_backing_pool_path(char** _path) { result_t get_backing_pool_path(char** _path) {
// Initialize the output parameters
*_path = NULL;
return format(_path, "/var/lib/sandbox/backings"); return format(_path, "/var/lib/sandbox/backings");
} }
result_t get_backing_path(char** _path, const char* backing) { result_t get_backing_path(char** _path, const char* backing) {
// Initialize the output parameters
*_path = NULL;
// Check the backing identifier // Check the backing identifier
result_t result = check_backing_identifier(backing); result_t result = check_backing_identifier(backing);
if (result != success()) if (result != success())
@ -92,6 +99,9 @@ result_t get_backing_path(char** _path, const char* backing) {
} }
result_t get_backing_default_path(char** _path) { result_t get_backing_default_path(char** _path) {
// Initialize the output parameters
*_path = NULL;
// Get the backing pool path // Get the backing pool path
char* pool_path; char* pool_path;
result_t result = get_backing_pool_path(&pool_path); result_t result = get_backing_pool_path(&pool_path);
@ -105,6 +115,148 @@ result_t get_backing_default_path(char** _path) {
return result; return result;
} }
result_t get_backing_temp_path(char** _path) {
// Initialize the output parameters
*_path = NULL;
// Get the backing pool path
char* pool_path;
result_t result = get_backing_pool_path(&pool_path);
if (result != success())
return result;
// Format the backing path
result = format(_path, "%s/temp", pool_path);
free(pool_path);
return result;
}
result_t add_backing(char** _backing, const char* container) {
// Initialize the output parameters
*_backing = NULL;
// Get the container path
char* path;
result_t result = get_container_path(&path, container);
if (result != success())
return result;
// Import the container as a backing
result = import_backing(_backing, path);
free(path);
return result;
}
result_t import_backing(char** _backing, const char* path) {
// Initialize the output parameters
*_backing = NULL;
// Get the temporary backing path
char* temp_path;
result_t result = get_backing_temp_path(&temp_path);
if (result != success())
return result;
// Copy the disk to the temporary backing path
result = copy_file(path, temp_path);
if (result != success()) {
free(temp_path);
return result;
}
// Get the disk info to know if the disk is backed
disk_info_t info;
result = get_disk_info(&info, temp_path);
if (result != success()) {
remove(temp_path);
free(temp_path);
return result;
}
if (info.backing_path != NULL) {
// Get the backing identifier of the parent
char* backing = strdup(basename(info.backing_path));
if (backing == NULL) {
free_disk_info(&info);
remove(temp_path);
free(temp_path);
return failure("Failed to get the backing identifier of the parent.");
}
// Check that the backing exists
result = check_backing_exists(backing);
if (result != success()) {
free_disk_info(&info);
remove(temp_path);
free(temp_path);
free(backing);
return result;
}
// Reback the disk to the parent
result = reback_disk(temp_path, backing);
if (result != success()) {
free_disk_info(&info);
remove(temp_path);
free(temp_path);
free(backing);
return result;
}
free(backing);
}
free_disk_info(&info);
// Get the md5 hash of the disk as the backing identifier
char* backing;
result = md5sum(&backing, temp_path);
if (result != success()) {
remove(temp_path);
free(temp_path);
return result;
}
// Check if the backing already exists
result = check_backing_exists(backing);
if (result == success()) {
result = failure("Backing '%s' already exists.", backing);
free(backing);
remove(temp_path);
free(temp_path);
return result;
}
// Get the path of the final backing
char* backing_path;
result = get_backing_path(&backing_path, backing);
if (result != success()) {
free(backing);
remove(temp_path);
free(temp_path);
return result;
}
// Move the temporary backing to the final backing path
errno = 0;
if (rename(temp_path, backing_path) != 0) {
result = failure("Failed to move the temporary backing to the final backing path (%s).", strerror(errno));
free(backing);
free(backing_path);
remove(temp_path);
free(temp_path);
return result;
}
free(backing_path);
free(temp_path);
*_backing = backing;
return result;
}
result_t remove_backing(const char* backing) { result_t remove_backing(const char* backing) {
// Check that the backing exists // Check that the backing exists
result_t result = check_backing_exists(backing); result_t result = check_backing_exists(backing);
@ -137,6 +289,9 @@ bool backing_filter(const char* file) {
} }
result_t list_backings(char*** _backings) { result_t list_backings(char*** _backings) {
// Initialize the output parameters
*_backings = NULL;
// Get the backing pool path // Get the backing pool path
char* pool_path; char* pool_path;
result_t result = get_backing_pool_path(&pool_path); result_t result = get_backing_pool_path(&pool_path);
@ -151,6 +306,9 @@ result_t list_backings(char*** _backings) {
} }
result_t get_default_backing(char** _backing) { result_t get_default_backing(char** _backing) {
// Initialize the output parameters
*_backing = NULL;
// Get the backing default path // Get the backing default path
char* path; char* path;
result_t result = get_backing_default_path(&path); result_t result = get_backing_default_path(&path);

View File

@ -8,8 +8,10 @@ result_t check_backing_exists(const char* backing);
result_t get_backing_pool_path(char** _path); result_t get_backing_pool_path(char** _path);
result_t get_backing_path(char** _path, const char* backing); result_t get_backing_path(char** _path, const char* backing);
result_t get_backing_default_path(char** _path); result_t get_backing_default_path(char** _path);
result_t get_backing_temp_path(char** _path);
result_t add_backing(const char* backing, const char* container); result_t add_backing(char** _backing, const char* container);
result_t import_backing(char** _backing, const char* path);
result_t remove_backing(const char* backing); result_t remove_backing(const char* backing);
bool backing_filter(const char* file); bool backing_filter(const char* file);

View File

@ -71,10 +71,16 @@ result_t check_container_exists(const char* container) {
} }
result_t get_container_pool_path(char** _path) { result_t get_container_pool_path(char** _path) {
// Initialize the output parameters
*_path = NULL;
return format(_path, "/var/lib/sandbox/containers"); return format(_path, "/var/lib/sandbox/containers");
} }
result_t get_container_path(char** _path, const char* container) { result_t get_container_path(char** _path, const char* container) {
// Initialize the output parameters
*_path = NULL;
// Check the container identifier // Check the container identifier
result_t result = check_container_identifier(container); result_t result = check_container_identifier(container);
if (result != success()) if (result != success())
@ -208,6 +214,9 @@ bool container_filter(const char* file) {
} }
result_t list_containers(char*** _containers) { result_t list_containers(char*** _containers) {
// Initialize the output parameters
*_containers = NULL;
// Get the container pool path // Get the container pool path
char* pool_path; char* pool_path;
result_t result = get_container_pool_path(&pool_path); result_t result = get_container_pool_path(&pool_path);

View File

@ -1,6 +1,8 @@
#include "sandbox.h" #include "sandbox.h"
#include "utils.h" #include "utils.h"
#include "backing.h"
#include "container.h"
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
@ -65,6 +67,13 @@ int main(int argc, char** argv) {
} }
// TODO: Parse commands from the command line // TODO: Parse commands from the command line
while (1) {
char* backing2;
result_t result = add_backing(&backing2, "test2");
if (result != success()) {
fprintf(stderr, "Failed to add backing: %s\n", error());
}
}
} }
int command_help(int argc, char* argv[]) { int command_help(int argc, char* argv[]) {

View File

@ -10,7 +10,7 @@
#include <errno.h> #include <errno.h>
#include <dirent.h> #include <dirent.h>
#include <fcntl.h> #include <fcntl.h>
#include <openssl/md5.h> #include <openssl/evp.h>
char ERROR_BUFFER[ERROR_BUFFER_SIZE]; char ERROR_BUFFER[ERROR_BUFFER_SIZE];
@ -412,6 +412,62 @@ result_t write_file(const char* path, const char* str) {
return result; return result;
} }
result_t copy_file(const char* src, const char* dst) {
// Open the source file
errno = 0;
int src_fd = open(src, O_RDONLY);
if (src_fd < 0)
return failure("Failed to open the source file '%s' (%s).", src, strerror(errno));
// Open the destination file
errno = 0;
int dst_fd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (dst_fd < 0) {
close(src_fd);
return failure("Failed to open the destination file '%s' (%s).", dst, strerror(errno));
}
// Copy the source file to the destination file
char buffer[4096];
ssize_t count;
while (1) {
// Read from the source file
errno = 0;
count = read(src_fd, buffer, sizeof(buffer));
if (count < 0) {
close(src_fd);
close(dst_fd);
return failure("Failed to read from the source file '%s' (%s).", src, strerror(errno));
}
// If the end of the file is reached, stop copying
if (count == 0)
break;
// Write to the destination file
while (count > 0) {
errno = 0;
ssize_t written = write(dst_fd, buffer, count);
if (written < 0) {
close(src_fd);
close(dst_fd);
return failure("Failed to write to the destination file '%s' (%s).", dst, strerror(errno));
}
count -= written;
}
}
// Close the source file
close(src_fd);
// Close the destination file
close(dst_fd);
return success();
}
result_t list_files(char*** _files, const char* path, bool (*filter)(const char*)) { result_t list_files(char*** _files, const char* path, bool (*filter)(const char*)) {
// Initialize the output parameters // Initialize the output parameters
*_files = NULL; *_files = NULL;
@ -493,3 +549,85 @@ result_t list_files(char*** _files, const char* path, bool (*filter)(const char*
*_files = files; *_files = files;
return success(); return success();
} }
result_t md5sum(char** _md5, const char* path) {
// Initialize the output parameters
*_md5 = NULL;
// Open the file
errno = 0;
int fd = open(path, O_RDONLY);
if (fd < 0)
return failure("Failed to open the file '%s' (%s).", path, strerror(errno));
// Initialize the MD5 context
EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
if (mdctx == NULL) {
close(fd);
return failure("Failed to initialize the MD5 context.");
}
if (EVP_DigestInit_ex(mdctx, EVP_md5(), NULL) != 1) {
EVP_MD_CTX_free(mdctx);
close(fd);
return failure("Failed to initialize the MD5 context.");
}
// Read the file and update the MD5 context
char buffer[4096];
ssize_t count;
while (1) {
// Read from the file
errno = 0;
count = read(fd, buffer, sizeof(buffer));
if (count < 0) {
EVP_MD_CTX_free(mdctx);
close(fd);
return failure("Failed to read from the file '%s' (%s).", path, strerror(errno));
}
// If the end of the file is reached, stop updating the MD5 context
if (count == 0)
break;
// Update the MD5 context
if (EVP_DigestUpdate(mdctx, buffer, count) != 1) {
EVP_MD_CTX_free(mdctx);
close(fd);
return failure("Failed to update the MD5 context.");
}
}
// Finalize the MD5 context
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
if (EVP_DigestFinal_ex(mdctx, md_value, &md_len) != 1) {
EVP_MD_CTX_free(mdctx);
close(fd);
return failure("Failed to finalize the MD5 context.");
}
EVP_MD_CTX_free(mdctx);
// Close the file
close(fd);
// Format the MD5 checksum
errno = 0;
char* md5 = malloc(2 * md_len + 1); // +1 for the null terminator
if (md5 == NULL)
return failure("Failed to allocate memory for the MD5 checksum (%s).", strerror(errno));
for (unsigned int i = 0; i < md_len; i++)
if (snprintf(md5 + 2 * i, 3, "%02x", md_value[i]) != 2) {
free(md5);
return failure("Failed to format the MD5 checksum.");
}
md5[2 * md_len] = '\0';
// Return the MD5 checksum
*_md5 = md5;
return success();
}

View File

@ -26,5 +26,8 @@ result_t read_fd(char** _str, int fd);
result_t write_fd(int fd, const char* str); result_t write_fd(int fd, const char* str);
result_t read_file(char** _str, const char* path); result_t read_file(char** _str, const char* path);
result_t write_file(const char* path, const char* str); result_t write_file(const char* path, const char* str);
result_t copy_file(const char* src, const char* dst);
result_t list_files(char*** _files, const char* path, bool (*filter)(const char*)); result_t list_files(char*** _files, const char* path, bool (*filter)(const char*));
result_t md5sum(char** _md5, const char* path);