>From 818447bdc0c7fb5048367276a5eb64108ad95e2a Mon Sep 17 00:00:00 2001 From: Christian Loehle <cloehle@xxxxxxxxxxxxx> Date: Mon, 14 Dec 2015 20:13:07 +0100 Subject: [PATCH] Add Jailhouse Driver v3 --- configure.ac | 7 + include/libvirt/virterror.h | 1 + m4/virt-driver-jailhouse.m4 | 35 +++ po/POTFILES.in | 1 + src/Makefile.am | 15 ++ src/conf/domain_conf.c | 3 +- src/conf/domain_conf.h | 1 + src/jailhouse/README | 14 ++ src/jailhouse/jailhouse_driver.c | 511 +++++++++++++++++++++++++++++++++++++++ src/jailhouse/jailhouse_driver.h | 28 +++ src/libvirt.c | 10 + src/util/virerror.c | 1 + 12 files changed, 626 insertions(+), 1 deletion(-) create mode 100644 m4/virt-driver-jailhouse.m4 create mode 100644 src/jailhouse/README create mode 100644 src/jailhouse/jailhouse_driver.c create mode 100644 src/jailhouse/jailhouse_driver.h diff --git a/configure.ac b/configure.ac index 98cf210..445b2ca 100644 --- a/configure.ac +++ b/configure.ac @@ -1087,6 +1087,12 @@ dnl LIBVIRT_DRIVER_CHECK_BHYVE dnl +dnl Checks for Jailhouse driver +dnl + +LIBVIRT_DRIVER_CHECK_JAILHOUSE + +dnl dnl check for shell that understands <> redirection without truncation, dnl needed by src/qemu/qemu_monitor_{text,json}.c. dnl @@ -2830,6 +2836,7 @@ AC_MSG_NOTICE([ ESX: $with_esx]) AC_MSG_NOTICE([ Hyper-V: $with_hyperv]) LIBVIRT_DRIVER_RESULT_VZ LIBVIRT_DRIVER_RESULT_BHYVE +LIBVIRT_DRIVER_RESULT_JAILHOUSE AC_MSG_NOTICE([ Test: $with_test]) AC_MSG_NOTICE([ Remote: $with_remote]) AC_MSG_NOTICE([ Network: $with_network]) diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index 0539e48..bbc7e2e 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -128,6 +128,7 @@ typedef enum { VIR_FROM_THREAD = 61, /* Error from thread utils */ VIR_FROM_ADMIN = 62, /* Error from admin backend */ VIR_FROM_LOGGING = 63, /* Error from log manager */ + VIR_FROM_JAILHOUSE = 64, /* Error from Jailhouse driver */ # ifdef VIR_ENUM_SENTINELS VIR_ERR_DOMAIN_LAST diff --git a/m4/virt-driver-jailhouse.m4 b/m4/virt-driver-jailhouse.m4 new file mode 100644 index 0000000..6c72043 --- /dev/null +++ b/m4/virt-driver-jailhouse.m4 @@ -0,0 +1,35 @@ +dnl The Jailhouse driver +dnl +dnl Copyright (C) 2005-2015 Red Hat, Inc. +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License, or (at your option) any later version. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library. If not, see +dnl <http://www.gnu.org/licenses/>. +dnl + +AC_DEFUN([LIBVIRT_DRIVER_CHECK_JAILHOUSE],[ + AC_ARG_WITH([jailhouse], + [AS_HELP_STRING([--with-jailhouse], + [add Jailhouse support @<:@default=yes@:>@])]) + m4_divert_text([DEFAULTS], [with_jailhouse=yes]) + + if test "$with_jailhouse" = "yes"; then + AC_DEFINE_UNQUOTED([WITH_JAILHOUSE], 1, [whether jailhouse driver is enabled]) + fi + + AM_CONDITIONAL([WITH_JAILHOUSE], [test "$with_jailhouse" = "yes"]) +]) + +AC_DEFUN([LIBVIRT_DRIVER_RESULT_JAILHOUSE],[ + AC_MSG_NOTICE([Jailhouse: $with_jailhouse]) +]) diff --git a/po/POTFILES.in b/po/POTFILES.in index 82e8d3e..29259f4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -61,6 +61,7 @@ src/hyperv/hyperv_wmi.c src/interface/interface_backend_netcf.c src/interface/interface_backend_udev.c src/internal.h +src/jailhouse/jailhouse_driver.c src/libvirt.c src/libvirt-admin.c src/libvirt-domain.c diff --git a/src/Makefile.am b/src/Makefile.am index 7219f7c..af46766 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -622,6 +622,7 @@ DRIVER_SOURCE_FILES = \ $(VMWARE_DRIVER_SOURCES) \ $(XEN_DRIVER_SOURCES) \ $(XENAPI_DRIVER_SOURCES) \ + $(JAILHOUSE_DRIVER_SOURCES) \ $(NULL) STATEFUL_DRIVER_SOURCE_FILES = \ @@ -904,6 +905,11 @@ BHYVE_DRIVER_SOURCES = \ bhyve/bhyve_utils.h \ $(NULL) +JAILHOUSE_DRIVER_SOURCES = \ + jailhouse/jailhouse_driver.c \ + jailhouse/jailhouse_driver.h \ + $(NULL) + NETWORK_DRIVER_SOURCES = \ network/bridge_driver.h network/bridge_driver.c \ network/bridge_driver_platform.h \ @@ -1480,6 +1486,14 @@ libvirt_driver_vz_la_LIBADD = $(PARALLELS_SDK_LIBS) $(LIBNL_LIBS) libvirt_driver_vz_la_SOURCES = $(VZ_DRIVER_SOURCES) endif WITH_VZ +if WITH_JAILHOUSE +noinst_LTLIBRARIES += libvirt_driver_jailhouse.la +libvirt_la_BUILT_LIBADD += libvirt_driver_jailhouse.la +libvirt_driver_jailhouse_la_CFLAGS = \ + -I$(srcdir)/conf $(AM_CFLAGS) +libvirt_driver_jailhouse_la_SOURCES = $(JAILHOUSE_DRIVER_SOURCES) +endif WITH_JAILHOUSE + if WITH_BHYVE noinst_LTLIBRARIES += libvirt_driver_bhyve_impl.la libvirt_driver_bhyve_la_SOURCES = @@ -1845,6 +1859,7 @@ EXTRA_DIST += \ $(HYPERV_DRIVER_EXTRA_DIST) \ $(VZ_DRIVER_SOURCES) \ $(BHYVE_DRIVER_SOURCES) \ + $(JAILHOUSE_DRIVER_SOURCES) \ $(NETWORK_DRIVER_SOURCES) \ $(INTERFACE_DRIVER_SOURCES) \ $(STORAGE_DRIVER_SOURCES) \ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5200c27..926c1a0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -107,7 +107,8 @@ VIR_ENUM_IMPL(virDomainVirt, VIR_DOMAIN_VIRT_LAST, "phyp", "parallels", "bhyve", - "vz") + "vz", + "jailhouse") VIR_ENUM_IMPL(virDomainOS, VIR_DOMAIN_OSTYPE_LAST, "hvm", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index cec681a..271811f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -225,6 +225,7 @@ typedef enum { VIR_DOMAIN_VIRT_PARALLELS, VIR_DOMAIN_VIRT_BHYVE, VIR_DOMAIN_VIRT_VZ, + VIR_DOMAIN_VIRT_JAILHOUSE, VIR_DOMAIN_VIRT_LAST } virDomainVirtType; diff --git a/src/jailhouse/README b/src/jailhouse/README new file mode 100644 index 0000000..02ba87d --- /dev/null +++ b/src/jailhouse/README @@ -0,0 +1,14 @@ +The jailhouse hypervisor driver for the libvirt project aims to provide +rudimentary support for managing jailhouse with the libvirt library. +The main advantage of this is the possibility to use virt-manager as a GUI to +manage Jailhouse cells. Thus the driver is mainly built around the API calls +that virt-manager uses and needs. +Due to the concept of Jailhouse a lot of libvirt functions can't be realized, +so this driver isn't as full-featured as upstream drivers of the +libvirt project. +Currently the driver relies on the Jailhouse binary, which has to be in $PATH +or passed when connecting a libvirt client to it +(e.g. virt-manager -c jailhouse:///path/to/jailhouse/tools/jailhouse). +Be aware though that the driver doesn't store any information about cells, +so most API calls use "jailhouse cell list" every time they're called to get +the current state. diff --git a/src/jailhouse/jailhouse_driver.c b/src/jailhouse/jailhouse_driver.c new file mode 100644 index 0000000..79e97f0 --- /dev/null +++ b/src/jailhouse/jailhouse_driver.c @@ -0,0 +1,511 @@ +/* + * virJailhouseDriver.c: hypervisor driver for managing Jailhouse cells + * + * Copyright (C) 2015 Linutronix GmbH + * + * 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 + * <http://www.gnu.org/licenses/>. + * + * Author: Christian Loehle + */ + +#include <config.h> +#include <string.h> +#include "jailhouse_driver.h" +#include "datatypes.h" +#include "virerror.h" +#include "viralloc.h" +#include "virlog.h" +#include "vircommand.h" +#include "virxml.h" +#include "configmake.h" +#include "virfile.h" +#include "virtypedparam.h" +#include "virstring.h" +#include "nodeinfo.h" +#include "capabilities.h" +#include "domain_conf.h" + +#define VIR_FROM_THIS VIR_FROM_JAILHOUSE + +#define IDLENGTH 8 +#define NAMELENGTH 24 +#define STATELENGTH 16 +#define CPULENGTH 24 +#define STATERUNNING 0 +#define STATERUNNINGSTRING "running " +#define STATERUNNINGLOCKED 1 +#define STATERUNNINGLOCKEDSTRING "running/locked " +#define STATESHUTDOWN 2 +#define STATESHUTDOWNSTRING "shut down " +#define STATEFAILED 3 +#define STATEFAILEDSTRING "failed " +#define JAILHOUSEBINARY "jailhouse" + +struct virJailhouseCell { + int id; + char name[NAMELENGTH+1]; + int state; + virBitmapPtr assignedCPUs; + virBitmapPtr failedCPUs; /* currently unused */ + unsigned char uuid[VIR_UUID_BUFLEN]; +}; +typedef struct virJailhouseCell virJailhouseCell; +typedef virJailhouseCell *virJailhouseCellPtr; + +/* + * Because virCommandRunRegex Callback gets called every line + */ +struct virJailhouseCellCallbackData { + size_t ncells; + virJailhouseCellPtr cells; +}; +typedef struct virJailhouseCellCallbackData virJailhouseCellCallbackData; +typedef virJailhouseCellCallbackData *virJailhouseCellCallbackDataPtr; + +/* + * The driver requeries the cells on most calls, it stores the result of the + * last query, so it can copy the UUIDs in the new query if the cell is the + * same(otherwise it just generates a new one). + * not preserving the UUID results in a lot of bugs in libvirts clients. + */ +struct virJailhouseDriver { + size_t lastQueryCellsCount; + virJailhouseCellPtr lastQueryCells; +}; +typedef struct virJailhouseDriver virJailhouseDriver; +typedef virJailhouseDriver *virJailhouseDriverPtr; + +static int virJailhouseParseListOutputCallback(char **const groups, void *data) +{ + virJailhouseCellCallbackDataPtr celldata = (virJailhouseCellCallbackDataPtr) data; + virJailhouseCellPtr cells = celldata->cells; + size_t count = celldata->ncells; + char* endptr = groups[0] + strlen(groups[0]) - 1; + char* state = groups[2]; + if (VIR_EXPAND_N(cells, count, 1)) + return -1; + celldata->ncells++; + + if (virStrToLong_i(groups[0], &endptr, 0, &cells[count-1].id)) + return -1; + if (!virStrcpy(cells[count-1].name, groups[1], NAMELENGTH+1)) + return -1; + if (STREQLEN(state, STATERUNNINGSTRING, STATELENGTH)) + cells[count-1].state = STATERUNNING; + else if (STREQLEN(state, STATESHUTDOWNSTRING, STATELENGTH)) + cells[count-1].state = STATESHUTDOWN; + else if (STREQLEN(state, STATERUNNINGLOCKEDSTRING, STATELENGTH)) + cells[count-1].state = STATERUNNINGLOCKED; + else + cells[count-1].state = STATEFAILED; + virBitmapParse(groups[3], 0, &cells[count-1].assignedCPUs, VIR_DOMAIN_CPUMASK_LEN); + virBitmapParse(groups[4], 0, &cells[count-1].failedCPUs, VIR_DOMAIN_CPUMASK_LEN); + celldata->cells = cells; + return 0; +} + +/* + * calls "jailhouse cell list" and parses the output in an array of virJailhouseCell + * example output: + * ID Name State Assigned CPUs Failed CPUs + * 0 QEMU-VM running 0-3 + */ +static ssize_t +virJailhouseParseListOutput(virJailhouseCellPtr *parsedCells) +{ + int nvars[] = { 5 }; + virJailhouseCellCallbackData callbackData; + const char *regex[] = { "([0-9]{1,8})\\s*([-0-9a-zA-Z]{1,24})\\s*([a-z/ ]{1,16})\\s*([0-9,-]{1,24})?\\s*([0-9,-]{1,24})?\\s*" }; + virCommandPtr cmd = virCommandNew(JAILHOUSEBINARY); + virCommandAddArg(cmd, "cell"); + virCommandAddArg(cmd, "list"); + virCommandAddEnvPassCommon(cmd); + callbackData.cells = NULL; + callbackData.ncells = 0; + if (virCommandRunRegex(cmd, 1, regex, nvars, &virJailhouseParseListOutputCallback, &callbackData, NULL) < 0) { + virCommandFree(cmd); + return -1; + } + virCommandFree(cmd); + *parsedCells = callbackData.cells; + return callbackData.ncells; +} + +/* + * Returns the libvirts equivalent of the cell state passed to it + */ +static virDomainState +virJailhouseCellToState(virJailhouseCellPtr cell) +{ + switch (cell->state) { + case STATERUNNING: return VIR_DOMAIN_RUNNING; + case STATERUNNINGLOCKED: return VIR_DOMAIN_RUNNING; + case STATESHUTDOWN: return VIR_DOMAIN_SHUTOFF; + case STATEFAILED: return VIR_DOMAIN_CRASHED; + default: return VIR_DOMAIN_NOSTATE; + } +} + +/* + * Returns a new virDomainPtr filled with the data of the virJailhouseCell + */ +static virDomainPtr +virJailhouseCellToDomainPtr(virConnectPtr conn, virJailhouseCellPtr cell) +{ + virDomainPtr dom = virGetDomain(conn, cell->name, cell->uuid); + dom->id = cell->id; + return dom; +} + +/* + * Check cells for cell and copies UUID if found, otherwise generates a new one, this is to preserve UUID in libvirt + */ +static void virJailhouseSetUUID(virJailhouseCellPtr cells, size_t count, virJailhouseCellPtr cell) +{ + size_t i; + for (i = 0; i < count; i++) { + if (strncmp(cells[i].name, cell->name, NAMELENGTH+1)) + continue; + memcpy(cell->uuid, cells[i].uuid, VIR_UUID_BUFLEN); + return; + } + virUUIDGenerate(cell->uuid); +} + +/* + * Frees the old list of cells, gets the new one and preserves UUID if cells were present in the old + */ +static int +virJailhouseGetCurrentCellList(virConnectPtr conn) +{ + virJailhouseDriverPtr driver = (virJailhouseDriverPtr)conn->privateData; + ssize_t count; + size_t i; + size_t lastCount = driver->lastQueryCellsCount; + virJailhouseCellPtr lastCells = driver->lastQueryCells; + virJailhouseCellPtr cells = NULL; + + count = virJailhouseParseListOutput(&cells); + for (i = 0; i < count; i++) + virJailhouseSetUUID(lastCells, lastCount, cells+i); + for (i = 0; i < lastCount; i++) { + virBitmapFree(lastCells[i].assignedCPUs); + virBitmapFree(lastCells[i].failedCPUs); + } + VIR_FREE(lastCells); + driver->lastQueryCells = cells; + driver->lastQueryCellsCount = count; + return count; +} + +/* + * Converts libvirts virDomainPtr to the internal virJailhouseCell by parsing the "jailhouse cell list" output + * and looking up the name of the virDomainPtr, returns NULL if cell is no longer present + */ +static virJailhouseCellPtr +virDomainPtrToCell(virDomainPtr dom) +{ + virJailhouseDriverPtr driver = dom->conn->privateData; + size_t cellsCount; + size_t i; + if (virJailhouseGetCurrentCellList(dom->conn) == -1) + return NULL; + cellsCount = driver->lastQueryCellsCount; + virJailhouseCellPtr cells = driver->lastQueryCells; + for (i = 0; i < cellsCount; i++) + if (dom->id == cells[i].id) + return cells+i; + return NULL; +} + +static virDrvOpenStatus +jailhouseConnectOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, unsigned int flags) +{ + virCheckFlags(0, VIR_DRV_OPEN_ERROR); + virJailhouseDriverPtr driver; + if (conn->uri->scheme == NULL || + STRNEQ(conn->uri->scheme, "jailhouse")) + return VIR_DRV_OPEN_DECLINED; + if (conn->uri->path != NULL && STRNEQ(conn->uri->path, "/")) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unexpected Jailhouse URI path '%s', try jailhouse:///"), + conn->uri->path); + return VIR_DRV_OPEN_ERROR; + } + if (VIR_ALLOC(driver) < 0) + return VIR_DRV_OPEN_ERROR; + driver->lastQueryCells = NULL; + driver->lastQueryCellsCount = 0; + conn->privateData = driver; + return VIR_DRV_OPEN_SUCCESS; +} + +static int +jailhouseConnectClose(virConnectPtr conn) +{ + + virJailhouseDriverPtr driver = (virJailhouseDriverPtr)conn->privateData; + size_t i; + size_t cellsCount = driver->lastQueryCellsCount; + virJailhouseCellPtr cells = driver->lastQueryCells; + for (i = 0; i < cellsCount; i++) { + virBitmapFree(cells[i].assignedCPUs); + virBitmapFree(cells[i].failedCPUs); + } + VIR_FREE(cells); + VIR_FREE(driver); + conn->privateData = NULL; + return 0; +} + +static int +jailhouseConnectNumOfDomains(virConnectPtr conn) +{ + if (virJailhouseGetCurrentCellList(conn) == -1) + return -1; + return ((virJailhouseDriverPtr)conn->privateData)->lastQueryCellsCount; +} + +static int +jailhouseConnectListDomains(virConnectPtr conn, int * ids, int maxids) +{ + virJailhouseDriverPtr driver = (virJailhouseDriverPtr)conn->privateData; + virJailhouseCellPtr cells; + size_t cellsCount; + size_t i; + if (virJailhouseGetCurrentCellList(conn) == -1) + return -1; + cellsCount = driver->lastQueryCellsCount; + cells = driver->lastQueryCells; + for (i = 0; i < maxids && i < cellsCount; i++) + ids[i] = cells[i].id; + return i; +} + +static int +jailhouseConnectListAllDomains(virConnectPtr conn, virDomainPtr ** domains, unsigned int flags) +{ + virCheckFlags(VIR_CONNECT_LIST_DOMAINS_ACTIVE, 0); + virJailhouseDriverPtr driver = (virJailhouseDriverPtr)conn->privateData; + virJailhouseCellPtr cells; + size_t cellsCount; + size_t i; + if (virJailhouseGetCurrentCellList(conn) == -1) + goto error; + + cellsCount = driver->lastQueryCellsCount; + cells = driver->lastQueryCells; + if (cellsCount == -1) + goto error; + if (VIR_ALLOC_N(*domains, cellsCount+1) < 0) + goto error; + for (i = 0; i < cellsCount; i++) + (*domains)[i] = virJailhouseCellToDomainPtr(conn, cells+i); + (*domains)[cellsCount] = NULL; + return cellsCount; + error: + *domains = NULL; + return -1; +} + +static virDomainPtr +jailhouseDomainLookupByID(virConnectPtr conn, int id) +{ + virJailhouseDriverPtr driver = (virJailhouseDriverPtr)conn->privateData; + size_t cellsCount; + size_t i; + if (virJailhouseGetCurrentCellList(conn) == -1) + return NULL; + + cellsCount = driver->lastQueryCellsCount; + if (cellsCount == -1) + return NULL; + virJailhouseCellPtr cells = driver->lastQueryCells; + for (i = 0; i < cellsCount; i++) + if (cells[i].id == id) + return virJailhouseCellToDomainPtr(conn, cells+i); + virReportError(VIR_ERR_NO_DOMAIN, NULL); + return NULL; +} + +static virDomainPtr +jailhouseDomainLookupByName(virConnectPtr conn, const char *lookupName) +{ + virJailhouseDriverPtr driver = (virJailhouseDriverPtr)conn->privateData; + size_t cellsCount; + size_t i; + if (virJailhouseGetCurrentCellList(conn) == -1) + return NULL; + + cellsCount = driver->lastQueryCellsCount; + if (cellsCount == -1) + return NULL; + virJailhouseCellPtr cells = driver->lastQueryCells; + for (i = 0; i < cellsCount; i++) + if (STREQ(cells[i].name, lookupName)) + return virJailhouseCellToDomainPtr(conn, cells+i); + virReportError(VIR_ERR_NO_DOMAIN, NULL); + return NULL; +} + +static virDomainPtr +jailhouseDomainLookupByUUID(virConnectPtr conn, const unsigned char * uuid) +{ + virJailhouseDriverPtr driver = (virJailhouseDriverPtr)conn->privateData; + size_t cellsCount; + size_t i; + if (virJailhouseGetCurrentCellList(conn) == -1) + return NULL; + cellsCount = driver->lastQueryCellsCount; + if (cellsCount == -1) + return NULL; + virJailhouseCellPtr cells = driver->lastQueryCells; + for (i = 0; i < cellsCount; i++) + if (memcmp(cells[i].uuid, (const char*)uuid, VIR_UUID_BUFLEN) == 0) + return virJailhouseCellToDomainPtr(conn, cells+i); + virReportError(VIR_ERR_NO_DOMAIN, NULL); + return NULL; +} + +/* + * There currently is no straightforward way for the driver to retrieve those, + * so maxMem, memory and cpuTime have dummy values + */ +static int +jailhouseDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) +{ + virJailhouseCellPtr cell = virDomainPtrToCell(domain); + if (cell == NULL) + return -1; + info->state = virJailhouseCellToState(cell); + info->maxMem = 0; + info->memory = 0; + info->nrVirtCpu = virBitmapCountBits(cell->assignedCPUs); + info->cpuTime = 0; + return 0; +} + +static int +jailhouseDomainGetState(virDomainPtr domain, int *state, + int *reason ATTRIBUTE_UNUSED, unsigned int flags) +{ + virCheckFlags(0, 0); + virJailhouseCellPtr cell = virDomainPtrToCell(domain); + if (cell == NULL) + return -1; + *state = virJailhouseCellToState(cell); + return 0; +} + +static int +jailhouseDomainDestroy(virDomainPtr domain) +{ + int resultcode; + virCommandPtr cmd = virCommandNew(JAILHOUSEBINARY); + virCommandAddArg(cmd, "cell"); + virCommandAddArg(cmd, "shutdown"); + virCommandAddArgFormat(cmd, "%d", domain->id); + virCommandAddEnvPassCommon(cmd); + resultcode = virCommandRun(cmd, NULL); + virCommandFree(cmd); + if (resultcode < 0) + return -1; + return 0; +} + +static int +jailhouseDomainCreate(virDomainPtr domain) +{ + int resultcode; + virCommandPtr cmd = virCommandNew(JAILHOUSEBINARY); + virCommandAddArg(cmd, "cell"); + virCommandAddArg(cmd, "start"); + virCommandAddArgFormat(cmd, "%d", domain->id); + virCommandAddEnvPassCommon(cmd); + resultcode = virCommandRun(cmd, NULL); + virCommandFree(cmd); + if (resultcode < 0) + return -1; + return 0; +} + +/* + * There currently is no reason why it shouldn't be + */ +static int +jailhouseConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED) +{ + return 1; +} + +static int +jailhouseNodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED, virNodeInfoPtr info) +{ + return nodeGetInfo(NULL, info); +} + +/* + * Returns a dummy capabilities XML for virt-manager + */ +static char * +jailhouseConnectGetCapabilities(virConnectPtr conn ATTRIBUTE_UNUSED) +{ + virCapsPtr caps = virCapabilitiesNew(VIR_ARCH_NONE, false, false); + char* xml = virCapabilitiesFormatXML(caps); + virObjectUnref(caps); + return xml; +} + +static char * +jailhouseDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) +{ + virCheckFlags(0, NULL); + char* xml; + virDomainDefPtr domainDef = virDomainDefNewFull(domain->name, domain->uuid, domain->id); + xml = virDomainDefFormat(domainDef, 0); + virDomainDefFree(domainDef); + return xml; +} + +static virHypervisorDriver jailhouseHypervisorDriver = { + .name = "jailhouse", + .connectOpen = jailhouseConnectOpen, /* 1.3.1 */ + .connectClose = jailhouseConnectClose, /* 1.3.1 */ + .connectGetCapabilities = jailhouseConnectGetCapabilities, /* 1.3.1 */ + .connectNumOfDomains = jailhouseConnectNumOfDomains, /* 1.3.1 */ + .connectListDomains = jailhouseConnectListDomains, /* 1.3.1 */ + .connectIsAlive = jailhouseConnectIsAlive, /* 1.3.1 */ + .connectListAllDomains = jailhouseConnectListAllDomains, /* 1.3.1 */ + .domainLookupByID = jailhouseDomainLookupByID, /* 1.3.1 */ + .domainLookupByName = jailhouseDomainLookupByName, /* 1.3.1 */ + .domainLookupByUUID = jailhouseDomainLookupByUUID, /* 1.3.1 */ + .domainGetInfo = jailhouseDomainGetInfo, /* 1.3.1 */ + .domainGetState = jailhouseDomainGetState, /* 1.3.1 */ + .domainGetXMLDesc = jailhouseDomainGetXMLDesc, /* 1.3.1 */ + .domainDestroy = jailhouseDomainDestroy, /* 1.3.1 */ + .domainCreate = jailhouseDomainCreate, /* 1.3.1 */ + .nodeGetInfo = jailhouseNodeGetInfo /* 1.3.1 */ +}; + +static virConnectDriver jailhouseConnectDriver = { + .hypervisorDriver = &jailhouseHypervisorDriver, +}; + +int +jailhouseRegister(void) +{ + return virRegisterConnectDriver(&jailhouseConnectDriver, + false); +} diff --git a/src/jailhouse/jailhouse_driver.h b/src/jailhouse/jailhouse_driver.h new file mode 100644 index 0000000..47c17e7 --- /dev/null +++ b/src/jailhouse/jailhouse_driver.h @@ -0,0 +1,28 @@ +/* + * jailhouse_driver.h: hypervisor driver for managing Jailhouse cells + * + * Copyright (C) 2015 Linutronix GmbH + * + * 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 + * <http://www.gnu.org/licenses/>. + * + * Author: Christian Loehle + */ + +#ifndef JAILHOUSE_DRIVER_H +# define JAILHOUSE_DRIVER_H + +int jailhouseRegister(void); + +#endif diff --git a/src/libvirt.c b/src/libvirt.c index dd58e9c..36d5994 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -98,6 +98,9 @@ #ifdef WITH_BHYVE # include "bhyve/bhyve_driver.h" #endif +#ifdef WITH_JAILHOUSE +# include "jailhouse/jailhouse_driver.h" +#endif #define VIR_FROM_THIS VIR_FROM_NONE @@ -437,6 +440,10 @@ virGlobalInit(void) if (vzRegister() == -1) goto error; # endif +#ifdef WITH_JAILHOUSE + if (jailhouseRegister() == -1) + goto error; +#endif #endif #ifdef WITH_REMOTE if (remoteRegister() == -1) @@ -1038,6 +1045,9 @@ do_open(const char *name, #ifndef WITH_VZ STRCASEEQ(ret->uri->scheme, "parallels") || #endif +#ifndef WITH_JAILHOUSE + STRCASEEQ(ret->uri->scheme, "jailhouse") || +#endif false)) { virReportErrorHelper(VIR_FROM_NONE, VIR_ERR_CONFIG_UNSUPPORTED, __FILE__, __FUNCTION__, __LINE__, diff --git a/src/util/virerror.c b/src/util/virerror.c index 098211a..06741bf 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -135,6 +135,7 @@ VIR_ENUM_IMPL(virErrorDomain, VIR_ERR_DOMAIN_LAST, "Thread jobs", "Admin Interface", "Log Manager", + "Jailhouse Driver", ) -- 2.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list