diff --git a/src/sandbox.c b/src/sandbox.c index 509983e..3234474 100755 --- a/src/sandbox.c +++ b/src/sandbox.c @@ -10,6 +10,7 @@ #include #include "pci.h" +#include "xml.h" #define ALIAS(...) \ (const char*[]) { __VA_ARGS__, NULL } diff --git a/src/xml.c b/src/xml.c index 6795ac2..0dc0261 100644 --- a/src/xml.c +++ b/src/xml.c @@ -1,20 +1,228 @@ #include "xml.h" +#include "pci.h" +#include "container.h" + +#include +#include + +result_t generate_container_xml(char** _xml, char* container, int cpu, uint64_t memory, char** pcis, char** iso_paths, int vnc_port, 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, "\n" + "sandbox\n" + "\n\n" + "%llu\n" + "%d\n" + "\n" + "\n\n" + "\n" + "hvm\n" + "\n" + "\n" + "\n\n" + "\n" + "\n" + "\n" + "\n" + "\n\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n\n" + "destroy\n" + "destroy\n" + "destroy\n" + "\n" + "\n" + "\n" + "\n" + "\n\n" + "\n" + "/usr/bin/qemu-system-x86_64\n" + "\n\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n\n" + "%s" + "\n\n" + "%s" + "\n\n" + "%s" + "\n\n" + "\n" + "\n" + "\n" + "\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, char* iso_path, int index) { // Initialize the output parameters *_xml = NULL; - if (index > 25) + if (index >= 26) return failure("Too many ISO images"); // Generate the XML - return format(_xml, "" - " " - " " - " " - " " - "", - iso_path, 'a' + index); + return format(_xml, "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n", + iso_path, 'b' + index, index + 2); // sda is reserved for the hard drive +} + +result_t generate_multi_iso_xml(char** _xml, char** iso_paths) { + // Initialize the output parameters + *_xml = NULL; + + char* xml = strdup(""); + if (xml == NULL) + return failure("Failed to allocate memory for XML"); + + // 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); + 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, 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 + long domain = 0; + long bus = 0; + long slot = 0; + long function = 0; + + // Generate the XML + return format(_xml, "\n" + "\n" + "
\n" + "\n" + "\n", + domain, bus, slot, function); +} + +result_t generate_multi_pci_xml(char** _xml, char** pcis) { + // Initialize the output parameters + *_xml = NULL; + + char* xml = strdup(""); + if (xml == NULL) + return failure("Failed to allocate memory for XML"); + + // 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, char* password) { @@ -22,8 +230,8 @@ result_t generate_vnc_xml(char** _xml, int vnc_port, char* password) { *_xml = NULL; // Generate the XML - if (vnc_port == -1) - return format(_xml, ""); + if (vnc_port != -1) + return format(_xml, "\n", vnc_port, password); else - return format(_xml, "", vnc_port, password); + return format(_xml, ""); } diff --git a/src/xml.h b/src/xml.h index 7aa0b35..ef762d4 100644 --- a/src/xml.h +++ b/src/xml.h @@ -7,12 +7,12 @@ /// @param container The container to generate the XML for. /// @param cpu The number of CPUs to allocate to the container. /// @param memory The amount of memory to allocate to the container, in bytes. -/// @param pci A null-terminated array of PCI devices to pass through to the container. -/// @param iso_path A null-terminated array of ISO image paths to attach to the container. +/// @param pcis A null-terminated array of PCI devices to pass through to the container. +/// @param iso_paths A null-terminated array of ISO image paths to attach to the container. /// @param vnc_port The VNC port to use for the container. If -1, no VNC server will be started. /// @param vnc_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_container_xml(char** _xml, char* container, int cpu, uint64_t memory, char** pci, char** iso_path, int vnc_port, char* vnc_password); +result_t generate_container_xml(char** _xml, char* container, int cpu, uint64_t memory, char** pcis, char** iso_paths, int vnc_port, char* vnc_password); /// @brief Generate the libvirt XML used to attach an ISO image to a container. /// @param _xml The string pointer to store the resulting XML in. @@ -21,15 +21,27 @@ result_t generate_container_xml(char** _xml, char* container, int cpu, uint64_t /// @return The result of the operation. result_t generate_iso_xml(char** _xml, char* iso_path, int index); -/// @brief Generate the libvirt XML used to start a VNC server for a container. +/// @brief Generate the libvirt XML used to attach multiple ISO images to 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. +/// @param iso_paths The paths to the ISO images to attach. /// @return The result of the operation. -result_t generate_vnc_xml(char** _xml, int vnc_port, char* password); +result_t generate_multi_iso_xml(char** _xml, char** iso_paths); /// @brief Generate the libvirt XML used to pass through a PCI device to a container. /// @param _xml The string pointer to store the resulting XML in. /// @param pci The PCI device to generate the XML for. /// @return The result of the operation. result_t generate_pci_xml(char** _xml, char* pci); + +/// @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, 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, char* password);