From: Prakhar Bansal <prakharbansal0910@xxxxxxxxx> --- include/libvirt/virterror.h | 2 +- libvirt.spec.in | 7 + m4/virt-driver-jailhouse.m4 | 42 +++++ meson.build | 4 + meson_options.txt | 1 + src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/jailhouse/Makefile.inc.am | 21 +++ src/jailhouse/jailhouse_driver.c | 219 +++++++++++++++++++++++++++ src/jailhouse/jailhouse_driver.h | 23 +++ src/jailhouse/libvirtd_jailhouse.aug | 43 ++++++ src/jailhouse/meson.build | 48 ++++++ src/libvirt.c | 10 ++ src/meson.build | 1 + src/qemu/qemu_command.c | 1 + src/util/virerror.c | 1 + 16 files changed, 424 insertions(+), 1 deletion(-) create mode 100644 m4/virt-driver-jailhouse.m4 create mode 100644 src/jailhouse/Makefile.inc.am create mode 100644 src/jailhouse/jailhouse_driver.c create mode 100644 src/jailhouse/jailhouse_driver.h create mode 100644 src/jailhouse/libvirtd_jailhouse.aug create mode 100644 src/jailhouse/meson.build diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index 0f1c32283d..97f2ac16d8 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -136,7 +136,7 @@ typedef enum { VIR_FROM_TPM = 70, /* Error from TPM */ VIR_FROM_BPF = 71, /* Error from BPF code */ - + VIR_FROM_JAILHOUSE = 72, /* Error from Jailhouse driver */ # ifdef VIR_ENUM_SENTINELS VIR_ERR_DOMAIN_LAST # endif diff --git a/libvirt.spec.in b/libvirt.spec.in index 62b401bd08..ca65063e79 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -17,6 +17,7 @@ %define with_lxc 0%{!?_without_lxc:1} %define with_libxl 0%{!?_without_libxl:1} %define with_vbox 0%{!?_without_vbox:1} +%define with_jailhouse 0%{!?_without_jailhouse:1} %define with_qemu_tcg %{with_qemu} @@ -1043,6 +1044,12 @@ exit 1 %define arg_vmware -Ddriver_vmware=disabled %endif +%if %{with_jailhouse} + %define arg_jailhouse --with-jailhouse +%else + %define arg_jailhouse --without-jailhouse +%endif + %if %{with_storage_rbd} %define arg_storage_rbd -Dstorage_rbd=enabled %else diff --git a/m4/virt-driver-jailhouse.m4 b/m4/virt-driver-jailhouse.m4 new file mode 100644 index 0000000000..9008c6ce30 --- /dev/null +++ b/m4/virt-driver-jailhouse.m4 @@ -0,0 +1,42 @@ +dnl The Jailhouse driver +dnl +dnl Copyright (C) 2016 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_ARG_JAILHOUSE], [ + LIBVIRT_ARG_WITH_FEATURE([JAILHOUSE], [Jailhouse], [check]) +]) + +AC_DEFUN([LIBVIRT_DRIVER_CHECK_JAILHOUSE], [ + if test "$with_jailhouse" = "check"; then + with_jailhouse=$with_linux + fi + + if test "$with_jailhouse" = "yes" && test "$with_linux" = "no"; then + AC_MSG_ERROR([The Jailhouse driver can be enabled on Linux only.]) + fi + + 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], [ + LIBVIRT_RESULT([Jailhouse], [$with_jailhouse]) +]) diff --git a/meson.build b/meson.build index 195d7cd784..f4f9ca4119 100644 --- a/meson.build +++ b/meson.build @@ -1895,6 +1895,10 @@ elif get_option('secdriver_selinux').enabled() error('You must install the libselinux development package in order to compile libvirt.') endif +if get_option('driver_jailhouse').enabled() + conf.set('WITH_JAILHOUSE', 1) +endif + if conf.has('WITH_QEMU') or conf.has('WITH_LXC') or conf.has('WITH_NETWORK') conf.set('WITH_BRIDGE', 1) endif diff --git a/meson_options.txt b/meson_options.txt index 7838630c1e..4f237be5dc 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -69,6 +69,7 @@ option('driver_vbox', type: 'feature', value: 'enabled', description: 'VirtualBo option('vbox_xpcomc_dir', type: 'string', value: '', description: 'Location of directory containing VirtualBox XPCOMC library') option('driver_vmware', type: 'feature', value: 'enabled', description: 'VMware driver') option('driver_vz', type: 'feature', value: 'auto', description: 'Virtuozzo driver') +option('driver_jailhouse', type: 'feature', value: 'auto', description: 'Jailhouse driver') option('secdriver_apparmor', type: 'feature', value: 'auto', description: 'use AppArmor security driver') option('apparmor_profiles', type: 'boolean', value: false, description: 'install apparmor profiles') diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 4d296f7bcb..b764a5962d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -130,6 +130,7 @@ VIR_ENUM_IMPL(virDomainVirt, "parallels", "bhyve", "vz", + "jailhouse", ); VIR_ENUM_IMPL(virDomainOS, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index cf76f340ee..46a8a1708c 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -139,6 +139,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/Makefile.inc.am b/src/jailhouse/Makefile.inc.am new file mode 100644 index 0000000000..02822b2ea1 --- /dev/null +++ b/src/jailhouse/Makefile.inc.am @@ -0,0 +1,21 @@ +# vim: filetype=automake + +JAILHOUSE_DRIVER_SOURCES = \ + jailhouse/jailhouse_driver.c \ + jailhouse/jailhouse_driver.h \ + $(NULL) + + +DRIVER_SOURCE_FILES += $(addprefix $(srcdir)/,$(JAILHOUSE_DRIVER_SOURCES)) + +EXTRA_DIST += $(JAILHOUSE_DRIVER_SOURCES) + +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) \ + $(NULL) +libvirt_driver_jailhouse_la_SOURCES = $(JAILHOUSE_DRIVER_SOURCES) +endif WITH_JAILHOUSE diff --git a/src/jailhouse/jailhouse_driver.c b/src/jailhouse/jailhouse_driver.c new file mode 100644 index 0000000000..0175ba771b --- /dev/null +++ b/src/jailhouse/jailhouse_driver.c @@ -0,0 +1,219 @@ +/* + * jailhouse_driver.c: Implementation of driver for Jailhouse hypervisor + * + * Copyright (C) 2020 Prakhar Bansal + * + * 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/>. + */ + +#include <config.h> + +#include "jailhouse_driver.h" +#include "virtypedparam.h" +#include "virerror.h" +#include "virstring.h" +#include "viralloc.h" +#include "domain_conf.h" +#include "virfile.h" +#include "datatypes.h" +#include "vircommand.h" +#include <string.h> + +#define UNUSED(x) (void)(x) + +static virDrvOpenStatus +jailhouseConnectOpen(virConnectPtr conn, + virConnectAuthPtr auth, + virConfPtr conf, + unsigned int flags) +{ + UNUSED(conn); + UNUSED(auth); + UNUSED(conf); + UNUSED(flags); + return 0; +} + +static int +jailhouseConnectClose(virConnectPtr conn) +{ + UNUSED(conn); + return 0; +} + +static const char * +jailhouseConnectGetType(virConnectPtr conn) +{ + UNUSED(conn); + return NULL; + +} + +static char * +jailhouseConnectGetHostname(virConnectPtr conn) +{ + UNUSED(conn); + return NULL; +} + +static int +jailhouseNodeGetInfo(virConnectPtr conn, + virNodeInfoPtr info) +{ + UNUSED(conn); + UNUSED(info); + return -1; +} + +static int +jailhouseConnectListDomains(virConnectPtr conn, + int *ids, + int maxids) +{ + UNUSED(conn); + UNUSED(ids); + UNUSED(maxids); + return -1; +} + +static int +jailhouseConnectNumOfDomains(virConnectPtr conn) +{ + UNUSED(conn); + return -1; +} + +static int +jailhouseConnectListAllDomains(virConnectPtr conn, + virDomainPtr **domain, + unsigned int flags) +{ + UNUSED(conn); + UNUSED(domain); + UNUSED(flags); + return -1; +} + +static virDomainPtr +jailhouseDomainLookupByID(virConnectPtr conn, + int id) +{ + UNUSED(conn); + UNUSED(id); + return NULL; +} + +static virDomainPtr +jailhouseDomainLookupByName(virConnectPtr conn, + const char *name) +{ + UNUSED(conn); + UNUSED(name); + return NULL; +} + +static virDomainPtr +jailhouseDomainLookupByUUID(virConnectPtr conn, + const unsigned char *uuid) +{ + UNUSED(conn); + UNUSED(uuid); + return NULL; +} + +static int +jailhouseDomainCreate(virDomainPtr domain) +{ + UNUSED(domain); + return -1; + +} + +static int +jailhouseDomainShutdown(virDomainPtr domain) +{ + UNUSED(domain); + return -1; +} + + +static int +jailhouseDomainDestroy(virDomainPtr domain) +{ + UNUSED(domain); + return -1; +} + +static int +jailhouseDomainGetInfo(virDomainPtr domain, + virDomainInfoPtr info) +{ + UNUSED(domain); + UNUSED(info); + return -1; +} + +static int +jailhouseDomainGetState(virDomainPtr domain, + int *state, + int *reason, + unsigned int flags) +{ + UNUSED(domain); + UNUSED(state); + UNUSED(reason); + UNUSED(flags); + return -1; +} + +static char * +jailhouseDomainGetXMLDesc(virDomainPtr domain, + unsigned int flags) +{ + UNUSED(domain); + UNUSED(flags); + return NULL; +} + +static virHypervisorDriver jailhouseHypervisorDriver = { + .name = "JAILHOUSE", + .connectOpen = jailhouseConnectOpen, /* 6.3.0 */ + .connectClose = jailhouseConnectClose, /* 6.3.0 */ + .connectListDomains = jailhouseConnectListDomains, /* 6.3.0 */ + .connectNumOfDomains = jailhouseConnectNumOfDomains, /* 6.3.0 */ + .connectListAllDomains = jailhouseConnectListAllDomains, /* 6.3.0 */ + .domainLookupByID = jailhouseDomainLookupByID, /* 6.3.0 */ + .domainLookupByUUID = jailhouseDomainLookupByUUID, /* 6.3.0 */ + .domainLookupByName = jailhouseDomainLookupByName, /* 6.3.0 */ + .domainGetXMLDesc = jailhouseDomainGetXMLDesc, /* 6.3.0 */ + .domainCreate = jailhouseDomainCreate, /* 6.3.0 */ + .connectGetType = jailhouseConnectGetType, /* 6.3.0 */ + .connectGetHostname = jailhouseConnectGetHostname, /* 6.3.0 */ + .nodeGetInfo = jailhouseNodeGetInfo, /* 6.3.0 */ + .domainShutdown = jailhouseDomainShutdown, /* 6.3.0 */ + .domainDestroy = jailhouseDomainDestroy, /* 6.3.0 */ + .domainGetInfo = jailhouseDomainGetInfo, /* 6.3.0 */ + .domainGetState = jailhouseDomainGetState, /* 6.3.0 */ +}; + +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 0000000000..b0dbc8d033 --- /dev/null +++ b/src/jailhouse/jailhouse_driver.h @@ -0,0 +1,23 @@ +/* + * jailhouse_driver.h: Libvirt driver for Jailhouse hypervisor + * + * Copyright (C) 2020 Prakhar Bansal + * + * 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/>. + */ + +#pragma once + +int jailhouseRegister(void); diff --git a/src/jailhouse/libvirtd_jailhouse.aug b/src/jailhouse/libvirtd_jailhouse.aug new file mode 100644 index 0000000000..96a186eae2 --- /dev/null +++ b/src/jailhouse/libvirtd_jailhouse.aug @@ -0,0 +1,43 @@ +(* /etc/libvirt/jailhouse.conf *) + +module Libvirtd_jailhouse = + autoload xfm + + let eol = del /[ \t]*\n/ "\n" + let value_sep = del /[ \t]*=[ \t]*/ " = " + let indent = del /[ \t]*/ "" + + let array_sep = del /,[ \t\n]*/ ", " + let array_start = del /\[[ \t\n]*/ "[ " + let array_end = del /\]/ "]" + + let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\"" + let bool_val = store /0|1/ + let int_val = store /[0-9]+/ + let str_array_element = [ seq "el" . str_val ] . del /[ \t\n]*/ "" + let str_array_val = counter "el" . array_start . ( str_array_element . ( array_sep . str_array_element ) * ) ? . array_end + + let str_entry (kw:string) = [ key kw . value_sep . str_val ] + let bool_entry (kw:string) = [ key kw . value_sep . bool_val ] + let int_entry (kw:string) = [ key kw . value_sep . int_val ] + let str_array_entry (kw:string) = [ key kw . value_sep . str_array_val ] + + (* Config entry grouped by function - same order as example config *) + let log_entry = bool_entry "log_with_libvirtd" + | str_entry "security_driver" + | bool_entry "security_default_confined" + | bool_entry "security_require_confined" + + (* Each entry in the config is one of the following three ... *) + let entry = log_entry + let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ] + let empty = [ label "#empty" . eol ] + + let record = indent . entry . eol + + let lns = ( record | comment | empty ) * + + let filter = incl "/etc/libvirt/jailhouse.conf" + . Util.stdexcl + + let xfm = transform lns filter diff --git a/src/jailhouse/meson.build b/src/jailhouse/meson.build new file mode 100644 index 0000000000..45ceeecca3 --- /dev/null +++ b/src/jailhouse/meson.build @@ -0,0 +1,48 @@ +jailhouse_sources = files( + 'jailhouse_driver.c', +) + +driver_source_files += jailhouse_sources +stateful_driver_source_files += jailhouse_sources + +if conf.has('WITH_JAILHOUSE') + jailhouse_driver_impl = static_library( + 'virt_driver_jailhouse_impl', + [ + jailhouse_sources, + ], + dependencies: [ + access_dep, + src_dep, + ], + include_directories: [ + conf_inc_dir, + hypervisor_inc_dir, + ], + ) + + virt_modules += { + 'name': 'virt_driver_jailhouse', + 'link_whole': [ + jailhouse_driver_impl, + ], + 'link_args': [ + libvirt_no_undefined, + ], + } + + virt_daemons += { + 'name': 'virtjailhoused', + 'c_args': [ + '-DDAEMON_NAME="virtjailhoused"', + '-DMODULE_NAME="jailhouse"' + ], + } + + virt_conf_files += files('jailhouse.conf') + virt_aug_files += files('libvirtd_jailhouse.aug') + + virt_daemon_confs += { + 'name': 'virtjailhoused', + } +endif diff --git a/src/libvirt.c b/src/libvirt.c index 0748eb2352..8a78cbcf3a 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -75,6 +75,9 @@ #ifdef WITH_BHYVE # include "bhyve/bhyve_driver.h" #endif +#ifdef WITH_JAILHOUSE +# include "jailhouse/jailhouse_driver.h" +#endif #include "access/viraccessmanager.h" #define VIR_FROM_THIS VIR_FROM_NONE @@ -271,6 +274,10 @@ virGlobalInit(void) if (hypervRegister() == -1) goto error; #endif +#ifdef WITH_JAILHOUSE + if (jailhouseRegister() == -1) + goto error; +#endif #ifdef WITH_REMOTE if (remoteRegister() == -1) goto error; @@ -1045,6 +1052,9 @@ virConnectOpenInternal(const char *name, #endif #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, diff --git a/src/meson.build b/src/meson.build index 897b5ecbca..9e2b97900e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -268,6 +268,7 @@ subdir('security') subdir('storage') subdir('bhyve') +subdir('jailhouse') subdir('esx') subdir('hyperv') subdir('libxl') diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 0ba348e911..78976c2153 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6843,6 +6843,7 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, case VIR_DOMAIN_VIRT_PHYP: case VIR_DOMAIN_VIRT_PARALLELS: case VIR_DOMAIN_VIRT_BHYVE: + case VIR_DOMAIN_VIRT_JAILHOUSE: case VIR_DOMAIN_VIRT_VZ: case VIR_DOMAIN_VIRT_NONE: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, diff --git a/src/util/virerror.c b/src/util/virerror.c index 80a7cfe0ed..560e0a1f0f 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -134,6 +134,7 @@ VIR_ENUM_IMPL(virErrorDomain, "Thread jobs", "Admin Interface", "Log Manager", + "Jailhouse Driver", "Xen XL Config", "Perf", /* 65 */ -- 2.26.2