Implemented creation of root disks
This commit is contained in:
231
src/entry.c
231
src/entry.c
@@ -7,6 +7,7 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
bool is_entry_id_valid(const char* entry_id) {
|
||||
@@ -43,6 +44,42 @@ Result get_entry_path(const char* entry_id, char** out_path) {
|
||||
return format(out_path, "%s/%s", ENTRY_POOL_DIR, entry_id);
|
||||
}
|
||||
|
||||
Result get_entry_disk_path(const char* entry_id, char** out_path) {
|
||||
*out_path = NULL;
|
||||
|
||||
// Get the path of the entry
|
||||
char* entry_path;
|
||||
Result result = get_entry_path(entry_id, &entry_path);
|
||||
if (result != SUCCESS)
|
||||
return result;
|
||||
|
||||
// Get the path of the disk
|
||||
result = format(out_path, "%s/disk", entry_path);
|
||||
|
||||
// Free the entry path
|
||||
free(entry_path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Result get_entry_type_path(const char* entry_id, char** out_path) {
|
||||
*out_path = NULL;
|
||||
|
||||
// Get the path of the entry
|
||||
char* entry_path;
|
||||
Result result = get_entry_path(entry_id, &entry_path);
|
||||
if (result != SUCCESS)
|
||||
return result;
|
||||
|
||||
// Get the path of the type file
|
||||
result = format(out_path, "%s/type", entry_path);
|
||||
|
||||
// Free the entry path
|
||||
free(entry_path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Result entry_exists(const char* entry_id, bool* out_exists) {
|
||||
*out_exists = false;
|
||||
|
||||
@@ -63,4 +100,196 @@ Result entry_exists(const char* entry_id, bool* out_exists) {
|
||||
*out_exists = exists;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Result add_entry(const char* entry_id, EntryType type) {
|
||||
// Check that it does not exist
|
||||
bool exists;
|
||||
Result result = entry_exists(entry_id, &exists);
|
||||
if (result != SUCCESS)
|
||||
return result;
|
||||
|
||||
if (exists) {
|
||||
log_message(LOG_LEVEL_ERROR, "The entry '%s' already exists.", entry_id);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// Get the path of the entry
|
||||
char* entry_path;
|
||||
result = get_entry_path(entry_id, &entry_path);
|
||||
if (result != SUCCESS)
|
||||
return result;
|
||||
|
||||
// Create the directory
|
||||
if (mkdir(entry_path, 0755) == -1) {
|
||||
log_message(LOG_LEVEL_ERROR, "Failed to create the directory '%s' (%s).", entry_path, strerror(errno));
|
||||
|
||||
free(entry_path);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// Free the entry path
|
||||
free(entry_path);
|
||||
|
||||
// Get the path of the type file
|
||||
char* type_path;
|
||||
result = get_entry_type_path(entry_id, &type_path);
|
||||
if (result != SUCCESS) {
|
||||
remove_entry(entry_id);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Write the type file
|
||||
const char* type_string;
|
||||
switch (type) {
|
||||
case ENTRY_TYPE_ROOT:
|
||||
type_string = ENTRY_TYPE_ROOT_STRING;
|
||||
break;
|
||||
case ENTRY_TYPE_BACKED:
|
||||
type_string = ENTRY_TYPE_BACKED_STRING;
|
||||
break;
|
||||
case ENTRY_TYPE_AUTOMATIC:
|
||||
type_string = ENTRY_TYPE_AUTOMATIC_STRING;
|
||||
break;
|
||||
default:
|
||||
log_message(LOG_LEVEL_ERROR, "Invalid entry type.");
|
||||
remove_entry(entry_id);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
result = write_file(type_path, type_string);
|
||||
|
||||
// Free the type path
|
||||
free(type_path);
|
||||
|
||||
if (result != SUCCESS) {
|
||||
remove_entry(entry_id);
|
||||
return result;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Result add_root_entry(const char* entry_id, uint64_t size) {
|
||||
// Add the entry
|
||||
Result result = add_entry(entry_id, ENTRY_TYPE_ROOT);
|
||||
if (result != SUCCESS)
|
||||
return result;
|
||||
|
||||
// Get the path of the disk
|
||||
char* disk_path;
|
||||
result = get_entry_disk_path(entry_id, &disk_path);
|
||||
if (result != SUCCESS) {
|
||||
remove_entry(entry_id);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Create the disk
|
||||
result = create_root_disk(disk_path, size, 0644);
|
||||
|
||||
// Free the disk path
|
||||
free(disk_path);
|
||||
|
||||
if (result != SUCCESS) {
|
||||
remove_entry(entry_id);
|
||||
return result;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Result remove_entry(const char* entry_id) {
|
||||
// Check that it exists
|
||||
bool exists;
|
||||
Result result = entry_exists(entry_id, &exists);
|
||||
if (result != SUCCESS)
|
||||
return result;
|
||||
|
||||
if (!exists) {
|
||||
log_message(LOG_LEVEL_ERROR, "The entry '%s' does not exist.", entry_id);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// Get the path of the entry
|
||||
char* entry_path;
|
||||
result = get_entry_path(entry_id, &entry_path);
|
||||
if (result != SUCCESS)
|
||||
return result;
|
||||
|
||||
// Remove the directory
|
||||
if (rmdir(entry_path) == -1) {
|
||||
log_message(LOG_LEVEL_ERROR, "Failed to remove the directory '%s' (%s).", entry_path, strerror(errno));
|
||||
|
||||
free(entry_path);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// Free the entry path
|
||||
free(entry_path);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Result get_entry_info(const char* entry_id, EntryInfo* out_info) {
|
||||
out_info->backing_id = NULL;
|
||||
out_info->type = ENTRY_TYPE_UNKNOWN;
|
||||
|
||||
// Get the path of the type file
|
||||
char* type_path;
|
||||
Result result = get_entry_type_path(entry_id, &type_path);
|
||||
if (result != SUCCESS)
|
||||
return result;
|
||||
|
||||
// Read the type file
|
||||
char* type;
|
||||
result = read_file(type_path, &type);
|
||||
if (result != SUCCESS) {
|
||||
free(type_path);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Free the type path
|
||||
free(type_path);
|
||||
|
||||
// Check the type
|
||||
if (strcmp(type, ENTRY_TYPE_ROOT_STRING) == 0)
|
||||
out_info->type = ENTRY_TYPE_ROOT;
|
||||
else if (strcmp(type, ENTRY_TYPE_BACKED_STRING) == 0)
|
||||
out_info->type = ENTRY_TYPE_BACKED;
|
||||
else if (strcmp(type, ENTRY_TYPE_AUTOMATIC_STRING) == 0)
|
||||
out_info->type = ENTRY_TYPE_AUTOMATIC;
|
||||
|
||||
// Free the type
|
||||
free(type);
|
||||
|
||||
// Get the path of the entry disk
|
||||
char* disk_path;
|
||||
result = get_entry_disk_path(entry_id, &disk_path);
|
||||
if (result != SUCCESS)
|
||||
return result;
|
||||
|
||||
// Get the information about the disk
|
||||
result = get_disk_info(disk_path, &out_info->disk_info);
|
||||
|
||||
// Free the disk path
|
||||
free(disk_path);
|
||||
|
||||
if (result != SUCCESS)
|
||||
return result;
|
||||
|
||||
// Check if the disk is backed
|
||||
if (out_info->disk_info.backing_file != NULL) {
|
||||
out_info->backing_id = strdup(basename(out_info->disk_info.backing_file));
|
||||
if (out_info->backing_id == NULL) {
|
||||
free_disk_info(&out_info->disk_info);
|
||||
return OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void free_entry_info(EntryInfo* info) {
|
||||
free(info->backing_id);
|
||||
free_disk_info(&info->disk_info);
|
||||
}
|
||||
|
Reference in New Issue
Block a user