diff options
author | Guido Günther <agx@sigxcpu.org> | 2015-05-29 17:22:23 +0200 |
---|---|---|
committer | Guido Günther <agx@sigxcpu.org> | 2015-05-29 17:22:23 +0200 |
commit | 540f826c5fa4eb2f63cea3fd285ccbd637319af6 (patch) | |
tree | 91b8508970eb48c77dff67abe65933ee866bb2a1 /src | |
parent | 29c488b31a84790fb6590beb36de3d7d30a2bc0f (diff) |
New upstream version 1.2.16~rc2
Diffstat (limited to 'src')
-rw-r--r-- | src/conf/interface_conf.c | 29 | ||||
-rw-r--r-- | src/libvirt-domain.c | 38 | ||||
-rw-r--r-- | src/libvirt-host.c | 6 | ||||
-rw-r--r-- | src/libvirt-interface.c | 6 | ||||
-rw-r--r-- | src/libvirt-network.c | 6 | ||||
-rw-r--r-- | src/libvirt-nodedev.c | 10 | ||||
-rw-r--r-- | src/libvirt-nwfilter.c | 6 | ||||
-rw-r--r-- | src/libvirt-secret.c | 4 | ||||
-rw-r--r-- | src/libvirt-storage.c | 16 | ||||
-rw-r--r-- | src/libxl/libxl_conf.c | 153 | ||||
-rw-r--r-- | src/libxl/libxl_conf.h | 2 | ||||
-rw-r--r-- | src/libxl/libxl_domain.c | 8 | ||||
-rw-r--r-- | src/libxl/libxl_driver.c | 4 | ||||
-rw-r--r-- | src/node_device/node_device_driver.c | 14 | ||||
-rw-r--r-- | src/nodeinfo.c | 30 | ||||
-rw-r--r-- | src/parallels/parallels_sdk.c | 3 | ||||
-rw-r--r-- | src/qemu/qemu_driver.c | 29 | ||||
-rw-r--r-- | src/storage/storage_backend_disk.c | 7 | ||||
-rw-r--r-- | src/storage/storage_backend_fs.c | 2 | ||||
-rw-r--r-- | src/storage/storage_driver.c | 65 | ||||
-rw-r--r-- | src/test/test_driver.c | 8 | ||||
-rw-r--r-- | src/util/vireventpoll.c | 5 |
22 files changed, 282 insertions, 169 deletions
diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c index c2eb94535..26e55cc4f 100644 --- a/src/conf/interface_conf.c +++ b/src/conf/interface_conf.c @@ -1,7 +1,7 @@ /* * interface_conf.c: interfaces XML handling * - * Copyright (C) 2006-2010, 2013, 2014 Red Hat, Inc. + * Copyright (C) 2006-2010, 2013-2015 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -548,39 +548,34 @@ virInterfaceDefParseBondItfs(virInterfaceDefPtr def, virInterfaceDefPtr itf; int nbItf; size_t i; - int ret = 0; + int ret = -1; nbItf = virXPathNodeSet("./interface", ctxt, &interfaces); - if (nbItf < 0) { - ret = -1; - goto error; - } + if (nbItf < 0) + goto cleanup; if (nbItf == 0) { - virReportError(VIR_ERR_XML_ERROR, - "%s", _("bond has no interfaces")); - ret = -1; - goto error; + ret = 0; + goto cleanup; } - if (VIR_ALLOC_N(def->data.bond.itf, nbItf) < 0) { - ret = -1; - goto error; - } + if (VIR_ALLOC_N(def->data.bond.itf, nbItf) < 0) + goto cleanup; + def->data.bond.nbItf = nbItf; for (i = 0; i < nbItf; i++) { ctxt->node = interfaces[i]; itf = virInterfaceDefParseXML(ctxt, VIR_INTERFACE_TYPE_BOND); if (itf == NULL) { - ret = -1; def->data.bond.nbItf = i; - goto error; + goto cleanup; } def->data.bond.itf[i] = itf; } - error: + ret = 0; + cleanup: VIR_FREE(interfaces); ctxt->node = bond; return ret; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 2edba1a5a..c40826def 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -167,7 +167,7 @@ virDomainPtr virDomainCreateXML(virConnectPtr conn, const char *xmlDesc, unsigned int flags) { - VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags); + VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, NULLSTR(xmlDesc), flags); virResetLastError(); @@ -235,7 +235,7 @@ virDomainCreateXMLWithFiles(virConnectPtr conn, const char *xmlDesc, unsigned int flags) { VIR_DEBUG("conn=%p, xmlDesc=%s, nfiles=%u, files=%p, flags=%x", - conn, xmlDesc, nfiles, files, flags); + conn, NULLSTR(xmlDesc), nfiles, files, flags); virResetLastError(); @@ -413,7 +413,7 @@ virDomainLookupByUUIDString(virConnectPtr conn, const char *uuidstr) virDomainPtr virDomainLookupByName(virConnectPtr conn, const char *name) { - VIR_DEBUG("conn=%p, name=%s", conn, name); + VIR_DEBUG("conn=%p, name=%s", conn, NULLSTR(name)); virResetLastError(); @@ -955,7 +955,7 @@ virDomainSaveFlags(virDomainPtr domain, const char *to, int virDomainRestore(virConnectPtr conn, const char *from) { - VIR_DEBUG("conn=%p, from=%s", conn, from); + VIR_DEBUG("conn=%p, from=%s", conn, NULLSTR(from)); virResetLastError(); @@ -1025,7 +1025,7 @@ virDomainRestoreFlags(virConnectPtr conn, const char *from, const char *dxml, unsigned int flags) { VIR_DEBUG("conn=%p, from=%s, dxml=%s, flags=%x", - conn, from, NULLSTR(dxml), flags); + conn, NULLSTR(from), NULLSTR(dxml), flags); virResetLastError(); @@ -1089,7 +1089,7 @@ virDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *file, unsigned int flags) { VIR_DEBUG("conn=%p, file=%s, flags=%x", - conn, file, flags); + conn, NULLSTR(file), flags); virResetLastError(); @@ -1162,7 +1162,7 @@ virDomainSaveImageDefineXML(virConnectPtr conn, const char *file, const char *dxml, unsigned int flags) { VIR_DEBUG("conn=%p, file=%s, dxml=%s, flags=%x", - conn, file, dxml, flags); + conn, NULLSTR(file), NULLSTR(dxml), flags); virResetLastError(); @@ -2623,7 +2623,7 @@ virConnectDomainXMLFromNative(virConnectPtr conn, unsigned int flags) { VIR_DEBUG("conn=%p, format=%s, config=%s, flags=%x", - conn, nativeFormat, nativeConfig, flags); + conn, NULLSTR(nativeFormat), NULLSTR(nativeConfig), flags); virResetLastError(); @@ -2673,7 +2673,7 @@ virConnectDomainXMLToNative(virConnectPtr conn, unsigned int flags) { VIR_DEBUG("conn=%p, format=%s, xml=%s, flags=%x", - conn, nativeFormat, domainXml, flags); + conn, NULLSTR(nativeFormat), NULLSTR(domainXml), flags); virResetLastError(); @@ -4597,7 +4597,7 @@ virDomainMigrateFinish(virConnectPtr dconn, { VIR_DEBUG("dconn=%p, dname=%s, cookie=%p, cookielen=%d, uri=%s, " "flags=%lx", dconn, NULLSTR(dname), cookie, cookielen, - uri, flags); + NULLSTR(uri), flags); virResetLastError(); @@ -4639,8 +4639,8 @@ virDomainMigratePrepare2(virConnectPtr dconn, { VIR_DEBUG("dconn=%p, cookie=%p, cookielen=%p, uri_in=%s, uri_out=%p," "flags=%lx, dname=%s, bandwidth=%lu, dom_xml=%s", dconn, - cookie, cookielen, uri_in, uri_out, flags, NULLSTR(dname), - bandwidth, dom_xml); + cookie, cookielen, NULLSTR(uri_in), uri_out, flags, NULLSTR(dname), + bandwidth, NULLSTR(dom_xml)); virResetLastError(); @@ -4681,7 +4681,7 @@ virDomainMigrateFinish2(virConnectPtr dconn, { VIR_DEBUG("dconn=%p, dname=%s, cookie=%p, cookielen=%d, uri=%s, " "flags=%lx, retcode=%d", dconn, NULLSTR(dname), cookie, - cookielen, uri, flags, retcode); + cookielen, NULLSTR(uri), flags, retcode); virResetLastError(); @@ -4721,7 +4721,7 @@ virDomainMigratePrepareTunnel(virConnectPtr conn, { VIR_DEBUG("conn=%p, stream=%p, flags=%lx, dname=%s, " "bandwidth=%lu, dom_xml=%s", conn, st, flags, - NULLSTR(dname), bandwidth, dom_xml); + NULLSTR(dname), bandwidth, NULLSTR(dom_xml)); virResetLastError(); @@ -4817,8 +4817,8 @@ virDomainMigratePrepare3(virConnectPtr dconn, VIR_DEBUG("dconn=%p, cookiein=%p, cookieinlen=%d, cookieout=%p, " "cookieoutlen=%p, uri_in=%s, uri_out=%p, flags=%lx, dname=%s, " "bandwidth=%lu, dom_xml=%s", - dconn, cookiein, cookieinlen, cookieout, cookieoutlen, uri_in, - uri_out, flags, NULLSTR(dname), bandwidth, dom_xml); + dconn, cookiein, cookieinlen, cookieout, cookieoutlen, NULLSTR(uri_in), + uri_out, flags, NULLSTR(dname), bandwidth, NULLSTR(dom_xml)); virResetLastError(); @@ -4866,7 +4866,7 @@ virDomainMigratePrepareTunnel3(virConnectPtr conn, "cookieoutlen=%p, flags=%lx, dname=%s, bandwidth=%lu, " "dom_xml=%s", conn, st, cookiein, cookieinlen, cookieout, cookieoutlen, flags, - NULLSTR(dname), bandwidth, dom_xml); + NULLSTR(dname), bandwidth, NULLSTR(dom_xml)); virResetLastError(); @@ -6377,7 +6377,7 @@ virDomainGetBlockInfo(virDomainPtr domain, const char *disk, virDomainPtr virDomainDefineXML(virConnectPtr conn, const char *xml) { - VIR_DEBUG("conn=%p, xml=%s", conn, xml); + VIR_DEBUG("conn=%p, xml=%s", conn, NULLSTR(xml)); virResetLastError(); @@ -6425,7 +6425,7 @@ virDomainDefineXML(virConnectPtr conn, const char *xml) virDomainPtr virDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags) { - VIR_DEBUG("conn=%p, xml=%s flags=%x", conn, xml, flags); + VIR_DEBUG("conn=%p, xml=%s flags=%x", conn, NULLSTR(xml), flags); virResetLastError(); diff --git a/src/libvirt-host.c b/src/libvirt-host.c index 03bee1f5d..9c88426ec 100644 --- a/src/libvirt-host.c +++ b/src/libvirt-host.c @@ -321,7 +321,7 @@ int virConnectGetMaxVcpus(virConnectPtr conn, const char *type) { - VIR_DEBUG("conn=%p, type=%s", conn, type); + VIR_DEBUG("conn=%p, type=%s", conn, NULLSTR(type)); virResetLastError(); @@ -965,7 +965,7 @@ virConnectCompareCPU(virConnectPtr conn, const char *xmlDesc, unsigned int flags) { - VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags); + VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, NULLSTR(xmlDesc), flags); virResetLastError(); @@ -1009,7 +1009,7 @@ virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models, unsigned int flags) { VIR_DEBUG("conn=%p, arch=%s, models=%p, flags=%x", - conn, arch, models, flags); + conn, NULLSTR(arch), models, flags); virResetLastError(); if (models) diff --git a/src/libvirt-interface.c b/src/libvirt-interface.c index 4c155ca17..3d1a5ff8d 100644 --- a/src/libvirt-interface.c +++ b/src/libvirt-interface.c @@ -284,7 +284,7 @@ virConnectListDefinedInterfaces(virConnectPtr conn, virInterfacePtr virInterfaceLookupByName(virConnectPtr conn, const char *name) { - VIR_DEBUG("conn=%p, name=%s", conn, name); + VIR_DEBUG("conn=%p, name=%s", conn, NULLSTR(name)); virResetLastError(); @@ -323,7 +323,7 @@ virInterfaceLookupByName(virConnectPtr conn, const char *name) virInterfacePtr virInterfaceLookupByMACString(virConnectPtr conn, const char *macstr) { - VIR_DEBUG("conn=%p, macstr=%s", conn, macstr); + VIR_DEBUG("conn=%p, macstr=%s", conn, NULLSTR(macstr)); virResetLastError(); @@ -464,7 +464,7 @@ virInterfaceGetXMLDesc(virInterfacePtr iface, unsigned int flags) virInterfacePtr virInterfaceDefineXML(virConnectPtr conn, const char *xml, unsigned int flags) { - VIR_DEBUG("conn=%p, xml=%s, flags=%x", conn, xml, flags); + VIR_DEBUG("conn=%p, xml=%s, flags=%x", conn, NULLSTR(xml), flags); virResetLastError(); diff --git a/src/libvirt-network.c b/src/libvirt-network.c index e3a365008..3136f27ee 100644 --- a/src/libvirt-network.c +++ b/src/libvirt-network.c @@ -290,7 +290,7 @@ virConnectListDefinedNetworks(virConnectPtr conn, char **const names, virNetworkPtr virNetworkLookupByName(virConnectPtr conn, const char *name) { - VIR_DEBUG("conn=%p, name=%s", conn, name); + VIR_DEBUG("conn=%p, name=%s", conn, NULLSTR(name)); virResetLastError(); @@ -404,7 +404,7 @@ virNetworkLookupByUUIDString(virConnectPtr conn, const char *uuidstr) virNetworkPtr virNetworkCreateXML(virConnectPtr conn, const char *xmlDesc) { - VIR_DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc); + VIR_DEBUG("conn=%p, xmlDesc=%s", conn, NULLSTR(xmlDesc)); virResetLastError(); @@ -444,7 +444,7 @@ virNetworkCreateXML(virConnectPtr conn, const char *xmlDesc) virNetworkPtr virNetworkDefineXML(virConnectPtr conn, const char *xml) { - VIR_DEBUG("conn=%p, xml=%s", conn, xml); + VIR_DEBUG("conn=%p, xml=%s", conn, NULLSTR(xml)); virResetLastError(); diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c index b6c6d1e96..c1ca57505 100644 --- a/src/libvirt-nodedev.c +++ b/src/libvirt-nodedev.c @@ -1,7 +1,7 @@ /* * libvirt-nodedev.c: entry points for virNodeDevPtr APIs * - * Copyright (C) 2006-2014 Red Hat, Inc. + * Copyright (C) 2006-2015 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -160,7 +160,7 @@ virNodeListDevices(virConnectPtr conn, unsigned int flags) { VIR_DEBUG("conn=%p, cap=%s, names=%p, maxnames=%d, flags=%x", - conn, cap, names, maxnames, flags); + conn, NULLSTR(cap), names, maxnames, flags); virResetLastError(); @@ -199,7 +199,7 @@ virNodeListDevices(virConnectPtr conn, virNodeDevicePtr virNodeDeviceLookupByName(virConnectPtr conn, const char *name) { - VIR_DEBUG("conn=%p, name=%p", conn, name); + VIR_DEBUG("conn=%p, name=%s", conn, NULLSTR(name)); virResetLastError(); @@ -242,7 +242,7 @@ virNodeDeviceLookupSCSIHostByWWN(virConnectPtr conn, const char *wwpn, unsigned int flags) { - VIR_DEBUG("conn=%p, wwnn=%p, wwpn=%p, flags=%x", conn, wwnn, wwpn, flags); + VIR_DEBUG("conn=%p, wwnn=%s, wwpn=%s, flags=%x", conn, NULLSTR(wwnn), NULLSTR(wwpn), flags); virResetLastError(); @@ -694,7 +694,7 @@ virNodeDeviceCreateXML(virConnectPtr conn, const char *xmlDesc, unsigned int flags) { - VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags); + VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, NULLSTR(xmlDesc), flags); virResetLastError(); diff --git a/src/libvirt-nwfilter.c b/src/libvirt-nwfilter.c index 8bb6fa0e7..30c7c1040 100644 --- a/src/libvirt-nwfilter.c +++ b/src/libvirt-nwfilter.c @@ -1,7 +1,7 @@ /* * libvirt-nwfilter.c: entry points for virNwfilterPtr APIs * - * Copyright (C) 2006-2014 Red Hat, Inc. + * Copyright (C) 2006-2015 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -162,7 +162,7 @@ virConnectListNWFilters(virConnectPtr conn, char **const names, int maxnames) virNWFilterPtr virNWFilterLookupByName(virConnectPtr conn, const char *name) { - VIR_DEBUG("conn=%p, name=%s", conn, name); + VIR_DEBUG("conn=%p, name=%s", conn, NULLSTR(name)); virResetLastError(); @@ -382,7 +382,7 @@ virNWFilterGetUUIDString(virNWFilterPtr nwfilter, char *buf) virNWFilterPtr virNWFilterDefineXML(virConnectPtr conn, const char *xmlDesc) { - VIR_DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc); + VIR_DEBUG("conn=%p, xmlDesc=%s", conn, NULLSTR(xmlDesc)); virResetLastError(); diff --git a/src/libvirt-secret.c b/src/libvirt-secret.c index e77f223df..fa306e3b1 100644 --- a/src/libvirt-secret.c +++ b/src/libvirt-secret.c @@ -1,7 +1,7 @@ /* * libvirt-secret.c: entry points for virSecretPtr APIs * - * Copyright (C) 2006-2014 Red Hat, Inc. + * Copyright (C) 2006-2015 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -336,7 +336,7 @@ virSecretLookupByUsage(virConnectPtr conn, virSecretPtr virSecretDefineXML(virConnectPtr conn, const char *xml, unsigned int flags) { - VIR_DEBUG("conn=%p, xml=%s, flags=%x", conn, xml, flags); + VIR_DEBUG("conn=%p, xml=%s, flags=%x", conn, NULLSTR(xml), flags); virResetLastError(); diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c index 474f19851..66dd9f0b8 100644 --- a/src/libvirt-storage.c +++ b/src/libvirt-storage.c @@ -364,7 +364,7 @@ virStoragePoolPtr virStoragePoolLookupByName(virConnectPtr conn, const char *name) { - VIR_DEBUG("conn=%p, name=%s", conn, name); + VIR_DEBUG("conn=%p, name=%s", conn, NULLSTR(name)); virResetLastError(); @@ -521,7 +521,7 @@ virStoragePoolCreateXML(virConnectPtr conn, const char *xmlDesc, unsigned int flags) { - VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags); + VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, NULLSTR(xmlDesc), flags); virResetLastError(); @@ -564,7 +564,7 @@ virStoragePoolDefineXML(virConnectPtr conn, const char *xml, unsigned int flags) { - VIR_DEBUG("conn=%p, xml=%s, flags=%x", conn, xml, flags); + VIR_DEBUG("conn=%p, xml=%s, flags=%x", conn, NULLSTR(xml), flags); virResetLastError(); @@ -1290,7 +1290,7 @@ virStorageVolPtr virStorageVolLookupByName(virStoragePoolPtr pool, const char *name) { - VIR_DEBUG("pool=%p, name=%s", pool, name); + VIR_DEBUG("pool=%p, name=%s", pool, NULLSTR(name)); virResetLastError(); @@ -1330,7 +1330,7 @@ virStorageVolPtr virStorageVolLookupByKey(virConnectPtr conn, const char *key) { - VIR_DEBUG("conn=%p, key=%s", conn, key); + VIR_DEBUG("conn=%p, key=%s", conn, NULLSTR(key)); virResetLastError(); @@ -1370,7 +1370,7 @@ virStorageVolPtr virStorageVolLookupByPath(virConnectPtr conn, const char *path) { - VIR_DEBUG("conn=%p, path=%s", conn, path); + VIR_DEBUG("conn=%p, path=%s", conn, NULLSTR(path)); virResetLastError(); @@ -1463,7 +1463,7 @@ virStorageVolCreateXML(virStoragePoolPtr pool, const char *xmlDesc, unsigned int flags) { - VIR_DEBUG("pool=%p, xmlDesc=%s, flags=%x", pool, xmlDesc, flags); + VIR_DEBUG("pool=%p, xmlDesc=%s, flags=%x", pool, NULLSTR(xmlDesc), flags); virResetLastError(); @@ -1516,7 +1516,7 @@ virStorageVolCreateXMLFrom(virStoragePoolPtr pool, unsigned int flags) { VIR_DEBUG("pool=%p, xmlDesc=%s, clonevol=%p, flags=%x", - pool, xmlDesc, clonevol, flags); + pool, NULLSTR(xmlDesc), clonevol, flags); virResetLastError(); diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 35b1d04ad..9b258acbb 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -1325,37 +1325,6 @@ libxlMakeVfbList(virPortAllocatorPtr graphicsports, d_config->vkbs = x_vkbs; d_config->num_vfbs = d_config->num_vkbs = nvfbs; - /* - * VNC or SDL info must also be set in libxl_domain_build_info - * for HVM domains. Use the first vfb device. - */ - if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { - libxl_domain_build_info *b_info = &d_config->b_info; - libxl_device_vfb vfb = d_config->vfbs[0]; - - if (libxl_defbool_val(vfb.vnc.enable)) { - libxl_defbool_set(&b_info->u.hvm.vnc.enable, true); - if (VIR_STRDUP(b_info->u.hvm.vnc.listen, vfb.vnc.listen) < 0) - goto error; - if (VIR_STRDUP(b_info->u.hvm.vnc.passwd, vfb.vnc.passwd) < 0) - goto error; - b_info->u.hvm.vnc.display = vfb.vnc.display; - libxl_defbool_set(&b_info->u.hvm.vnc.findunused, - libxl_defbool_val(vfb.vnc.findunused)); - } else if (libxl_defbool_val(vfb.sdl.enable)) { - libxl_defbool_set(&b_info->u.hvm.sdl.enable, true); - libxl_defbool_set(&b_info->u.hvm.sdl.opengl, - libxl_defbool_val(vfb.sdl.opengl)); - if (VIR_STRDUP(b_info->u.hvm.sdl.display, vfb.sdl.display) < 0) - goto error; - if (VIR_STRDUP(b_info->u.hvm.sdl.xauthority, vfb.sdl.xauthority) < 0) - goto error; - } - - if (VIR_STRDUP(b_info->u.hvm.keymap, vfb.keymap) < 0) - goto error; - } - return 0; error: @@ -1369,6 +1338,114 @@ libxlMakeVfbList(virPortAllocatorPtr graphicsports, } /* + * Populate vfb info in libxl_domain_build_info struct for HVM domains. + * Prior to calling this function, libxlMakeVfbList must be called to + * populate libxl_domain_config->vfbs. + */ +static int +libxlMakeBuildInfoVfb(virPortAllocatorPtr graphicsports, + virDomainDefPtr def, + libxl_domain_config *d_config) +{ + libxl_domain_build_info *b_info = &d_config->b_info; + libxl_device_vfb x_vfb; + size_t i; + + if (def->os.type != VIR_DOMAIN_OSTYPE_HVM) + return 0; + + if (def->ngraphics == 0) + return 0; + + /* + * Prefer SPICE, otherwise use first libxl_device_vfb device in + * libxl_domain_config->vfbs. Prior to calling this function, + */ + for (i = 0; i < def->ngraphics; i++) { + virDomainGraphicsDefPtr l_vfb = def->graphics[i]; + unsigned short port; + const char *listenAddr; + + if (l_vfb->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE) + continue; + + libxl_defbool_set(&b_info->u.hvm.spice.enable, true); + + if (l_vfb->data.spice.autoport) { + if (virPortAllocatorAcquire(graphicsports, &port) < 0) + return -1; + l_vfb->data.spice.port = port; + } + b_info->u.hvm.spice.port = l_vfb->data.spice.port; + + listenAddr = virDomainGraphicsListenGetAddress(l_vfb, 0); + if (VIR_STRDUP(b_info->u.hvm.spice.host, listenAddr) < 0) + return -1; + + if (VIR_STRDUP(b_info->u.hvm.keymap, l_vfb->data.spice.keymap) < 0) + return -1; + + if (l_vfb->data.spice.auth.passwd) { + if (VIR_STRDUP(b_info->u.hvm.spice.passwd, + l_vfb->data.spice.auth.passwd) < 0) + return -1; + libxl_defbool_set(&b_info->u.hvm.spice.disable_ticketing, false); + } else { + libxl_defbool_set(&b_info->u.hvm.spice.disable_ticketing, true); + } + + switch (l_vfb->data.spice.mousemode) { + /* client mouse mode is default in xl.cfg */ + case VIR_DOMAIN_GRAPHICS_SPICE_MOUSE_MODE_DEFAULT: + case VIR_DOMAIN_GRAPHICS_SPICE_MOUSE_MODE_CLIENT: + libxl_defbool_set(&b_info->u.hvm.spice.agent_mouse, true); + break; + case VIR_DOMAIN_GRAPHICS_SPICE_MOUSE_MODE_SERVER: + libxl_defbool_set(&b_info->u.hvm.spice.agent_mouse, false); + break; + } + +#ifdef LIBXL_HAVE_SPICE_VDAGENT + if (l_vfb->data.spice.copypaste == VIR_TRISTATE_BOOL_YES) { + libxl_defbool_set(&b_info->u.hvm.spice.vdagent, true); + libxl_defbool_set(&b_info->u.hvm.spice.clipboard_sharing, true); + } else { + libxl_defbool_set(&b_info->u.hvm.spice.vdagent, false); + libxl_defbool_set(&b_info->u.hvm.spice.clipboard_sharing, false); + } +#endif + + return 0; + } + + x_vfb = d_config->vfbs[0]; + + if (libxl_defbool_val(x_vfb.vnc.enable)) { + libxl_defbool_set(&b_info->u.hvm.vnc.enable, true); + if (VIR_STRDUP(b_info->u.hvm.vnc.listen, x_vfb.vnc.listen) < 0) + return -1; + if (VIR_STRDUP(b_info->u.hvm.vnc.passwd, x_vfb.vnc.passwd) < 0) + return -1; + b_info->u.hvm.vnc.display = x_vfb.vnc.display; + libxl_defbool_set(&b_info->u.hvm.vnc.findunused, + libxl_defbool_val(x_vfb.vnc.findunused)); + } else if (libxl_defbool_val(x_vfb.sdl.enable)) { + libxl_defbool_set(&b_info->u.hvm.sdl.enable, true); + libxl_defbool_set(&b_info->u.hvm.sdl.opengl, + libxl_defbool_val(x_vfb.sdl.opengl)); + if (VIR_STRDUP(b_info->u.hvm.sdl.display, x_vfb.sdl.display) < 0) + return -1; + if (VIR_STRDUP(b_info->u.hvm.sdl.xauthority, x_vfb.sdl.xauthority) < 0) + return -1; + } + + if (VIR_STRDUP(b_info->u.hvm.keymap, x_vfb.keymap) < 0) + return -1; + + return 0; +} + +/* * Get domain0 autoballoon configuration. Honor user-specified * setting in libxl.conf first. If not specified, autoballooning * is disabled when domain0's memory is set with 'dom0_mem'. @@ -1664,6 +1741,17 @@ libxlMakeVideo(virDomainDefPtr def, libxl_domain_config *d_config) } break; +#ifdef LIBXL_HAVE_QXL + case VIR_DOMAIN_VIDEO_TYPE_QXL: + b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_QXL; + if (def->videos[0]->vram < 128 * 1024) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("videoram must be at least 128MB for QXL")); + return -1; + } + break; +#endif + default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("video type %s is not supported by libxl"), @@ -1766,6 +1854,9 @@ libxlBuildDomainConfig(virPortAllocatorPtr graphicsports, if (libxlMakeVfbList(graphicsports, def, d_config) < 0) return -1; + if (libxlMakeBuildInfoVfb(graphicsports, def, d_config) < 0) + return -1; + if (libxlMakePCIList(def, d_config) < 0) return -1; diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h index 0a1c0db9d..9c29b1e28 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -140,7 +140,7 @@ struct _libxlDriverPrivate { virObjectEventStatePtr domainEventState; /* Immutable pointer, self-locking APIs */ - virPortAllocatorPtr reservedVNCPorts; + virPortAllocatorPtr reservedGraphicsPorts; /* Immutable pointer, self-locking APIs */ virPortAllocatorPtr migrationPorts; diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 5f5f8e53f..c7f0ed9d2 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -324,6 +324,10 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, dev->data.video->vram = 4 * 1024; } break; + case VIR_DOMAIN_VIDEO_TYPE_QXL: + if (dev->data.video->vram == 0) + dev->data.video->vram = 128 * 1024; + break; } } @@ -715,7 +719,7 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver, vm->def->graphics[0]->data.vnc.autoport) { vnc_port = vm->def->graphics[0]->data.vnc.port; if (vnc_port >= LIBXL_VNC_PORT_MIN) { - if (virPortAllocatorRelease(driver->reservedVNCPorts, + if (virPortAllocatorRelease(driver->reservedGraphicsPorts, vnc_port) < 0) VIR_DEBUG("Could not mark port %d as unused", vnc_port); } @@ -979,7 +983,7 @@ libxlDomainStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, VIR_FREE(managed_save_path); } - if (libxlBuildDomainConfig(driver->reservedVNCPorts, vm->def, + if (libxlBuildDomainConfig(driver->reservedGraphicsPorts, vm->def, cfg->ctx, &d_config) < 0) goto cleanup; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 12be81609..c297d1227 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -410,7 +410,7 @@ libxlStateCleanup(void) virObjectUnref(libxl_driver->config); virObjectUnref(libxl_driver->xmlopt); virObjectUnref(libxl_driver->domains); - virObjectUnref(libxl_driver->reservedVNCPorts); + virObjectUnref(libxl_driver->reservedGraphicsPorts); virObjectUnref(libxl_driver->migrationPorts); virLockManagerPluginUnref(libxl_driver->lockManager); @@ -523,7 +523,7 @@ libxlStateInitialize(bool privileged, } /* Allocate bitmap for vnc port reservation */ - if (!(libxl_driver->reservedVNCPorts = + if (!(libxl_driver->reservedGraphicsPorts = virPortAllocatorNew(_("VNC"), LIBXL_VNC_PORT_MIN, LIBXL_VNC_PORT_MAX, diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index 34ba1fad2..768db7fbb 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -248,7 +248,9 @@ nodeDeviceLookupByName(virConnectPtr conn, const char *name) nodeDeviceUnlock(); if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, NULL); + virReportError(VIR_ERR_NO_NODE_DEVICE, + _("no node device with matching name '%s'"), + name); goto cleanup; } @@ -597,8 +599,10 @@ nodeDeviceCreateXML(virConnectPtr conn, * we're returning what we get... */ if (dev == NULL) - virReportError(VIR_ERR_NO_NODE_DEVICE, NULL); - + virReportError(VIR_ERR_NO_NODE_DEVICE, + _("no node device for '%s' with matching " + "wwnn '%s' and wwpn '%s'"), + def->name, wwnn, wwpn); cleanup: nodeDeviceUnlock(); virNodeDeviceDefFree(def); @@ -621,7 +625,9 @@ nodeDeviceDestroy(virNodeDevicePtr dev) nodeDeviceUnlock(); if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, NULL); + virReportError(VIR_ERR_NO_NODE_DEVICE, + _("no node device with matching name '%s'"), + dev->name); goto out; } diff --git a/src/nodeinfo.c b/src/nodeinfo.c index 22df95cf2..29f1aa731 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -1641,26 +1641,36 @@ nodeCapsInitNUMAFake(virCapsPtr caps ATTRIBUTE_UNUSED) virCapsHostNUMACellCPUPtr cpus; int ncpus; int s, c, t; - int id; + int id, cid; + int onlinecpus ATTRIBUTE_UNUSED; if (nodeGetInfo(&nodeinfo) < 0) return -1; ncpus = VIR_NODEINFO_MAXCPUS(nodeinfo); + onlinecpus = nodeinfo.cpus; if (VIR_ALLOC_N(cpus, ncpus) < 0) return -1; - id = 0; + id = cid = 0; for (s = 0; s < nodeinfo.sockets; s++) { for (c = 0; c < nodeinfo.cores; c++) { for (t = 0; t < nodeinfo.threads; t++) { - cpus[id].id = id; - cpus[id].socket_id = s; - cpus[id].core_id = c; - if (!(cpus[id].siblings = virBitmapNew(ncpus))) - goto error; - ignore_value(virBitmapSetBit(cpus[id].siblings, id)); +#ifdef __linux__ + if (virNodeGetCpuValue(SYSFS_CPU_PATH, id, "online", 1)) { +#endif + cpus[cid].id = id; + cpus[cid].socket_id = s; + cpus[cid].core_id = c; + if (!(cpus[cid].siblings = virBitmapNew(ncpus))) + goto error; + ignore_value(virBitmapSetBit(cpus[cid].siblings, id)); + cid++; +#ifdef __linux__ + } +#endif + id++; } } @@ -1668,7 +1678,11 @@ nodeCapsInitNUMAFake(virCapsPtr caps ATTRIBUTE_UNUSED) if (virCapabilitiesAddHostNUMACell(caps, 0, nodeinfo.memory, +#ifdef __linux__ + onlinecpus, cpus, +#else ncpus, cpus, +#endif 0, NULL, 0, NULL) < 0) goto error; diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index bedee2c5f..39c200a47 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -205,6 +205,9 @@ prlsdkInit(void) { PRL_RESULT ret; + /* Disable console output */ + PrlApi_SwitchConsoleLogging(0); + ret = PrlApi_InitEx(PARALLELS_API_VER, PAM_SERVER, 0, 0); if (PRL_FAILED(ret)) { logPrlError(ret); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index aa0acdef0..d1b00a201 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10524,6 +10524,7 @@ qemuDomainGetNumaParameters(virDomainPtr dom, size_t i; virDomainObjPtr vm = NULL; virDomainDefPtr persistentDef = NULL; + virDomainNumatuneMemMode tmpmode = VIR_DOMAIN_NUMATUNE_MEM_STRICT; char *nodeset = NULL; int ret = -1; virCapsPtr caps = NULL; @@ -10567,12 +10568,12 @@ qemuDomainGetNumaParameters(virDomainPtr dom, switch (i) { case 0: /* fill numa mode here */ + ignore_value(virDomainNumatuneGetMode(def->numa, -1, &tmpmode)); + if (virTypedParameterAssign(param, VIR_DOMAIN_NUMA_MODE, - VIR_TYPED_PARAM_INT, 0) < 0) + VIR_TYPED_PARAM_INT, tmpmode) < 0) goto cleanup; - virDomainNumatuneGetMode(def->numa, -1, - (virDomainNumatuneMemMode *) ¶m->value.i); break; case 1: /* fill numa nodeset here */ @@ -18945,7 +18946,12 @@ qemuDomainSetTime(virDomainPtr dom, goto endjob; } - if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_RTC_RESET_REINJECTION)) { + /* On x86, the rtc-reset-reinjection QMP command must be called after + * setting the time to avoid trouble down the line. If the command is + * not available, don't set the time at all and report an error */ + if (ARCH_IS_X86(vm->def->os.arch) && + !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_RTC_RESET_REINJECTION)) + { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("cannot set time: qemu doesn't support " "rtc-reset-reinjection command")); @@ -18968,13 +18974,16 @@ qemuDomainSetTime(virDomainPtr dom, goto endjob; } - qemuDomainObjEnterMonitor(driver, vm); - rv = qemuMonitorRTCResetReinjection(priv->mon); - if (qemuDomainObjExitMonitor(driver, vm) < 0) - goto endjob; + /* Don't try to call rtc-reset-reinjection if it's not available */ + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_RTC_RESET_REINJECTION)) { + qemuDomainObjEnterMonitor(driver, vm); + rv = qemuMonitorRTCResetReinjection(priv->mon); + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto endjob; - if (rv < 0) - goto endjob; + if (rv < 0) + goto endjob; + } ret = 0; diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c index 4dc63d753..c4bd6fe2c 100644 --- a/src/storage/storage_backend_disk.c +++ b/src/storage/storage_backend_disk.c @@ -309,7 +309,12 @@ virStorageBackendDiskReadPartitions(virStoragePoolObjPtr pool, pool->def->source.devices[0].path, NULL); - pool->def->allocation = pool->def->capacity = pool->def->available = 0; + /* If a volume is passed, virStorageBackendDiskMakeVol only updates the + * pool allocation for that single volume. + */ + if (!vol) + pool->def->allocation = 0; + pool->def->capacity = pool->def->available = 0; ret = virCommandRunNul(cmd, 6, diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index bcbbb3ae2..337b8d3b9 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -807,7 +807,7 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, (needs_create_as_uid || !virFileExists(pool->def->target.path))) mode = VIR_STORAGE_DEFAULT_POOL_PERM_MODE; if (needs_create_as_uid) - flags |= VIR_DIR_CREATE_AS_UID; + dir_create_flags |= VIR_DIR_CREATE_AS_UID; /* Now create the final dir in the path with the uid/gid/mode * requested in the config. If the dir already exists, just set diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index ac4a74a1a..394e4d455 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -1634,7 +1634,6 @@ storageVolDeleteInternal(virStorageVolPtr obj, { size_t i; int ret = -1; - unsigned long long orig_pool_available, orig_pool_allocation; if (!backend->deleteVol) { virReportError(VIR_ERR_NO_SUPPORT, @@ -1643,20 +1642,18 @@ storageVolDeleteInternal(virStorageVolPtr obj, goto cleanup; } - orig_pool_available = pool->def->available; - orig_pool_allocation = pool->def->allocation; - if (backend->deleteVol(obj->conn, pool, vol, flags) < 0) goto cleanup; /* Update pool metadata - don't update meta data from error paths - * in this module since the allocation/available weren't adjusted yet + * in this module since the allocation/available weren't adjusted yet. + * Ignore the disk backend since it updates the pool values. */ if (updateMeta) { - if (orig_pool_allocation == pool->def->allocation) + if (pool->def->type != VIR_STORAGE_POOL_DISK) { pool->def->allocation -= vol->target.allocation; - if (orig_pool_available == pool->def->available) pool->def->available += vol->target.allocation; + } } for (i = 0; i < pool->volumes.count; i++) { @@ -1775,7 +1772,6 @@ storageVolCreateXML(virStoragePoolPtr obj, virStorageVolDefPtr voldef = NULL; virStorageVolPtr ret = NULL, volobj = NULL; virStorageVolDefPtr buildvoldef = NULL; - unsigned long long orig_pool_available, orig_pool_allocation; virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL); @@ -1823,9 +1819,6 @@ storageVolCreateXML(virStoragePoolPtr obj, goto cleanup; } - orig_pool_available = pool->def->available; - orig_pool_allocation = pool->def->allocation; - /* Wipe any key the user may have suggested, as volume creation * will generate the canonical key. */ VIR_FREE(voldef->key); @@ -1882,11 +1875,13 @@ storageVolCreateXML(virStoragePoolPtr obj, backend->refreshVol(obj->conn, pool, voldef) < 0) goto cleanup; - /* Update pool metadata */ - if (orig_pool_allocation == pool->def->allocation) + /* Update pool metadata ignoring the disk backend since + * it updates the pool values. + */ + if (pool->def->type != VIR_STORAGE_POOL_DISK) { pool->def->allocation += buildvoldef->target.allocation; - if (orig_pool_available == pool->def->available) pool->def->available -= buildvoldef->target.allocation; + } VIR_INFO("Creating volume '%s' in storage pool '%s'", volobj->name, pool->def->name); @@ -1914,7 +1909,6 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, virStorageVolDefPtr origvol = NULL, newvol = NULL; virStorageVolPtr ret = NULL, volobj = NULL; unsigned long long allocation; - unsigned long long orig_pool_available, orig_pool_allocation; int buildret; virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA | @@ -2017,9 +2011,6 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, pool->volumes.count+1) < 0) goto cleanup; - orig_pool_available = pool->def->available; - orig_pool_allocation = pool->def->allocation; - /* 'Define' the new volume so we get async progress reporting. * Wipe any key the user may have suggested, as volume creation * will generate the canonical key. */ @@ -2072,11 +2063,13 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, } newvol = NULL; - /* Updating pool metadata */ - if (orig_pool_allocation == pool->def->allocation) + /* Updating pool metadata ignoring the disk backend since + * it updates the pool values + */ + if (pool->def->type != VIR_STORAGE_POOL_DISK) { pool->def->allocation += allocation; - if (orig_pool_available == pool->def->available) pool->def->available -= allocation; + } VIR_INFO("Creating volume '%s' in storage pool '%s'", volobj->name, pool->def->name); @@ -2292,7 +2285,7 @@ storageVolResize(virStorageVolPtr obj, virStorageBackendPtr backend; virStoragePoolObjPtr pool = NULL; virStorageVolDefPtr vol = NULL; - unsigned long long abs_capacity, delta; + unsigned long long abs_capacity, delta = 0; int ret = -1; virCheckFlags(VIR_STORAGE_VOL_RESIZE_ALLOCATE | @@ -2320,7 +2313,10 @@ storageVolResize(virStorageVolPtr obj, } if (flags & VIR_STORAGE_VOL_RESIZE_DELTA) { - abs_capacity = vol->target.capacity + capacity; + if (flags & VIR_STORAGE_VOL_RESIZE_SHRINK) + abs_capacity = vol->target.capacity - MIN(capacity, vol->target.capacity); + else + abs_capacity = vol->target.capacity + capacity; flags &= ~VIR_STORAGE_VOL_RESIZE_DELTA; } else { abs_capacity = capacity; @@ -2341,18 +2337,10 @@ storageVolResize(virStorageVolPtr obj, goto cleanup; } - if (flags & VIR_STORAGE_VOL_RESIZE_SHRINK) - delta = vol->target.allocation - abs_capacity; - else + if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE) delta = abs_capacity - vol->target.allocation; - /* If the operation is going to increase the allocation value and not - * just the capacity value, then let's make sure there's enough space - * in the pool in order to perform that operation - */ - if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE && - !(flags & VIR_STORAGE_VOL_RESIZE_SHRINK) && - delta > pool->def->available) { + if (delta > pool->def->available) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Not enough space left in storage pool")); goto cleanup; @@ -2375,15 +2363,8 @@ storageVolResize(virStorageVolPtr obj, */ if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE) { vol->target.allocation = abs_capacity; - - /* Update pool metadata */ - if (flags & VIR_STORAGE_VOL_RESIZE_SHRINK) { - pool->def->allocation -= delta; - pool->def->available += delta; - } else { - pool->def->allocation += delta; - pool->def->available -= delta; - } + pool->def->allocation += delta; + pool->def->available -= delta; } ret = 0; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 038b2b89b..d1f0af3a9 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -5673,7 +5673,9 @@ testNodeDeviceLookupByName(virConnectPtr conn, const char *name) testDriverUnlock(driver); if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, NULL); + virReportError(VIR_ERR_NO_NODE_DEVICE, + _("no node device with matching name '%s'"), + name); goto cleanup; } @@ -5893,7 +5895,9 @@ testNodeDeviceDestroy(virNodeDevicePtr dev) testDriverUnlock(driver); if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, NULL); + virReportError(VIR_ERR_NO_NODE_DEVICE, + _("no node device with matching name '%s'"), + dev->name); goto out; } diff --git a/src/util/vireventpoll.c b/src/util/vireventpoll.c index ffda206b8..5e99b3cc6 100644 --- a/src/util/vireventpoll.c +++ b/src/util/vireventpoll.c @@ -357,9 +357,10 @@ static int virEventPollCalculateTimeout(int *timeout) return -1; EVENT_DEBUG("Schedule timeout then=%llu now=%llu", then, now); - *timeout = then - now; - if (*timeout < 0) + if (then <= now) *timeout = 0; + else + *timeout = ((then - now) > INT_MAX) ? INT_MAX : (then - now); } else { *timeout = -1; } |