Files
libvirt/src/libvirt.c
T

1342 lines
35 KiB
C
Raw Normal View History

2012-05-28 17:23:16 +01:00
/*
* libvirt.c: Main interfaces for the libvirt library to handle virtualization
2005-11-02 12:50:21 +00:00
* domains from a process running in domain 0
*
2013-12-31 07:57:17 -07:00
* Copyright (C) 2005-2006, 2008-2014 Red Hat, Inc.
2005-11-02 12:50:21 +00:00
*
2012-07-27 17:39:53 +08:00
* 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
2012-07-27 17:39:53 +08:00
* <http://www.gnu.org/licenses/>.
2005-11-02 12:50:21 +00:00
*
* Daniel Veillard <veillard@redhat.com>
*/
#include <config.h>
2005-11-02 12:50:21 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
2010-04-28 21:31:16 -06:00
#include <sys/wait.h>
2009-01-22 20:27:01 +00:00
#include <time.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include "getpass.h"
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
2013-01-08 21:09:09 +00:00
#ifdef WITH_CURL
# include <curl/curl.h>
#endif
#include "virerror.h"
2012-12-12 17:59:27 +00:00
#include "virlog.h"
#include "datatypes.h"
#include "driver.h"
2012-12-13 18:01:25 +00:00
#include "viruuid.h"
2012-12-12 18:06:53 +00:00
#include "viralloc.h"
#include "configmake.h"
2012-12-12 16:35:35 +00:00
#include "virconf.h"
2013-01-08 21:02:05 +00:00
#if WITH_GNUTLS
2013-07-25 16:03:17 -06:00
# if WITH_GNUTLS_GCRYPT
# include <gcrypt.h>
# endif
2013-01-07 14:54:18 +00:00
# include "rpc/virnettlscontext.h"
#endif
2012-12-12 16:27:01 +00:00
#include "vircommand.h"
#include "virfile.h"
#include "virrandom.h"
2012-02-24 19:48:55 +01:00
#include "viruri.h"
2012-12-13 15:49:48 +00:00
#include "virthread.h"
#include "virstring.h"
2013-05-02 15:30:48 -06:00
#include "virutil.h"
#include "virtypedparam.h"
2011-06-01 16:36:21 +01:00
#ifdef WITH_TEST
# include "test/test_driver.h"
#endif
#ifdef WITH_REMOTE
# include "remote/remote_driver.h"
#endif
#ifdef WITH_OPENVZ
# include "openvz/openvz_driver.h"
#endif
#ifdef WITH_VMWARE
# include "vmware/vmware_driver.h"
#endif
#ifdef WITH_PHYP
# include "phyp/phyp_driver.h"
#endif
#ifdef WITH_ESX
# include "esx/esx_driver.h"
#endif
#ifdef WITH_HYPERV
# include "hyperv/hyperv_driver.h"
#endif
#ifdef WITH_XENAPI
# include "xenapi/xenapi_driver.h"
2008-11-21 12:16:08 +00:00
#endif
2014-02-18 14:08:10 +04:00
#ifdef WITH_BHYVE
# include "bhyve/bhyve_driver.h"
#endif
#define VIR_FROM_THIS VIR_FROM_NONE
VIR_LOG_INIT("libvirt");
2005-11-02 12:50:21 +00:00
/*
* TODO:
* - use lock to protect against concurrent accesses ?
2008-04-04 07:58:29 +00:00
* - use reference counting to guarantee coherent pointer state ?
2005-11-02 12:50:21 +00:00
*/
#define MAX_DRIVERS 21
2015-01-20 16:16:26 +00:00
static virConnectDriverPtr virConnectDriverTab[MAX_DRIVERS];
static int virConnectDriverTabCount;
static virStateDriverPtr virStateDriverTab[MAX_DRIVERS];
2014-10-28 12:38:04 -06:00
static int virStateDriverTabCount;
2012-10-10 16:11:43 +01:00
2015-01-20 16:16:26 +00:00
static virNetworkDriverPtr virSharedNetworkDriver;
static virInterfaceDriverPtr virSharedInterfaceDriver;
static virStorageDriverPtr virSharedStorageDriver;
static virNodeDeviceDriverPtr virSharedNodeDeviceDriver;
static virSecretDriverPtr virSharedSecretDriver;
static virNWFilterDriverPtr virSharedNWFilterDriver;
2006-03-27 15:24:36 +00:00
#if defined(POLKIT_AUTH)
2013-12-27 19:42:30 -07:00
static int
virConnectAuthGainPolkit(const char *privilege)
{
2011-10-21 11:09:23 -06:00
virCommandPtr cmd;
int ret = -1;
if (geteuid() == 0)
return 0;
2011-10-21 11:09:23 -06:00
cmd = virCommandNewArgList(POLKIT_AUTH, "--obtain", privilege, NULL);
if (virCommandRun(cmd, NULL) < 0)
2011-10-21 11:09:23 -06:00
goto cleanup;
2011-10-21 11:09:23 -06:00
ret = 0;
cleanup:
2011-10-21 11:09:23 -06:00
virCommandFree(cmd);
return ret;
}
#endif
2013-12-27 19:42:30 -07:00
static int
virConnectAuthCallbackDefault(virConnectCredentialPtr cred,
unsigned int ncred,
void *cbdata ATTRIBUTE_UNUSED)
{
2013-07-08 15:09:33 +01:00
size_t i;
for (i = 0; i < ncred; i++) {
char buf[1024];
char *bufptr = buf;
size_t len;
switch (cred[i].type) {
2008-02-20 16:54:35 +00:00
case VIR_CRED_EXTERNAL: {
if (STRNEQ(cred[i].challenge, "PolicyKit"))
return -1;
2008-04-04 15:09:19 +00:00
#if defined(POLKIT_AUTH)
if (virConnectAuthGainPolkit(cred[i].prompt) < 0)
2008-02-20 16:54:35 +00:00
return -1;
2008-04-04 15:09:19 +00:00
#else
/*
* Ignore & carry on. Although we can't auth
* directly, the user may have authenticated
* themselves already outside context of libvirt
*/
#endif
2008-02-20 16:54:35 +00:00
break;
}
2008-04-04 15:09:19 +00:00
case VIR_CRED_USERNAME:
case VIR_CRED_AUTHNAME:
case VIR_CRED_ECHOPROMPT:
case VIR_CRED_REALM:
2010-02-24 14:19:28 -05:00
if (printf("%s: ", cred[i].prompt) < 0)
2008-02-20 16:54:35 +00:00
return -1;
if (fflush(stdout) != 0)
return -1;
if (!fgets(buf, sizeof(buf), stdin)) {
if (feof(stdin)) { /* Treat EOF as "" */
buf[0] = '\0';
break;
}
return -1;
}
len = strlen(buf);
if (len != 0 && buf[len-1] == '\n')
buf[len-1] = '\0';
break;
case VIR_CRED_PASSPHRASE:
case VIR_CRED_NOECHOPROMPT:
2010-02-24 14:19:28 -05:00
if (printf("%s: ", cred[i].prompt) < 0)
2008-02-20 16:54:35 +00:00
return -1;
if (fflush(stdout) != 0)
return -1;
bufptr = getpass("");
if (!bufptr)
return -1;
break;
default:
return -1;
}
2008-05-22 15:12:25 +00:00
if (cred[i].type != VIR_CRED_EXTERNAL) {
if (VIR_STRDUP(cred[i].result,
STREQ(bufptr, "") && cred[i].defresult ?
cred[i].defresult : bufptr) < 0)
2008-05-22 15:12:25 +00:00
return -1;
cred[i].resultlen = strlen(cred[i].result);
}
}
return 0;
}
2013-12-27 19:42:30 -07:00
/* Don't typically want VIR_CRED_USERNAME. It enables you to authenticate
* as one user, and act as another. It just results in annoying
* prompts for the username twice & is very rarely what you want
*/
static int virConnectCredTypeDefault[] = {
VIR_CRED_AUTHNAME,
VIR_CRED_ECHOPROMPT,
VIR_CRED_REALM,
VIR_CRED_PASSPHRASE,
VIR_CRED_NOECHOPROMPT,
2008-02-20 16:54:35 +00:00
VIR_CRED_EXTERNAL,
};
static virConnectAuth virConnectAuthDefault = {
virConnectCredTypeDefault,
sizeof(virConnectCredTypeDefault)/sizeof(int),
virConnectAuthCallbackDefault,
NULL,
};
/*
* virConnectAuthPtrDefault
*
* A default implementation of the authentication callbacks. This
* implementation is suitable for command line based tools. It will
* prompt for username, passwords, realm and one time keys as needed.
* It will print on STDOUT, and read from STDIN. If this is not
* suitable for the application's needs an alternative implementation
* should be provided.
*/
virConnectAuthPtr virConnectAuthPtrDefault = &virConnectAuthDefault;
#if HAVE_WINSOCK2_H
static int
2016-04-19 12:18:40 -04:00
virWinsockInit(void)
{
WORD winsock_version, err;
WSADATA winsock_data;
/* http://msdn2.microsoft.com/en-us/library/ms742213.aspx */
winsock_version = MAKEWORD (2, 2);
err = WSAStartup (winsock_version, &winsock_data);
2008-10-24 08:55:13 +00:00
return err == 0 ? 0 : -1;
}
#endif
2013-01-07 14:54:18 +00:00
2013-07-25 16:03:17 -06:00
#ifdef WITH_GNUTLS_GCRYPT
2013-12-27 19:42:30 -07:00
static int
virTLSMutexInit(void **priv)
{
2009-07-17 20:20:08 +01:00
virMutexPtr lock = NULL;
2013-07-04 12:20:00 +02:00
if (VIR_ALLOC_QUIET(lock) < 0)
2009-07-17 20:20:08 +01:00
return ENOMEM;
if (virMutexInit(lock) < 0) {
VIR_FREE(lock);
return errno;
}
*priv = lock;
return 0;
}
2013-12-27 19:42:30 -07:00
static int
virTLSMutexDestroy(void **priv)
2009-07-17 20:20:08 +01:00
{
virMutexPtr lock = *priv;
virMutexDestroy(lock);
VIR_FREE(lock);
return 0;
}
2013-12-27 19:42:30 -07:00
static int
virTLSMutexLock(void **priv)
2009-07-17 20:20:08 +01:00
{
virMutexPtr lock = *priv;
virMutexLock(lock);
return 0;
}
2013-12-27 19:42:30 -07:00
static int
virTLSMutexUnlock(void **priv)
2009-07-17 20:20:08 +01:00
{
virMutexPtr lock = *priv;
virMutexUnlock(lock);
return 0;
}
2013-12-27 19:42:30 -07:00
2009-07-17 20:20:08 +01:00
static struct gcry_thread_cbs virTLSThreadImpl = {
2009-12-18 12:02:07 +01:00
/* GCRY_THREAD_OPTION_VERSION was added in gcrypt 1.4.2 */
2013-01-07 14:54:18 +00:00
# ifdef GCRY_THREAD_OPTION_VERSION
2009-07-17 20:20:08 +01:00
(GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)),
2013-01-07 14:54:18 +00:00
# else
2009-12-18 12:02:07 +01:00
GCRY_THREAD_OPTION_PTHREAD,
2013-01-07 14:54:18 +00:00
# endif
2009-07-17 20:20:08 +01:00
NULL,
virTLSMutexInit,
virTLSMutexDestroy,
virTLSMutexLock,
virTLSMutexUnlock,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
2013-07-25 16:03:17 -06:00
#endif /* WITH_GNUTLS_GCRYPT */
2009-07-17 20:20:08 +01:00
2009-01-15 19:56:05 +00:00
2014-10-28 12:38:04 -06:00
static bool virGlobalError;
2012-10-10 16:11:43 +01:00
static virOnceControl virGlobalOnce = VIR_ONCE_CONTROL_INITIALIZER;
2006-03-27 15:24:36 +00:00
2012-10-10 16:11:43 +01:00
static void
virGlobalInit(void)
{
/* It would be nice if we could trace the use of this call, to
* help diagnose in log files if a user calls something other than
* virConnectOpen first. But we can't rely on VIR_DEBUG working
* until after initialization is complete, and since this is
* one-shot, we never get here again. */
2009-01-20 12:01:45 +00:00
if (virThreadInitialize() < 0 ||
virErrorInitialize() < 0)
2012-10-10 16:11:43 +01:00
goto error;
2009-01-15 19:56:05 +00:00
#ifndef LIBVIRT_SETUID_RPC_CLIENT
if (virIsSUID()) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("libvirt.so is not safe to use from setuid programs"));
goto error;
}
#endif
2013-07-25 16:03:17 -06:00
#ifdef WITH_GNUTLS_GCRYPT
/*
* This sequence of API calls it copied exactly from
* gnutls 2.12.23 source lib/gcrypt/init.c, with
* exception that GCRYCTL_ENABLE_QUICK_RANDOM, is
* dropped
*/
if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0) {
gcry_control(GCRYCTL_SET_THREAD_CBS, &virTLSThreadImpl);
gcry_check_version(NULL);
gcry_control(GCRYCTL_DISABLE_SECMEM, NULL, 0);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
}
2013-01-07 14:54:18 +00:00
#endif
2009-07-17 20:20:08 +01:00
virLogSetFromEnv();
2013-01-08 21:02:05 +00:00
#ifdef WITH_GNUTLS
virNetTLSInit();
2013-01-07 14:54:18 +00:00
#endif
2013-01-08 21:09:09 +00:00
#if WITH_CURL
curl_global_init(CURL_GLOBAL_DEFAULT);
#endif
2011-05-09 17:24:09 +08:00
VIR_DEBUG("register drivers");
#if HAVE_WINSOCK2_H
2016-04-19 12:18:40 -04:00
if (virWinsockInit() == -1)
2012-10-10 16:11:43 +01:00
goto error;
#endif
if (!bindtextdomain(PACKAGE, LOCALEDIR))
2012-10-10 16:11:43 +01:00
goto error;
/*
* Note we must avoid everything except 'remote' driver
* for virt-login-shell usage
*/
#ifndef LIBVIRT_SETUID_RPC_CLIENT
2006-03-27 15:24:36 +00:00
/*
* Note that the order is important: the first ones have a higher
* priority when calling virConnectOpen.
2006-03-27 15:24:36 +00:00
*/
# ifdef WITH_TEST
2012-10-10 16:11:43 +01:00
if (testRegister() == -1)
goto error;
# endif
# ifdef WITH_OPENVZ
2012-10-10 16:11:43 +01:00
if (openvzRegister() == -1)
goto error;
# endif
# ifdef WITH_VMWARE
2012-10-10 16:11:43 +01:00
if (vmwareRegister() == -1)
goto error;
# endif
# ifdef WITH_PHYP
2012-10-10 16:11:43 +01:00
if (phypRegister() == -1)
goto error;
# endif
# ifdef WITH_ESX
2012-10-10 16:11:43 +01:00
if (esxRegister() == -1)
goto error;
# endif
# ifdef WITH_HYPERV
2012-10-10 16:11:43 +01:00
if (hypervRegister() == -1)
goto error;
# endif
# ifdef WITH_XENAPI
2012-10-10 16:11:43 +01:00
if (xenapiRegister() == -1)
goto error;
# endif
2012-07-31 22:56:05 +04:00
#endif
2011-06-01 16:36:21 +01:00
#ifdef WITH_REMOTE
if (remoteRegister() == -1)
2012-10-10 16:11:43 +01:00
goto error;
#endif
2007-02-14 01:40:09 +00:00
2012-10-10 16:11:43 +01:00
return;
error:
2012-10-10 16:11:43 +01:00
virGlobalError = true;
}
2013-12-27 19:42:30 -07:00
2012-10-10 16:11:43 +01:00
/**
* virInitialize:
*
* Initialize the library.
*
* This method is invoked automatically by any of the virConnectOpen() API
* calls, and by virGetVersion(). Since release 1.0.0, there is no need to
* call this method even in a multithreaded application, since
* initialization is performed in a thread safe manner; but applications
* using an older version of the library should manually call this before
* setting up competing threads that attempt virConnectOpen in parallel.
2012-10-10 16:11:43 +01:00
*
* The only other time it would be necessary to call virInitialize is if the
* application did not invoke virConnectOpen as its first API call, such
* as when calling virEventRegisterImpl() before setting up connections,
* or when using virSetErrorFunc() to alter error reporting of the first
* connection attempt.
2012-10-10 16:11:43 +01:00
*
* Returns 0 in case of success, -1 in case of error
*/
int
virInitialize(void)
{
if (virOnce(&virGlobalOnce, virGlobalInit) < 0)
return -1;
if (virGlobalError)
return -1;
return 0;
2006-03-27 15:24:36 +00:00
}
2013-12-27 19:42:30 -07:00
2009-01-15 19:56:05 +00:00
#ifdef WIN32
BOOL WINAPI
DllMain(HINSTANCE instance, DWORD reason, LPVOID ignore);
2009-01-15 19:56:05 +00:00
BOOL WINAPI
DllMain(HINSTANCE instance ATTRIBUTE_UNUSED,
DWORD reason,
LPVOID ignore ATTRIBUTE_UNUSED)
2009-01-15 19:56:05 +00:00
{
switch (reason) {
case DLL_PROCESS_ATTACH:
virInitialize();
break;
case DLL_THREAD_ATTACH:
/* Nothing todo in libvirt yet */
break;
case DLL_THREAD_DETACH:
/* Release per-thread local data */
virThreadOnExit();
break;
case DLL_PROCESS_DETACH:
/* Don't bother releasing per-thread data
since (hopefully) windows cleans up
everything on process exit */
break;
}
return TRUE;
}
#endif
2006-03-27 15:24:36 +00:00
2013-12-27 19:42:30 -07:00
/**
2015-01-20 16:16:26 +00:00
* virSetSharedNetworkDriver:
* @driver: pointer to a network driver block
*
* Register a network virtualization driver
*
2015-01-20 16:16:26 +00:00
* Returns 0 on success, or -1 in case of error.
*/
int
2015-01-20 16:16:26 +00:00
virSetSharedNetworkDriver(virNetworkDriverPtr driver)
{
virCheckNonNullArgReturn(driver, -1);
2007-03-08 14:53:41 +00:00
2015-01-20 16:16:26 +00:00
if (virSharedNetworkDriver) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("A network driver is already registered"));
return -1;
}
VIR_DEBUG("registering %s as network driver", driver->name);
2008-11-21 12:16:08 +00:00
2015-01-20 16:16:26 +00:00
virSharedNetworkDriver = driver;
return 0;
}
2013-12-27 19:42:30 -07:00
2009-05-20 14:26:49 +00:00
/**
2015-01-20 16:16:26 +00:00
* virSetSharedInterfaceDriver:
2009-09-04 15:40:52 +02:00
* @driver: pointer to an interface driver block
2009-05-20 14:26:49 +00:00
*
2009-09-04 15:40:52 +02:00
* Register an interface virtualization driver
2009-05-20 14:26:49 +00:00
*
* Returns the driver priority or -1 in case of error.
*/
int
2015-01-20 16:16:26 +00:00
virSetSharedInterfaceDriver(virInterfaceDriverPtr driver)
2009-05-20 14:26:49 +00:00
{
virCheckNonNullArgReturn(driver, -1);
2009-05-20 14:26:49 +00:00
2015-01-20 16:16:26 +00:00
if (virSharedInterfaceDriver) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("A interface driver is already registered"));
return -1;
}
2009-05-20 14:26:49 +00:00
2015-01-20 16:16:26 +00:00
VIR_DEBUG("registering %s as interface driver", driver->name);
virSharedInterfaceDriver = driver;
return 0;
2009-05-20 14:26:49 +00:00
}
2013-12-27 19:42:30 -07:00
2008-02-20 15:06:53 +00:00
/**
2015-01-20 16:16:26 +00:00
* virSetSharedStorageDriver:
2008-02-20 15:06:53 +00:00
* @driver: pointer to a storage driver block
*
* Register a storage virtualization driver
*
* Returns the driver priority or -1 in case of error.
*/
int
2015-01-20 16:16:26 +00:00
virSetSharedStorageDriver(virStorageDriverPtr driver)
2008-02-20 15:06:53 +00:00
{
virCheckNonNullArgReturn(driver, -1);
2008-02-20 15:06:53 +00:00
2015-01-20 16:16:26 +00:00
if (virSharedStorageDriver) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("A storage driver is already registered"));
return -1;
}
VIR_DEBUG("registering %s as storage driver", driver->name);
2008-11-21 12:16:08 +00:00
2015-01-20 16:16:26 +00:00
virSharedStorageDriver = driver;
return 0;
2008-02-20 15:06:53 +00:00
}
2013-12-27 19:42:30 -07:00
/**
2015-01-20 16:16:26 +00:00
* virSetSharedNodeDeviceDriver:
* @driver: pointer to a device monitor block
*
* Register a device monitor
*
* Returns the driver priority or -1 in case of error.
*/
int
2015-01-20 16:16:26 +00:00
virSetSharedNodeDeviceDriver(virNodeDeviceDriverPtr driver)
{
virCheckNonNullArgReturn(driver, -1);
2015-01-20 16:16:26 +00:00
if (virSharedNodeDeviceDriver) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("A node device driver is already registered"));
return -1;
}
2008-11-21 12:46:39 +00:00
2015-01-20 16:16:26 +00:00
VIR_DEBUG("registering %s as device driver", driver->name);
virSharedNodeDeviceDriver = driver;
return 0;
}
2013-12-27 19:42:30 -07:00
2009-08-14 21:42:19 +02:00
/**
2015-01-20 16:16:26 +00:00
* virSetSharedSecretDriver:
2009-08-14 21:42:19 +02:00
* @driver: pointer to a secret driver block
*
* Register a secret driver
*
* Returns the driver priority or -1 in case of error.
*/
int
2015-01-20 16:16:26 +00:00
virSetSharedSecretDriver(virSecretDriverPtr driver)
2009-08-14 21:42:19 +02:00
{
virCheckNonNullArgReturn(driver, -1);
2009-08-14 21:42:19 +02:00
2015-01-20 16:16:26 +00:00
if (virSharedSecretDriver) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("A secret driver is already registered"));
return -1;
}
VIR_DEBUG("registering %s as secret driver", driver->name);
2009-08-14 21:42:19 +02:00
2015-01-20 16:16:26 +00:00
virSharedSecretDriver = driver;
return 0;
2009-08-14 21:42:19 +02:00
}
2013-12-27 19:42:30 -07:00
2010-03-25 13:46:02 -04:00
/**
2015-01-20 16:16:26 +00:00
* virSetSharedNWFilterDriver:
2010-03-25 13:46:02 -04:00
* @driver: pointer to a network filter driver block
*
* Register a network filter virtualization driver
*
* Returns the driver priority or -1 in case of error.
*/
int
2015-01-20 16:16:26 +00:00
virSetSharedNWFilterDriver(virNWFilterDriverPtr driver)
2010-03-25 13:46:02 -04:00
{
virCheckNonNullArgReturn(driver, -1);
2010-03-25 13:46:02 -04:00
2015-01-20 16:16:26 +00:00
if (virSharedNWFilterDriver) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("A network filter driver is already registered"));
return -1;
}
2010-03-25 13:46:02 -04:00
2015-01-20 16:16:26 +00:00
VIR_DEBUG("registering %s as network filter driver", driver->name);
virSharedNWFilterDriver = driver;
return 0;
2010-03-25 13:46:02 -04:00
}
/**
2015-01-20 16:16:26 +00:00
* virRegisterConnectDriver:
* @driver: pointer to a driver block
2015-01-20 16:16:26 +00:00
* @setSharedDrivers: populate shared drivers
*
2015-01-20 16:16:26 +00:00
* Register a virtualization driver, optionally filling in
* any empty pointers for shared secondary drivers
*
* Returns the driver priority or -1 in case of error.
*/
int
2015-01-20 16:16:26 +00:00
virRegisterConnectDriver(virConnectDriverPtr driver,
bool setSharedDrivers)
{
VIR_DEBUG("driver=%p name=%s", driver,
2015-01-20 16:16:26 +00:00
driver ? NULLSTR(driver->hypervisorDriver->name) : "(null)");
virCheckNonNullArgReturn(driver, -1);
2015-01-20 16:16:26 +00:00
if (virConnectDriverTabCount >= MAX_DRIVERS) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Too many drivers, cannot register %s"),
driver->hypervisorDriver->name);
return -1;
}
2007-03-08 14:53:41 +00:00
VIR_DEBUG("registering %s as driver %d",
2015-01-20 16:16:26 +00:00
driver->hypervisorDriver->name, virConnectDriverTabCount);
if (setSharedDrivers) {
if (driver->interfaceDriver == NULL)
driver->interfaceDriver = virSharedInterfaceDriver;
if (driver->networkDriver == NULL)
driver->networkDriver = virSharedNetworkDriver;
if (driver->nodeDeviceDriver == NULL)
driver->nodeDeviceDriver = virSharedNodeDeviceDriver;
if (driver->nwfilterDriver == NULL)
driver->nwfilterDriver = virSharedNWFilterDriver;
if (driver->secretDriver == NULL)
driver->secretDriver = virSharedSecretDriver;
if (driver->storageDriver == NULL)
driver->storageDriver = virSharedStorageDriver;
}
2015-01-20 16:16:26 +00:00
virConnectDriverTab[virConnectDriverTabCount] = driver;
return virConnectDriverTabCount++;
}
2013-12-27 19:42:30 -07:00
/**
* virRegisterStateDriver:
* @driver: pointer to a driver block
*
* Register a virtualization driver
*
* Returns the driver priority or -1 in case of error.
*/
int
virRegisterStateDriver(virStateDriverPtr driver)
{
virCheckNonNullArgReturn(driver, -1);
2015-01-20 16:16:26 +00:00
if (virStateDriverTabCount >= MAX_DRIVERS) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Too many drivers, cannot register %s"),
driver->name);
return -1;
}
virStateDriverTab[virStateDriverTabCount] = driver;
return virStateDriverTabCount++;
}
2013-12-27 19:42:30 -07:00
2008-11-25 10:31:52 +00:00
/**
* virStateInitialize:
* @privileged: set to true if running with root privilege, false otherwise
* @callback: callback to invoke to inhibit shutdown of the daemon
* @opaque: data to pass to @callback
2008-11-25 10:31:52 +00:00
*
* Initialize all virtualization drivers. Accomplished in two phases,
* the first being state and structure initialization followed by any
* auto start supported by the driver. This is done to ensure dependencies
* that some drivers may have on another driver having been initialized
* will exist, such as the storage driver's need to use the secret driver.
2008-11-25 10:31:52 +00:00
*
* Returns 0 if all succeed, -1 upon any failure.
2008-11-25 10:31:52 +00:00
*/
2013-12-27 19:42:30 -07:00
int
virStateInitialize(bool privileged,
virStateInhibitCallback callback,
void *opaque)
{
2013-07-08 15:09:33 +01:00
size_t i;
if (virInitialize() < 0)
return -1;
for (i = 0; i < virStateDriverTabCount; i++) {
if (virStateDriverTab[i]->stateInitialize) {
2012-06-15 13:48:34 +01:00
VIR_DEBUG("Running global init for %s state driver",
virStateDriverTab[i]->name);
if (virStateDriverTab[i]->stateInitialize(privileged,
callback,
opaque) < 0) {
VIR_ERROR(_("Initialization of %s state driver failed: %s"),
virStateDriverTab[i]->name,
2016-05-19 21:10:19 +02:00
virGetLastErrorMessage());
2012-06-15 13:48:34 +01:00
return -1;
}
}
}
for (i = 0; i < virStateDriverTabCount; i++) {
if (virStateDriverTab[i]->stateAutoStart) {
VIR_DEBUG("Running global auto start for %s state driver",
virStateDriverTab[i]->name);
virStateDriverTab[i]->stateAutoStart();
}
}
2012-06-15 13:48:34 +01:00
return 0;
}
2013-12-27 19:42:30 -07:00
2008-11-25 10:31:52 +00:00
/**
* virStateCleanup:
*
* Run each virtualization driver's cleanup method.
*
* Returns 0 if all succeed, -1 upon any failure.
2008-11-25 10:31:52 +00:00
*/
2013-12-27 19:42:30 -07:00
int
virStateCleanup(void)
{
int r;
2013-07-08 15:09:33 +01:00
int ret = 0;
for (r = virStateDriverTabCount - 1; r >= 0; r--) {
if (virStateDriverTab[r]->stateCleanup &&
virStateDriverTab[r]->stateCleanup() < 0)
ret = -1;
}
return ret;
}
2013-12-27 19:42:30 -07:00
2008-11-25 10:31:52 +00:00
/**
* virStateReload:
*
* Run each virtualization driver's reload method.
*
* Returns 0 if all succeed, -1 upon any failure.
2008-11-25 10:31:52 +00:00
*/
2013-12-27 19:42:30 -07:00
int
virStateReload(void)
{
2013-07-08 15:09:33 +01:00
size_t i;
int ret = 0;
for (i = 0; i < virStateDriverTabCount; i++) {
if (virStateDriverTab[i]->stateReload &&
virStateDriverTab[i]->stateReload() < 0)
ret = -1;
}
return ret;
}
2013-12-27 19:42:30 -07:00
2012-10-31 19:03:52 +00:00
/**
* virStateStop:
*
* Run each virtualization driver's "stop" method.
*
* Returns 0 if successful, -1 on failure
*/
2013-12-27 19:42:30 -07:00
int
virStateStop(void)
{
2013-07-08 15:09:33 +01:00
size_t i;
int ret = 0;
2012-10-31 19:03:52 +00:00
for (i = 0; i < virStateDriverTabCount; i++) {
if (virStateDriverTab[i]->stateStop &&
virStateDriverTab[i]->stateStop())
2012-10-31 19:03:52 +00:00
ret = 1;
}
return ret;
}
/**
* virGetVersion:
* @libVer: return value for the library version (OUT)
* @type: ignored; pass NULL
* @typeVer: pass NULL; for historical purposes duplicates @libVer if
* non-NULL
*
* Provides version information. @libVer is the version of the
* library and will always be set unless an error occurs, in which case
* an error code will be returned. @typeVer exists for historical
* compatibility; if it is not NULL it will duplicate @libVer (it was
* originally intended to return hypervisor information based on @type,
* but due to the design of remote clients this is not reliable). To
* get the version of the running hypervisor use the virConnectGetVersion()
* function instead. To get the libvirt library version used by a
* connection use the virConnectGetLibVersion() instead.
*
* This function includes a call to virInitialize() when necessary.
*
* Returns -1 in case of failure, 0 otherwise, and values for @libVer and
* @typeVer have the format major * 1,000,000 + minor * 1,000 + release.
*/
int
virGetVersion(unsigned long *libVer, const char *type ATTRIBUTE_UNUSED,
unsigned long *typeVer)
{
2012-10-10 16:11:43 +01:00
if (virInitialize() < 0)
goto error;
VIR_DEBUG("libVir=%p, type=%s, typeVer=%p", libVer, type, typeVer);
virResetLastError();
if (libVer == NULL)
goto error;
*libVer = LIBVIR_VERSION_NUMBER;
if (typeVer != NULL)
2009-02-17 10:33:41 +00:00
*typeVer = LIBVIR_VERSION_NUMBER;
return 0;
error:
virDispatchError(NULL);
return -1;
}
2012-03-14 12:30:52 +00:00
static int
virConnectGetDefaultURI(virConfPtr conf,
char **name)
2012-03-14 12:30:52 +00:00
{
int ret = -1;
2013-10-09 11:18:15 +01:00
const char *defname = virGetEnvBlockSUID("LIBVIRT_DEFAULT_URI");
2012-03-14 12:30:52 +00:00
if (defname && *defname) {
VIR_DEBUG("Using LIBVIRT_DEFAULT_URI '%s'", defname);
if (VIR_STRDUP(*name, defname) < 0)
2012-03-14 12:30:52 +00:00
goto cleanup;
} else {
if (virConfGetValueString(conf, "uri_default", name) < 0)
goto cleanup;
if (*name)
VIR_DEBUG("Using config file uri '%s'", *name);
2012-03-14 12:30:52 +00:00
}
ret = 0;
cleanup:
return ret;
}
2013-12-27 19:42:30 -07:00
2016-04-16 08:59:08 -04:00
/*
* Check to see if an invalid URI like qemu://system (missing /) was passed,
* offer the suggested fix.
*/
static int
virConnectCheckURIMissingSlash(const char *uristr, virURIPtr uri)
{
2016-04-20 13:25:07 -04:00
if (!uri->scheme || !uri->path || !uri->server)
return 0;
2016-04-16 08:59:08 -04:00
/* To avoid false positives, only check drivers that mandate
a path component in the URI, like /system or /session */
if (STRNEQ(uri->scheme, "qemu") &&
STRNEQ(uri->scheme, "vbox") &&
STRNEQ(uri->scheme, "vz"))
return 0;
if (STREQ(uri->server, "session") ||
STREQ(uri->server, "system")) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("invalid URI %s (maybe you want %s:///%s)"),
uristr, uri->scheme, uri->server);
return -1;
}
return 0;
}
static virConnectPtr
2016-04-19 12:18:40 -04:00
virConnectOpenInternal(const char *name,
virConnectAuthPtr auth,
unsigned int flags)
{
2013-07-08 15:09:33 +01:00
size_t i;
int res;
virConnectPtr ret;
2012-03-14 12:30:52 +00:00
virConfPtr conf = NULL;
char *uristr = NULL;
ret = virGetConnect();
if (ret == NULL)
return NULL;
2015-10-12 16:09:53 +02:00
if (virConfLoadConfig(&conf, NULL) < 0)
2012-03-14 12:30:52 +00:00
goto failed;
if (name && name[0] == '\0')
name = NULL;
if (!name && virIsSUID()) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("An explicit URI must be provided when setuid"));
goto failed;
}
/* Convert xen -> xen:/// for back compat */
if (name && STRCASEEQ(name, "xen"))
name = "xen:///";
/* Convert xen:// -> xen:/// because xmlParseURI cannot parse the
* former. This allows URIs such as xen://localhost to work.
*/
if (name && STREQ(name, "xen://"))
name = "xen:///";
/*
2013-12-28 11:10:06 -07:00
* If no URI is passed, then check for an environment string if not
* available probe the compiled in drivers to find a default hypervisor
* if detectable.
*/
if (name) {
if (VIR_STRDUP(uristr, name) < 0)
goto failed;
} else {
if (virConnectGetDefaultURI(conf, &uristr) < 0)
goto failed;
}
if (uristr) {
char *alias = NULL;
if (!(flags & VIR_CONNECT_NO_ALIASES) &&
virURIResolveAlias(conf, uristr, &alias) < 0)
goto failed;
if (alias) {
VIR_FREE(uristr);
uristr = alias;
}
if (!(ret->uri = virURIParse(uristr))) {
VIR_FREE(alias);
goto failed;
}
VIR_DEBUG("Split \"%s\" to URI components:\n"
" scheme %s\n"
" server %s\n"
" user %s\n"
" port %d\n"
2015-10-27 19:14:01 +01:00
" path %s",
uristr,
2012-03-20 13:33:41 +00:00
NULLSTR(ret->uri->scheme), NULLSTR(ret->uri->server),
NULLSTR(ret->uri->user), ret->uri->port,
NULLSTR(ret->uri->path));
if (virConnectCheckURIMissingSlash(uristr,
2016-04-16 08:59:08 -04:00
ret->uri) < 0) {
goto failed;
}
} else {
2011-05-09 17:24:09 +08:00
VIR_DEBUG("no name, allowing driver auto-select");
}
2008-02-20 16:54:35 +00:00
/* Cleansing flags */
ret->flags = flags & VIR_CONNECT_RO;
2015-01-20 16:16:26 +00:00
for (i = 0; i < virConnectDriverTabCount; i++) {
/* We're going to probe the remote driver next. So we have already
* probed all other client-side-only driver before, but none of them
* accepted the URI.
* If the scheme corresponds to a known but disabled client-side-only
* driver then report a useful error, instead of a cryptic one about
* not being able to connect to libvirtd or not being able to find
* certificates. */
2015-01-20 16:16:26 +00:00
if (STREQ(virConnectDriverTab[i]->hypervisorDriver->name, "remote") &&
ret->uri != NULL && ret->uri->scheme != NULL &&
(
#ifndef WITH_PHYP
STRCASEEQ(ret->uri->scheme, "phyp") ||
#endif
#ifndef WITH_ESX
STRCASEEQ(ret->uri->scheme, "vpx") ||
STRCASEEQ(ret->uri->scheme, "esx") ||
STRCASEEQ(ret->uri->scheme, "gsx") ||
2011-07-13 16:47:01 +02:00
#endif
#ifndef WITH_HYPERV
STRCASEEQ(ret->uri->scheme, "hyperv") ||
#endif
#ifndef WITH_XENAPI
STRCASEEQ(ret->uri->scheme, "xenapi") ||
2012-07-31 22:56:05 +04:00
#endif
#ifndef WITH_VZ
2012-07-31 22:56:05 +04:00
STRCASEEQ(ret->uri->scheme, "parallels") ||
#endif
false)) {
virReportErrorHelper(VIR_FROM_NONE, VIR_ERR_CONFIG_UNSUPPORTED,
__FILE__, __FUNCTION__, __LINE__,
_("libvirt was built without the '%s' driver"),
ret->uri->scheme);
goto failed;
}
2015-01-20 16:16:26 +00:00
VIR_DEBUG("trying driver %zu (%s) ...",
i, virConnectDriverTab[i]->hypervisorDriver->name);
ret->driver = virConnectDriverTab[i]->hypervisorDriver;
ret->interfaceDriver = virConnectDriverTab[i]->interfaceDriver;
ret->networkDriver = virConnectDriverTab[i]->networkDriver;
ret->nodeDeviceDriver = virConnectDriverTab[i]->nodeDeviceDriver;
ret->nwfilterDriver = virConnectDriverTab[i]->nwfilterDriver;
ret->secretDriver = virConnectDriverTab[i]->secretDriver;
ret->storageDriver = virConnectDriverTab[i]->storageDriver;
res = virConnectDriverTab[i]->hypervisorDriver->connectOpen(ret, auth, conf, flags);
2013-07-08 15:09:33 +01:00
VIR_DEBUG("driver %zu %s returned %s",
2015-01-20 16:16:26 +00:00
i, virConnectDriverTab[i]->hypervisorDriver->name,
2012-12-03 16:41:45 +08:00
res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
(res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
(res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status")));
if (res == VIR_DRV_OPEN_SUCCESS) {
break;
} else {
ret->driver = NULL;
2015-01-20 16:16:26 +00:00
ret->interfaceDriver = NULL;
ret->networkDriver = NULL;
ret->nodeDeviceDriver = NULL;
ret->nwfilterDriver = NULL;
ret->secretDriver = NULL;
ret->storageDriver = NULL;
if (res == VIR_DRV_OPEN_ERROR)
goto failed;
}
}
if (!ret->driver) {
/* If we reach here, then all drivers declined the connection. */
virReportError(VIR_ERR_NO_CONNECT, "%s", NULLSTR(name));
goto failed;
}
2012-03-14 12:30:52 +00:00
virConfFree(conf);
VIR_FREE(uristr);
2012-03-14 12:30:52 +00:00
return ret;
failed:
VIR_FREE(uristr);
2012-03-14 12:30:52 +00:00
virConfFree(conf);
virObjectUnref(ret);
return NULL;
}
2013-12-27 19:42:30 -07:00
/**
* virConnectOpen:
2013-03-25 16:50:27 +01:00
* @name: (optional) URI of the hypervisor
*
* This function should be called first to get a connection to the
* Hypervisor and xen store
*
2012-03-14 12:30:52 +00:00
* If @name is NULL, if the LIBVIRT_DEFAULT_URI environment variable is set,
* then it will be used. Otherwise if the client configuration file
* has the "uri_default" parameter set, then it will be used. Finally
* probing will be done to determine a suitable default driver to activate.
* This involves trying each hypervisor in turn until one successfully opens.
*
* If connecting to an unprivileged hypervisor driver which requires
* the libvirtd daemon to be active, it will automatically be launched
* if not already running. This can be prevented by setting the
* environment variable LIBVIRT_AUTOSTART=0
*
* URIs are documented at http://libvirt.org/uri.html
2013-12-31 23:17:16 -07:00
*
* virConnectClose should be used to release the resources after the connection
* is no longer needed.
*
2013-12-31 23:17:16 -07:00
* Returns a pointer to the hypervisor connection or NULL in case of error
*/
virConnectPtr
virConnectOpen(const char *name)
{
virConnectPtr ret = NULL;
2012-10-10 16:11:43 +01:00
if (virInitialize() < 0)
goto error;
2008-02-20 16:54:35 +00:00
2013-03-25 16:50:27 +01:00
VIR_DEBUG("name=%s", NULLSTR(name));
virResetLastError();
2016-04-19 12:18:40 -04:00
ret = virConnectOpenInternal(name, NULL, 0);
if (!ret)
goto error;
return ret;
error:
virDispatchError(NULL);
return NULL;
}
2013-12-27 19:42:30 -07:00
/**
* virConnectOpenReadOnly:
2013-03-25 16:50:27 +01:00
* @name: (optional) URI of the hypervisor
*
* This function should be called first to get a restricted connection to the
2008-04-04 07:58:29 +00:00
* library functionalities. The set of APIs usable are then restricted
* on the available methods to control the domains.
*
* See virConnectOpen for notes about environment variables which can
* have an effect on opening drivers and freeing the connection resources
*
* URIs are documented at http://libvirt.org/uri.html
2013-12-31 23:17:16 -07:00
*
* Returns a pointer to the hypervisor connection or NULL in case of error
*/
virConnectPtr
virConnectOpenReadOnly(const char *name)
{
virConnectPtr ret = NULL;
2012-10-10 16:11:43 +01:00
if (virInitialize() < 0)
goto error;
2008-02-20 16:54:35 +00:00
2013-03-25 16:50:27 +01:00
VIR_DEBUG("name=%s", NULLSTR(name));
virResetLastError();
2016-04-19 12:18:40 -04:00
ret = virConnectOpenInternal(name, NULL, VIR_CONNECT_RO);
if (!ret)
goto error;
return ret;
error:
virDispatchError(NULL);
return NULL;
}
2013-12-27 19:42:30 -07:00
/**
* virConnectOpenAuth:
2013-03-25 16:50:27 +01:00
* @name: (optional) URI of the hypervisor
* @auth: Authenticate callback parameters
2012-01-09 13:56:42 -07:00
* @flags: bitwise-OR of virConnectFlags
*
* This function should be called first to get a connection to the
* Hypervisor. If necessary, authentication will be performed fetching
* credentials via the callback
*
* See virConnectOpen for notes about environment variables which can
* have an effect on opening drivers and freeing the connection resources
*
* URIs are documented at http://libvirt.org/uri.html
2013-12-31 23:17:16 -07:00
*
* Returns a pointer to the hypervisor connection or NULL in case of error
*/
virConnectPtr
virConnectOpenAuth(const char *name,
virConnectAuthPtr auth,
2011-07-06 13:55:47 -06:00
unsigned int flags)
{
virConnectPtr ret = NULL;
2012-10-10 16:11:43 +01:00
if (virInitialize() < 0)
goto error;
2008-02-20 16:54:35 +00:00
2011-07-06 12:18:34 -06:00
VIR_DEBUG("name=%s, auth=%p, flags=%x", NULLSTR(name), auth, flags);
virResetLastError();
2016-04-19 12:18:40 -04:00
ret = virConnectOpenInternal(name, auth, flags);
if (!ret)
goto error;
return ret;
error:
virDispatchError(NULL);
return NULL;
2005-11-02 12:50:21 +00:00
}
2013-12-27 19:42:30 -07:00
2014-11-21 20:27:25 -05:00
2005-11-02 12:50:21 +00:00
/**
* virConnectClose:
2005-11-02 12:50:21 +00:00
* @conn: pointer to the hypervisor connection
*
* This function closes the connection to the Hypervisor. This should
* not be called if further interaction with the Hypervisor are needed
* especially if there is running domain which need further monitoring by
* the application.
*
* Connections are reference counted; the count is explicitly
* increased by the initial open (virConnectOpen, virConnectOpenAuth,
* and the like) as well as virConnectRef; it is also temporarily
* increased by other API that depend on the connection remaining
* alive. The open and every virConnectRef call should have a
* matching virConnectClose, and all other references will be released
* after the corresponding operation completes.
*
* Returns a positive number if at least 1 reference remains on
* success. The returned value should not be assumed to be the total
* reference count. A return of 0 implies no references remain and
* the connection is closed and memory has been freed. A return of -1
* implies a failure.
*
* It is possible for the last virConnectClose to return a positive
* value if some other object still has a temporary reference to the
* connection, but the application should not try to further use a
* connection after the virConnectClose that matches the initial open.
2005-11-02 12:50:21 +00:00
*/
int
virConnectClose(virConnectPtr conn)
{
VIR_DEBUG("conn=%p", conn);
2009-01-20 12:01:45 +00:00
virResetLastError();
2013-12-27 20:31:17 -07:00
virCheckConnectReturn(conn, -1);
if (!virObjectUnref(conn))
return 0;
return 1;
2005-11-02 12:50:21 +00:00
}
2013-12-27 19:42:30 -07:00
/* Helper function called to validate incoming client array on any
* interface that sets typed parameters in the hypervisor. */
int
virTypedParameterValidateSet(virConnectPtr conn,
virTypedParameterPtr params,
int nparams)
{
bool string_okay;
size_t i;
string_okay = VIR_DRV_SUPPORTS_FEATURE(conn->driver,
conn,
VIR_DRV_FEATURE_TYPED_PARAM_STRING);
for (i = 0; i < nparams; i++) {
if (strnlen(params[i].field, VIR_TYPED_PARAM_FIELD_LENGTH) ==
VIR_TYPED_PARAM_FIELD_LENGTH) {
virReportInvalidArg(params,
_("string parameter name '%.*s' too long"),
VIR_TYPED_PARAM_FIELD_LENGTH,
params[i].field);
return -1;
}
if (params[i].type == VIR_TYPED_PARAM_STRING) {
if (string_okay) {
if (!params[i].value.s) {
virReportInvalidArg(params,
_("NULL string parameter '%s'"),
params[i].field);
return -1;
}
} else {
virReportInvalidArg(params,
_("string parameter '%s' unsupported"),
params[i].field);
return -1;
}
}
}
return 0;
}