Added a function to convert multiple IOMMU groups into a single array
This commit is contained in:
parent
b1efb848b2
commit
839b6ddabc
81
src/pci.c
81
src/pci.c
@ -80,11 +80,11 @@ result_t get_iommu_group(int* _group, const char* pci) {
|
|||||||
char iommu_group_path[256]; // 256 should be enough for the path
|
char iommu_group_path[256]; // 256 should be enough for the path
|
||||||
ssize_t len = readlink(path, iommu_group_path, sizeof(iommu_group_path) - 1);
|
ssize_t len = readlink(path, iommu_group_path, sizeof(iommu_group_path) - 1);
|
||||||
|
|
||||||
// Check for errors during the readlink call
|
|
||||||
if (len == -1) {
|
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
|
// Check for errors during the readlink call
|
||||||
|
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);
|
||||||
}
|
|
||||||
|
|
||||||
// Null-terminate the path
|
// Null-terminate the path
|
||||||
iommu_group_path[len] = '\0';
|
iommu_group_path[len] = '\0';
|
||||||
@ -165,3 +165,78 @@ result_t get_iommu_group_devices(char*** _devices, int group) {
|
|||||||
free(path);
|
free(path);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result_t get_iommu_groups_devices(char*** _devices, const int* groups, int groups_count) {
|
||||||
|
// Initialize the output parameters
|
||||||
|
*_devices = NULL;
|
||||||
|
|
||||||
|
char*** devices = malloc(groups_count * sizeof(char**));
|
||||||
|
if (devices == NULL)
|
||||||
|
return failure("Failed to allocate memory for IOMMU group devices.");
|
||||||
|
|
||||||
|
// Get the devices of each IOMMU group
|
||||||
|
for (int i = 0; i < groups_count; i++) {
|
||||||
|
result_t result = get_iommu_group_devices(&devices[i], groups[i]);
|
||||||
|
if (result != success()) {
|
||||||
|
// Free every individual device
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
char** group_devices = devices[j];
|
||||||
|
for (int k = 0; group_devices[k] != NULL; k++)
|
||||||
|
free(group_devices[k]);
|
||||||
|
free(devices[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the devices array
|
||||||
|
free(devices);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the number of devices
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < groups_count; i++) {
|
||||||
|
char** group_devices = devices[i];
|
||||||
|
for (int j = 0; group_devices[j] != NULL; j++)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate memory for the output
|
||||||
|
char** output_devices = malloc((count + 1) * sizeof(char*));
|
||||||
|
if (output_devices == NULL) {
|
||||||
|
// Free every individual device
|
||||||
|
for (int i = 0; i < groups_count; i++) {
|
||||||
|
char** group_devices = devices[i];
|
||||||
|
for (int j = 0; group_devices[j] != NULL; j++)
|
||||||
|
free(group_devices[j]);
|
||||||
|
free(devices[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the devices array
|
||||||
|
free(devices);
|
||||||
|
return failure("Failed to allocate memory for IOMMU group devices.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the devices to the output
|
||||||
|
int index = 0;
|
||||||
|
for (int i = 0; i < groups_count; i++) {
|
||||||
|
char** group_devices = devices[i];
|
||||||
|
for (int j = 0; group_devices[j] != NULL; j++) {
|
||||||
|
output_devices[index] = group_devices[j];
|
||||||
|
group_devices[j] = NULL;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the group devices
|
||||||
|
free(group_devices);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Null-terminate the output
|
||||||
|
output_devices[count] = NULL;
|
||||||
|
|
||||||
|
// Free the devices array
|
||||||
|
free(devices);
|
||||||
|
|
||||||
|
*_devices = output_devices;
|
||||||
|
|
||||||
|
return success();
|
||||||
|
}
|
||||||
|
@ -35,3 +35,10 @@ bool pci_filter(const char* file);
|
|||||||
/// @param group The IOMMU group to get the devices of.
|
/// @param group The IOMMU group to get the devices of.
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t get_iommu_group_devices(char*** _devices, int group);
|
result_t get_iommu_group_devices(char*** _devices, int group);
|
||||||
|
|
||||||
|
/// @brief Get the PCI devices in the given IOMMU groups.
|
||||||
|
/// @param _devices The string array pointer to store the resulting devices in. The caller is responsible for freeing the strings and the array.
|
||||||
|
/// @param groups The IOMMU groups to get the devices of.
|
||||||
|
/// @param groups_count The number of IOMMU groups.
|
||||||
|
/// @return The result of the operation.
|
||||||
|
result_t get_iommu_groups_devices(char*** _devices, const int* groups, int groups_count);
|
@ -244,7 +244,7 @@ result_t execute(int* _exit_code, char** _stdoutbuf, char** _stderrbuf, const ch
|
|||||||
|
|
||||||
// Allocate memory for the arguments array
|
// Allocate memory for the arguments array
|
||||||
errno = 0;
|
errno = 0;
|
||||||
char** argv = malloc((argc + 1) * sizeof(char*)); // +1 for the NULL terminator
|
char** argv = malloc((argc + 1) * sizeof(char*)); // +1 for the null terminator
|
||||||
if (argv == NULL)
|
if (argv == NULL)
|
||||||
return failure("Failed to allocate memory for the arguments array (%s).", strerror(errno));
|
return failure("Failed to allocate memory for the arguments array (%s).", strerror(errno));
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ result_t generate_container_xml(char** _xml, char* container, int cpu, uint64_t
|
|||||||
|
|
||||||
// Generate the XML
|
// Generate the XML
|
||||||
result = format(_xml, "<domain type='kvm'>\n"
|
result = format(_xml, "<domain type='kvm'>\n"
|
||||||
"<name>%s</name>\n"
|
"<name>" LIBVIRT_DOMAIN "</name>\n"
|
||||||
"\n<!-- Resources -->\n"
|
"\n<!-- Resources -->\n"
|
||||||
"<memory unit='B'>%llu</memory>\n"
|
"<memory unit='B'>%llu</memory>\n"
|
||||||
"<vcpu placement='static'>%d</vcpu>\n"
|
"<vcpu placement='static'>%d</vcpu>\n"
|
||||||
@ -96,7 +96,7 @@ result_t generate_container_xml(char** _xml, char* container, int cpu, uint64_t
|
|||||||
"<memballoon model='none'/>\n"
|
"<memballoon model='none'/>\n"
|
||||||
"</devices>\n"
|
"</devices>\n"
|
||||||
"</domain>\n",
|
"</domain>\n",
|
||||||
LIBVIRT_DOMAIN, memory, cpu, container_path, iso_xml, vnc_xml, pci_xml);
|
memory, cpu, container_path, iso_xml, vnc_xml, pci_xml);
|
||||||
|
|
||||||
// Free the PCI, ISO, and VNC XML
|
// Free the PCI, ISO, and VNC XML
|
||||||
free(pci_xml);
|
free(pci_xml);
|
||||||
|
Loading…
Reference in New Issue
Block a user