Added add-backing and remove-backing commands (still missing recursive remove)

This commit is contained in:
Alexei KADIR 2024-02-18 15:23:01 +01:00
parent 444bbc6ebe
commit 5613fbdcab
4 changed files with 186 additions and 3 deletions

View File

@ -84,6 +84,124 @@ Status DoesBackingExist(const char* backing_identifier, bool* _result) {
return SUCCESS; return SUCCESS;
} }
Status AddBacking(const char* backing_identifier, const char* entry_identifier) {
// Check that the backing does not already exist
bool exists;
Status status = DoesBackingExist(backing_identifier, &exists);
if (status != SUCCESS)
return status;
if (exists) {
Log(LOG_LEVEL_ERROR, "The backing '%s' already exists.", backing_identifier);
return FAILURE;
}
// Check that the entry disk exists
status = DoesEntryDiskExist(entry_identifier, &exists);
if (status != SUCCESS)
return status;
if (!exists) {
Log(LOG_LEVEL_ERROR, "The entry disk '%s' does not exist. Cannot create backing from it.", entry_identifier);
return FAILURE;
}
// Get information about the entry disk
DiskInfo entry_info;
status = GetEntryDiskInfo(entry_identifier, &entry_info);
if (status != SUCCESS)
return status;
// Check that the backing used by the entry actually exists (broken backing chain)
if (entry_info.backing_identifier != NULL) {
status = DoesBackingExist(entry_info.backing_identifier, &exists);
if (status != SUCCESS) {
FreeDiskInfo(&entry_info);
return status;
}
if (!exists) {
Log(LOG_LEVEL_ERROR, "The backing '%s' of the entry disk '%s' does not exist.", entry_info.backing_identifier, entry_identifier);
FreeDiskInfo(&entry_info);
return FAILURE;
}
}
// Copy the entry disk to the backing disk
char* entry_disk_path = NULL;
status = GetEntryDiskPath(entry_identifier, &entry_disk_path);
if (status != SUCCESS) {
FreeDiskInfo(&entry_info);
return status;
}
char* backing_path = NULL;
status = GetBackingPath(backing_identifier, &backing_path);
if (status != SUCCESS) {
free(entry_disk_path);
FreeDiskInfo(&entry_info);
return status;
}
status = CopyFile(entry_disk_path, backing_path);
if (status != SUCCESS) {
free(entry_disk_path);
free(backing_path);
FreeDiskInfo(&entry_info);
return status;
}
free(entry_disk_path);
// If the entry disk has a backing, rebase the backing to the new backing
if (entry_info.backing_identifier != NULL) {
status = RebaseDisk(backing_path, entry_info.backing_identifier);
if (status != SUCCESS) {
RemoveBacking(backing_identifier);
free(backing_path);
FreeDiskInfo(&entry_info);
return status;
}
}
free(backing_path);
FreeDiskInfo(&entry_info);
return SUCCESS;
}
Status RemoveBacking(const char* backing_identifier) {
// Check that the backing exists
bool exists;
Status status = DoesBackingExist(backing_identifier, &exists);
if (status != SUCCESS)
return status;
if (!exists) {
Log(LOG_LEVEL_ERROR, "The backing '%s' does not exist.", backing_identifier);
return FAILURE;
}
// Get the backing path
char* backing_path = NULL;
status = GetBackingPath(backing_identifier, &backing_path);
if (status != SUCCESS)
return status;
// Remove the backing
if (unlink(backing_path) != 0) {
Log(LOG_LEVEL_ERROR, "Failed to remove the backing '%s' (%s).", backing_identifier, strerror(errno));
free(backing_path);
return FAILURE;
}
free(backing_path);
// TODO: Remove all the backings that use this backing as a base
return SUCCESS;
}
Status ListBackings(char*** _backings) { Status ListBackings(char*** _backings) {
*_backings = NULL; *_backings = NULL;

View File

@ -155,7 +155,7 @@ Status RebaseDisk(const char* path, const char* backing_file) {
// char* stdout; // char* stdout;
char* stderrb; char* stderrb;
Status status = RunExecutable(&exit_code, NULL, &stderrb, "/usr/bin/qemu-img", "rebase", "-u", "-b", backing_file, path, NULL); Status status = RunExecutable(&exit_code, NULL, &stderrb, "/usr/bin/qemu-img", "rebase", "-f", "qcow2", "-F", "qcow2", "-u", "-b", backing_file, path, NULL);
// Check if the disk was created successfully // Check if the disk was created successfully
if (status != SUCCESS) if (status != SUCCESS)

View File

@ -33,7 +33,13 @@ Command COMMANDS[] = {
{CommandResetDisk, "reset-disk", "<entry id> [--update|-u] [--backed|-b <backing id>]", "Resets the disk of an entry.", {CommandResetDisk, "reset-disk", "<entry id> [--update|-u] [--backed|-b <backing id>]", "Resets the disk of an entry.",
"TODO: Add details."}, "TODO: Add details."},
{CommandTrimDisk, "trim-disk", "<entry id>", "Trims the disk of an entry.", {CommandTrimDisk, "trim-disk", "<entry id>", "Trims the disk of an entry.",
"TODO: Add details."}}; "TODO: Add details."},
{},
{CommandAddBacking, "add-backing", "<backing id> <entry id>", "Adds a new backing to the sandbox.",
"TODO: Add details."},
{CommandRemoveBacking, "remove-backing", "<backing id>", "Removes a backing from the sandbox.",
"TODO: Add details."},
};
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
struct passwd* pw = getpwnam(SANDBOX_USER); struct passwd* pw = getpwnam(SANDBOX_USER);
@ -149,6 +155,9 @@ int CommandVersion(int argc, char* argv[]) {
} }
fprintf(stdout, "Sandbox utility v%s\n", VERSION); fprintf(stdout, "Sandbox utility v%s\n", VERSION);
AddBacking("2 - Test", "test");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
@ -365,6 +374,11 @@ int CommandAddDisk(int argc, char* argv[]) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (backing_id == NULL) {
Log(LOG_LEVEL_ERROR, "No backings exist to use as the default backing.");
return EXIT_FAILURE;
}
// Add the backed disk // Add the backed disk
status = AddBackedEntryDisk(entry_id, backing_id); status = AddBackedEntryDisk(entry_id, backing_id);
if (status != SUCCESS) { if (status != SUCCESS) {
@ -462,6 +476,11 @@ int CommandResetDisk(int argc, char* argv[]) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (backing_id == NULL) {
Log(LOG_LEVEL_ERROR, "No backings exist to use as the default backing.");
return EXIT_FAILURE;
}
// Reset the disk // Reset the disk
status = ResetEntryDisk(entry_id, backing_id); status = ResetEntryDisk(entry_id, backing_id);
if (status != SUCCESS) { if (status != SUCCESS) {
@ -511,3 +530,46 @@ int CommandTrimDisk(int argc, char* argv[]) {
Log(LOG_LEVEL_INFO, "Successfully trimmed disk from entry '%s'.", entry_id); Log(LOG_LEVEL_INFO, "Successfully trimmed disk from entry '%s'.", entry_id);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
int CommandAddBacking(int argc, char* argv[]) {
if (argc < 2) {
Log(LOG_LEVEL_ERROR, "Too few arguments supplied to command 'add-backing'.");
return EXIT_FAILURE;
} else if (argc > 2) {
Log(LOG_LEVEL_ERROR, "Too many arguments supplied to command 'add-backing'.");
return EXIT_FAILURE;
}
// Extract the backing identifier and entry identifier
const char* backing_id = argv[0];
const char* entry_id = argv[1];
// Add the backing
Status status = AddBacking(backing_id, entry_id);
if (status != SUCCESS)
return EXIT_FAILURE;
Log(LOG_LEVEL_INFO, "Successfully added backing '%s' from entry '%s'.", backing_id, entry_id);
return EXIT_SUCCESS;
}
int CommandRemoveBacking(int argc, char* argv[]) {
if (argc < 1) {
Log(LOG_LEVEL_ERROR, "Too few arguments supplied to command 'remove-backing'.");
return EXIT_FAILURE;
} else if (argc > 1) {
Log(LOG_LEVEL_ERROR, "Too many arguments supplied to command 'remove-backing'.");
return EXIT_FAILURE;
}
// Extract the backing identifier
const char* backing_id = argv[0];
// Remove the backing
Status status = RemoveBacking(backing_id);
if (status != SUCCESS)
return EXIT_FAILURE;
Log(LOG_LEVEL_INFO, "Successfully removed backing '%s'.", backing_id);
return EXIT_SUCCESS;
}

View File

@ -25,4 +25,7 @@ int CommandClearEntries(int argc, char* argv[]);
int CommandAddDisk(int argc, char* argv[]); int CommandAddDisk(int argc, char* argv[]);
int CommandRemoveDisk(int argc, char* argv[]); int CommandRemoveDisk(int argc, char* argv[]);
int CommandResetDisk(int argc, char* argv[]); int CommandResetDisk(int argc, char* argv[]);
int CommandTrimDisk(int argc, char* argv[]); int CommandTrimDisk(int argc, char* argv[]);
int CommandAddBacking(int argc, char* argv[]);
int CommandRemoveBacking(int argc, char* argv[]);