/* Get autoballoon option based on presence of dom0_mem Xen command line option. */ static int auto_autoballoon(void) { const libxl_version_info *info; regex_t regex; int ret; info = libxl_get_version_info(ctx); if (!info) return 1; /* default to on */ ret = regcomp(®ex, "(^| )dom0_mem=((|min:|max:)[0-9]+[bBkKmMgG]?,?)+($| )", REG_NOSUB | REG_EXTENDED); if (ret) return 1; ret = regexec(®ex, info->commandline, 0, NULL, 0); regfree(®ex); return ret == REG_NOMATCH; }
int libxl__prepare_acpi(libxl__gc *gc, libxl_domain_build_info *info, struct xc_dom_image *dom) { const libxl_version_info *vers; int rc = 0; struct acpitable acpitables[MAX_TABLE_NUMS]; vers = libxl_get_version_info(CTX); if (vers == NULL) { rc = ERROR_FAIL; goto out; } LOG(DEBUG, "constructing ACPI tables for Xen version %d.%d guest", vers->xen_version_major, vers->xen_version_minor); dom->acpi_modules[0].data = NULL; dom->acpi_modules[0].length = 0; dom->acpi_modules[0].guest_addr_out = GUEST_ACPI_BASE; rc = libxl__allocate_acpi_tables(gc, info, dom, acpitables); if (rc) goto out; make_acpi_rsdp(gc, dom, acpitables); make_acpi_xsdt(gc, dom, acpitables); make_acpi_gtdt(gc, dom, acpitables); rc = make_acpi_madt(gc, dom, info, acpitables); if (rc) goto out; make_acpi_fadt(gc, dom, acpitables); make_acpi_dsdt(gc, dom, acpitables); out: return rc; }
static int libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps) { const libxl_version_info *ver_info; int err; regex_t regex; char *str, *token; regmatch_t subs[4]; char *saveptr = NULL; size_t i; virArch hostarch = caps->host.arch; struct guest_arch guest_archs[32]; int nr_guest_archs = 0; memset(guest_archs, 0, sizeof(guest_archs)); if ((ver_info = libxl_get_version_info(ctx)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to get version info from libxenlight")); return -1; } err = regcomp(®ex, XEN_CAP_REGEX, REG_EXTENDED); if (err != 0) { char error[100]; regerror(err, ®ex, error, sizeof(error)); virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to compile regex %s"), error); return -1; } /* Format of capabilities string is documented in the code in * xen-unstable.hg/xen/arch/.../setup.c. * * It is a space-separated list of supported guest architectures. * * For x86: * TYP-VER-ARCH[p] * ^ ^ ^ ^ * | | | +-- PAE supported * | | +------- x86_32 or x86_64 * | +----------- the version of Xen, eg. "3.0" * +--------------- "xen" or "hvm" for para or full virt respectively * * For IA64: * TYP-VER-ARCH[be] * ^ ^ ^ ^ * | | | +-- Big-endian supported * | | +------- always "ia64" * | +----------- the version of Xen, eg. "3.0" * +--------------- "xen" or "hvm" for para or full virt respectively */ /* Split capabilities string into tokens. strtok_r is OK here because * we "own" the buffer. Parse out the features from each token. */ for (str = ver_info->capabilities, nr_guest_archs = 0; nr_guest_archs < sizeof(guest_archs) / sizeof(guest_archs[0]) && (token = strtok_r(str, " ", &saveptr)) != NULL; str = NULL) { if (regexec(®ex, token, sizeof(subs) / sizeof(subs[0]), subs, 0) == 0) { int hvm = STRPREFIX(&token[subs[1].rm_so], "hvm"); virArch arch; int pae = 0, nonpae = 0, ia64_be = 0; if (STRPREFIX(&token[subs[2].rm_so], "x86_32")) { arch = VIR_ARCH_I686; if (subs[3].rm_so != -1 && STRPREFIX(&token[subs[3].rm_so], "p")) pae = 1; else nonpae = 1; } else if (STRPREFIX(&token[subs[2].rm_so], "x86_64")) { arch = VIR_ARCH_X86_64; } else if (STRPREFIX(&token[subs[2].rm_so], "ia64")) { arch = VIR_ARCH_ITANIUM; if (subs[3].rm_so != -1 && STRPREFIX(&token[subs[3].rm_so], "be")) ia64_be = 1; } else if (STRPREFIX(&token[subs[2].rm_so], "powerpc64")) { arch = VIR_ARCH_PPC64; } else if (STRPREFIX(&token[subs[2].rm_so], "armv7l")) { arch = VIR_ARCH_ARMV7L; } else if (STRPREFIX(&token[subs[2].rm_so], "aarch64")) { arch = VIR_ARCH_AARCH64; } else { continue; } /* Search for existing matching (model,hvm) tuple */ for (i = 0; i < nr_guest_archs; i++) { if ((guest_archs[i].arch == arch) && guest_archs[i].hvm == hvm) break; } /* Too many arch flavours - highly unlikely ! */ if (i >= ARRAY_CARDINALITY(guest_archs)) continue; /* Didn't find a match, so create a new one */ if (i == nr_guest_archs) nr_guest_archs++; guest_archs[i].arch = arch; guest_archs[i].hvm = hvm; /* Careful not to overwrite a previous positive setting with a negative one here - some archs can do both pae & non-pae, but Xen reports separately capabilities so we're merging archs */ if (pae) guest_archs[i].pae = pae; if (nonpae) guest_archs[i].nonpae = nonpae; if (ia64_be) guest_archs[i].ia64_be = ia64_be; } } regfree(®ex); for (i = 0; i < nr_guest_archs; ++i) { virCapsGuestPtr guest; char const *const xen_machines[] = {guest_archs[i].hvm ? "xenfv" : "xenpv"}; virCapsGuestMachinePtr *machines; if ((machines = virCapabilitiesAllocMachines(xen_machines, 1)) == NULL) return -1; if ((guest = virCapabilitiesAddGuest(caps, guest_archs[i].hvm ? "hvm" : "xen", guest_archs[i].arch, "qemu-dm", (guest_archs[i].hvm ? "hvmloader" : NULL), 1, machines)) == NULL) { virCapabilitiesFreeMachines(machines, 1); return -1; } machines = NULL; if (virCapabilitiesAddGuestDomain(guest, "xen", NULL, NULL, 0, NULL) == NULL) return -1; if (guest_archs[i].pae && virCapabilitiesAddGuestFeature(guest, "pae", 1, 0) == NULL) return -1; if (guest_archs[i].nonpae && virCapabilitiesAddGuestFeature(guest, "nonpae", 1, 0) == NULL) return -1; if (guest_archs[i].ia64_be && virCapabilitiesAddGuestFeature(guest, "ia64_be", 1, 0) == NULL) return -1; if (guest_archs[i].hvm) { if (virCapabilitiesAddGuestFeature(guest, "acpi", 1, 1) == NULL) return -1; if (virCapabilitiesAddGuestFeature(guest, "apic", 1, 0) == NULL) return -1; if (virCapabilitiesAddGuestFeature(guest, "hap", 0, 1) == NULL) return -1; } } return 0; }
int hyperxl_initialize_driver(hyperxl_driver** pdriver, bool verbose) { #ifndef LIBXL_HAVE_BUILDINFO_KERNEL return -1; #else hyperxl_driver *driver; const libxl_version_info* version = NULL; uint32_t mem = 0; xentoollog_level log_level = XTL_INFO; *pdriver = (hyperxl_driver*)malloc(sizeof(hyperxl_driver)); if ( *pdriver == NULL ) { return -1; } driver = *pdriver; if (verbose) { log_level = XTL_DEBUG; } driver->logger = (xentoollog_logger*)xtl_createlogger_hyperxl(log_level, 0); if (driver->logger == NULL) { goto release_driver; } if(libxl_ctx_alloc(&driver->ctx, LIBXL_VERSION, 0, driver->logger)) { goto close_logger; } libxl_childproc_setmode(driver->ctx, &libxl_child_hooks, driver->ctx); version = libxl_get_version_info(driver->ctx); if (version == NULL) { goto free_ctx; } driver->version = version->xen_version_major * 1000000 + version->xen_version_minor * 1000; driver->capabilities = strdup(version->capabilities); if(libxl_get_free_memory(driver->ctx, &mem)) { goto free_ctx; } libxl_event_register_callbacks(driver->ctx, &ev_hooks, driver); return 0; free_ctx: libxl_ctx_free(driver->ctx); close_logger: xtl_logger_destroy(driver->logger); release_driver: free(driver); driver = NULL; return -1; #endif //LIBXL_HAVE_BUILDINFO_KERNEL }
libxlDriverConfigPtr libxlDriverConfigNew(void) { libxlDriverConfigPtr cfg; char *log_file = NULL; char ebuf[1024]; unsigned int free_mem; if (libxlConfigInitialize() < 0) return NULL; if (!(cfg = virObjectNew(libxlDriverConfigClass))) return NULL; if (VIR_STRDUP(cfg->configDir, LIBXL_CONFIG_DIR) < 0) goto error; if (VIR_STRDUP(cfg->autostartDir, LIBXL_AUTOSTART_DIR) < 0) goto error; if (VIR_STRDUP(cfg->logDir, LIBXL_LOG_DIR) < 0) goto error; if (VIR_STRDUP(cfg->stateDir, LIBXL_STATE_DIR) < 0) goto error; if (VIR_STRDUP(cfg->libDir, LIBXL_LIB_DIR) < 0) goto error; if (VIR_STRDUP(cfg->saveDir, LIBXL_SAVE_DIR) < 0) goto error; if (VIR_STRDUP(cfg->autoDumpDir, LIBXL_DUMP_DIR) < 0) goto error; if (virAsprintf(&log_file, "%s/libxl-driver.log", cfg->logDir) < 0) goto error; if (virFileMakePath(cfg->logDir) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to create log dir '%s': %s"), cfg->logDir, virStrerror(errno, ebuf, sizeof(ebuf))); goto error; } if ((cfg->logger_file = fopen(log_file, "a")) == NULL) { VIR_ERROR(_("Failed to create log file '%s': %s"), log_file, virStrerror(errno, ebuf, sizeof(ebuf))); goto error; } VIR_FREE(log_file); cfg->logger = (xentoollog_logger *)xtl_createlogger_stdiostream(cfg->logger_file, XTL_DEBUG, 0); if (!cfg->logger) { VIR_ERROR(_("cannot create logger for libxenlight, disabling driver")); goto error; } if (libxl_ctx_alloc(&cfg->ctx, LIBXL_VERSION, 0, cfg->logger)) { VIR_ERROR(_("cannot initialize libxenlight context, probably not " "running in a Xen Dom0, disabling driver")); goto error; } if ((cfg->verInfo = libxl_get_version_info(cfg->ctx)) == NULL) { VIR_ERROR(_("cannot version information from libxenlight, " "disabling driver")); goto error; } cfg->version = (cfg->verInfo->xen_version_major * 1000000) + (cfg->verInfo->xen_version_minor * 1000); /* This will fill xenstore info about free and dom0 memory if missing, * should be called before starting first domain */ if (libxl_get_free_memory(cfg->ctx, &free_mem)) { VIR_ERROR(_("Unable to configure libxl's memory management parameters")); goto error; } /* setup autoballoon */ if (libxlGetAutoballoonConf(cfg, &cfg->autoballoon) < 0) goto error; return cfg; error: VIR_FREE(log_file); virObjectUnref(cfg); return NULL; }