mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
libvirt: pass a directory path into drivers for embedded usage
The intent here is to allow the virt drivers to be run directly embedded in an arbitrary process without interfering with libvirtd. To achieve this they need to store all their configuration & state in a separate directory tree from the main system or session libvirtd instances. This can be useful for doing testing of the virt drivers in "make check" without interfering with the user's own libvirtd instances. It can also be used for applications using KVM/QEMU as a piece of infrastructure to build an service, rather than for general purpose OS hosting. A long standing example is libguestfs, which would prefer if its temporary VMs did show up in the main libvirtd VM list, because this confuses apps such as OpenStack Nova. A more recent example would be Kata which is using KVM as a technology to build containers. Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Cole Robinson <crobinso@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
fd2a9dda87
commit
207709a031
@ -32,6 +32,7 @@ typedef enum {
|
|||||||
|
|
||||||
typedef virDrvStateInitResult
|
typedef virDrvStateInitResult
|
||||||
(*virDrvStateInitialize)(bool privileged,
|
(*virDrvStateInitialize)(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback,
|
virStateInhibitCallback callback,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
|
|
||||||
|
@ -89,9 +89,16 @@ virNetcfDriverStateDispose(void *obj)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
netcfStateInitialize(bool privileged,
|
netcfStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||||
void *opaque G_GNUC_UNUSED)
|
void *opaque G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (virNetcfDriverStateInitialize() < 0)
|
if (virNetcfDriverStateInitialize() < 0)
|
||||||
return VIR_DRV_STATE_INIT_ERROR;
|
return VIR_DRV_STATE_INIT_ERROR;
|
||||||
|
|
||||||
|
@ -1145,11 +1145,18 @@ udevStateCleanup(void);
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
udevStateInitialize(bool privileged,
|
udevStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||||
void *opaque G_GNUC_UNUSED)
|
void *opaque G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
int ret = VIR_DRV_STATE_INIT_ERROR;
|
int ret = VIR_DRV_STATE_INIT_ERROR;
|
||||||
|
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC(driver) < 0)
|
if (VIR_ALLOC(driver) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
@ -605,16 +605,36 @@ virRegisterStateDriver(virStateDriverPtr driver)
|
|||||||
* virStateInitialize:
|
* virStateInitialize:
|
||||||
* @privileged: set to true if running with root privilege, false otherwise
|
* @privileged: set to true if running with root privilege, false otherwise
|
||||||
* @mandatory: set to true if all drivers must report success, not skipped
|
* @mandatory: set to true if all drivers must report success, not skipped
|
||||||
|
* @root: directory to use for embedded mode
|
||||||
* @callback: callback to invoke to inhibit shutdown of the daemon
|
* @callback: callback to invoke to inhibit shutdown of the daemon
|
||||||
* @opaque: data to pass to @callback
|
* @opaque: data to pass to @callback
|
||||||
*
|
*
|
||||||
* Initialize all virtualization drivers.
|
* Initialize all virtualization drivers.
|
||||||
*
|
*
|
||||||
|
* Passing a non-NULL @root instructs the driver to run in embedded mode.
|
||||||
|
* Instead of using the compile time $prefix as the basis for directory
|
||||||
|
* paths, @root should be used instead. In addition any '/libvirt'
|
||||||
|
* component of the paths should be stripped.
|
||||||
|
*
|
||||||
|
* eg consider a build with prefix=/usr/local. A driver might use the
|
||||||
|
* locations
|
||||||
|
*
|
||||||
|
* /usr/local/etc/libvirt/$DRIVER/
|
||||||
|
* /usr/local/var/lib/libvirt/$DRIVER/
|
||||||
|
* /usr/local/run/libvirt/$DRIVER/
|
||||||
|
*
|
||||||
|
* When run with @root, the locations should instead be
|
||||||
|
*
|
||||||
|
* @root/etc/$DRIVER/
|
||||||
|
* @root/var/lib/$DRIVER/
|
||||||
|
* @root/run/$DRIVER/
|
||||||
|
*
|
||||||
* Returns 0 if all succeed, -1 upon any failure.
|
* Returns 0 if all succeed, -1 upon any failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
virStateInitialize(bool privileged,
|
virStateInitialize(bool privileged,
|
||||||
bool mandatory,
|
bool mandatory,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback,
|
virStateInhibitCallback callback,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
@ -629,6 +649,7 @@ virStateInitialize(bool privileged,
|
|||||||
VIR_DEBUG("Running global init for %s state driver",
|
VIR_DEBUG("Running global init for %s state driver",
|
||||||
virStateDriverTab[i]->name);
|
virStateDriverTab[i]->name);
|
||||||
ret = virStateDriverTab[i]->stateInitialize(privileged,
|
ret = virStateDriverTab[i]->stateInitialize(privileged,
|
||||||
|
root,
|
||||||
callback,
|
callback,
|
||||||
opaque);
|
opaque);
|
||||||
VIR_DEBUG("State init result %d (mandatory=%d)", ret, mandatory);
|
VIR_DEBUG("State init result %d (mandatory=%d)", ret, mandatory);
|
||||||
|
@ -31,8 +31,10 @@ typedef void (*virStateInhibitCallback)(bool inhibit,
|
|||||||
|
|
||||||
int virStateInitialize(bool privileged,
|
int virStateInitialize(bool privileged,
|
||||||
bool mandatory,
|
bool mandatory,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback inhibit,
|
virStateInhibitCallback inhibit,
|
||||||
void *opaque);
|
void *opaque)
|
||||||
|
ATTRIBUTE_NONNULL(2);
|
||||||
int virStateCleanup(void);
|
int virStateCleanup(void);
|
||||||
int virStateReload(void);
|
int virStateReload(void);
|
||||||
int virStateStop(void);
|
int virStateStop(void);
|
||||||
|
@ -648,6 +648,7 @@ libxlAddDom0(libxlDriverPrivatePtr driver)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
libxlStateInitialize(bool privileged,
|
libxlStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback,
|
virStateInhibitCallback callback,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
@ -656,6 +657,12 @@ libxlStateInitialize(bool privileged,
|
|||||||
char ebuf[1024];
|
char ebuf[1024];
|
||||||
bool autostart = true;
|
bool autostart = true;
|
||||||
|
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!libxlDriverShouldLoad(privileged))
|
if (!libxlDriverShouldLoad(privileged))
|
||||||
return VIR_DRV_STATE_INIT_SKIPPED;
|
return VIR_DRV_STATE_INIT_SKIPPED;
|
||||||
|
|
||||||
|
@ -85,6 +85,7 @@ VIR_LOG_INIT("lxc.lxc_driver");
|
|||||||
|
|
||||||
|
|
||||||
static int lxcStateInitialize(bool privileged,
|
static int lxcStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback,
|
virStateInhibitCallback callback,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
static int lxcStateCleanup(void);
|
static int lxcStateCleanup(void);
|
||||||
@ -1526,12 +1527,19 @@ lxcSecurityInit(virLXCDriverConfigPtr cfg)
|
|||||||
|
|
||||||
|
|
||||||
static int lxcStateInitialize(bool privileged,
|
static int lxcStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||||
void *opaque G_GNUC_UNUSED)
|
void *opaque G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
virLXCDriverConfigPtr cfg = NULL;
|
virLXCDriverConfigPtr cfg = NULL;
|
||||||
bool autostart = true;
|
bool autostart = true;
|
||||||
|
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check that the user is root, silently disable if not */
|
/* Check that the user is root, silently disable if not */
|
||||||
if (!privileged) {
|
if (!privileged) {
|
||||||
VIR_INFO("Not running privileged, disabling driver");
|
VIR_INFO("Not running privileged, disabling driver");
|
||||||
|
@ -702,6 +702,7 @@ firewalld_dbus_filter_bridge(DBusConnection *connection G_GNUC_UNUSED,
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
networkStateInitialize(bool privileged,
|
networkStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||||
void *opaque G_GNUC_UNUSED)
|
void *opaque G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
@ -713,6 +714,12 @@ networkStateInitialize(bool privileged,
|
|||||||
DBusConnection *sysbus = NULL;
|
DBusConnection *sysbus = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC(network_driver) < 0)
|
if (VIR_ALLOC(network_driver) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -580,6 +580,7 @@ device_prop_modified(LibHalContext *ctx G_GNUC_UNUSED,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
nodeStateInitialize(bool privileged G_GNUC_UNUSED,
|
nodeStateInitialize(bool privileged G_GNUC_UNUSED,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||||
void *opaque G_GNUC_UNUSED)
|
void *opaque G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
@ -591,6 +592,12 @@ nodeStateInitialize(bool privileged G_GNUC_UNUSED,
|
|||||||
DBusConnection *sysbus;
|
DBusConnection *sysbus;
|
||||||
DBusError err;
|
DBusError err;
|
||||||
|
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ensure caps_tbl is sorted by capability name */
|
/* Ensure caps_tbl is sorted by capability name */
|
||||||
qsort(caps_tbl, G_N_ELEMENTS(caps_tbl), sizeof(caps_tbl[0]),
|
qsort(caps_tbl, G_N_ELEMENTS(caps_tbl), sizeof(caps_tbl[0]),
|
||||||
cmpstringp);
|
cmpstringp);
|
||||||
|
@ -1781,6 +1781,7 @@ udevPCITranslateInit(bool privileged G_GNUC_UNUSED)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
nodeStateInitialize(bool privileged,
|
nodeStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||||
void *opaque G_GNUC_UNUSED)
|
void *opaque G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
@ -1788,6 +1789,12 @@ nodeStateInitialize(bool privileged,
|
|||||||
struct udev *udev = NULL;
|
struct udev *udev = NULL;
|
||||||
virThread enumThread;
|
virThread enumThread;
|
||||||
|
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC(driver) < 0)
|
if (VIR_ALLOC(driver) < 0)
|
||||||
return VIR_DRV_STATE_INIT_ERROR;
|
return VIR_DRV_STATE_INIT_ERROR;
|
||||||
|
|
||||||
|
@ -177,11 +177,18 @@ virNWFilterTriggerRebuildImpl(void *opaque)
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
nwfilterStateInitialize(bool privileged,
|
nwfilterStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||||
void *opaque G_GNUC_UNUSED)
|
void *opaque G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
DBusConnection *sysbus = NULL;
|
DBusConnection *sysbus = NULL;
|
||||||
|
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (virDBusHasSystemBus() &&
|
if (virDBusHasSystemBus() &&
|
||||||
!(sysbus = virDBusGetSystemBus()))
|
!(sysbus = virDBusGetSystemBus()))
|
||||||
return VIR_DRV_STATE_INIT_ERROR;
|
return VIR_DRV_STATE_INIT_ERROR;
|
||||||
|
@ -631,6 +631,7 @@ qemuDomainFindMaxID(virDomainObjPtr vm,
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
qemuStateInitialize(bool privileged,
|
qemuStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback,
|
virStateInhibitCallback callback,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
@ -644,6 +645,12 @@ qemuStateInitialize(bool privileged,
|
|||||||
const char *defsecmodel = NULL;
|
const char *defsecmodel = NULL;
|
||||||
g_autofree virSecurityManagerPtr *sec_managers = NULL;
|
g_autofree virSecurityManagerPtr *sec_managers = NULL;
|
||||||
|
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC(qemu_driver) < 0)
|
if (VIR_ALLOC(qemu_driver) < 0)
|
||||||
return VIR_DRV_STATE_INIT_ERROR;
|
return VIR_DRV_STATE_INIT_ERROR;
|
||||||
|
|
||||||
|
@ -835,6 +835,7 @@ static void daemonRunStateInit(void *opaque)
|
|||||||
* seriously delay OS bootup process */
|
* seriously delay OS bootup process */
|
||||||
if (virStateInitialize(virNetDaemonIsPrivileged(dmn),
|
if (virStateInitialize(virNetDaemonIsPrivileged(dmn),
|
||||||
mandatory,
|
mandatory,
|
||||||
|
NULL,
|
||||||
daemonInhibitCallback,
|
daemonInhibitCallback,
|
||||||
dmn) < 0) {
|
dmn) < 0) {
|
||||||
VIR_ERROR(_("Driver state initialization failed"));
|
VIR_ERROR(_("Driver state initialization failed"));
|
||||||
|
@ -232,6 +232,7 @@ static int remoteSplitURIScheme(virURIPtr uri,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
remoteStateInitialize(bool privileged G_GNUC_UNUSED,
|
remoteStateInitialize(bool privileged G_GNUC_UNUSED,
|
||||||
|
const char *root G_GNUC_UNUSED,
|
||||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||||
void *opaque G_GNUC_UNUSED)
|
void *opaque G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -452,9 +452,16 @@ secretStateCleanup(void)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
secretStateInitialize(bool privileged,
|
secretStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||||
void *opaque G_GNUC_UNUSED)
|
void *opaque G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC(driver) < 0)
|
if (VIR_ALLOC(driver) < 0)
|
||||||
return VIR_DRV_STATE_INIT_ERROR;
|
return VIR_DRV_STATE_INIT_ERROR;
|
||||||
|
|
||||||
|
@ -250,6 +250,7 @@ storageDriverAutostart(void)
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
storageStateInitialize(bool privileged,
|
storageStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||||
void *opaque G_GNUC_UNUSED)
|
void *opaque G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
@ -257,6 +258,12 @@ storageStateInitialize(bool privileged,
|
|||||||
g_autofree char *rundir = NULL;
|
g_autofree char *rundir = NULL;
|
||||||
bool autostart = true;
|
bool autostart = true;
|
||||||
|
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC(driver) < 0)
|
if (VIR_ALLOC(driver) < 0)
|
||||||
return VIR_DRV_STATE_INIT_ERROR;
|
return VIR_DRV_STATE_INIT_ERROR;
|
||||||
|
|
||||||
|
@ -4094,12 +4094,19 @@ vzStateCleanup(void)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
vzStateInitialize(bool privileged,
|
vzStateInitialize(bool privileged,
|
||||||
|
const char *root,
|
||||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||||
void *opaque G_GNUC_UNUSED)
|
void *opaque G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
if (!privileged)
|
if (!privileged)
|
||||||
return VIR_DRV_STATE_INIT_SKIPPED;
|
return VIR_DRV_STATE_INIT_SKIPPED;
|
||||||
|
|
||||||
|
if (root != NULL) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||||
|
_("Driver does not support embedded mode"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
vz_driver_privileged = privileged;
|
vz_driver_privileged = privileged;
|
||||||
|
|
||||||
if (virFileMakePathWithMode(VZ_STATEDIR, S_IRWXU) < 0) {
|
if (virFileMakePathWithMode(VZ_STATEDIR, S_IRWXU) < 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user