11,712 po/sq.po

Large diffs are not rendered by default.

11,749 po/sr.po

Large diffs are not rendered by default.

Large diffs are not rendered by default.

11,712 po/sv.po

Large diffs are not rendered by default.

11,797 po/ta.po

Large diffs are not rendered by default.

11,796 po/te.po

Large diffs are not rendered by default.

11,712 po/th.po

Large diffs are not rendered by default.

11,712 po/tr.po

Large diffs are not rendered by default.

11,830 po/uk.po

Large diffs are not rendered by default.

11,712 po/ur.po

Large diffs are not rendered by default.

11,794 po/vi.po

Large diffs are not rendered by default.

11,796 po/zh_CN.po

Large diffs are not rendered by default.

11,715 po/zh_TW.po

Large diffs are not rendered by default.

11,712 po/zu.po

Large diffs are not rendered by default.

@@ -171,6 +171,7 @@ UTIL_SOURCES = \
util/viruri.h util/viruri.c \
util/virutil.c util/virutil.h \
util/viruuid.c util/viruuid.h \
util/virxdrdefs.h \
util/virxml.c util/virxml.h \
$(NULL)

@@ -2283,7 +2284,7 @@ libvirt_lxc_la_LIBADD = libvirt.la $(CYGWIN_EXTRA_LIBADD)
# have a RPC client for local UNIX socket access only. We use
# the ../config-post.h header to disable all external deps that
# we don't want
if WITH_LXC
if WITH_SETUID_RPC_CLIENT
noinst_LTLIBRARIES += libvirt-setuid-rpc-client.la

libvirt_setuid_rpc_client_la_SOURCES = \
@@ -2360,7 +2361,7 @@ libvirt_setuid_rpc_client_la_CFLAGS = \
$(SECDRIVER_CFLAGS) \
$(XDR_CFLAGS) \
$(NULL)
endif WITH_LXC
endif WITH_SETUID_RPC_CLIENT

lockdriverdir = $(libdir)/libvirt/lock-driver
lockdriver_LTLIBRARIES =
@@ -22,6 +22,8 @@
* Author: Martin Kletzander <mkletzan@redhat.com>
*/

%#include "virxdrdefs.h"

/*----- Data types. -----*/

