"secure-boot",
);
+VIR_ENUM_IMPL(virDomainOsACPITable,
+ VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST,
+ "slic",
+);
+
VIR_ENUM_IMPL(virDomainCFPC,
VIR_DOMAIN_CFPC_LAST,
"none",
g_free(def);
}
+void virDomainOSACPITableDefFree(virDomainOSACPITableDef *def)
+{
+ if (!def)
+ return;
+ g_free(def->path);
+ g_free(def);
+}
+
+
static void
virDomainOSDefClear(virDomainOSDef *os)
{
g_free(os->cmdline);
g_free(os->dtb);
g_free(os->root);
- g_free(os->slic_table);
+ for (i = 0; i < os->nacpiTables; i++)
+ virDomainOSACPITableDefFree(os->acpiTables[i]);
+ g_free(os->acpiTables);
virDomainLoaderDefFree(os->loader);
g_free(os->bootloader);
g_free(os->bootloaderArgs);
int n;
g_autofree xmlNodePtr *nodes = NULL;
g_autofree char *tmp = NULL;
+ size_t ntables = 0;
+ virDomainOSACPITableDef **tables = NULL;
+ size_t i;
if ((n = virXPathNodeSet("./os/acpi/table", ctxt, &nodes)) < 0)
return -1;
- if (n > 1) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("Only one acpi table is supported"));
- return -1;
- }
+ if (n == 0)
+ return 0;
- if (n == 1) {
- tmp = virXMLPropString(nodes[0], "type");
+ tables = g_new0(virDomainOSACPITableDef *, n);
+ for (i = 0; i < n; i++) {
+ g_autofree char *path = virXMLNodeContentString(nodes[i]);
+ virDomainOsACPITable type;
+ size_t j;
- if (!tmp) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("Missing acpi table type"));
- return -1;
- }
+ if (!path)
+ goto error;
- if (STREQ_NULLABLE(tmp, "slic")) {
- VIR_FREE(tmp);
- if (!(tmp = virXMLNodeContentString(nodes[0])))
- return -1;
+ if (virXMLPropEnum(nodes[i], "type",
+ virDomainOsACPITableTypeFromString,
+ VIR_XML_PROP_REQUIRED,
+ &type) < 0)
+ goto error;
- def->os.slic_table = virFileSanitizePath(tmp);
- } else {
- virReportError(VIR_ERR_XML_ERROR,
- _("Unknown acpi table type: %1$s"),
- tmp);
- return -1;
+ for (j = 0; j < i; j++) {
+ if (tables[j]->type == type) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("ACPI table type '%1$s' may only appear once"),
+ virDomainOsACPITableTypeToString(type));
+ goto error;
+ }
}
+
+ tables[ntables] = g_new0(virDomainOSACPITableDef, 1);
+ tables[ntables]->type = type;
+ tables[ntables]->path = virFileSanitizePath(path);
+ ntables++;
}
+ def->os.nacpiTables = ntables;
+ def->os.acpiTables = tables;
+
return 0;
+
+ error:
+ for (i = 0; i < ntables; i++) {
+ virDomainOSACPITableDefFree(tables[i]);
+ }
+ g_free(tables);
+ return -1;
}
def->os.dtb);
virBufferEscapeString(buf, "<root>%s</root>\n",
def->os.root);
- if (def->os.slic_table) {
+
+ if (def->os.nacpiTables) {
virBufferAddLit(buf, "<acpi>\n");
virBufferAdjustIndent(buf, 2);
- virBufferEscapeString(buf, "<table type='slic'>%s</table>\n",
- def->os.slic_table);
+ for (i = 0; i < def->os.nacpiTables; i++) {
+ virBufferAsprintf(buf, "<table type='%s'>",
+ virDomainOsACPITableTypeToString(def->os.acpiTables[i]->type));
+ virBufferEscapeString(buf, "%s</table>\n",
+ def->os.acpiTables[i]->path);
+ }
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</acpi>\n");
}
VIR_ENUM_DECL(virDomainOsDefFirmwareFeature);
+typedef enum {
+ VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC,
+
+ VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST
+} virDomainOsACPITable;
+
+VIR_ENUM_DECL(virDomainOsACPITable);
+
+struct _virDomainOSACPITableDef {
+ virDomainOsACPITable type;
+ char *path;
+};
+
+typedef struct _virDomainOSACPITableDef virDomainOSACPITableDef;
+void virDomainOSACPITableDefFree(virDomainOSACPITableDef *def);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainOSACPITableDef, virDomainOSACPITableDefFree);
+
+
struct _virDomainOSDef {
int type;
virDomainOsDefFirmware firmware;
char *cmdline;
char *dtb;
char *root;
- char *slic_table;
+ size_t nacpiTables;
+ virDomainOSACPITableDef **acpiTables;
virDomainLoaderDef *loader;
char *bootloader;
char *bootloaderArgs;
virDomainObjUpdateModificationImpact;
virDomainObjWait;
virDomainObjWaitUntil;
+virDomainOsACPITableTypeFromString;
+virDomainOsACPITableTypeToString;
virDomainOsDefFirmwareTypeFromString;
virDomainOsDefFirmwareTypeToString;
virDomainOSTypeFromString;
VIR_TRISTATE_SWITCH_ON);
#endif
- /* copy SLIC table path to acpi_firmware */
- b_info->u.hvm.acpi_firmware = g_strdup(def->os.slic_table);
+ /* copy the table path to acpi_firmware */
+ if (def->os.nacpiTables)
+ b_info->u.hvm.acpi_firmware = g_strdup(def->os.acpiTables[0]->path);
if (def->nsounds > 0) {
/*
g_autofree char *bios = NULL;
g_autofree char *bios_path = NULL;
g_autofree char *boot = NULL;
+ g_autofree char *slic = NULL;
int val = 0;
if (xenConfigGetString(conf, "bios", &bios, NULL) < 0)
}
}
- if (xenConfigCopyStringOpt(conf, "acpi_firmware", &def->os.slic_table) < 0)
+ if (xenConfigCopyStringOpt(conf, "acpi_firmware", &slic) < 0)
return -1;
+ if (slic != NULL) {
+ def->os.nacpiTables = 1;
+ def->os.acpiTables = g_new0(virDomainOSACPITableDef *, 1);
+ def->os.acpiTables[0] = g_new0(virDomainOSACPITableDef, 1);
+ def->os.acpiTables[0]->type = VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC;
+ def->os.acpiTables[0]->path = g_steal_pointer(&slic);
+ }
if (xenConfigCopyStringOpt(conf, "kernel", &def->os.kernel) < 0)
return -1;
return -1;
}
- if (def->os.slic_table &&
- xenConfigSetString(conf, "acpi_firmware", def->os.slic_table) < 0)
+ if (def->os.nacpiTables &&
+ xenConfigSetString(conf, "acpi_firmware",
+ def->os.acpiTables[0]->path) < 0)
return -1;
if (def->os.kernel &&
"restrictive",
);
+VIR_ENUM_DECL(qemuACPITableSIG);
+VIR_ENUM_IMPL(qemuACPITableSIG,
+ VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST,
+ "SLIC");
+
const char *
qemuAudioDriverTypeToString(virDomainAudioType type)
{
g_auto(virBuffer) boot_buf = VIR_BUFFER_INITIALIZER;
g_autofree char *boot_opts_str = NULL;
+ size_t i;
if (def->os.bootmenu) {
if (def->os.bootmenu == VIR_TRISTATE_BOOL_YES)
virCommandAddArgList(cmd, "-append", def->os.cmdline, NULL);
if (def->os.dtb)
virCommandAddArgList(cmd, "-dtb", def->os.dtb, NULL);
- if (def->os.slic_table) {
+ for (i = 0; i < def->os.nacpiTables; i++) {
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
virCommandAddArg(cmd, "-acpitable");
- virBufferAddLit(&buf, "sig=SLIC,file=");
- virQEMUBuildBufferEscapeComma(&buf, def->os.slic_table);
+ virBufferAsprintf(&buf, "sig=%s,file=",
+ qemuACPITableSIGTypeToString(def->os.acpiTables[i]->type));
+ virQEMUBuildBufferEscapeComma(&buf, def->os.acpiTables[i]->path);
virCommandAddArgBuffer(cmd, &buf);
}
virSecurityDACRestoreFileLabel(mgr, def->os.dtb) < 0)
rc = -1;
- if (def->os.slic_table &&
- virSecurityDACRestoreFileLabel(mgr, def->os.slic_table) < 0)
- rc = -1;
+ for (i = 0; i < def->os.nacpiTables; i++) {
+ if (virSecurityDACRestoreFileLabel(mgr, def->os.acpiTables[i]->path) < 0)
+ rc = -1;
+ }
if (def->pstore &&
virSecurityDACRestoreFileLabel(mgr, def->pstore->path) < 0)
user, group, true) < 0)
return -1;
- if (def->os.slic_table &&
- virSecurityDACSetOwnership(mgr, NULL,
- def->os.slic_table,
- user, group, true) < 0)
- return -1;
+ for (i = 0; i < def->os.nacpiTables; i++) {
+ if (virSecurityDACSetOwnership(mgr, NULL,
+ def->os.acpiTables[i]->path,
+ user, group, true) < 0)
+ return -1;
+ }
if (def->pstore &&
virSecurityDACSetOwnership(mgr, NULL,
virSecuritySELinuxRestoreFileLabel(mgr, def->os.dtb, true) < 0)
rc = -1;
- if (def->os.slic_table &&
- virSecuritySELinuxRestoreFileLabel(mgr, def->os.slic_table, true) < 0)
- rc = -1;
+ for (i = 0; i < def->os.nacpiTables; i++) {
+ if (virSecuritySELinuxRestoreFileLabel(mgr, def->os.acpiTables[i]->path, true) < 0)
+ rc = -1;
+ }
if (def->pstore &&
virSecuritySELinuxRestoreFileLabel(mgr, def->pstore->path, true) < 0)
data->content_context, true) < 0)
return -1;
- if (def->os.slic_table &&
- virSecuritySELinuxSetFilecon(mgr, def->os.slic_table,
- data->content_context, true) < 0)
- return -1;
+ for (i = 0; i < def->os.nacpiTables; i++) {
+ if (virSecuritySELinuxSetFilecon(mgr, def->os.acpiTables[i]->path,
+ data->content_context, true) < 0)
+ return -1;
+ }
if (def->pstore &&
virSecuritySELinuxSetFilecon(mgr, def->pstore->path,
if (vah_add_file(&buf, ctl->def->os.dtb, "r") != 0)
goto cleanup;
- if (ctl->def->os.slic_table)
- if (vah_add_file(&buf, ctl->def->os.slic_table, "r") != 0)
+ for (i = 0; i < ctl->def->os.nacpiTables; i++) {
+ if (vah_add_file(&buf, ctl->def->os.acpiTables[i]->path, "r") != 0)
goto cleanup;
+ }
if (ctl->def->pstore)
if (vah_add_file(&buf, ctl->def->pstore->path, "rw") != 0)