/* * bhyve_firmware.c: bhyve firmware management * * Copyright (C) 2021 Roman Bogorodskiy * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . * */ #include #include #include "viralloc.h" #include "virlog.h" #include "virfile.h" #include "bhyve_conf.h" #include "bhyve_firmware.h" #define VIR_FROM_THIS VIR_FROM_BHYVE VIR_LOG_INIT("bhyve.bhyve_firmware"); #define BHYVE_DEFAULT_FIRMWARE "BHYVE_UEFI.fd" int bhyveFirmwareFillDomain(bhyveConn *driver, virDomainDef *def, unsigned int flags) { g_autoptr(DIR) dir = NULL; g_autoptr(virBhyveDriverConfig) cfg = virBhyveDriverGetConfig(driver); const char *firmware_dir = cfg->firmwareDir; struct dirent *entry; g_autofree char *matching_firmware = NULL; g_autofree char *first_found = NULL; virCheckFlags(0, -1); if (def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_NONE) return 0; if (virDirOpenIfExists(&dir, firmware_dir) > 0) { while ((virDirRead(dir, &entry, firmware_dir)) > 0) { if (g_str_has_prefix(entry->d_name, ".")) continue; if (STREQ(entry->d_name, BHYVE_DEFAULT_FIRMWARE)) { matching_firmware = g_strdup(entry->d_name); break; } if (!first_found) first_found = g_strdup(entry->d_name); } } if (!matching_firmware) { if (!first_found) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("no firmwares found in %s"), firmware_dir); return -1; } else { matching_firmware = g_steal_pointer(&first_found); } } if (!def->os.loader) def->os.loader = g_new0(virDomainLoaderDef, 1); def->os.loader->type = VIR_DOMAIN_LOADER_TYPE_PFLASH; def->os.loader->readonly = VIR_TRISTATE_BOOL_YES; VIR_FREE(def->os.loader->path); def->os.loader->path = g_build_filename(firmware_dir, matching_firmware, NULL); return 0; }