/* Length of long, but not unbounded, strings.
@@ -37,11 +39,11 @@ typedef string admin_nonnull_string<ADMIN_STRING_MAX>;
typedef admin_nonnull_string *admin_string;

/*----- Protocol. -----*/
struct admin_daemon_open_args {
struct admin_connect_open_args {
unsigned int flags;
};

struct admin_daemon_get_version_ret {
struct admin_connect_get_lib_version_ret {
unsigned hyper libVer;
};

@@ -70,15 +72,15 @@ enum admin_procedure {
/**
* @generate: none
*/
ADMIN_PROC_DAEMON_OPEN = 1,
ADMIN_PROC_CONNECT_OPEN = 1,

/**
* @generate: none
*/
ADMIN_PROC_DAEMON_CLOSE = 2,
ADMIN_PROC_CONNECT_CLOSE = 2,

/**
* @generate: both
*/
ADMIN_PROC_DAEMON_GET_VERSION = 3
ADMIN_PROC_CONNECT_GET_LIB_VERSION = 3
};
@@ -48,7 +48,7 @@ remoteAdminPrivDispose(void *opaque)


static int
callFull(virAdmDaemonPtr dmn ATTRIBUTE_UNUSED,
callFull(virAdmConnectPtr conn ATTRIBUTE_UNUSED,
remoteAdminPrivPtr priv,
int *fdin,
size_t fdinlen,
@@ -86,15 +86,15 @@ callFull(virAdmDaemonPtr dmn ATTRIBUTE_UNUSED,
}

static int
call(virAdmDaemonPtr dmn,
call(virAdmConnectPtr conn,
unsigned int flags,
int proc_nr,
xdrproc_t args_filter, char *args,
xdrproc_t ret_filter, char *ret)
{
virCheckFlags(0, -1);

return callFull(dmn, dmn->privateData,
return callFull(conn, conn->privateData,
NULL, 0, NULL, NULL, proc_nr,
args_filter, args, ret_filter, ret);
}
@@ -106,14 +106,14 @@ remoteAdminClientCloseFunc(virNetClientPtr client ATTRIBUTE_UNUSED,
int reason,
void *opaque)
{
virAdmDaemonCloseCallbackDataPtr cbdata = opaque;
virAdmConnectCloseCallbackDataPtr cbdata = opaque;

virObjectLock(cbdata);

if (cbdata->callback) {
VIR_DEBUG("Triggering connection close callback %p reason=%d, opaque=%p",
cbdata->callback, reason, cbdata->opaque);
cbdata->callback(cbdata->dmn, reason, cbdata->opaque);
cbdata->callback(cbdata->conn, reason, cbdata->opaque);

if (cbdata->freeCallback)
cbdata->freeCallback(cbdata->opaque);
@@ -124,11 +124,11 @@ remoteAdminClientCloseFunc(virNetClientPtr client ATTRIBUTE_UNUSED,
}

static int
remoteAdminDaemonOpen(virAdmDaemonPtr dmn, unsigned int flags)
remoteAdminConnectOpen(virAdmConnectPtr conn, unsigned int flags)
{
int rv = -1;
remoteAdminPrivPtr priv = dmn->privateData;
admin_daemon_open_args args;
remoteAdminPrivPtr priv = conn->privateData;
admin_connect_open_args args;

virObjectLock(priv);

@@ -140,13 +140,13 @@ remoteAdminDaemonOpen(virAdmDaemonPtr dmn, unsigned int flags)
virResetLastError();
}

virObjectRef(dmn->closeCallback);
virObjectRef(conn->closeCallback);
virNetClientSetCloseCallback(priv->client, remoteAdminClientCloseFunc,
dmn->closeCallback,
conn->closeCallback,
virObjectFreeCallback);

if (call(dmn, 0, ADMIN_PROC_DAEMON_OPEN,
(xdrproc_t)xdr_admin_daemon_open_args, (char *)&args,
if (call(conn, 0, ADMIN_PROC_CONNECT_OPEN,
(xdrproc_t)xdr_admin_connect_open_args, (char *)&args,
(xdrproc_t)xdr_void, (char *)NULL) == -1) {
goto done;
}
@@ -159,14 +159,14 @@ remoteAdminDaemonOpen(virAdmDaemonPtr dmn, unsigned int flags)
}

static int
remoteAdminDaemonClose(virAdmDaemonPtr dmn)
remoteAdminConnectClose(virAdmConnectPtr conn)
{
int rv = -1;
remoteAdminPrivPtr priv = dmn->privateData;
remoteAdminPrivPtr priv = conn->privateData;

virObjectLock(priv);

if (call(dmn, 0, ADMIN_PROC_DAEMON_CLOSE,
if (call(conn, 0, ADMIN_PROC_CONNECT_CLOSE,
(xdrproc_t)xdr_void, (char *)NULL,
(xdrproc_t)xdr_void, (char *)NULL) == -1) {
goto done;
@@ -184,10 +184,10 @@ remoteAdminDaemonClose(virAdmDaemonPtr dmn)
static void
remoteAdminPrivFree(void *opaque)
{
virAdmDaemonPtr dmn = opaque;
virAdmConnectPtr conn = opaque;

remoteAdminDaemonClose(dmn);
virObjectUnref(dmn->privateData);
remoteAdminConnectClose(conn);
virObjectUnref(conn->privateData);
}

static remoteAdminPrivPtr
@@ -1,12 +1,12 @@
/* -*- c -*- */
struct admin_daemon_open_args {
struct admin_connect_open_args {
u_int flags;
};
struct admin_daemon_get_version_ret {
struct admin_connect_get_lib_version_ret {
uint64_t libVer;
};
enum admin_procedure {
ADMIN_PROC_DAEMON_OPEN = 1,
ADMIN_PROC_DAEMON_CLOSE = 2,
ADMIN_PROC_DAEMON_GET_VERSION = 3,
ADMIN_PROC_CONNECT_OPEN = 1,
ADMIN_PROC_CONNECT_CLOSE = 2,
ADMIN_PROC_CONNECT_GET_LIB_VERSION = 3,
};
@@ -232,7 +232,7 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn,

/* CPUs */
virCommandAddArg(cmd, "-c");
virCommandAddArgFormat(cmd, "%d", def->vcpus);
virCommandAddArgFormat(cmd, "%d", virDomainDefGetVcpus(def));

/* Memory */
virCommandAddArg(cmd, "-m");
@@ -60,6 +60,7 @@ virDomainXMLPrivateDataCallbacks virBhyveDriverPrivateDataCallbacks = {
static int
bhyveDomainDefPostParse(virDomainDefPtr def,
virCapsPtr caps ATTRIBUTE_UNUSED,
unsigned int parseFlags ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
/* Add an implicit PCI root controller */
@@ -78,6 +79,7 @@ static int
bhyveDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
const virDomainDef *def ATTRIBUTE_UNUSED,
virCapsPtr caps ATTRIBUTE_UNUSED,
unsigned int parseFlags ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
if (virDomainDeviceDefCheckUnsupportedMemoryDevice(dev) < 0)
@@ -304,7 +304,7 @@ bhyveDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)

info->state = virDomainObjGetState(vm, NULL);
info->maxMem = virDomainDefGetMemoryActual(vm->def);
info->nrVirtCpu = vm->def->vcpus;
info->nrVirtCpu = virDomainDefGetVcpus(vm->def);
ret = 0;

cleanup:
@@ -825,7 +825,7 @@ virDomainVirtioSerialAddrFindController(virDomainVirtioSerialAddrSetPtr addrs,
* Adds virtio serial ports of the existing controller
* to the address set.
*/
int
static int
virDomainVirtioSerialAddrSetAddController(virDomainVirtioSerialAddrSetPtr addrs,
virDomainControllerDefPtr cont)
{
@@ -884,27 +884,6 @@ virDomainVirtioSerialAddrSetAddControllers(virDomainVirtioSerialAddrSetPtr addrs
return 0;
}

/* virDomainVirtioSerialAddrSetRemoveController
*
* Removes a virtio serial controller from the address set.
*/
void
virDomainVirtioSerialAddrSetRemoveController(virDomainVirtioSerialAddrSetPtr addrs,
virDomainControllerDefPtr cont)
{
ssize_t pos;

if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL)
return;

VIR_DEBUG("Removing virtio serial controller index %u "
"from the address set", cont->idx);

pos = virDomainVirtioSerialAddrFindController(addrs, cont->idx);

if (pos >= 0)
VIR_DELETE_ELEMENT(addrs->controllers, pos, addrs->ncontrollers);
}

void
virDomainVirtioSerialAddrSetFree(virDomainVirtioSerialAddrSetPtr addrs)
@@ -206,14 +206,6 @@ typedef virDomainVirtioSerialAddrSet *virDomainVirtioSerialAddrSetPtr;
virDomainVirtioSerialAddrSetPtr
virDomainVirtioSerialAddrSetCreate(void);
int
virDomainVirtioSerialAddrSetAddController(virDomainVirtioSerialAddrSetPtr addrs,
virDomainControllerDefPtr cont)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void
virDomainVirtioSerialAddrSetRemoveController(virDomainVirtioSerialAddrSetPtr addrs,
virDomainControllerDefPtr cont)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int
virDomainVirtioSerialAddrSetAddControllers(virDomainVirtioSerialAddrSetPtr addrs,
virDomainDefPtr def)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
@@ -885,7 +885,7 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success)

virDomainAuditMemory(vm, 0, virDomainDefGetMemoryActual(vm->def),
"start", true);
virDomainAuditVcpu(vm, 0, vm->def->vcpus, "start", true);
virDomainAuditVcpu(vm, 0, virDomainDefGetVcpus(vm->def), "start", true);
if (vm->def->niothreadids)
virDomainAuditIOThread(vm, 0, vm->def->niothreadids, "start", true);

Large diffs are not rendered by default.

@@ -1176,6 +1176,7 @@ struct _virDomainChrSourceDef {
/* no <source> for null, vc, stdio */
struct {
char *path;
int append; /* enum virTristateSwitch */
} file; /* pty, file, pipe, or device */
struct {
char *master;
@@ -1634,6 +1635,7 @@ struct _virDomainMemballoonDef {
int model;
virDomainDeviceInfo info;
int period; /* seconds between collections */
int autodeflate; /* enum virTristateSwitch */
};

struct _virDomainNVRAMDef {
@@ -2145,6 +2147,14 @@ struct _virDomainCputune {
virDomainThreadSchedParamPtr iothreadsched;
};


typedef struct _virDomainVcpuInfo virDomainVcpuInfo;
typedef virDomainVcpuInfo *virDomainVcpuInfoPtr;

struct _virDomainVcpuInfo {
bool online;
};

typedef struct _virDomainBlkiotune virDomainBlkiotune;
typedef virDomainBlkiotune *virDomainBlkiotunePtr;

@@ -2218,8 +2228,8 @@ struct _virDomainDef {
virDomainBlkiotune blkio;
virDomainMemtune mem;

unsigned int vcpus;
unsigned int maxvcpus;
virDomainVcpuInfoPtr vcpus;
size_t maxvcpus;
int placement_mode;
virBitmapPtr cpumask;

@@ -2343,6 +2353,14 @@ struct _virDomainDef {
xmlNodePtr metadata;
};

int virDomainDefSetVcpusMax(virDomainDefPtr def, unsigned int vcpus);
bool virDomainDefHasVcpusOffline(const virDomainDef *def);
unsigned int virDomainDefGetVcpusMax(const virDomainDef *def);
int virDomainDefSetVcpus(virDomainDefPtr def, unsigned int vcpus);
unsigned int virDomainDefGetVcpus(const virDomainDef *def);
virDomainVcpuInfoPtr virDomainDefGetVcpu(virDomainDefPtr def, unsigned int vcpu)
ATTRIBUTE_RETURN_CHECK;

unsigned long long virDomainDefGetMemoryInitial(const virDomainDef *def);
void virDomainDefSetMemoryTotal(virDomainDefPtr def, unsigned long long size);
void virDomainDefSetMemoryInitial(virDomainDefPtr def, unsigned long long size);
@@ -2404,6 +2422,9 @@ struct _virDomainObj {
void (*privateDataFreeFunc)(void *);

int taint;

unsigned long long original_memlock; /* Original RLIMIT_MEMLOCK, zero if no
* restore will be required later */
};

typedef bool (*virDomainObjListACLFilter)(virConnectPtr conn,
@@ -2419,12 +2440,14 @@ typedef virDomainXMLOption *virDomainXMLOptionPtr;
* overall domain defaults. */
typedef int (*virDomainDefPostParseCallback)(virDomainDefPtr def,
virCapsPtr caps,
unsigned int parseFlags,
void *opaque);
/* Called once per device, for adjusting per-device settings while
* leaving the overall domain otherwise unchanged. */
typedef int (*virDomainDeviceDefPostParseCallback)(virDomainDeviceDefPtr dev,
const virDomainDef *def,
virCapsPtr caps,
unsigned int parseFlags,
void *opaque);

typedef struct _virDomainDefParserConfig virDomainDefParserConfig;
@@ -3067,6 +3090,8 @@ VIR_ENUM_DECL(virDomainCpuPlacementMode)

VIR_ENUM_DECL(virDomainStartupPolicy)

int
virDomainDefAddUSBController(virDomainDefPtr def, int idx, int model);
int
virDomainDefMaybeAddController(virDomainDefPtr def,
int type,
@@ -220,7 +220,8 @@ static virStoragePoolTypeInfo poolTypeInfo[] = {
},
.volOptions = {
.defaultFormat = VIR_STORAGE_FILE_RAW,
.formatToString = virStoragePoolFormatDiskTypeToString,
.formatFromString = virStorageVolumeFormatFromString,
.formatToString = virStorageFileFormatTypeToString,
}
},
{.poolType = VIR_STORAGE_POOL_SHEEPDOG,
@@ -59,11 +59,11 @@ static void virStreamDispose(void *obj);
static void virStorageVolDispose(void *obj);
static void virStoragePoolDispose(void *obj);

virClassPtr virAdmDaemonClass;
virClassPtr virAdmDaemonCloseCallbackDataClass;
virClassPtr virAdmConnectClass;
virClassPtr virAdmConnectCloseCallbackDataClass;

static void virAdmDaemonDispose(void *obj);
static void virAdmDaemonCloseCallbackDataDispose(void *obj);
static void virAdmConnectDispose(void *obj);
static void virAdmConnectCloseCallbackDataDispose(void *obj);

static int
virDataTypesOnceInit(void)
@@ -92,8 +92,8 @@ virDataTypesOnceInit(void)
DECLARE_CLASS(virStorageVol);
DECLARE_CLASS(virStoragePool);

DECLARE_CLASS_LOCKABLE(virAdmDaemon);
DECLARE_CLASS_LOCKABLE(virAdmDaemonCloseCallbackData);
DECLARE_CLASS_LOCKABLE(virAdmConnect);
DECLARE_CLASS_LOCKABLE(virAdmConnectCloseCallbackData);

#undef DECLARE_CLASS_COMMON
#undef DECLARE_CLASS_LOCKABLE
@@ -814,18 +814,18 @@ virDomainSnapshotDispose(void *obj)
}


virAdmDaemonPtr
virAdmDaemonNew(void)
virAdmConnectPtr
virAdmConnectNew(void)
{
virAdmDaemonPtr ret;
virAdmConnectPtr ret;

if (virDataTypesInitialize() < 0)
return NULL;

if (!(ret = virObjectLockableNew(virAdmDaemonClass)))
if (!(ret = virObjectLockableNew(virAdmConnectClass)))
return NULL;

if (!(ret->closeCallback = virObjectLockableNew(virAdmDaemonCloseCallbackDataClass)))
if (!(ret->closeCallback = virObjectLockableNew(virAdmConnectCloseCallbackDataClass)))
goto error;

return ret;
@@ -836,21 +836,21 @@ virAdmDaemonNew(void)
}

static void
virAdmDaemonDispose(void *obj)
virAdmConnectDispose(void *obj)
{
virAdmDaemonPtr dmn = obj;
virAdmConnectPtr conn = obj;

if (dmn->privateDataFreeFunc)
dmn->privateDataFreeFunc(dmn);
if (conn->privateDataFreeFunc)
conn->privateDataFreeFunc(conn);

virURIFree(dmn->uri);
virObjectUnref(dmn->closeCallback);
virURIFree(conn->uri);
virObjectUnref(conn->closeCallback);
}

static void
virAdmDaemonCloseCallbackDataDispose(void *obj)
virAdmConnectCloseCallbackDataDispose(void *obj)
{
virAdmDaemonCloseCallbackDataPtr cb_data = obj;
virAdmConnectCloseCallbackDataPtr cb_data = obj;

virObjectLock(cb_data);

@@ -41,7 +41,7 @@ extern virClassPtr virStreamClass;
extern virClassPtr virStorageVolClass;
extern virClassPtr virStoragePoolClass;

extern virClassPtr virAdmDaemonClass;
extern virClassPtr virAdmConnectClass;

# define virCheckConnectReturn(obj, retval) \
do { \
@@ -297,19 +297,19 @@ extern virClassPtr virAdmDaemonClass;
dom, NULLSTR(_domname), _uuidstr, __VA_ARGS__); \
} while (0)

# define virCheckAdmDaemonReturn(obj, retval) \
# define virCheckAdmConnectReturn(obj, retval) \
do { \
if (!virObjectIsClass(obj, virAdmDaemonClass)) { \
if (!virObjectIsClass(obj, virAdmConnectClass)) { \
virReportErrorHelper(VIR_FROM_THIS, VIR_ERR_INVALID_CONN, \
__FILE__, __FUNCTION__, __LINE__, \
__FUNCTION__); \
virDispatchError(NULL); \
return retval; \
} \
} while (0)
# define virCheckAdmDaemonGoto(obj, label) \
# define virCheckAdmConnectGoto(obj, label) \
do { \
if (!virObjectIsClass(obj, virAdmDaemonClass)) { \
if (!virObjectIsClass(obj, virAdmConnectClass)) { \
virReportErrorHelper(VIR_FROM_THIS, VIR_ERR_INVALID_CONN, \
__FILE__, __FUNCTION__, __LINE__, \
__FUNCTION__); \
@@ -331,8 +331,8 @@ extern virClassPtr virAdmDaemonClass;

typedef struct _virConnectCloseCallbackData virConnectCloseCallbackData;
typedef virConnectCloseCallbackData *virConnectCloseCallbackDataPtr;
typedef struct _virAdmDaemonCloseCallbackData virAdmDaemonCloseCallbackData;
typedef virAdmDaemonCloseCallbackData *virAdmDaemonCloseCallbackDataPtr;
typedef struct _virAdmConnectCloseCallbackData virAdmConnectCloseCallbackData;
typedef virAdmConnectCloseCallbackData *virAdmConnectCloseCallbackDataPtr;

/**
* Internal structures holding data related to connection close callbacks.
@@ -346,11 +346,11 @@ struct _virConnectCloseCallbackData {
virFreeCallback freeCallback;
};

struct _virAdmDaemonCloseCallbackData {
struct _virAdmConnectCloseCallbackData {
virObjectLockable parent;

virAdmDaemonPtr dmn;
virAdmDaemonCloseFunc callback;
virAdmConnectPtr conn;
virAdmConnectCloseFunc callback;
void *opaque;
virFreeCallback freeCallback;
};
@@ -402,19 +402,19 @@ struct _virConnect {
};

/**
* _virAdmDaemon:
* _virAdmConnect:
*
* Internal structure associated to an admin connection
*/
struct _virAdmDaemon {
struct _virAdmConnect {
virObjectLockable object;
virURIPtr uri;

void *privateData;
virFreeCallback privateDataFreeFunc;

/* Per-connection close callback */
virAdmDaemonCloseCallbackDataPtr closeCallback;
virAdmConnectCloseCallbackDataPtr closeCallback;
};


@@ -599,6 +599,6 @@ virNWFilterPtr virGetNWFilter(virConnectPtr conn,
virDomainSnapshotPtr virGetDomainSnapshot(virDomainPtr domain,
const char *name);

virAdmDaemonPtr virAdmDaemonNew(void);
virAdmConnectPtr virAdmConnectNew(void);

#endif /* __VIR_DATATYPES_H__ */
@@ -2743,7 +2743,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
ctx.autodetectSCSIControllerModel = NULL;
ctx.datacenterPath = priv->primary->datacenterPath;

def = virVMXParseConfig(&ctx, priv->xmlopt, vmx);
def = virVMXParseConfig(&ctx, priv->xmlopt, priv->caps, vmx);

if (def) {
if (powerState != esxVI_VirtualMachinePowerState_PoweredOff)
@@ -2802,7 +2802,7 @@ esxConnectDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
ctx.autodetectSCSIControllerModel = NULL;
ctx.datacenterPath = NULL;

def = virVMXParseConfig(&ctx, priv->xmlopt, nativeConfig);
def = virVMXParseConfig(&ctx, priv->xmlopt, priv->caps, nativeConfig);

if (def)
xml = virDomainDefFormat(def, VIR_DOMAIN_DEF_FORMAT_INACTIVE);
@@ -873,8 +873,14 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
virDomainDefSetMemoryTotal(def, memorySettingData->data->Limit * 1024); /* megabyte to kilobyte */
def->mem.cur_balloon = memorySettingData->data->VirtualQuantity * 1024; /* megabyte to kilobyte */

def->vcpus = processorSettingData->data->VirtualQuantity;
def->maxvcpus = processorSettingData->data->VirtualQuantity;
if (virDomainDefSetVcpusMax(def,
processorSettingData->data->VirtualQuantity) < 0)
goto cleanup;

if (virDomainDefSetVcpus(def,
processorSettingData->data->VirtualQuantity) < 0)
goto cleanup;

def->os.type = VIR_DOMAIN_OSTYPE_HVM;

/* FIXME: devices section is totally missing */

Large diffs are not rendered by default.

@@ -3428,7 +3428,7 @@ virDomainMigrateUnmanagedParams(virDomainPtr domain,
unsigned int flags)
{
VIR_DOMAIN_DEBUG(domain, "dconnuri=%s, params=%p, nparams=%d, flags=%x",
dconnuri, params, nparams, flags);
NULLSTR(dconnuri), params, nparams, flags);
VIR_TYPED_PARAMS_DEBUG(params, nparams);

if ((flags & VIR_MIGRATE_PEER2PEER) &&
@@ -4404,7 +4404,7 @@ virDomainMigrateToURI2(virDomainPtr domain,
else
dconnuri = NULL;

if (virDomainMigrateUnmanaged(domain, NULL, flags,
if (virDomainMigrateUnmanaged(domain, dxml, flags,
dname, dconnuri, miguri, bandwidth) < 0)
goto error;

@@ -10572,15 +10572,17 @@ virDomainGetBlockIoTune(virDomainPtr dom,
* Typical use sequence is below.
*
* getting total stats: set start_cpu as -1, ncpus 1
* virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0) => nparams
* params = calloc(nparams, sizeof(virTypedParameter))
* virDomainGetCPUStats(dom, params, nparams, -1, 1, 0) => total stats.
*
* virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0); // nparams
* params = calloc(nparams, sizeof(virTypedParameter))
* virDomainGetCPUStats(dom, params, nparams, -1, 1, 0); // total stats.
*
* getting per-cpu stats:
* virDomainGetCPUStats(dom, NULL, 0, 0, 0, 0) => ncpus
* virDomainGetCPUStats(dom, NULL, 0, 0, 1, 0) => nparams
* params = calloc(ncpus * nparams, sizeof(virTypedParameter))
* virDomainGetCPUStats(dom, params, nparams, 0, ncpus, 0) => per-cpu stats
*
* virDomainGetCPUStats(dom, NULL, 0, 0, 0, 0); // ncpus
* virDomainGetCPUStats(dom, NULL, 0, 0, 1, 0); // nparams
* params = calloc(ncpus * nparams, sizeof(virTypedParameter));
* virDomainGetCPUStats(dom, params, nparams, 0, ncpus, 0); // per-cpu stats
*
* Returns -1 on failure, or the number of statistics that were
* populated per cpu on success (this will be less than the total
@@ -10932,6 +10934,7 @@ virDomainGetTime(virDomainPtr dom,
virResetLastError();

virCheckDomainReturn(dom, -1);
virCheckReadOnlyGoto(dom->conn->flags, error);

if (dom->conn->driver->domainGetTime) {
int ret = dom->conn->driver->domainGetTime(dom, seconds,
@@ -11544,7 +11547,8 @@ virDomainInterfaceAddresses(virDomainPtr dom,
*ifaces = NULL;
virCheckDomainReturn(dom, -1);
virCheckNonNullArgGoto(ifaces, error);
virCheckReadOnlyGoto(dom->conn->flags, error);
if (source == VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT)
virCheckReadOnlyGoto(dom->conn->flags, error);

if (dom->conn->driver->domainInterfaceAddresses) {
int ret;
@@ -505,7 +505,7 @@ virStoragePoolLookupByVolume(virStorageVolPtr vol)
* virStoragePoolCreateXML:
* @conn: pointer to hypervisor connection
* @xmlDesc: XML description for new pool
* @flags: extra flags; not used yet, so callers should always pass 0
* @flags: bitwise-OR of virStoragePoolCreateFlags
*
* Create a new storage based on its XML description. The
* pool is not persistent, so its definition will disappear
@@ -670,7 +670,7 @@ virStoragePoolUndefine(virStoragePoolPtr pool)
/**
* virStoragePoolCreate:
* @pool: pointer to storage pool
* @flags: extra flags; not used yet, so callers should always pass 0
* @flags: bitwise-OR of virStoragePoolCreateFlags
*
* Starts an inactive storage pool
*
@@ -1684,7 +1684,7 @@ virStorageVolUpload(virStorageVolPtr vol,
/**
* virStorageVolDelete:
* @vol: pointer to storage volume
* @flags: extra flags; not used yet, so callers should always pass 0
* @flags: bitwise-OR of virStorageVolDeleteFlags
*
* Delete the storage volume from the pool
*
@@ -1725,7 +1725,12 @@ virStorageVolDelete(virStorageVolPtr vol,
* @vol: pointer to storage volume
* @flags: extra flags; not used yet, so callers should always pass 0
*
* Ensure data previously on a volume is not accessible to future reads
* Ensure data previously on a volume is not accessible to future
* reads. Also note, that depending on the actual volume
* representation, this call may not really overwrite the
* physical location of the volume. For instance, files stored
* journaled, log structured, copy-on-write, versioned, and
* network file systems are known to be problematic.
*
* Returns 0 on success, or -1 on error
*/
@@ -1765,8 +1770,13 @@ virStorageVolWipe(virStorageVolPtr vol,
* @algorithm: one of virStorageVolWipeAlgorithm
* @flags: future flags, use 0 for now
*
* Similar to virStorageVolWipe, but one can choose
* between different wiping algorithms.
* Similar to virStorageVolWipe, but one can choose between
* different wiping algorithms. Also note, that depending on the
* actual volume representation, this call may not really
* overwrite the physical location of the volume. For instance,
* files stored journaled, log structured, copy-on-write,
* versioned, and network file systems are known to be
* problematic.
*
* Returns 0 on success, or -1 on error.
*/
@@ -6,8 +6,8 @@
#

# admin/admin_protocol.x
xdr_admin_daemon_get_version_ret;
xdr_admin_daemon_open_args;
xdr_admin_connect_get_lib_version_ret;
xdr_admin_connect_open_args;

# Let emacs know we want case-insensitive sorting
# Local Variables:
@@ -12,13 +12,13 @@
#
LIBVIRT_ADMIN_1.3.0 {
global:
virAdmDaemonClose;
virAdmDaemonGetURI;
virAdmDaemonGetVersion;
virAdmDaemonIsAlive;
virAdmDaemonOpen;
virAdmDaemonRef;
virAdmDaemonRegisterCloseCallback;
virAdmDaemonUnregisterCloseCallback;
virAdmConnectOpen;
virAdmConnectClose;
virAdmConnectRef;
virAdmGetVersion;
virAdmConnectIsAlive;
virAdmConnectGetURI;
virAdmConnectGetLibVersion;
virAdmConnectRegisterCloseCallback;
virAdmConnectUnregisterCloseCallback;
};
@@ -111,11 +111,9 @@ virDomainVirtioSerialAddrAutoAssign;
virDomainVirtioSerialAddrIsComplete;
virDomainVirtioSerialAddrRelease;
virDomainVirtioSerialAddrReserve;
virDomainVirtioSerialAddrSetAddController;
virDomainVirtioSerialAddrSetAddControllers;
virDomainVirtioSerialAddrSetCreate;
virDomainVirtioSerialAddrSetFree;
virDomainVirtioSerialAddrSetRemoveController;


# conf/domain_audit.h
@@ -200,6 +198,7 @@ virDomainControllerTypeToString;
virDomainCpuPlacementModeTypeFromString;
virDomainCpuPlacementModeTypeToString;
virDomainDefAddImplicitControllers;
virDomainDefAddUSBController;
virDomainDefCheckABIStability;
virDomainDefCheckDuplicateDiskInfo;
virDomainDefCheckUnsupportedMemoryHotplug;
@@ -217,8 +216,12 @@ virDomainDefGetDefaultEmulator;
virDomainDefGetMemoryActual;
virDomainDefGetMemoryInitial;
virDomainDefGetSecurityLabelDef;
virDomainDefGetVcpu;
virDomainDefGetVcpus;
virDomainDefGetVcpusMax;
virDomainDefHasDeviceAddress;
virDomainDefHasMemoryHotplug;
virDomainDefHasVcpusOffline;
virDomainDefMaybeAddController;
virDomainDefMaybeAddInput;
virDomainDefNeedsPlacementAdvice;
@@ -230,6 +233,8 @@ virDomainDefParseString;
virDomainDefPostParse;
virDomainDefSetMemoryInitial;
virDomainDefSetMemoryTotal;
virDomainDefSetVcpus;
virDomainDefSetVcpusMax;
virDomainDeleteConfig;
virDomainDeviceAddressIsValid;
virDomainDeviceAddressTypeToString;
@@ -1999,6 +2004,8 @@ virPCIGetVirtualFunctionIndex;
virPCIGetVirtualFunctionInfo;
virPCIGetVirtualFunctions;
virPCIIsVirtualFunction;
virPCIStubDriverTypeFromString;
virPCIStubDriverTypeToString;


# util/virpidfile.h
@@ -2034,6 +2041,7 @@ virPortAllocatorSetUsed;
virProcessAbort;
virProcessExitWithStatus;
virProcessGetAffinity;
virProcessGetMaxMemLock;
virProcessGetNamespaces;
virProcessGetPids;
virProcessGetStartTime;
@@ -2387,6 +2395,7 @@ virGetGroupID;
virGetGroupList;
virGetGroupName;
virGetHostname;
virGetHostnameQuiet;
virGetListenFDs;
virGetSCSIHostNameByParentaddr;
virGetSCSIHostNumber;
@@ -15,6 +15,7 @@ xenParseSxpr;
xenParseSxprChar;
xenParseSxprSound;
xenParseSxprString;
xenParseSxprVifRate;

# xenconfig/xen_xm.h
xenFormatXM;
@@ -643,11 +643,11 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
else
libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_PV);

b_info->max_vcpus = def->maxvcpus;
if (libxl_cpu_bitmap_alloc(ctx, &b_info->avail_vcpus, def->maxvcpus))
b_info->max_vcpus = virDomainDefGetVcpusMax(def);
if (libxl_cpu_bitmap_alloc(ctx, &b_info->avail_vcpus, b_info->max_vcpus))
return -1;
libxl_bitmap_set_none(&b_info->avail_vcpus);
for (i = 0; i < def->vcpus; i++)
for (i = 0; i < virDomainDefGetVcpus(def); i++)
libxl_bitmap_set((&b_info->avail_vcpus), i);

if (def->clock.ntimers > 0 &&
@@ -1093,6 +1093,7 @@ libxlMakeNic(virDomainDefPtr def,
{
bool ioemu_nic = def->os.type == VIR_DOMAIN_OSTYPE_HVM;
virDomainNetType actual_type = virDomainNetGetActualType(l_nic);
virNetDevBandwidthPtr actual_bw;

/* TODO: Where is mtu stored?
*
@@ -1206,6 +1207,44 @@ libxlMakeNic(virDomainDefPtr def,
#endif
}

/*
* Set bandwidth.
* From $xen-sources/docs/misc/xl-network-configuration.markdown:
*
*
* Specifies the rate at which the outgoing traffic will be limited to.
* The default if this keyword is not specified is unlimited.
*
* The rate may be specified as "<RATE>/s" or optionally "<RATE>/s@<INTERVAL>".
*
* `RATE` is in bytes and can accept suffixes:
* GB, MB, KB, B for bytes.
* Gb, Mb, Kb, b for bits.
* `INTERVAL` is in microseconds and can accept suffixes: ms, us, s.
* It determines the frequency at which the vif transmission credit
* is replenished. The default is 50ms.

* Vif rate limiting is credit-based. It means that for "1MB/s@20ms",
* the available credit will be equivalent of the traffic you would have
* done at "1MB/s" during 20ms. This will results in a credit of 20,000
* bytes replenished every 20,000 us.
*
*
* libvirt doesn't support the notion of rate limiting over an interval.
* Similar to xl's behavior when interval is not specified, set a default
* interval of 50ms and calculate the number of bytes per interval based
* on the specified average bandwidth.
*/
actual_bw = virDomainNetGetActualBandwidth(l_nic);
if (actual_bw && actual_bw->out && actual_bw->out->average) {
uint64_t bytes_per_sec = actual_bw->out->average * 1024;
uint64_t bytes_per_interval =
(((uint64_t) bytes_per_sec * 50000UL) / 1000000UL);

x_nic->rate_bytes_per_interval = bytes_per_interval;
x_nic->rate_interval_usecs = 50000UL;
}

return 0;
}

@@ -74,6 +74,9 @@ libxlDomainObjInitJob(libxlDomainObjPrivatePtr priv)
if (virCondInit(&priv->job.cond) < 0)
return -1;

if (VIR_ALLOC(priv->job.current) < 0)
return -1;

return 0;
}

@@ -90,6 +93,7 @@ static void
libxlDomainObjFreeJob(libxlDomainObjPrivatePtr priv)
{
ignore_value(virCondDestroy(&priv->job.cond));
VIR_FREE(priv->job.current);
}

/* Give up waiting for mutex after 30 seconds */
@@ -131,6 +135,8 @@ libxlDomainObjBeginJob(libxlDriverPrivatePtr driver ATTRIBUTE_UNUSED,
VIR_DEBUG("Starting job: %s", libxlDomainJobTypeToString(job));
priv->job.active = job;
priv->job.owner = virThreadSelfID();
priv->job.started = now;
priv->job.current->type = VIR_DOMAIN_JOB_UNBOUNDED;

return 0;

@@ -179,6 +185,27 @@ libxlDomainObjEndJob(libxlDriverPrivatePtr driver ATTRIBUTE_UNUSED,
return virObjectUnref(obj);
}

int
libxlDomainJobUpdateTime(struct libxlDomainJobObj *job)
{
virDomainJobInfoPtr jobInfo = job->current;
unsigned long long now;

if (!job->started)
return 0;

if (virTimeMillisNow(&now) < 0)
return -1;

if (now < job->started) {
job->started = 0;
return 0;
}

jobInfo->timeElapsed = now - job->started;
return 0;
}

static void *
libxlDomainObjPrivateAlloc(void)
{
@@ -258,6 +285,7 @@ static int
libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
const virDomainDef *def,
virCapsPtr caps ATTRIBUTE_UNUSED,
unsigned int parseFlags ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
if (dev->type == VIR_DOMAIN_DEVICE_CHR &&
@@ -343,6 +371,7 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
static int
libxlDomainDefPostParse(virDomainDefPtr def,
virCapsPtr caps ATTRIBUTE_UNUSED,
unsigned int parseFlags ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
/* Xen PV domains always have a PV console, so add one to the domain config
@@ -959,6 +988,10 @@ libxlDomainStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
VIR_FREE(managed_save_path);
}

if (virDomainObjSetDefTransient(cfg->caps, driver->xmlopt,
vm, true) < 0)
goto cleanup;

if (libxlBuildDomainConfig(driver->reservedGraphicsPorts, vm->def,
cfg->ctx, &d_config) < 0)
goto cleanup;
@@ -53,6 +53,8 @@ struct libxlDomainJobObj {
virCond cond; /* Use to coordinate jobs */
enum libxlDomainJob active; /* Currently running job */
int owner; /* Thread which set current job */
unsigned long long started; /* When the job started */
virDomainJobInfoPtr current; /* Statistics for the current job */
};

typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate;
@@ -88,6 +90,10 @@ libxlDomainObjEndJob(libxlDriverPrivatePtr driver,
virDomainObjPtr obj)
ATTRIBUTE_RETURN_CHECK;

int
libxlDomainJobUpdateTime(struct libxlDomainJobObj *job)
ATTRIBUTE_RETURN_CHECK;

void
libxlDomainEventQueue(libxlDriverPrivatePtr driver,
virObjectEventPtr event);
@@ -552,8 +552,11 @@ libxlAddDom0(libxlDriverPrivatePtr driver)
def = NULL;

virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED);
vm->def->vcpus = d_info.vcpu_online;
vm->def->maxvcpus = d_info.vcpu_max_id + 1;
if (virDomainDefSetVcpusMax(vm->def, d_info.vcpu_max_id + 1))
goto cleanup;

if (virDomainDefSetVcpus(vm->def, d_info.vcpu_online) < 0)
goto cleanup;
vm->def->mem.cur_balloon = d_info.current_memkb;
virDomainDefSetMemoryTotal(vm->def, d_info.max_memkb);

@@ -1598,7 +1601,7 @@ libxlDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
}

info->state = virDomainObjGetState(vm, NULL);
info->nrVirtCpu = vm->def->vcpus;
info->nrVirtCpu = virDomainDefGetVcpus(vm->def);
ret = 0;

cleanup:
@@ -2157,8 +2160,8 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
goto endjob;
}

if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM) && vm->def->maxvcpus < max)
max = vm->def->maxvcpus;
if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM) && virDomainDefGetVcpusMax(vm->def) < max)
max = virDomainDefGetVcpusMax(vm->def);

if (nvcpus > max) {
virReportError(VIR_ERR_INVALID_ARG,
@@ -2184,13 +2187,13 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,

switch (flags) {
case VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_CONFIG:
def->maxvcpus = nvcpus;
if (nvcpus < def->vcpus)
def->vcpus = nvcpus;
if (virDomainDefSetVcpusMax(def, nvcpus) < 0)
goto cleanup;
break;

case VIR_DOMAIN_VCPU_CONFIG:
def->vcpus = nvcpus;
if (virDomainDefSetVcpus(def, nvcpus) < 0)
goto cleanup;
break;

case VIR_DOMAIN_VCPU_LIVE:
@@ -2200,7 +2203,8 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
" with libxenlight"), vm->def->id);
goto endjob;
}
vm->def->vcpus = nvcpus;
if (virDomainDefSetVcpus(vm->def, nvcpus) < 0)
goto endjob;
break;

case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG:
@@ -2210,8 +2214,9 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
" with libxenlight"), vm->def->id);
goto endjob;
}
vm->def->vcpus = nvcpus;
def->vcpus = nvcpus;
if (virDomainDefSetVcpus(vm->def, nvcpus) < 0 ||
virDomainDefSetVcpus(def, nvcpus) < 0)
goto endjob;
break;
}

@@ -2296,7 +2301,10 @@ libxlDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
def = vm->newDef ? vm->newDef : vm->def;
}

ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus;
if (flags & VIR_DOMAIN_VCPU_MAXIMUM)
ret = virDomainDefGetVcpusMax(def);
else
ret = virDomainDefGetVcpus(def);

cleanup:
if (vm)
@@ -2433,8 +2441,8 @@ libxlDomainGetVcpuPinInfo(virDomainPtr dom, int ncpumaps,
sa_assert(targetDef);

/* Clamp to actual number of vcpus */
if (ncpumaps > targetDef->vcpus)
ncpumaps = targetDef->vcpus;
if (ncpumaps > virDomainDefGetVcpus(targetDef))
ncpumaps = virDomainDefGetVcpus(targetDef);

if ((hostcpus = libxl_get_max_cpus(cfg->ctx)) < 0)
goto cleanup;
@@ -2587,22 +2595,23 @@ libxlConnectDomainXMLFromNative(virConnectPtr conn,
goto cleanup;
if (!(def = xenParseXL(conf,
cfg->caps,
cfg->verInfo->xen_version_major)))
driver->xmlopt)))
goto cleanup;
} else if (STREQ(nativeFormat, LIBXL_CONFIG_FORMAT_XM)) {
if (!(conf = virConfReadMem(nativeConfig, strlen(nativeConfig), 0)))
goto cleanup;

if (!(def = xenParseXM(conf,
cfg->verInfo->xen_version_major,
cfg->caps)))
cfg->caps,
driver->xmlopt)))
goto cleanup;
} else if (STREQ(nativeFormat, LIBXL_CONFIG_FORMAT_SEXPR)) {
/* only support latest xend config format */
if (!(def = xenParseSxprString(nativeConfig,
XEND_CONFIG_VERSION_3_1_0,
NULL,
-1))) {
-1,
cfg->caps,
driver->xmlopt))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("parsing sxpr config failed"));
goto cleanup;
@@ -2647,10 +2656,10 @@ libxlConnectDomainXMLToNative(virConnectPtr conn, const char * nativeFormat,
goto cleanup;

if (STREQ(nativeFormat, LIBXL_CONFIG_FORMAT_XL)) {
if (!(conf = xenFormatXL(def, conn, cfg->verInfo->xen_version_major)))
if (!(conf = xenFormatXL(def, conn)))
goto cleanup;
} else if (STREQ(nativeFormat, LIBXL_CONFIG_FORMAT_XM)) {
if (!(conf = xenFormatXM(conn, def, cfg->verInfo->xen_version_major)))
if (!(conf = xenFormatXM(conn, def)))
goto cleanup;
} else {

@@ -4694,7 +4703,7 @@ libxlDomainGetPerCPUStats(libxlDriverPrivatePtr driver,
if (nparams == 0 && ncpus != 0)
return LIBXL_NB_TOTAL_CPU_STAT_PARAM;
else if (nparams == 0)
return vm->def->maxvcpus;
return virDomainDefGetVcpusMax(vm->def);

cfg = libxlDriverConfigGet(driver);
if ((vcpuinfo = libxl_list_vcpu(cfg->ctx, vm->def->id, &maxcpu,
@@ -4828,6 +4837,95 @@ libxlDomainMemoryStats(virDomainPtr dom,

#undef LIBXL_SET_MEMSTAT

static int
libxlDomainGetJobInfo(virDomainPtr dom,
virDomainJobInfoPtr info)
{
libxlDomainObjPrivatePtr priv;
virDomainObjPtr vm;
int ret = -1;

if (!(vm = libxlDomObjFromDomain(dom)))
goto cleanup;

if (virDomainGetJobInfoEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;

priv = vm->privateData;
if (!priv->job.active) {
memset(info, 0, sizeof(*info));
info->type = VIR_DOMAIN_JOB_NONE;
ret = 0;
goto cleanup;
}

/* In libxl we don't have an estimated completion time
* thus we always set to unbounded and update time
* for the active job. */
if (libxlDomainJobUpdateTime(&priv->job) < 0)
goto cleanup;

memcpy(info, priv->job.current, sizeof(virDomainJobInfo));
ret = 0;

cleanup:
if (vm)
virObjectUnlock(vm);
return ret;
}

static int
libxlDomainGetJobStats(virDomainPtr dom,
int *type,
virTypedParameterPtr *params,
int *nparams,
unsigned int flags)
{
libxlDomainObjPrivatePtr priv;
virDomainObjPtr vm;
virDomainJobInfoPtr jobInfo;
int ret = -1;
int maxparams = 0;

/* VIR_DOMAIN_JOB_STATS_COMPLETED not supported yet */
virCheckFlags(0, -1);

if (!(vm = libxlDomObjFromDomain(dom)))
goto cleanup;

if (virDomainGetJobStatsEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;

priv = vm->privateData;
jobInfo = priv->job.current;
if (!priv->job.active) {
*type = VIR_DOMAIN_JOB_NONE;
*params = NULL;
*nparams = 0;
ret = 0;
goto cleanup;
}

/* In libxl we don't have an estimated completion time
* thus we always set to unbounded and update time
* for the active job. */
if (libxlDomainJobUpdateTime(&priv->job) < 0)
goto cleanup;

if (virTypedParamsAddULLong(params, nparams, &maxparams,
VIR_DOMAIN_JOB_TIME_ELAPSED,
jobInfo->timeElapsed) < 0)
goto cleanup;

*type = jobInfo->type;
ret = 0;

cleanup:
if (vm)
virObjectUnlock(vm);
return ret;
}

static int
libxlConnectDomainEventRegisterAny(virConnectPtr conn, virDomainPtr dom, int eventID,
virConnectDomainEventGenericCallback callback,
@@ -4972,8 +5070,7 @@ libxlNodeDeviceDetachFlags(virNodeDevicePtr dev,
goto cleanup;

if (!driverName || STREQ(driverName, "xen")) {
if (virPCIDeviceSetStubDriver(pci, "pciback") < 0)
goto cleanup;
virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN);
} else {
virReportError(VIR_ERR_INVALID_ARG,
_("unsupported driver name '%s'"), driverName);
@@ -5421,6 +5518,8 @@ static virHypervisorDriver libxlHypervisorDriver = {
#endif
.nodeGetFreeMemory = libxlNodeGetFreeMemory, /* 0.9.0 */
.nodeGetCellsFreeMemory = libxlNodeGetCellsFreeMemory, /* 1.1.1 */
.domainGetJobInfo = libxlDomainGetJobInfo, /* 1.3.1 */
.domainGetJobStats = libxlDomainGetJobStats, /* 1.3.1 */
.domainMemoryStats = libxlDomainMemoryStats, /* 1.3.0 */
.domainGetCPUStats = libxlDomainGetCPUStats, /* 1.3.0 */
.connectDomainEventRegister = libxlConnectDomainEventRegister, /* 0.9.0 */
@@ -1,12 +1,16 @@
#!/bin/sh

# the following is the LSB init header see
# http://www.linux-foundation.org/spec//booksets/LSB-Core-generic/LSB-Core-generic.html#INITSCRCOMCONV
# http://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/initscrcomconv.html
#
### BEGIN INIT INFO
# Provides: virtlockd
# Default-Start:
# Default-Stop: 0 1 2 3 4 5 6
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Required-Start:
# Required-Stop:
# Should-Start: $network $remote_fs
# Should-Stop: $network $remote_fs
# Short-Description: virtual machine lock manager
# Description: This is a daemon for managing locks
# on virtual machine disk images
@@ -16,7 +20,7 @@
#
# virtlockd: virtual machine lock manager
#
# chkconfig: - 96 04
# chkconfig: 345 96 04
# description: This is a daemon for managing locks \
# on virtual machine disk images
#
@@ -2,6 +2,7 @@
*/

%#include "internal.h"
%#include "virxdrdefs.h"

typedef opaque virLogManagerProtocolUUID[VIR_UUID_BUFLEN];

@@ -1,12 +1,16 @@
#!/bin/sh

# the following is the LSB init header see
# http://www.linux-foundation.org/spec//booksets/LSB-Core-generic/LSB-Core-generic.html#INITSCRCOMCONV
# http://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/initscrcomconv.html
#
### BEGIN INIT INFO
# Provides: virtlogd
# Default-Start:
# Default-Stop: 0 1 2 3 4 5 6
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Required-Start:
# Required-Stop:
# Should-Start: $network $remote_fs
# Should-Stop: $network $remote_fs
# Short-Description: virtual machine log manager
# Description: This is a daemon for managing logs
# of virtual machine consoles
@@ -16,7 +20,7 @@
#
# virtlogd: virtual machine log manager
#
# chkconfig: - 96 04
# chkconfig: 345 96 04
# description: This is a daemon for managing logs \
# of virtual machine consoles
#
@@ -42,7 +46,7 @@ start() {
daemon --pidfile $PIDFILE --check $SERVICE $PROCESS --daemon $VIRTLOGD_ARGS
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch @localstatedir@/log/subsys/$SERVICE
[ $RETVAL -eq 0 ] && touch @localstatedir@/lock/subsys/$SERVICE
}

stop() {
@@ -52,7 +56,7 @@ stop() {
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
rm -f @localstatedir@/log/subsys/$SERVICE
rm -f @localstatedir@/lock/subsys/$SERVICE
rm -f $PIDFILE
fi
}
@@ -84,7 +88,7 @@ case "$1" in
reload
;;
condrestart|try-restart)
[ -f @localstatedir@/log/subsys/$SERVICE ] && restart || :
[ -f @localstatedir@/lock/subsys/$SERVICE ] && restart || :
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|force-reload|try-restart}"
@@ -771,7 +771,7 @@ static int virLXCControllerGetNumadAdvice(virLXCControllerPtr ctrl,
* either <vcpu> or <numatune> is 'auto'.
*/
if (virDomainDefNeedsPlacementAdvice(ctrl->def)) {
nodeset = virNumaGetAutoPlacementAdvice(ctrl->def->vcpus,
nodeset = virNumaGetAutoPlacementAdvice(virDomainDefGetVcpus(ctrl->def),
ctrl->def->mem.cur_balloon);
if (!nodeset)
goto cleanup;
@@ -241,6 +241,7 @@ virDomainXMLPrivateDataCallbacks virLXCDriverPrivateDataCallbacks = {
static int
virLXCDomainDefPostParse(virDomainDefPtr def,
virCapsPtr caps,
unsigned int parseFlags ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
/* check for emulator and create a default one if needed */
@@ -260,6 +261,7 @@ static int
virLXCDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
const virDomainDef *def ATTRIBUTE_UNUSED,
virCapsPtr caps ATTRIBUTE_UNUSED,
unsigned int parseFlags ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
if (dev->type == VIR_DOMAIN_DEVICE_CHR &&
@@ -617,7 +617,7 @@ static int lxcDomainGetInfo(virDomainPtr dom,
}

info->maxMem = virDomainDefGetMemoryActual(vm->def);
info->nrVirtCpu = vm->def->vcpus;
info->nrVirtCpu = virDomainDefGetVcpus(vm->def);
ret = 0;

cleanup:
@@ -1055,6 +1055,8 @@ static char *lxcConnectDomainXMLFromNative(virConnectPtr conn,
{
char *xml = NULL;
virDomainDefPtr def = NULL;
virLXCDriverPtr driver = conn->privateData;
virCapsPtr caps = virLXCDriverGetCapabilities(driver, false);

virCheckFlags(0, NULL);

@@ -1067,12 +1069,13 @@ static char *lxcConnectDomainXMLFromNative(virConnectPtr conn,
goto cleanup;
}

if (!(def = lxcParseConfigString(nativeConfig)))
if (!(def = lxcParseConfigString(nativeConfig, caps, driver->xmlopt)))
goto cleanup;

xml = virDomainDefFormat(def, 0);

cleanup:
virObjectUnref(caps);
virDomainDefFree(def);
return xml;
}
@@ -4,24 +4,7 @@
* the libvirt_lxc helper program.
*/

/* cygwin's xdr implementation defines xdr_u_int64_t instead of xdr_uint64_t
* and lacks IXDR_PUT_INT32 and IXDR_GET_INT32
*/
%#ifdef HAVE_XDR_U_INT64_T
%# define xdr_uint64_t xdr_u_int64_t
%#endif
%#ifndef IXDR_PUT_INT32
%# define IXDR_PUT_INT32 IXDR_PUT_LONG
%#endif
%#ifndef IXDR_GET_INT32
%# define IXDR_GET_INT32 IXDR_GET_LONG
%#endif
%#ifndef IXDR_PUT_U_INT32
%# define IXDR_PUT_U_INT32 IXDR_PUT_U_LONG
%#endif
%#ifndef IXDR_GET_U_INT32
%# define IXDR_GET_U_INT32 IXDR_GET_U_LONG
%#endif
%#include "virxdrdefs.h"

enum virLXCMonitorExitStatus {
VIR_LXC_MONITOR_EXIT_STATUS_ERROR,
@@ -991,7 +991,9 @@ lxcSetCapDrop(virDomainDefPtr def, virConfPtr properties)
}

virDomainDefPtr
lxcParseConfigString(const char *config)
lxcParseConfigString(const char *config,
virCapsPtr caps,
virDomainXMLOptionPtr xmlopt)
{
virDomainDefPtr vmdef = NULL;
virConfPtr properties = NULL;
@@ -1019,8 +1021,11 @@ lxcParseConfigString(const char *config)

/* Value not handled by the LXC driver, setting to
* minimum required to make XML parsing pass */
vmdef->maxvcpus = 1;
vmdef->vcpus = 1;
if (virDomainDefSetVcpusMax(vmdef, 1) < 0)
goto error;

if (virDomainDefSetVcpus(vmdef, 1) < 0)
goto error;

vmdef->nfss = 0;
vmdef->os.type = VIR_DOMAIN_OSTYPE_EXE;
@@ -1088,6 +1093,10 @@ lxcParseConfigString(const char *config)
/* lxc.cap.drop */
lxcSetCapDrop(vmdef, properties);

if (virDomainDefPostParse(vmdef, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
xmlopt) < 0)
goto cleanup;

goto cleanup;

error:
@@ -27,6 +27,8 @@

# define LXC_CONFIG_FORMAT "lxc-tools"

virDomainDefPtr lxcParseConfigString(const char *config);
virDomainDefPtr lxcParseConfigString(const char *config,
virCapsPtr caps,
virDomainXMLOptionPtr xmlopt);

#endif /* __LXC_NATIVE_H__ */
@@ -344,11 +344,12 @@ char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
net->ifname, &net->mac,
linkdev,
virDomainNetGetActualDirectMode(net),
false, def->uuid,
def->uuid,
prof,
&res_ifname,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
cfg->stateDir,
NULL, 0,
macvlan_create_flags) < 0)
goto cleanup;

@@ -33,6 +33,7 @@
#include "conf/domain_conf.h"
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>

#if HAVE_LINUX_KVM_H
# include <linux/kvm.h>
@@ -582,8 +582,11 @@ int openvzLoadDomains(struct openvz_driver *driver)
if (ret == 0 || vcpus == 0)
vcpus = openvzGetNodeCPUs();

def->maxvcpus = vcpus;
def->vcpus = vcpus;
if (virDomainDefSetVcpusMax(def, vcpus) < 0)
goto cleanup;

if (virDomainDefSetVcpus(def, vcpus) < 0)
goto cleanup;

/* XXX load rest of VM config data .... */

@@ -89,6 +89,7 @@ struct openvz_driver ovz_driver;
static int
openvzDomainDefPostParse(virDomainDefPtr def,
virCapsPtr caps ATTRIBUTE_UNUSED,
unsigned int parseFlags ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
/* fill the init path */
@@ -109,6 +110,7 @@ static int
openvzDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
const virDomainDef *def ATTRIBUTE_UNUSED,
virCapsPtr caps ATTRIBUTE_UNUSED,
unsigned int parseFlags ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
if (dev->type == VIR_DOMAIN_DEVICE_CHR &&
@@ -465,7 +467,7 @@ static int openvzDomainGetInfo(virDomainPtr dom,

info->maxMem = virDomainDefGetMemoryActual(vm->def);
info->memory = vm->def->mem.cur_balloon;
info->nrVirtCpu = vm->def->vcpus;
info->nrVirtCpu = virDomainDefGetVcpus(vm->def);
ret = 0;

cleanup:
@@ -1030,13 +1032,13 @@ openvzDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int fla
if (openvzDomainSetNetworkConfig(conn, vm->def) < 0)
goto cleanup;

if (vm->def->vcpus != vm->def->maxvcpus) {
if (virDomainDefHasVcpusOffline(vm->def)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("current vcpu count must equal maximum"));
goto cleanup;
}
if (vm->def->maxvcpus > 0) {
if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
if (virDomainDefGetVcpusMax(vm->def)) {
if (openvzDomainSetVcpusInternal(vm, virDomainDefGetVcpusMax(vm->def)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not set number of vCPUs"));
goto cleanup;
@@ -1133,8 +1135,8 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
vm->def->id = vm->pid;
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED);

if (vm->def->maxvcpus > 0) {
if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
if (virDomainDefGetVcpusMax(vm->def) > 0) {
if (openvzDomainSetVcpusInternal(vm, virDomainDefGetVcpusMax(vm->def)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not set number of vCPUs"));
goto cleanup;
@@ -1368,7 +1370,12 @@ static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
if (virRun(prog, NULL) < 0)
return -1;

vm->def->maxvcpus = vm->def->vcpus = nvcpus;
if (virDomainDefSetVcpusMax(vm->def, nvcpus) < 0)
return -1;

if (virDomainDefSetVcpus(vm->def, nvcpus) < 0)
return -1;

return 0;
}

@@ -1096,6 +1096,7 @@ openSSHSession(virConnectPtr conn, virConnectAuthPtr auth,
static int
phypDomainDefPostParse(virDomainDefPtr def,
virCapsPtr caps ATTRIBUTE_UNUSED,
unsigned int parseFlags ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
/* memory hotplug tunables are not supported by this driver */
@@ -1110,6 +1111,7 @@ static int
phypDomainDeviceDefPostParse(virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
const virDomainDef *def ATTRIBUTE_UNUSED,
virCapsPtr caps ATTRIBUTE_UNUSED,
unsigned int parseFlags ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
return 0;
@@ -3295,8 +3297,11 @@ phypDomainGetXMLDesc(virDomainPtr dom, unsigned int flags)
goto err;
}

def.maxvcpus = vcpus;
def.vcpus = vcpus;
if (virDomainDefSetVcpusMax(&def, vcpus) < 0)
goto err;

if (virDomainDefSetVcpus(&def, vcpus) < 0)
goto err;

return virDomainDefFormat(&def,
virDomainDefFormatConvertXMLFlags(flags));
@@ -3522,11 +3527,12 @@ phypBuildLpar(virConnectPtr conn, virDomainDefPtr def)
if (system_type == HMC)
virBufferAsprintf(&buf, " -m %s", managed_system);
virBufferAsprintf(&buf, " -r lpar -p %s -i min_mem=%lld,desired_mem=%lld,"
"max_mem=%lld,desired_procs=%d,virtual_scsi_adapters=%s",
"max_mem=%lld,desired_procs=%u,virtual_scsi_adapters=%s",
def->name, def->mem.cur_balloon,
def->mem.cur_balloon,
virDomainDefGetMemoryInitial(def),
(int) def->vcpus, virDomainDiskGetSource(def->disks[0]));
virDomainDefGetVcpus(def),
virDomainDiskGetSource(def->disks[0]));
ret = phypExecBuffer(session, &buf, &exit_status, conn, false);

if (exit_status < 0) {
@@ -710,7 +710,7 @@ qemuAgentIO(int watch, int fd, int events, void *opaque)

qemuAgentPtr
qemuAgentOpen(virDomainObjPtr vm,
virDomainChrSourceDefPtr config,
const virDomainChrSourceDef *config,
qemuAgentCallbacksPtr cb)
{
qemuAgentPtr mon;
@@ -1241,7 +1241,8 @@ void qemuAgentNotifyEvent(qemuAgentPtr mon,
}
} else {
/* shouldn't happen but one never knows */
VIR_WARN("Received unexpected event %d", event);
VIR_WARN("Received unexpected event %d (expected %d)",
event, mon->await_event);
}
}

@@ -44,7 +44,7 @@ struct _qemuAgentCallbacks {


qemuAgentPtr qemuAgentOpen(virDomainObjPtr vm,
virDomainChrSourceDefPtr config,
const virDomainChrSourceDef *config,
qemuAgentCallbacksPtr cb);

void qemuAgentClose(qemuAgentPtr mon);
@@ -1,7 +1,7 @@
/*
* qemu_capabilities.c: QEMU capabilities generation
*
* Copyright (C) 2006-2015 Red Hat, Inc.
* Copyright (C) 2006-2016 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -308,6 +308,12 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,

"virtio-tablet", /* 205 */
"virtio-input-host",
"chardev-file-append",
"ich9-disable-s3",
"ich9-disable-s4",

"vserport-change-event", /* 210 */
"virtio-balloon-pci.deflate-on-oom",
);


@@ -1479,6 +1485,7 @@ struct virQEMUCapsStringFlags virQEMUCapsEvents[] = {
{ "SPICE_MIGRATE_COMPLETED", QEMU_CAPS_SEAMLESS_MIGRATION },
{ "DEVICE_DELETED", QEMU_CAPS_DEVICE_DEL_EVENT },
{ "MIGRATION", QEMU_CAPS_MIGRATION_EVENT },
{ "VSERPORT_CHANGE", QEMU_CAPS_VSERPORT_CHANGE },
};

struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
@@ -1562,6 +1569,10 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "virtio-input-host-pci", QEMU_CAPS_VIRTIO_INPUT_HOST },
};

static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBalloon[] = {
{ "deflate-on-oom", QEMU_CAPS_VIRTIO_BALLOON_AUTODEFLATE },
};

static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = {
{ "multifunction", QEMU_CAPS_PCI_MULTIFUNCTION },
{ "bootindex", QEMU_CAPS_BOOTINDEX },
@@ -1595,9 +1606,9 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsIDEDrive[] = {
{ "wwn", QEMU_CAPS_IDE_DRIVE_WWN },
};

static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsPixx4PM[] = {
{ "disable_s3", QEMU_CAPS_DISABLE_S3 },
{ "disable_s4", QEMU_CAPS_DISABLE_S4 },
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsPiix4PM[] = {
{ "disable_s3", QEMU_CAPS_PIIX_DISABLE_S3 },
{ "disable_s4", QEMU_CAPS_PIIX_DISABLE_S4 },
};

static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsUSBRedir[] = {
@@ -1649,6 +1660,11 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioGpu[] = {
{ "virgl", QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL },
};

static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsICH9[] = {
{ "disable_s3", QEMU_CAPS_ICH9_DISABLE_S3 },
{ "disable_s4", QEMU_CAPS_ICH9_DISABLE_S4 },
};

struct virQEMUCapsObjectTypeProps {
const char *type;
struct virQEMUCapsStringFlags *props;
@@ -1678,8 +1694,8 @@ static struct virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = {
ARRAY_CARDINALITY(virQEMUCapsObjectPropsSCSIDisk) },
{ "ide-drive", virQEMUCapsObjectPropsIDEDrive,
ARRAY_CARDINALITY(virQEMUCapsObjectPropsIDEDrive) },
{ "PIIX4_PM", virQEMUCapsObjectPropsPixx4PM,
ARRAY_CARDINALITY(virQEMUCapsObjectPropsPixx4PM) },
{ "PIIX4_PM", virQEMUCapsObjectPropsPiix4PM,
ARRAY_CARDINALITY(virQEMUCapsObjectPropsPiix4PM) },
{ "usb-redir", virQEMUCapsObjectPropsUSBRedir,
ARRAY_CARDINALITY(virQEMUCapsObjectPropsUSBRedir) },
{ "usb-host", virQEMUCapsObjectPropsUSBHost,
@@ -1704,6 +1720,14 @@ static struct virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = {
ARRAY_CARDINALITY(virQEMUCapsObjectPropsQxlVga) },
{ "virtio-gpu-pci", virQEMUCapsObjectPropsVirtioGpu,
ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioGpu) },
{ "ICH9-LPC", virQEMUCapsObjectPropsICH9,
ARRAY_CARDINALITY(virQEMUCapsObjectPropsICH9) },
{ "virtio-balloon-pci", virQEMUCapsObjectPropsVirtioBalloon,
ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBalloon) },
{ "virtio-balloon-ccw", virQEMUCapsObjectPropsVirtioBalloon,
ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBalloon) },
{ "virtio-balloon-device", virQEMUCapsObjectPropsVirtioBalloon,
ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBalloon) },
};


@@ -2600,6 +2624,7 @@ static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = {
{ "drive", "throttling.bps-total-max", QEMU_CAPS_DRIVE_IOTUNE_MAX},
{ "machine", "aes-key-wrap", QEMU_CAPS_AES_KEY_WRAP },
{ "machine", "dea-key-wrap", QEMU_CAPS_DEA_KEY_WRAP },
{ "chardev", "append", QEMU_CAPS_CHARDEV_FILE_APPEND },
};

static int
@@ -1,7 +1,7 @@
/*
* qemu_capabilities.h: QEMU capabilities generation
*
* Copyright (C) 2006-2015 Red Hat, Inc.
* Copyright (C) 2006-2016 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -190,10 +190,10 @@ typedef enum {
QEMU_CAPS_SCSI_LSI, /* -device lsi */
QEMU_CAPS_VIRTIO_SCSI, /* -device virtio-scsi-* */
QEMU_CAPS_BLOCKIO, /* -device ...logical_block_size & co */
QEMU_CAPS_DISABLE_S3, /* S3 BIOS Advertisement on/off */
QEMU_CAPS_PIIX_DISABLE_S3, /* -M pc S3 BIOS Advertisement on/off */

/* 105 */
QEMU_CAPS_DISABLE_S4, /* S4 BIOS Advertisement on/off */
QEMU_CAPS_PIIX_DISABLE_S4, /* -M pc S4 BIOS Advertisement on/off */
QEMU_CAPS_USB_REDIR_FILTER, /* usb-redir.filter */
QEMU_CAPS_IDE_DRIVE_WWN, /* Is ide-drive.wwn available? */
QEMU_CAPS_SCSI_DISK_WWN, /* Is scsi-disk.wwn available? */
@@ -335,6 +335,14 @@ typedef enum {
/* 205 */
QEMU_CAPS_VIRTIO_TABLET, /* -device virtio-tablet-{device,pci} */
QEMU_CAPS_VIRTIO_INPUT_HOST, /* -device virtio-input-host-{device,pci} */
QEMU_CAPS_CHARDEV_FILE_APPEND, /* -chardev file,append=on|off */
QEMU_CAPS_ICH9_DISABLE_S3, /* -M q35 S3 BIOS Advertisement on/off */
QEMU_CAPS_ICH9_DISABLE_S4, /* -M q35 S4 BIOS Advertisement on/off */

/* 210 */
QEMU_CAPS_VSERPORT_CHANGE, /* VSERPORT_CHANGE event */
QEMU_CAPS_VIRTIO_BALLOON_AUTODEFLATE, /* virtio-balloon-{device,pci,ccw}.
* deflate-on-oom */

QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
@@ -820,7 +820,12 @@ qemuRestoreCgroupState(virDomainObjPtr vm)
if (virCgroupSetCpusetMems(priv->cgroup, mem_mask) < 0)
goto error;

for (i = 0; i < priv->nvcpupids; i++) {
for (i = 0; i < virDomainDefGetVcpusMax(vm->def); i++) {
virDomainVcpuInfoPtr vcpu = virDomainDefGetVcpu(vm->def, i);

if (!vcpu->online)
continue;

if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_VCPU, i,
false, &cgroup_temp) < 0 ||
virCgroupSetCpusetMemoryMigrate(cgroup_temp, true) < 0 ||
@@ -1018,24 +1023,16 @@ qemuSetupCgroupForVcpu(virDomainObjPtr vm)
/*
* If CPU cgroup controller is not initialized here, then we need
* neither period nor quota settings. And if CPUSET controller is
* not initialized either, then there's nothing to do anyway.
* not initialized either, then there's nothing to do anyway. CPU pinning
* will be set via virProcessSetAffinity.
*/
if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU) &&
!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
return 0;

/* We are trying to setup cgroups for CPU pinning, which can also be done
* with virProcessSetAffinity, thus the lack of cgroups is not fatal here.
*/
if (priv->cgroup == NULL)
return 0;

if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
/* If we don't know VCPU<->PID mapping or all vcpu runs in the same
* thread, we cannot control each vcpu.
*/
/* If vCPU<->pid mapping is missing we can't do vCPU pinning */
if (!qemuDomainHasVcpuPids(vm))
return 0;
}

if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
@@ -1044,16 +1041,17 @@ qemuSetupCgroupForVcpu(virDomainObjPtr vm)
&mem_mask, -1) < 0)
goto cleanup;

for (i = 0; i < priv->nvcpupids; i++) {
for (i = 0; i < virDomainDefGetVcpusMax(def); i++) {
virDomainVcpuInfoPtr vcpu = virDomainDefGetVcpu(def, i);

if (!vcpu->online)
continue;

virCgroupFree(&cgroup_vcpu);
if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_VCPU, i,
true, &cgroup_vcpu) < 0)
goto cleanup;

/* move the thread for vcpu to sub dir */
if (virCgroupAddTask(cgroup_vcpu, priv->vcpupids[i]) < 0)
goto cleanup;

if (period || quota) {
if (qemuSetupCgroupVcpuBW(cgroup_vcpu, period, quota) < 0)
goto cleanup;
@@ -1081,12 +1079,15 @@ qemuSetupCgroupForVcpu(virDomainObjPtr vm)
}
}

if (!cpumap)
continue;

if (qemuSetupCgroupCpusetCpus(cgroup_vcpu, cpumap) < 0)
if (cpumap && qemuSetupCgroupCpusetCpus(cgroup_vcpu, cpumap) < 0)
goto cleanup;
}

/* move the thread for vcpu to sub dir */
if (virCgroupAddTask(cgroup_vcpu,
qemuDomainGetVcpuPid(vm, i)) < 0)
goto cleanup;

}
virCgroupFree(&cgroup_vcpu);
VIR_FREE(mem_mask);
@@ -1129,9 +1130,6 @@ qemuSetupCgroupForEmulator(virDomainObjPtr vm)
!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
return 0;

if (priv->cgroup == NULL)
return 0; /* Not supported, so claim success */

if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_EMULATOR, 0,
true, &cgroup_emulator) < 0)
goto cleanup;
@@ -1202,12 +1200,6 @@ qemuSetupCgroupForIOThreads(virDomainObjPtr vm)
!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
return 0;

/* We are trying to setup cgroups for CPU pinning, which can also be done
* with virProcessSetAffinity, thus the lack of cgroups is not fatal here.
*/
if (priv->cgroup == NULL)
return 0;

if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
virDomainNumatuneMaybeFormatNodeset(vm->def->numa,
@@ -1224,11 +1216,6 @@ qemuSetupCgroupForIOThreads(virDomainObjPtr vm)
true, &cgroup_iothread) < 0)
goto cleanup;

/* move the thread for iothread to sub dir */
if (virCgroupAddTask(cgroup_iothread,
def->iothreadids[i]->thread_id) < 0)
goto cleanup;

if (period || quota) {
if (qemuSetupCgroupVcpuBW(cgroup_iothread, period, quota) < 0)
goto cleanup;
@@ -1255,6 +1242,11 @@ qemuSetupCgroupForIOThreads(virDomainObjPtr vm)
goto cleanup;
}

/* move the thread for iothread to sub dir */
if (virCgroupAddTask(cgroup_iothread,
def->iothreadids[i]->thread_id) < 0)
goto cleanup;

virCgroupFree(&cgroup_iothread);
}
VIR_FREE(mem_mask);

Large diffs are not rendered by default.

@@ -180,6 +180,7 @@ char *qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev,
/* Current, best practice */
char *qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
virDomainHostdevDefPtr dev,
int bootIndex,
const char *configfd,
virQEMUCapsPtr qemuCaps);

@@ -232,6 +233,8 @@ int qemuNetworkIfaceConnect(virDomainDefPtr def,
int qemuPhysIfaceConnect(virDomainDefPtr def,
virQEMUDriverPtr driver,
virDomainNetDefPtr net,
int *tapfd,
size_t tapfdSize,
virNetDevVPortProfileOp vmop);

int qemuOpenVhostNet(virDomainDefPtr def,
@@ -24,6 +24,8 @@
#ifndef __QEMUD_CONF_H
# define __QEMUD_CONF_H

# include <unistd.h>

# include "virebtables.h"
# include "internal.h"
# include "capabilities.h"

Large diffs are not rendered by default.

@@ -116,7 +116,7 @@ struct _qemuDomainJobInfo {
destination. */
bool timeDeltaSet;
/* Raw values from QEMU */
qemuMonitorMigrationStatus status;
qemuMonitorMigrationStats stats;
};

struct qemuDomainJobObj {
@@ -298,6 +298,7 @@ int qemuDomainObjEnterMonitorAsync(virQEMUDriverPtr driver,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;


qemuAgentPtr qemuDomainGetAgent(virDomainObjPtr vm);
void qemuDomainObjEnterAgent(virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1);
void qemuDomainObjExitAgent(virDomainObjPtr obj)
@@ -486,7 +487,7 @@ int qemuDomainAlignMemorySizes(virDomainDefPtr def);
void qemuDomainMemoryDeviceAlignSize(virDomainDefPtr def,
virDomainMemoryDefPtr mem);

virDomainChrSourceDefPtr qemuFindAgentConfig(virDomainDefPtr def);
virDomainChrDefPtr qemuFindAgentConfig(virDomainDefPtr def);

bool qemuDomainMachineIsQ35(const virDomainDef *def);
bool qemuDomainMachineIsI440FX(const virDomainDef *def);
@@ -497,11 +498,15 @@ bool qemuDomainMachineHasBuiltinIDE(const virDomainDef *def);
int qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
virDomainObjPtr vm);

unsigned long long qemuDomainGetMlockLimitBytes(virDomainDefPtr def);
bool qemuDomainRequiresMlock(virDomainDefPtr def);
unsigned long long qemuDomainGetMemLockLimitBytes(virDomainDefPtr def);
bool qemuDomainRequiresMemLock(virDomainDefPtr def);
int qemuDomainAdjustMaxMemLock(virDomainObjPtr vm);

int qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
virQEMUCapsPtr qemuCaps,
const virDomainMemoryDef *mem);

bool qemuDomainHasVcpuPids(virDomainObjPtr vm);
pid_t qemuDomainGetVcpuPid(virDomainObjPtr vm, unsigned int vcpu);

#endif /* __QEMU_DOMAIN_H__ */

Large diffs are not rendered by default.

@@ -442,7 +442,13 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
char *devstr = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
bool releaseaddr = false;
bool addedToAddrSet = false;

if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("'%s' controller cannot be hot plugged."),
virDomainControllerTypeToString(controller->type));
return -1;
}

if (virDomainControllerFind(vm->def, controller->type, controller->idx) >= 0) {
virReportError(VIR_ERR_OPERATION_FAILED,
@@ -477,20 +483,6 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
if (qemuAssignDeviceControllerAlias(vm->def, priv->qemuCaps, controller) < 0)
goto cleanup;

if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
controller->model == -1 &&
!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("USB controller hotplug unsupported in this QEMU binary"));
goto cleanup;
}

if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL &&
virDomainVirtioSerialAddrSetAddController(priv->vioserialaddrs,
controller) < 0)
goto cleanup;
addedToAddrSet = true;

if (!(devstr = qemuBuildControllerDevStr(vm->def, controller, priv->qemuCaps, NULL)))
goto cleanup;
}
@@ -519,9 +511,6 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
}

cleanup:
if (ret != 0 && addedToAddrSet)
virDomainVirtioSerialAddrSetRemoveController(priv->vioserialaddrs,
controller);
if (ret != 0 && releaseaddr)
qemuDomainReleaseDeviceAddress(vm, &controller->info, NULL);

@@ -951,15 +940,17 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
goto cleanup;
} else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
tapfdSize = vhostfdSize = 1;
if (VIR_ALLOC(tapfd) < 0)
tapfdSize = vhostfdSize = net->driver.virtio.queues;
if (!tapfdSize)
tapfdSize = vhostfdSize = 1;
if (VIR_ALLOC_N(tapfd, tapfdSize) < 0)
goto cleanup;
*tapfd = -1;
if (VIR_ALLOC(vhostfd) < 0)
memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
if (VIR_ALLOC_N(vhostfd, vhostfdSize) < 0)
goto cleanup;
*vhostfd = -1;
if ((tapfd[0] = qemuPhysIfaceConnect(vm->def, driver, net,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0)
memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
if (qemuPhysIfaceConnect(vm->def, driver, net, tapfd, tapfdSize,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE) < 0)
goto cleanup;
iface_connected = true;
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
@@ -1280,17 +1271,14 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
}

/* Temporarily add the hostdev to the domain definition. This is needed
* because qemuDomainRequiresMlock() and qemuDomainGetMlockLimitBytes()
* require the hostdev to be already part of the domain definition, but
* other functions like qemuAssignDeviceHostdevAlias() used below expect
* it *not* to be there. A better way to handle this would be nice */
* because qemuDomainAdjustMaxMemLock() requires the hostdev to be already
* part of the domain definition, but other functions like
* qemuAssignDeviceHostdevAlias() used below expect it *not* to be there.
* A better way to handle this would be nice */
vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
if (qemuDomainRequiresMlock(vm->def)) {
if (virProcessSetMaxMemLock(vm->pid,
qemuDomainGetMlockLimitBytes(vm->def)) < 0) {
vm->def->hostdevs[--(vm->def->nhostdevs)] = NULL;
goto error;
}
if (qemuDomainAdjustMaxMemLock(vm) < 0) {
vm->def->hostdevs[--(vm->def->nhostdevs)] = NULL;
goto error;
}
vm->def->hostdevs[--(vm->def->nhostdevs)] = NULL;

@@ -1325,8 +1313,8 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
goto error;
}

if (!(devstr = qemuBuildPCIHostdevDevStr(vm->def, hostdev, configfd_name,
priv->qemuCaps)))
if (!(devstr = qemuBuildPCIHostdevDevStr(vm->def, hostdev, 0,
configfd_name, priv->qemuCaps)))
goto error;

qemuDomainObjEnterMonitor(driver, vm);
@@ -1776,7 +1764,6 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
virJSONValuePtr props = NULL;
virObjectEventPtr event;
bool fix_balloon = false;
bool mlock = false;
int id;
int ret = -1;

@@ -1808,12 +1795,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
goto cleanup;
}

mlock = qemuDomainRequiresMlock(vm->def);

if (mlock &&
virProcessSetMaxMemLock(vm->pid,
qemuDomainGetMlockLimitBytes(vm->def)) < 0) {
mlock = false;
if (qemuDomainAdjustMaxMemLock(vm) < 0) {
virJSONValueFree(props);
goto removedef;
}
@@ -1874,13 +1856,10 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
mem = NULL;

/* reset the mlock limit */
if (mlock) {
virErrorPtr err = virSaveLastError();
ignore_value(virProcessSetMaxMemLock(vm->pid,
qemuDomainGetMlockLimitBytes(vm->def)));
virSetError(err);
virFreeError(err);
}
virErrorPtr err = virSaveLastError();
ignore_value(qemuDomainAdjustMaxMemLock(vm));
virSetError(err);
virFreeError(err);

goto audit;
}
@@ -2974,9 +2953,7 @@ qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver,
virDomainMemoryDefFree(mem);

/* decrease the mlock limit after memory unplug if necessary */
if (qemuDomainRequiresMlock(vm->def))
ignore_value(virProcessSetMaxMemLock(vm->pid,
qemuDomainGetMlockLimitBytes(vm->def)));
ignore_value(qemuDomainAdjustMaxMemLock(vm));

return 0;
}
@@ -3063,6 +3040,10 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
switch ((virDomainHostdevSubsysType) hostdev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
qemuDomainRemovePCIHostDevice(driver, vm, hostdev);
/* QEMU might no longer need to lock as much memory, eg. we just
* detached the last VFIO device, so adjust the limit here */
if (qemuDomainAdjustMaxMemLock(vm) < 0)
VIR_WARN("Failed to adjust locked memory limit");
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
qemuDomainRemoveUSBHostDevice(driver, vm, hostdev);
@@ -3088,6 +3069,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
networkReleaseActualDevice(vm->def, net);
virDomainNetDefFree(net);
}

ret = 0;

cleanup:

Large diffs are not rendered by default.

@@ -160,8 +160,10 @@ VIR_ONCE_GLOBAL_INIT(qemuMonitor)

VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
QEMU_MONITOR_MIGRATION_STATUS_LAST,
"inactive", "active", "completed", "failed", "cancelling",
"cancelled", "setup")
"inactive", "setup",
"active",
"completed", "failed",
"cancelling", "cancelled")

VIR_ENUM_IMPL(qemuMonitorMigrationCaps,
QEMU_MONITOR_MIGRATION_CAPS_LAST,
@@ -1955,6 +1957,9 @@ qemuMonitorSetBalloon(qemuMonitorPtr mon,
}


/*
* Returns: 0 if CPU modification was successful or -1 on failure
*/
int
qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, bool online)
{
@@ -2098,15 +2103,15 @@ qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon,


int
qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
qemuMonitorMigrationStatusPtr status)
qemuMonitorGetMigrationStats(qemuMonitorPtr mon,
qemuMonitorMigrationStatsPtr stats)
{
QEMU_CHECK_MONITOR(mon);

if (mon->json)
return qemuMonitorJSONGetMigrationStatus(mon, status);
return qemuMonitorJSONGetMigrationStats(mon, stats);
else
return qemuMonitorTextGetMigrationStatus(mon, status);
return qemuMonitorTextGetMigrationStats(mon, stats);
}


@@ -455,24 +455,24 @@ int qemuMonitorGetMigrationCacheSize(qemuMonitorPtr mon,
int qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon,
unsigned long long cacheSize);

enum {
typedef enum {
QEMU_MONITOR_MIGRATION_STATUS_INACTIVE,
QEMU_MONITOR_MIGRATION_STATUS_SETUP,
QEMU_MONITOR_MIGRATION_STATUS_ACTIVE,
QEMU_MONITOR_MIGRATION_STATUS_COMPLETED,
QEMU_MONITOR_MIGRATION_STATUS_ERROR,
QEMU_MONITOR_MIGRATION_STATUS_CANCELLING,
QEMU_MONITOR_MIGRATION_STATUS_CANCELLED,
QEMU_MONITOR_MIGRATION_STATUS_SETUP,

QEMU_MONITOR_MIGRATION_STATUS_LAST
};
} qemuMonitorMigrationStatus;

VIR_ENUM_DECL(qemuMonitorMigrationStatus)

typedef struct _qemuMonitorMigrationStatus qemuMonitorMigrationStatus;
typedef qemuMonitorMigrationStatus *qemuMonitorMigrationStatusPtr;
struct _qemuMonitorMigrationStatus {
int status;
typedef struct _qemuMonitorMigrationStats qemuMonitorMigrationStats;
typedef qemuMonitorMigrationStats *qemuMonitorMigrationStatsPtr;
struct _qemuMonitorMigrationStats {
int status; /* qemuMonitorMigrationStatus */
unsigned long long total_time;
/* total or expected depending on status */
bool downtime_set;
@@ -493,6 +493,8 @@ struct _qemuMonitorMigrationStatus {
unsigned long long ram_duplicate;
unsigned long long ram_normal;
unsigned long long ram_normal_bytes;
unsigned long long ram_dirty_rate;
unsigned long long ram_iteration;

unsigned long long disk_transferred;
unsigned long long disk_remaining;
@@ -507,8 +509,8 @@ struct _qemuMonitorMigrationStatus {
unsigned long long xbzrle_overflow;
};

int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
qemuMonitorMigrationStatusPtr status);
int qemuMonitorGetMigrationStats(qemuMonitorPtr mon,
qemuMonitorMigrationStatsPtr stats);

typedef enum {
QEMU_MONITOR_MIGRATION_CAPS_XBZRLE,
@@ -2158,10 +2158,6 @@ qemuMonitorJSONSetBalloon(qemuMonitorPtr mon,
}


/*
* Returns: 0 if CPU hotplug not supported, +1 if CPU hotplug worked
* or -1 on failure
*/
int qemuMonitorJSONSetCPU(qemuMonitorPtr mon,
int cpu, bool online)
{
@@ -2188,10 +2184,6 @@ int qemuMonitorJSONSetCPU(qemuMonitorPtr mon,
else
ret = qemuMonitorJSONCheckError(cmd, reply);

/* this function has non-standard return values, so adapt it */
if (ret == 0)
ret = 1;

cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
@@ -2230,10 +2222,14 @@ int qemuMonitorJSONEjectMedia(qemuMonitorPtr mon,
if (ret == 0)
ret = qemuMonitorJSONCheckError(cmd, reply);

VIR_DEBUG("%s", virJSONValueToString(reply, false));

if (ret < 0 && c_strcasestr(virJSONValueToString(reply, false), "is locked"))
ret = -2;
if (ret < 0) {
virJSONValuePtr error = virJSONValueObjectGet(reply, "error");
if (error) {
const char *errorStr = virJSONValueObjectGetString(error, "desc");
if (errorStr && c_strcasestr(errorStr, "is locked"))
ret = -2;
}
}

virJSONValueFree(cmd);
virJSONValueFree(reply);
@@ -2425,10 +2421,13 @@ qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon,


static int
qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
qemuMonitorMigrationStatusPtr status)
qemuMonitorJSONGetMigrationStatsReply(virJSONValuePtr reply,
qemuMonitorMigrationStatsPtr stats)
{
virJSONValuePtr ret;
virJSONValuePtr ram;
virJSONValuePtr disk;
virJSONValuePtr comp;
const char *statusstr;
int rc;
double mbps;
@@ -2445,55 +2444,63 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
return -1;
}

status->status = qemuMonitorMigrationStatusTypeFromString(statusstr);
if (status->status < 0) {
stats->status = qemuMonitorMigrationStatusTypeFromString(statusstr);
if (stats->status < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected migration status in %s"), statusstr);
return -1;
}

ignore_value(virJSONValueObjectGetNumberUlong(ret, "total-time",
&status->total_time));
if (status->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
&stats->total_time));
if (stats->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
rc = virJSONValueObjectGetNumberUlong(ret, "downtime",
&status->downtime);
&stats->downtime);
} else {
rc = virJSONValueObjectGetNumberUlong(ret, "expected-downtime",
&status->downtime);
&stats->downtime);
}
if (rc == 0)
status->downtime_set = true;
stats->downtime_set = true;

if (virJSONValueObjectGetNumberUlong(ret, "setup-time",
&status->setup_time) == 0)
status->setup_time_set = true;
&stats->setup_time) == 0)
stats->setup_time_set = true;

switch ((qemuMonitorMigrationStatus) stats->status) {
case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
case QEMU_MONITOR_MIGRATION_STATUS_SETUP:
case QEMU_MONITOR_MIGRATION_STATUS_ERROR:
case QEMU_MONITOR_MIGRATION_STATUS_CANCELLED:
case QEMU_MONITOR_MIGRATION_STATUS_LAST:
break;

if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE ||
status->status == QEMU_MONITOR_MIGRATION_STATUS_CANCELLING ||
status->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
virJSONValuePtr ram = virJSONValueObjectGetObject(ret, "ram");
case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED:
case QEMU_MONITOR_MIGRATION_STATUS_CANCELLING:
ram = virJSONValueObjectGetObject(ret, "ram");
if (!ram) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("migration was active, but no RAM info was set"));
return -1;
}

if (virJSONValueObjectGetNumberUlong(ram, "transferred",
&status->ram_transferred) < 0) {
&stats->ram_transferred) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("migration was active, but RAM 'transferred' "
"data was missing"));
return -1;
}
if (virJSONValueObjectGetNumberUlong(ram, "remaining",
&status->ram_remaining) < 0) {
&stats->ram_remaining) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("migration was active, but RAM 'remaining' "
"data was missing"));
return -1;
}
if (virJSONValueObjectGetNumberUlong(ram, "total",
&status->ram_total) < 0) {
&stats->ram_total) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("migration was active, but RAM 'total' "
"data was missing"));
@@ -2503,21 +2510,25 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
if (virJSONValueObjectGetNumberDouble(ram, "mbps", &mbps) == 0 &&
mbps > 0) {
/* mpbs from QEMU reports Mbits/s (M as in 10^6 not Mi as 2^20) */
status->ram_bps = mbps * (1000 * 1000 / 8);
stats->ram_bps = mbps * (1000 * 1000 / 8);
}

if (virJSONValueObjectGetNumberUlong(ram, "duplicate",
&status->ram_duplicate) == 0)
status->ram_duplicate_set = true;
&stats->ram_duplicate) == 0)
stats->ram_duplicate_set = true;
ignore_value(virJSONValueObjectGetNumberUlong(ram, "normal",
&status->ram_normal));
&stats->ram_normal));
ignore_value(virJSONValueObjectGetNumberUlong(ram, "normal-bytes",
&status->ram_normal_bytes));
&stats->ram_normal_bytes));
ignore_value(virJSONValueObjectGetNumberUlong(ram, "dirty-pages-rate",
&stats->ram_dirty_rate));
ignore_value(virJSONValueObjectGetNumberUlong(ram, "dirty-sync-count",
&stats->ram_iteration));

virJSONValuePtr disk = virJSONValueObjectGetObject(ret, "disk");
disk = virJSONValueObjectGetObject(ret, "disk");
if (disk) {
rc = virJSONValueObjectGetNumberUlong(disk, "transferred",
&status->disk_transferred);
&stats->disk_transferred);
if (rc < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("disk migration was active, but "
@@ -2526,7 +2537,7 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
}

rc = virJSONValueObjectGetNumberUlong(disk, "remaining",
&status->disk_remaining);
&stats->disk_remaining);
if (rc < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("disk migration was active, but 'remaining' "
@@ -2535,7 +2546,7 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
}

rc = virJSONValueObjectGetNumberUlong(disk, "total",
&status->disk_total);
&stats->disk_total);
if (rc < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("disk migration was active, but 'total' "
@@ -2546,15 +2557,15 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
if (virJSONValueObjectGetNumberDouble(disk, "mbps", &mbps) == 0 &&
mbps > 0) {
/* mpbs from QEMU reports Mbits/s (M as in 10^6 not Mi as 2^20) */
status->disk_bps = mbps * (1000 * 1000 / 8);
stats->disk_bps = mbps * (1000 * 1000 / 8);
}
}

virJSONValuePtr comp = virJSONValueObjectGetObject(ret, "xbzrle-cache");
comp = virJSONValueObjectGetObject(ret, "xbzrle-cache");
if (comp) {
status->xbzrle_set = true;
stats->xbzrle_set = true;
rc = virJSONValueObjectGetNumberUlong(comp, "cache-size",
&status->xbzrle_cache_size);
&stats->xbzrle_cache_size);
if (rc < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("XBZRLE is active, but 'cache-size' data "
@@ -2563,7 +2574,7 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
}

rc = virJSONValueObjectGetNumberUlong(comp, "bytes",
&status->xbzrle_bytes);
&stats->xbzrle_bytes);
if (rc < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("XBZRLE is active, but 'bytes' data "
@@ -2572,7 +2583,7 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
}

rc = virJSONValueObjectGetNumberUlong(comp, "pages",
&status->xbzrle_pages);
&stats->xbzrle_pages);
if (rc < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("XBZRLE is active, but 'pages' data "
@@ -2581,7 +2592,7 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
}

rc = virJSONValueObjectGetNumberUlong(comp, "cache-miss",
&status->xbzrle_cache_miss);
&stats->xbzrle_cache_miss);
if (rc < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("XBZRLE is active, but 'cache-miss' data "
@@ -2590,29 +2601,30 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
}

rc = virJSONValueObjectGetNumberUlong(comp, "overflow",
&status->xbzrle_overflow);
&stats->xbzrle_overflow);
if (rc < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("XBZRLE is active, but 'overflow' data "
"was missing"));
return -1;
}
}
break;
}

return 0;
}


int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
qemuMonitorMigrationStatusPtr status)
int qemuMonitorJSONGetMigrationStats(qemuMonitorPtr mon,
qemuMonitorMigrationStatsPtr stats)
{
int ret;
virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-migrate",
NULL);
virJSONValuePtr reply = NULL;

memset(status, 0, sizeof(*status));
memset(stats, 0, sizeof(*stats));

if (!cmd)
return -1;
@@ -2623,11 +2635,11 @@ int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
ret = qemuMonitorJSONCheckError(cmd, reply);

if (ret == 0 &&
qemuMonitorJSONGetMigrationStatusReply(reply, status) < 0)
qemuMonitorJSONGetMigrationStatsReply(reply, stats) < 0)
ret = -1;

if (ret < 0)
memset(status, 0, sizeof(*status));
memset(stats, 0, sizeof(*stats));
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
@@ -123,8 +123,8 @@ int qemuMonitorJSONGetMigrationCacheSize(qemuMonitorPtr mon,
int qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon,
unsigned long long cacheSize);

int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
qemuMonitorMigrationStatusPtr status);
int qemuMonitorJSONGetMigrationStats(qemuMonitorPtr mon,
qemuMonitorMigrationStatsPtr stats);

int qemuMonitorJSONGetMigrationCapabilities(qemuMonitorPtr mon,
char ***capabilities);