Added some signatures for XML generation and domain management
This commit is contained in:
parent
2cad33d0e6
commit
f2f94b70d4
@ -1,8 +0,0 @@
|
|||||||
#include "domain.h"
|
|
||||||
|
|
||||||
#include "sandbox.h"
|
|
||||||
#include "container.h"
|
|
||||||
#include "pci.h"
|
|
||||||
#include "xml.h"
|
|
||||||
|
|
||||||
#include <libvirt/libvirt.h>
|
|
22
src/domain.h
22
src/domain.h
@ -1,3 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
/// @brief Converts a container identifier to a domain identifier.
|
||||||
|
/// @param _domain The string pointer to store the resulting domain identifier in. The caller is responsible for freeing the string.
|
||||||
|
/// @param container The container identifier to convert.
|
||||||
|
/// @return The result of the operation.
|
||||||
|
result_t container_to_domain_identifier(char** _domain, const char* container);
|
||||||
|
|
||||||
|
/// @brief Converts a domain identifier to a container identifier.
|
||||||
|
/// @param _container The string pointer to store the resulting container identifier in. The caller is responsible for freeing the string.
|
||||||
|
/// @param domain The domain identifier to convert.
|
||||||
|
/// @return The result of the operation.
|
||||||
|
result_t domain_to_container_identifier(char** _container, const char* domain);
|
||||||
|
|
||||||
|
/// @brief Checks whether the given string is a valid domain identifier. If the string is not a valid domain identifier, the call will return a failure result with an error message.
|
||||||
|
/// @param domain The string to check.
|
||||||
|
/// @return The result of the operation.
|
||||||
|
result_t check_domain_identifier(const char* domain);
|
||||||
|
|
||||||
|
/// @brief Checks whether the given domain exists. If the domain does not exist, the call will return a failure result with an error message.
|
||||||
|
/// @param domain The domain to check.
|
||||||
|
/// @return The result of the operation.
|
||||||
|
result_t check_domain_exists(const char* domain);
|
||||||
|
42
src/pci.c
42
src/pci.c
@ -8,36 +8,36 @@
|
|||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
result_t check_pci_address(const char* pci) {
|
result_t check_pci_address(const char* pci_address) {
|
||||||
// Check the length of the string (should be 12 characters, eg. 0000:00:00.0)
|
// Check the length of the string (should be 12 characters, eg. 0000:00:00.0)
|
||||||
if (strlen(pci) != 12)
|
if (strlen(pci_address) != 12)
|
||||||
return failure("Invalid PCI address '%s'. Valid PCI addresses are in the format '0000:00:00.0'.", pci);
|
return failure("Invalid PCI address '%s'. Valid PCI addresses are in the format '0000:00:00.0'.", pci_address);
|
||||||
|
|
||||||
// Check the format of the string
|
// Check the format of the string
|
||||||
for (int i = 0; i < 12; i++)
|
for (int i = 0; i < 12; i++)
|
||||||
if (i == 4 || i == 7) {
|
if (i == 4 || i == 7) {
|
||||||
if (pci[i] != ':')
|
if (pci_address[i] != ':')
|
||||||
return failure("Invalid PCI address '%s'. Missing colon at position %d. Valid PCI addresses are in the format '0000:00:00.0'.", pci, i);
|
return failure("Invalid PCI address '%s'. Missing colon at position %d. Valid PCI addresses are in the format '0000:00:00.0'.", pci_address, i);
|
||||||
} else if (i == 10) {
|
} else if (i == 10) {
|
||||||
if (pci[i] != '.')
|
if (pci_address[i] != '.')
|
||||||
return failure("Invalid PCI address '%s'. Missing dot at position %d. Valid PCI addresses are in the format '0000:00:00.0'.", pci, i);
|
return failure("Invalid PCI address '%s'. Missing dot at position %d. Valid PCI addresses are in the format '0000:00:00.0'.", pci_address, i);
|
||||||
} else {
|
} else {
|
||||||
if (!isxdigit(pci[i]))
|
if (!isxdigit(pci_address[i]))
|
||||||
return failure("Invalid PCI address '%s'. Non-hexadecimal character '%c' at position %d. Valid PCI addresses are in the format '0000:00:00.0'.", pci, pci[i], i);
|
return failure("Invalid PCI address '%s'. Non-hexadecimal character '%c' at position %d. Valid PCI addresses are in the format '0000:00:00.0'.", pci_address, pci_address[i], i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t check_pci_exists(const char* pci) {
|
result_t check_pci_exists(const char* pci_address) {
|
||||||
// Check the PCI address format
|
// Check the PCI address format
|
||||||
result_t result = check_pci_address(pci);
|
result_t result = check_pci_address(pci_address);
|
||||||
if (result != success())
|
if (result != success())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
// Check if the PCI address exists by checking if the sysfs directory exists
|
// Check if the PCI address exists by checking if the sysfs directory exists
|
||||||
char* path;
|
char* path;
|
||||||
result = format(&path, "/sys/bus/pci/devices/%s", pci);
|
result = format(&path, "/sys/bus/pci/devices/%s", pci_address);
|
||||||
if (result != success())
|
if (result != success())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ result_t check_pci_exists(const char* pci) {
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(path, &st) != 0 || !S_ISDIR(st.st_mode)) {
|
if (stat(path, &st) != 0 || !S_ISDIR(st.st_mode)) {
|
||||||
free(path);
|
free(path);
|
||||||
return failure("PCI address '%s' does not exist.", pci);
|
return failure("PCI address '%s' does not exist.", pci_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the path
|
// Free the path
|
||||||
@ -54,18 +54,18 @@ result_t check_pci_exists(const char* pci) {
|
|||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t get_iommu_group(int* _group, const char* pci) {
|
result_t get_iommu_group(int* _group, const char* pci_address) {
|
||||||
// Initialize the output parameter
|
// Initialize the output parameter
|
||||||
*_group = -1;
|
*_group = -1;
|
||||||
|
|
||||||
// Check that the PCI address exists
|
// Check that the PCI address exists
|
||||||
result_t result = check_pci_exists(pci);
|
result_t result = check_pci_exists(pci_address);
|
||||||
if (result != success())
|
if (result != success())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
// Get the IOMMU group if the PCI device has one
|
// Get the IOMMU group if the PCI device has one
|
||||||
char* path;
|
char* path;
|
||||||
result = format(&path, "/sys/bus/pci/devices/%s/iommu_group", pci);
|
result = format(&path, "/sys/bus/pci/devices/%s/iommu_group", pci_address);
|
||||||
if (result != success())
|
if (result != success())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ result_t get_iommu_group(int* _group, const char* pci) {
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path, &st) != 0 || !S_ISLNK(st.st_mode)) {
|
if (lstat(path, &st) != 0 || !S_ISLNK(st.st_mode)) {
|
||||||
free(path);
|
free(path);
|
||||||
return failure("PCI address '%s' does not have an IOMMU group. Please ensure that the IOMMU is enabled in the kernel.", pci);
|
return failure("PCI address '%s' does not have an IOMMU group. Please ensure that the IOMMU is enabled in the kernel.", pci_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the IOMMU group by getting the path of the symlink, and getting the basename of the path
|
// Read the IOMMU group by getting the path of the symlink, and getting the basename of the path
|
||||||
@ -84,7 +84,7 @@ result_t get_iommu_group(int* _group, const char* pci) {
|
|||||||
|
|
||||||
// Check for errors during the readlink call
|
// Check for errors during the readlink call
|
||||||
if (len == -1)
|
if (len == -1)
|
||||||
return failure("Failed to read IOMMU group of PCI address '%s'.", pci);
|
return failure("Failed to read IOMMU group of PCI address '%s'.", pci_address);
|
||||||
|
|
||||||
// Null-terminate the path
|
// Null-terminate the path
|
||||||
iommu_group_path[len] = '\0';
|
iommu_group_path[len] = '\0';
|
||||||
@ -95,14 +95,14 @@ result_t get_iommu_group(int* _group, const char* pci) {
|
|||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t get_iommu_groups(int** _groups, int* _count, const char** pcis) {
|
result_t get_iommu_groups(int** _groups, int* _count, const char** pci_addresses) {
|
||||||
// Initialize the output parameters
|
// Initialize the output parameters
|
||||||
*_groups = NULL;
|
*_groups = NULL;
|
||||||
*_count = 0;
|
*_count = 0;
|
||||||
|
|
||||||
// Count the number of PCI devices
|
// Count the number of PCI devices
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (pcis[count] != NULL)
|
while (pci_addresses[count] != NULL)
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
// Allocate memory for the groups
|
// Allocate memory for the groups
|
||||||
@ -113,7 +113,7 @@ result_t get_iommu_groups(int** _groups, int* _count, const char** pcis) {
|
|||||||
// Get the IOMMU groups of the PCI devices
|
// Get the IOMMU groups of the PCI devices
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
// Get the IOMMU group of the PCI device
|
// Get the IOMMU group of the PCI device
|
||||||
result_t result = get_iommu_group(&groups[i], pcis[i]);
|
result_t result = get_iommu_group(&groups[i], pci_addresses[i]);
|
||||||
if (result != success()) {
|
if (result != success()) {
|
||||||
free(groups);
|
free(groups);
|
||||||
return result;
|
return result;
|
||||||
|
16
src/pci.h
16
src/pci.h
@ -3,27 +3,27 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
/// @brief Checks whether the given string is a valid PCI address. If the string is not a valid PCI address, the call will return a failure result with an error message.
|
/// @brief Checks whether the given string is a valid PCI address. If the string is not a valid PCI address, the call will return a failure result with an error message.
|
||||||
/// @param pci The string to check.
|
/// @param pci_address The string to check.
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t check_pci_address(const char* pci);
|
result_t check_pci_address(const char* pci_address);
|
||||||
|
|
||||||
/// @brief Checks whether the given PCI address exists. If the PCI address does not exist, the call will return a failure result with an error message.
|
/// @brief Checks whether the given PCI address exists. If the PCI address does not exist, the call will return a failure result with an error message.
|
||||||
/// @param pci The PCI address to check.
|
/// @param pci_address The PCI address to check.
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t check_pci_exists(const char* pci);
|
result_t check_pci_exists(const char* pci_address);
|
||||||
|
|
||||||
/// @brief Gets the IOMMU group of the given PCI address.
|
/// @brief Gets the IOMMU group of the given PCI address.
|
||||||
/// @param _group The integer pointer to store the resulting IOMMU group in.
|
/// @param _group The integer pointer to store the resulting IOMMU group in.
|
||||||
/// @param pci The PCI address to get the IOMMU group of.
|
/// @param pci_address The PCI address to get the IOMMU group of.
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t get_iommu_group(int* _group, const char* pci);
|
result_t get_iommu_group(int* _group, const char* pci_address);
|
||||||
|
|
||||||
/// @brief Gets the IOMMU groups of the given PCI addresses.
|
/// @brief Gets the IOMMU groups of the given PCI addresses.
|
||||||
/// @param _groups The integer array pointer to store the resulting IOMMU groups in. The caller is responsible for freeing the array.
|
/// @param _groups The integer array pointer to store the resulting IOMMU groups in. The caller is responsible for freeing the array.
|
||||||
/// @param _count The integer pointer to store the number of IOMMU groups in.
|
/// @param _count The integer pointer to store the number of IOMMU groups in.
|
||||||
/// @param pcis The PCI addresses to get the IOMMU groups of.
|
/// @param pci_addresses The PCI addresses to get the IOMMU groups of.
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t get_iommu_groups(int** _groups, int* _count, const char** pcis);
|
result_t get_iommu_groups(int** _groups, int* _count, const char** pci_addresses);
|
||||||
|
|
||||||
/// @brief Checks that the given file is a PCI device. This function is used as a filter for listing PCI devices.
|
/// @brief Checks that the given file is a PCI device. This function is used as a filter for listing PCI devices.
|
||||||
/// @param file The file to check.
|
/// @param file The file to check.
|
||||||
|
@ -68,6 +68,7 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Parse commands from the command line
|
// TODO: Parse commands from the command line
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int command_help(int argc, char* argv[]) {
|
int command_help(int argc, char* argv[]) {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#define SANDBOX_VERSION "0.1.4"
|
#define SANDBOX_VERSION "0.1.4"
|
||||||
#define SANDBOX_USER "sandbox"
|
#define SANDBOX_USER "sandbox"
|
||||||
|
|
||||||
#define LIBVIRT_DOMAIN "sandbox"
|
#define DOMAIN_IDENTIFIER_PREFIX "sandbox-"
|
||||||
#define LIBVIRT_DRIVER "qemu:///system"
|
#define LIBVIRT_DRIVER "qemu:///system"
|
||||||
|
|
||||||
#define CONFIG_FILE "/etc/sandbox.d/sandbox.conf"
|
#define CONFIG_FILE "/etc/sandbox.d/sandbox.conf"
|
||||||
|
246
src/xml.c
246
src/xml.c
@ -1,246 +0,0 @@
|
|||||||
#include "xml.h"
|
|
||||||
|
|
||||||
#include "pci.h"
|
|
||||||
#include "container.h"
|
|
||||||
#include "sandbox.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
result_t generate_container_xml(char** _xml, const char* container, int cpu, uint64_t memory, const char** pcis, const char** iso_paths, int vnc_port, const char* vnc_password) {
|
|
||||||
// Initialize the output parameters
|
|
||||||
*_xml = NULL;
|
|
||||||
|
|
||||||
// Generate the PCI XML
|
|
||||||
char* pci_xml;
|
|
||||||
result_t result = generate_multi_pci_xml(&pci_xml, pcis);
|
|
||||||
if (result != success())
|
|
||||||
return result;
|
|
||||||
|
|
||||||
// Generate the ISO XML
|
|
||||||
char* iso_xml;
|
|
||||||
result = generate_multi_iso_xml(&iso_xml, iso_paths);
|
|
||||||
if (result != success()) {
|
|
||||||
free(pci_xml);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the VNC XML
|
|
||||||
char* vnc_xml;
|
|
||||||
result = generate_vnc_xml(&vnc_xml, vnc_port, vnc_password);
|
|
||||||
if (result != success()) {
|
|
||||||
free(pci_xml);
|
|
||||||
free(iso_xml);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the container path
|
|
||||||
char* container_path;
|
|
||||||
result = get_container_path(&container_path, container);
|
|
||||||
if (result != success()) {
|
|
||||||
free(pci_xml);
|
|
||||||
free(iso_xml);
|
|
||||||
free(vnc_xml);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the XML
|
|
||||||
result = format(_xml, "<domain type='kvm'>\n"
|
|
||||||
"<name>" LIBVIRT_DOMAIN "</name>\n"
|
|
||||||
"\n<!-- Resources -->\n"
|
|
||||||
"<memory unit='B'>%llu</memory>\n"
|
|
||||||
"<vcpu placement='static'>%d</vcpu>\n"
|
|
||||||
"<cpu mode='host-passthrough'/>\n"
|
|
||||||
"\n<!-- OS -->\n"
|
|
||||||
"<os>\n"
|
|
||||||
"<type arch='x86_64' machine='q35'>hvm</type>\n"
|
|
||||||
"<bootmenu enable='no'/>\n"
|
|
||||||
"</os>\n"
|
|
||||||
"\n<!-- Features -->\n"
|
|
||||||
"<features>\n"
|
|
||||||
"<acpi/>\n"
|
|
||||||
"<apic/>\n"
|
|
||||||
"</features>\n"
|
|
||||||
"\n<!-- Clock -->\n"
|
|
||||||
"<clock offset='utc'>\n"
|
|
||||||
"<timer name='rtc' tickpolicy='catchup'/>\n"
|
|
||||||
"<timer name='pit' tickpolicy='delay'/>\n"
|
|
||||||
"<timer name='hpet' present='no'/>\n"
|
|
||||||
"</clock>\n"
|
|
||||||
"\n<!-- Behavior -->\n"
|
|
||||||
"<on_poweroff>destroy</on_poweroff>\n"
|
|
||||||
"<on_reboot>destroy</on_reboot>\n"
|
|
||||||
"<on_crash>destroy</on_crash>\n"
|
|
||||||
"<pm>\n"
|
|
||||||
"<suspend-to-mem enabled='yes'/>\n"
|
|
||||||
"<suspend-to-disk enabled='yes'/>\n"
|
|
||||||
"</pm>\n"
|
|
||||||
"\n<!-- Devices -->\n"
|
|
||||||
"<devices>\n"
|
|
||||||
"<emulator>/usr/bin/qemu-system-x86_64</emulator>\n"
|
|
||||||
"\n<!-- Disks -->\n"
|
|
||||||
"<disk type='file' device='disk'>\n"
|
|
||||||
"<driver name='qemu' type='qcow2'/>\n"
|
|
||||||
"<source file='%s'/>\n"
|
|
||||||
"<target dev='sda' bus='sata'/>\n"
|
|
||||||
"<boot order='1'/>\n"
|
|
||||||
"</disk>\n"
|
|
||||||
"\n<!-- ISOs -->\n"
|
|
||||||
"%s"
|
|
||||||
"\n<!-- VNC -->\n"
|
|
||||||
"%s"
|
|
||||||
"\n<!-- PCIs -->\n"
|
|
||||||
"%s"
|
|
||||||
"\n<!-- Misc -->\n"
|
|
||||||
"<watchdog model='itco' action='poweroff'/>\n"
|
|
||||||
"<memballoon model='none'/>\n"
|
|
||||||
"</devices>\n"
|
|
||||||
"</domain>\n",
|
|
||||||
memory, cpu, container_path, iso_xml, vnc_xml, pci_xml);
|
|
||||||
|
|
||||||
// Free the PCI, ISO, and VNC XML
|
|
||||||
free(pci_xml);
|
|
||||||
free(iso_xml);
|
|
||||||
free(vnc_xml);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result_t generate_iso_xml(char** _xml, const char* iso_path, int index) {
|
|
||||||
// Initialize the output parameters
|
|
||||||
*_xml = NULL;
|
|
||||||
|
|
||||||
if (index >= 26)
|
|
||||||
return failure("Too many ISO images");
|
|
||||||
|
|
||||||
// Generate the XML
|
|
||||||
return format(_xml, "<disk type='file' device='cdrom'>\n"
|
|
||||||
"<driver name='qemu' type='raw'/>\n"
|
|
||||||
"<source file='%s'/>\n"
|
|
||||||
"<target dev='sd%c' bus='sata'/>\n"
|
|
||||||
"<boot order='%d'/>\n"
|
|
||||||
"<readonly/>\n"
|
|
||||||
"</disk>\n",
|
|
||||||
iso_path, 'a' + index, index + 1); // sda is reserved for the hard drive
|
|
||||||
}
|
|
||||||
|
|
||||||
result_t generate_multi_iso_xml(char** _xml, const char** iso_paths) {
|
|
||||||
// Initialize the output parameters
|
|
||||||
*_xml = NULL;
|
|
||||||
|
|
||||||
char* xml = strdup("");
|
|
||||||
if (xml == NULL)
|
|
||||||
return failure("Failed to allocate memory for XML");
|
|
||||||
|
|
||||||
if (iso_paths == NULL) {
|
|
||||||
*_xml = xml;
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
// For each ISO path, generate the XML and append it to the result
|
|
||||||
for (int i = 0; iso_paths[i] != NULL; i++) {
|
|
||||||
// Generate the XML for the ISO
|
|
||||||
char* iso_xml;
|
|
||||||
result_t result = generate_iso_xml(&iso_xml, iso_paths[i], i + 1); // +1 to skip the hard drive
|
|
||||||
if (result != success()) {
|
|
||||||
free(xml);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the ISO XML to the result
|
|
||||||
char* new_xml;
|
|
||||||
result = format(&new_xml, "%s%s", xml == NULL ? "" : xml, iso_xml);
|
|
||||||
|
|
||||||
free(iso_xml);
|
|
||||||
|
|
||||||
// Check that the append operation was successful
|
|
||||||
if (result != success()) {
|
|
||||||
free(xml);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap the XML strings
|
|
||||||
free(xml);
|
|
||||||
xml = new_xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
*_xml = xml;
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
result_t generate_pci_xml(char** _xml, const char* pci) {
|
|
||||||
// Initialize the output parameters
|
|
||||||
*_xml = NULL;
|
|
||||||
|
|
||||||
// Check that the PCI address is valid
|
|
||||||
result_t result = check_pci_address(pci);
|
|
||||||
if (result != success())
|
|
||||||
return result;
|
|
||||||
|
|
||||||
// Split the PCI address into its components
|
|
||||||
unsigned int domain, bus, slot, function;
|
|
||||||
sscanf(pci, "%04x:%02x:%02x.%01x", &domain, &bus, &slot, &function);
|
|
||||||
|
|
||||||
// Generate the XML
|
|
||||||
return format(_xml, "<hostdev mode='subsystem' type='pci' managed='yes'>\n"
|
|
||||||
"<source>\n"
|
|
||||||
"<address domain='0x%04x' bus='0x%02x' slot='0x%02x' function='0x%01x'/>\n"
|
|
||||||
"</source>\n"
|
|
||||||
"</hostdev>\n",
|
|
||||||
domain, bus, slot, function);
|
|
||||||
}
|
|
||||||
|
|
||||||
result_t generate_multi_pci_xml(char** _xml, const char** pcis) {
|
|
||||||
// Initialize the output parameters
|
|
||||||
*_xml = NULL;
|
|
||||||
|
|
||||||
char* xml = strdup("");
|
|
||||||
if (xml == NULL)
|
|
||||||
return failure("Failed to allocate memory for XML");
|
|
||||||
|
|
||||||
if (pcis == NULL) {
|
|
||||||
*_xml = xml;
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
// For each PCI address, generate the XML and append it to the result
|
|
||||||
for (int i = 0; pcis[i] != NULL; i++) {
|
|
||||||
// Generate the XML for the PCI address
|
|
||||||
char* pci_xml;
|
|
||||||
result_t result = generate_pci_xml(&pci_xml, pcis[i]);
|
|
||||||
if (result != success()) {
|
|
||||||
free(xml);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the PCI XML to the result
|
|
||||||
char* new_xml;
|
|
||||||
result = format(&new_xml, "%s%s", xml == NULL ? "" : xml, pci_xml);
|
|
||||||
|
|
||||||
free(pci_xml);
|
|
||||||
|
|
||||||
// Check that the append operation was successful
|
|
||||||
if (result != success()) {
|
|
||||||
free(xml);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap the XML strings
|
|
||||||
free(xml);
|
|
||||||
xml = new_xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
*_xml = xml;
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
result_t generate_vnc_xml(char** _xml, int vnc_port, const char* password) {
|
|
||||||
// Initialize the output parameters
|
|
||||||
*_xml = NULL;
|
|
||||||
|
|
||||||
// Generate the XML
|
|
||||||
if (vnc_port != -1)
|
|
||||||
return format(_xml, "<graphics type='vnc' port='%d' autoport='no' listen='0.0.0.0' passwd='%s'/>\n", vnc_port, password);
|
|
||||||
else
|
|
||||||
return format(_xml, "");
|
|
||||||
}
|
|
57
src/xml.h
57
src/xml.h
@ -2,46 +2,33 @@
|
|||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
/// @brief Generate the libvirt XML used to start a container with the given parameters.
|
/// @brief Generates the XML configuration for a sandbox domain, using the given parameters.
|
||||||
/// @param _xml The string pointer to store the resulting XML in. The caller is responsible for freeing the string.
|
/// @param _xml The string pointer to store the resulting XML configuration in. The caller is responsible for freeing the string.
|
||||||
/// @param container The container to generate the XML for.
|
/// @param container The container to generate the XML configuration for.
|
||||||
/// @param cpu The number of CPUs to allocate to the container.
|
/// @param memory The memory size of the domain, in bytes.
|
||||||
/// @param memory The amount of memory to allocate to the container, in bytes.
|
/// @param vcpus The number of virtual CPUs of the domain.
|
||||||
/// @param pcis A null-terminated array of PCI devices to pass through to the container. If NULL, no PCI devices will be passed through.
|
/// @param pci_addresses The PCI addresses of the devices to pass through to the domain.
|
||||||
/// @param iso_paths A null-terminated array of ISO image paths to attach to the container. If NULL, no ISO images will be attached.
|
/// @param iso_paths The paths to the ISO images to pass through to the domain.
|
||||||
/// @param vnc_port The VNC port to use for the container. If -1, no VNC server will be started.
|
/// @param vnc_port The VNC port to use for the domain, or 0 to disable VNC.
|
||||||
/// @param vnc_password The password to use for the VNC server. This parameter is ignored if VNC is not enabled.
|
/// @param vnc_password The VNC password to use for the domain. If the VNC server is disabled, this parameter is ignored.
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t generate_container_xml(char** _xml, const char* container, int cpu, uint64_t memory, const char** pcis, const char** iso_paths, int vnc_port, const char* vnc_password);
|
result_t generate_domain_xml(char** _xml, const char* container, uint64_t memory, int vcpus, const char** pci_addresses, const char** iso_paths, int vnc_port, const char* vnc_password);
|
||||||
|
|
||||||
/// @brief Generate the libvirt XML used to attach an ISO image to a container.
|
/// @brief Generates the XML configuration for passing through the given PCI devices.
|
||||||
/// @param _xml The string pointer to store the resulting XML in.
|
/// @param _xml The string pointer to store the resulting XML configuration in. The caller is responsible for freeing the string.
|
||||||
/// @param iso_path The path to the ISO image to attach.
|
/// @param pci_addresses The PCI addresses of the devices to pass through.
|
||||||
/// @param index The index of the ISO image within the container. Must be positive, unique, and less than 26.
|
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t generate_iso_xml(char** _xml, const char* iso_path, int index);
|
result_t generate_pci_xml(char** _xml, const char** pci_addresses);
|
||||||
|
|
||||||
/// @brief Generate the libvirt XML used to attach multiple ISO images to a container.
|
/// @brief Generates the XML configuration for attaching the given ISO images.
|
||||||
/// @param _xml The string pointer to store the resulting XML in.
|
/// @param _xml The string pointer to store the resulting XML configuration in. The caller is responsible for freeing the string.
|
||||||
/// @param iso_paths The paths to the ISO images to attach.
|
/// @param iso_paths The paths to the ISO images to attach.
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t generate_multi_iso_xml(char** _xml, const char** iso_paths);
|
result_t generate_iso_xml(char** _xml, const char** iso_paths);
|
||||||
|
|
||||||
/// @brief Generate the libvirt XML used to pass through a PCI device to a container.
|
/// @brief Generates the XML configuration for a VNC server.
|
||||||
/// @param _xml The string pointer to store the resulting XML in.
|
/// @param _xml The string pointer to store the resulting XML configuration in. The caller is responsible for freeing the string.
|
||||||
/// @param pci The PCI device to generate the XML for.
|
/// @param vnc_port The VNC port to use. If 0, the VNC server will be disabled.
|
||||||
|
/// @param vnc_password The VNC password to use. If the VNC server is disabled, this parameter is ignored.
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t generate_pci_xml(char** _xml, const char* pci);
|
result_t generate_vnc_xml(char** _xml, int vnc_port, const char* vnc_password);
|
||||||
|
|
||||||
/// @brief Generate the libvirt XML used to pass through multiple PCI devices to a container.
|
|
||||||
/// @param _xml The string pointer to store the resulting XML in.
|
|
||||||
/// @param pcis The PCI devices to generate the XML for.
|
|
||||||
/// @return The result of the operation.
|
|
||||||
result_t generate_multi_pci_xml(char** _xml, const char** pcis);
|
|
||||||
|
|
||||||
/// @brief Generate the libvirt XML used to start a VNC server for a container.
|
|
||||||
/// @param _xml The string pointer to store the resulting XML in.
|
|
||||||
/// @param vnc_port The VNC port to use for the container.
|
|
||||||
/// @param password The password to use for the VNC server. This parameter is ignored if VNC is not enabled.
|
|
||||||
/// @return The result of the operation.
|
|
||||||
result_t generate_vnc_xml(char** _xml, int vnc_port, const char* password);
|
|
||||||
|
65
xml
65
xml
@ -1,65 +0,0 @@
|
|||||||
<domain type='kvm'>
|
|
||||||
<name>sandbox</name>
|
|
||||||
|
|
||||||
<!-- Resources -->
|
|
||||||
<memory unit='B'>1073741824</memory>
|
|
||||||
<vcpu placement='static'>1</vcpu>
|
|
||||||
<cpu mode='host-passthrough'/>
|
|
||||||
|
|
||||||
<!-- OS -->
|
|
||||||
<os>
|
|
||||||
<type arch='x86_64' machine='q35'>hvm</type>
|
|
||||||
<bootmenu enable='no'/>
|
|
||||||
</os>
|
|
||||||
|
|
||||||
<!-- Features -->
|
|
||||||
<features>
|
|
||||||
<acpi/>
|
|
||||||
<apic/>
|
|
||||||
</features>
|
|
||||||
|
|
||||||
<!-- Clock -->
|
|
||||||
<clock offset='utc'>
|
|
||||||
<timer name='rtc' tickpolicy='catchup'/>
|
|
||||||
<timer name='pit' tickpolicy='delay'/>
|
|
||||||
<timer name='hpet' present='no'/>
|
|
||||||
</clock>
|
|
||||||
|
|
||||||
<!-- Behavior -->
|
|
||||||
<on_poweroff>destroy</on_poweroff>
|
|
||||||
<on_reboot>destroy</on_reboot>
|
|
||||||
<on_crash>destroy</on_crash>
|
|
||||||
<pm>
|
|
||||||
<suspend-to-mem enabled='yes'/>
|
|
||||||
<suspend-to-disk enabled='yes'/>
|
|
||||||
</pm>
|
|
||||||
|
|
||||||
<!-- Devices -->
|
|
||||||
<devices>
|
|
||||||
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
|
||||||
|
|
||||||
<!-- Disks -->
|
|
||||||
<disk type='file' device='disk'>
|
|
||||||
<driver name='qemu' type='qcow2'/>
|
|
||||||
<source file='/var/lib/sandbox/containers/test'/>
|
|
||||||
<target dev='sda' bus='sata'/>
|
|
||||||
<boot order='1'/>
|
|
||||||
</disk>
|
|
||||||
|
|
||||||
<!-- ISOs -->
|
|
||||||
|
|
||||||
<!-- VNC -->
|
|
||||||
<graphics type='vnc' port='5900' autoport='no' listen='0.0.0.0' passwd='test'/>
|
|
||||||
|
|
||||||
<!-- PCIs -->
|
|
||||||
<hostdev mode='subsystem' type='pci' managed='yes'>
|
|
||||||
<source>
|
|
||||||
<address domain='0x0000' bus='0x00' slot='0x00' function='0x0'/>
|
|
||||||
</source>
|
|
||||||
</hostdev>
|
|
||||||
|
|
||||||
<!-- Misc -->
|
|
||||||
<watchdog model='itco' action='poweroff'/>
|
|
||||||
<memballoon model='none'/>
|
|
||||||
</devices>
|
|
||||||
</domain>
|
|
Loading…
Reference in New Issue
Block a user