[libvirt] [PATCH] fix a ambiguous output of the command:'virsh vol-create-as'
by Hongwei Bi
I created a storage volume(eg: test) from a storage pool(eg:vg10) using
the following command:"virsh vol-create-as --pool vg10 --name test --capacity 300M."
When I re-executed the above command, the output was as the following:
"error: Failed to create vol test
error: Storage volume not found: storage vol 'test' already exists"
I think the output "Storage volume not found" is not appropriate. Because in fact storage
vol test has been found at this time. And then I think virErrorNumber should includes
VIR_ERR_STORAGE_EXIST which can also be used elsewhere. So I make this patch. The result
is as following:
"error: Failed to create vol test
error: storage volume 'test' exists already"
---
include/libvirt/virterror.h | 1 +
src/storage/storage_driver.c | 4 ++--
src/util/virerror.c | 6 ++++++
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index c1960c8..28ef30a 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -296,6 +296,7 @@ typedef enum {
VIR_ERR_ACCESS_DENIED = 88, /* operation on the object/resource
was denied */
VIR_ERR_DBUS_SERVICE = 89, /* error from a dbus service */
+ VIR_ERR_STORAGE_EXIST = 90, /* the storage vol already exist */
} virErrorNumber;
/**
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 6c39284..aa5a144 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -1538,8 +1538,8 @@ storageVolCreateXML(virStoragePoolPtr obj,
goto cleanup;
if (virStorageVolDefFindByName(pool, voldef->name)) {
- virReportError(VIR_ERR_NO_STORAGE_VOL,
- _("storage vol '%s' already exists"), voldef->name);
+ virReportError(VIR_ERR_STORAGE_EXIST,
+ _("'%s'"), voldef->name);
goto cleanup;
}
diff --git a/src/util/virerror.c b/src/util/virerror.c
index ca25678..35bb017 100644
--- a/src/util/virerror.c
+++ b/src/util/virerror.c
@@ -1004,6 +1004,12 @@ virErrorMsg(virErrorNumber error, const char *info)
else
errmsg = _("Storage volume not found: %s");
break;
+ case VIR_ERR_STORAGE_EXIST:
+ if (info == NULL)
+ errmsg = _("this storage volume exists already");
+ else
+ errmsg = _("storage volume %s exists already");
+ break;
case VIR_ERR_STORAGE_PROBE_FAILED:
if (info == NULL)
errmsg = _("Storage pool probe failed");
--
1.7.1
11 years, 1 month
Re: [libvirt] [PATCH] add migration APIs to libxl driver
by Bamvor Jian Zhang
> ---
> src/libxl/libxl_conf.h | 4 +
> src/libxl/libxl_driver.c | 641
> ++++++++++++++++++++++++++++++++++++++++++++++
> src/libxl/libxl_driver.h | 5 +
> 3 files changed, 650 insertions(+), 0 deletions(-)
>
> diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
> index 8ba0ee4..2041cc2 100644
> --- a/src/libxl/libxl_conf.h
> +++ b/src/libxl/libxl_conf.h
> @@ -41,6 +41,9 @@
> # define LIBXL_VNC_PORT_MIN 5900
> # define LIBXL_VNC_PORT_MAX 65535
>
> +# define LIBXL_MIGRATION_PORT_MIN 49152
> +# define LIBXL_MIGRATION_PORT_MAX 49216
> +
there is a overlap between vnc and migration port. althrought, it will try
next port in virPortAllocatorAcquire after bind fail.
> # define LIBXL_CONFIG_DIR SYSCONFDIR "/libvirt/libxl"
> # define LIBXL_AUTOSTART_DIR LIBXL_CONFIG_DIR "/autostart"
> # define LIBXL_STATE_DIR LOCALSTATEDIR "/run/libvirt/libxl"
> @@ -109,6 +112,7 @@ struct _libxlDriverPrivate {
>
> /* Immutable pointer, self-locking APIs */
> virPortAllocatorPtr reservedVNCPorts;
> + virPortAllocatorPtr reservedMigPorts;
>
> /* Immutable pointer, lockless APIs*/
> virSysinfoDefPtr hostsysinfo;
> diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
> index e2a6d44..93b7153 100644
> --- a/src/libxl/libxl_driver.c
> +++ b/src/libxl/libxl_driver.c
> @@ -32,6 +32,12 @@
> #include <libxl_utils.h>
> #include <fcntl.h>
> #include <regex.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +#include <arpa/inet.h>
> +#include <netdb.h>
>
> #include "internal.h"
> #include "virlog.h"
> @@ -52,6 +58,7 @@
> #include "virsysinfo.h"
> #include "viraccessapicheck.h"
> #include "viratomic.h"
> +#include "rpc/virnetsocket.h"
>
> #define VIR_FROM_THIS VIR_FROM_LIBXL
>
> @@ -69,6 +76,20 @@
>
> static libxlDriverPrivatePtr libxl_driver = NULL;
>
> +typedef struct _libxlMigrateReceiveArgs {
> + virConnectPtr conn;
> + virDomainObjPtr vm;
> +
> + /* for freeing listen sockets */
> + virNetSocketPtr *socks;
> + size_t nsocks;
> +} libxlMigrateReceiveArgs;
> +
> +static const char libxlMigrateReceiverReady[]=
> + "libvirt libxl migration receiver ready, send binary domain data";
> +static const char libxlMigrateReceiverFinish[]=
> + "domain received, ready to unpause";
> +
> /* Function declarations */
> static int
> libxlDomainManagedSaveLoad(virDomainObjPtr vm,
> @@ -836,6 +857,12 @@ libxlStateInitialize(bool privileged,
> LIBXL_VNC_PORT_MAX)))
> goto error;
>
> + /* Allocate bitmap for migration port reservation */
> + if (!(libxl_driver->reservedMigPorts =
> + virPortAllocatorNew(LIBXL_MIGRATION_PORT_MIN,
> + LIBXL_MIGRATION_PORT_MAX)))
> + goto error;
> +
> if (!(libxl_driver->domains = virDomainObjListNew()))
> goto error;
>
> @@ -4175,11 +4202,620 @@ libxlConnectSupportsFeature(virConnectPtr conn,
> int feature)
> switch (feature) {
> case VIR_DRV_FEATURE_TYPED_PARAM_STRING:
> return 1;
> + case VIR_DRV_FEATURE_MIGRATION_V3:
> + return 1;
> default:
> return 0;
> }
> }
>
> +static int
> +libxlCheckMessageBanner(int fd, const char *banner, int banner_sz)
> +{
> + char buf[banner_sz];
> + int ret = 0;
> +
> + do {
> + ret = saferead(fd, buf, banner_sz);
> + } while (ret == -1 && errno == EAGAIN);
> +
> + if (ret != banner_sz || memcmp(buf, banner, banner_sz)) {
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static char *
> +libxlDomainMigrateBegin3(virDomainPtr domain,
> + const char *xmlin,
> + char **cookieout ATTRIBUTE_UNUSED,
> + int *cookieoutlen ATTRIBUTE_UNUSED,
> + unsigned long flags,
> + const char *dname ATTRIBUTE_UNUSED,
> + unsigned long resource ATTRIBUTE_UNUSED)
> +{
> + libxlDriverPrivatePtr driver = domain->conn->privateData;
> + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
> + virDomainObjPtr vm;
> + virDomainDefPtr def = NULL;
> + char *xml = NULL;
> +
> + virCheckFlags(LIBXL_MIGRATION_FLAGS, NULL);
> +
> + vm = virDomainObjListFindByUUID(driver->domains, domain->uuid);
> + if (!vm) {
> + char uuidstr[VIR_UUID_STRING_BUFLEN];
> + virUUIDFormat(domain->uuid, uuidstr);
> + virReportError(VIR_ERR_OPERATION_INVALID,
> + _("no domain with matching uuid '%s'"), uuidstr);
> + goto cleanup;
> + }
libxlDomObjFromDomain is introduced in commit 0d87fd0aa by Jim.
> +
> + if (!virDomainObjIsActive(vm)) {
> + virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> + _("domain is not running"));
> + goto cleanup;
> + }
> +
> + if (virDomainMigrateBegin3EnsureACL(domain->conn, vm->def) < 0)
> + goto cleanup;
> +
> + if (xmlin) {
> + if (!(def = virDomainDefParseString(xmlin, cfg->caps,
> + driver->xmlopt,
> + 1 << VIR_DOMAIN_VIRT_XEN,
> + VIR_DOMAIN_XML_INACTIVE)))
> + goto cleanup;
> +
> + xml = virDomainDefFormat(def, VIR_DOMAIN_XML_SECURE);
> + } else {
> + xml = virDomainDefFormat(vm->def, VIR_DOMAIN_XML_SECURE);
> + }
> +
> +cleanup:
> + virDomainDefFree(def);
> + if (vm)
> + virObjectUnlock(vm);
> + virObjectUnref(cfg);
> + return xml;
> +}
> +
> +static void
> +doMigrateReceive(virNetSocketPtr sock,
> + int events ATTRIBUTE_UNUSED,
> + void *opaque)
> +{
> + libxlMigrateReceiveArgs *data = opaque;
> + virConnectPtr conn = data->conn;
> + virDomainObjPtr vm = data->vm;
> + virNetSocketPtr *socks = data->socks;
> + size_t nsocks = data->nsocks;
> + libxlDriverPrivatePtr driver = conn->privateData;
> + virNetSocketPtr client_sock;
> + int recv_fd;
> + int len;
> + size_t i;
> + int ret;
> +
> + virNetSocketAccept(sock, &client_sock);
> + if (client_sock == NULL) {
> + virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> + _("Fail to accept migration connection"));
> + goto cleanup;
> + }
> + VIR_DEBUG("Accepted migration\n");
> + recv_fd = virNetSocketDupFD(client_sock, true);
> + virObjectUnref(client_sock);
> +
> + len = sizeof(libxlMigrateReceiverReady);
> + if (safewrite(recv_fd, libxlMigrateReceiverReady, len) != len) {
> + virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> + _("Failed to write libxlMigrateReceiverReady"));
> + goto cleanup;
> + }
> +
> + virObjectLock(vm);
> + ret = libxlVmStart(driver, vm, false, recv_fd);
> + virObjectUnlock(vm);
> +
> + if (ret < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Failed to restore domain with libxenlight"));
> + if (!vm->persistent) {
> + virDomainObjListRemove(driver->domains, vm);
> + vm = NULL;
> + }
> + goto cleanup;
> + }
> +
> + len = sizeof(libxlMigrateReceiverFinish);
> + if (safewrite(recv_fd, libxlMigrateReceiverFinish, len) != len) {
> + virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> + _("Failed to write libxlMigrateReceiverFinish"));
> + }
> +
> + /* Remove all listen socks from event handler, and close them. */
> + if (nsocks) {
> + for (i = 0; i < nsocks; i++) {
> + virNetSocketUpdateIOCallback(socks[i], 0);
> + virNetSocketRemoveIOCallback(socks[i]);
> + virNetSocketClose(socks[i]);
> + virObjectUnref(socks[i]);
> + }
> + VIR_FREE(socks);
> + }
> +
> +cleanup:
> + VIR_FORCE_CLOSE(recv_fd);
> + VIR_FREE(opaque);
> + return;
> +}
> +
> +static int
> +doMigrateSend(libxlDriverPrivatePtr driver,
> + virDomainObjPtr vm,
> + unsigned long flags,
> + int sockfd)
> +{
> + libxlDomainObjPrivatePtr priv;
> + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
> + virDomainEventPtr event = NULL;
> + int live = 0;
> + int ret = -1;
> +
> + if (flags & VIR_MIGRATE_LIVE)
> + live = LIBXL_SUSPEND_LIVE;
> +
> + priv = vm->privateData;
> +
> + /* read fixed message from dest (ready to receive) */
> + if (libxlCheckMessageBanner(sockfd, libxlMigrateReceiverReady,
> + sizeof(libxlMigrateReceiverReady)))
> + goto cleanup;
> +
> + if (libxl_domain_suspend(priv->ctx, vm->def->id, sockfd, live, NULL)
> != 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Failed to save domain '%d' with libxenlight"),
> + vm->def->id);
> + goto cleanup;
> + }
> +
> + /* read fixed message from dest (receive completed) */
> + if (libxlCheckMessageBanner(sockfd, libxlMigrateReceiverFinish,
> + sizeof(libxlMigrateReceiverFinish))) {
> + if (libxl_domain_resume(priv->ctx, vm->def->id, 0, 0) != 0) {
> + VIR_DEBUG("Failed to resume domain '%d' with libxenlight",
> + vm->def->id);
> + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,
> + VIR_DOMAIN_PAUSED_MIGRATION);
> + event = virDomainEventNewFromObj(vm,
> VIR_DOMAIN_EVENT_SUSPENDED,
> +
> VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED);
> + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
> + goto cleanup;
> + }
> + goto cleanup;
> + }
> +
> + ret = 0;
> +
> +cleanup:
> + if (event)
> + libxlDomainEventQueue(driver, event);
> + virObjectUnref(cfg);
> + return ret;
> +}
> +
> +static int
> +libxlDomainMigratePrepare3(virConnectPtr dconn,
> + const char *cookiein ATTRIBUTE_UNUSED,
> + int cookieinlen ATTRIBUTE_UNUSED,
> + char **cookieout ATTRIBUTE_UNUSED,
> + int *cookieoutlen ATTRIBUTE_UNUSED,
> + const char *uri_in,
> + char **uri_out,
> + unsigned long flags,
> + const char *dname,
> + unsigned long resource ATTRIBUTE_UNUSED,
> + const char *dom_xml)
> +{
> + libxlDriverPrivatePtr driver = dconn->privateData;
> + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
> + virDomainDefPtr def = NULL;
> + virDomainObjPtr vm = NULL;
> + char *hostname = NULL;
> + unsigned short port;
> + char portstr[100];
> + virURIPtr uri = NULL;
> + virNetSocketPtr *socks = NULL;
> + size_t nsocks = 0;
> + int nsocks_listen = 0;
> + libxlMigrateReceiveArgs *args;
> + size_t i;
> + int ret = -1;
> +
> + virCheckFlags(LIBXL_MIGRATION_FLAGS, -1);
> +
> + libxlDriverLock(driver);
> + if (!dom_xml) {
> + virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> + _("no domain XML passed"));
> + goto cleanup;
> + }
> + def = virDomainDefParseString(dom_xml, cfg->caps, driver->xmlopt,
> + 1 << VIR_DOMAIN_VIRT_XEN,
> + VIR_DOMAIN_XML_INACTIVE);
> +
> + /* Target domain name, maybe renamed. */
> + if (dname) {
> + if (VIR_STRDUP(def->name, dname) < 0)
> + goto cleanup;
> + }
> +
> + if (!(vm = virDomainObjListAdd(driver->domains, def,
> + driver->xmlopt,
> + VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
> + VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
> + NULL)))
> + goto cleanup;
> +
> + def = NULL;
> +
> + if (virDomainMigratePrepare3EnsureACL(dconn, vm->def) < 0)
> + goto cleanup;
> +
> + /* Create socket connection to receive migration data */
> + if (!uri_in) {
> + hostname = virGetHostname();
> + if (hostname == NULL)
> + goto cleanup;
> +
> + if (virPortAllocatorAcquire(driver->reservedMigPorts, &port) < 0)
> + goto cleanup;
> +
> + if (port == 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + "%s", _("Unable to find an unused migrate
> port"));
> + goto cleanup;
> + }
> +
> + if (virAsprintf(uri_out, "tcp://%s:%d", hostname, port) < 0)
> + goto cleanup;
> + } else {
> + if (!strstr(uri_in, "//")) {
> + /* not full URI, add prefix tcp:// */
> + char *tmp;
> + if (virAsprintf(&tmp, "tcp://%s", uri_in) < 0)
> + goto cleanup;
> + uri = virURIParse(tmp);
> + VIR_FREE(tmp);
> + } else {
> + uri = virURIParse(uri_in);
> + }
> +
> + if (uri == NULL) {
> + virReportError(VIR_ERR_INVALID_ARG,
> + _("unable to parse URI: %s"),
> + uri_in);
> + goto cleanup;
> + }
> +
> + if (uri->server == NULL) {
> + virReportError(VIR_ERR_INVALID_ARG,
> + _("missing host in migration URI: %s"),
> + uri_in);
> + goto cleanup;
> + } else {
> + hostname = uri->server;
> + }
> +
> + if (uri->port == 0) {
> + if (virPortAllocatorAcquire(driver->reservedMigPorts, &port) <
> 0)
> + goto cleanup;
> +
> + if (port == 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Unable to find an unused migrate port"));
> + goto cleanup;
> + }
> + } else {
> + port = uri->port;
> + }
> +
> + if (virAsprintf(uri_out, "tcp://%s:%d", hostname, port) < 0)
> + goto cleanup;
> + }
> +
> + snprintf(portstr, sizeof(portstr), "%d", port);
> +
> + if (virNetSocketNewListenTCP(hostname, portstr, &socks, &nsocks) < 0) {
> + virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> + _("Fail to create socket for incoming migration"));
> + goto cleanup;
> + }
> +
> + if (VIR_ALLOC(args) < 0)
> + goto cleanup;
> +
> + args->conn = dconn;
> + args->vm = vm;
> + args->socks = socks;
> + args->nsocks = nsocks;
> +
> + for (i = 0 ; i < nsocks ; i++) {
> + if (virNetSocketSetBlocking(socks[i], true) < 0)
> + continue;
> + if (virNetSocketListen(socks[i], 1) < 0)
> + continue;
> +
> + if (virNetSocketAddIOCallback(socks[i],
> + 0,
> + doMigrateReceive,
> + args,
> + NULL) < 0) {
> + continue;
> + }
> +
> + virNetSocketUpdateIOCallback(socks[i], VIR_EVENT_HANDLE_READABLE);
> + nsocks_listen ++;
> + }
> +
> + if (!nsocks_listen)
> + goto cleanup;
> +
> + ret = 0;
> + goto end;
> +
> +cleanup:
> + if (nsocks) {
> + for (i = 0 ; i < nsocks ; i++) {
> + virNetSocketClose(socks[i]);
> + virObjectUnref(socks[i]);
> + }
> + VIR_FREE(socks);
> + }
> +
> +end:
> + virURIFree(uri);
> + if (vm)
> + virObjectUnlock(vm);
> + virObjectUnref(cfg);
> + libxlDriverUnlock(driver);
> + return ret;
> +}
> +
> +static int
> +libxlDomainMigratePerform3(virDomainPtr dom,
> + const char *xmlin ATTRIBUTE_UNUSED,
> + const char *cookiein ATTRIBUTE_UNUSED,
> + int cookieinlen ATTRIBUTE_UNUSED,
> + char **cookieout ATTRIBUTE_UNUSED,
> + int *cookieoutlen ATTRIBUTE_UNUSED,
> + const char *dconnuri ATTRIBUTE_UNUSED,
> + const char *uri,
> + unsigned long flags,
> + const char *dname ATTRIBUTE_UNUSED,
> + unsigned long resource ATTRIBUTE_UNUSED)
> +{
> + libxlDriverPrivatePtr driver = dom->conn->privateData;
> + virDomainObjPtr vm;
> + char *hostname = NULL;
> + unsigned short port = 0;
> + char portstr[100];
> + virURIPtr uri_p = NULL;
> + virNetSocketPtr sock;
> + int sockfd = -1;
> + int saved_errno = EINVAL;
> + int ret = -1;
> +
> + virCheckFlags(LIBXL_MIGRATION_FLAGS, -1);
> +
> + vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
> + if (!vm) {
> + char uuidstr[VIR_UUID_STRING_BUFLEN];
> + virUUIDFormat(dom->uuid, uuidstr);
> + virReportError(VIR_ERR_OPERATION_INVALID,
> + _("no domain with matching uuid '%s'"), uuidstr);
> + goto cleanup;
> + }
same here.
> +
> + if (virDomainMigratePerform3EnsureACL(dom->conn, vm->def) < 0)
> + goto cleanup;
> +
> + /* parse dst host:port from uri */
> + uri_p = virURIParse(uri);
> + if (uri_p == NULL || uri_p->server == NULL || uri_p->port == 0)
> + goto cleanup;
> +
> + hostname = uri_p->server;
> + port = uri_p->port;
> + snprintf(portstr, sizeof(portstr), "%d", port);
> +
> + /* socket connect to dst host:port */
> + if (virNetSocketNewConnectTCP(hostname, portstr, &sock) < 0) {
> + virReportSystemError(saved_errno,
> + _("unable to connect to '%s:%s'"),
> + hostname, portstr);
> + goto cleanup;
> + }
> +
> + if (virNetSocketSetBlocking(sock, true) < 0) {
> + virObjectUnref(sock);
> + goto cleanup;
> + }
> +
> + sockfd = virNetSocketDupFD(sock, true);
> + virObjectUnref(sock);
> +
> + /* suspend vm and send saved data to dst through socket fd */
> + ret = doMigrateSend(driver, vm, flags, sockfd);
> +
> +cleanup:
> + VIR_FORCE_CLOSE(sockfd);
> + virURIFree(uri_p);
> + if (vm)
> + virObjectUnlock(vm);
> + return ret;
> +}
> +
> +static virDomainPtr
> +libxlDomainMigrateFinish3(virConnectPtr dconn,
> + const char *dname,
> + const char *cookiein ATTRIBUTE_UNUSED,
> + int cookieinlen ATTRIBUTE_UNUSED,
> + char **cookieout ATTRIBUTE_UNUSED,
> + int *cookieoutlen ATTRIBUTE_UNUSED,
> + const char *dconnuri ATTRIBUTE_UNUSED,
> + const char *uri,
> + unsigned long flags,
> + int cancelled)
> +{
> + libxlDriverPrivatePtr driver = dconn->privateData;
> + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
> + unsigned short port = 0;
> + virURIPtr uri_p = NULL;
> + virDomainObjPtr vm = NULL;
> + virDomainPtr dom = NULL;
> + libxlDomainObjPrivatePtr priv;
> + virDomainEventPtr event = NULL;
> + int rc;
> +
> + virCheckFlags(LIBXL_MIGRATION_FLAGS, NULL);
> +
> + uri_p = virURIParse(uri);
> + if (uri_p == NULL || uri_p->port == 0)
> + VIR_DEBUG("Fail to parse port from URI");
> + port = uri_p->port;
> + if (LIBXL_MIGRATION_PORT_MIN <= port && port <
> LIBXL_MIGRATION_PORT_MAX) {
> + if (virPortAllocatorRelease(driver->reservedMigPorts, port) < 0)
> + VIR_DEBUG("Could not mark port %d as unused", port);
> + }
> +
> + vm = virDomainObjListFindByName(driver->domains, dname);
> + if (!vm)
> + goto cleanup;
> +
> + if (virDomainMigrateFinish3EnsureACL(dconn, vm->def) < 0)
> + goto cleanup;
> +
> + if (!cancelled) {
> + if (!(flags & VIR_MIGRATE_PAUSED)) {
> + priv = vm->privateData;
> + rc = libxl_domain_unpause(priv->ctx, vm->def->id);
> + if (rc) {
> + virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> + _("Failed to unpause domain"));
> + goto error;
> + }
> +
> + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
> VIR_DOMAIN_RUNNING_BOOTED);
> + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
> + goto error;
> + }
> +
> + dom = virGetDomain(dconn, vm->def->name, vm->def->uuid);
> + goto cleanup;
> + }
> +
> +error:
> + if (libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_SAVED)) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Failed to destroy domain '%d'"), vm->def->id);
> + goto cleanup;
> + }
> + event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED,
> + VIR_DOMAIN_EVENT_STOPPED_SAVED);
> + if (!vm->persistent) {
> + virDomainObjListRemove(driver->domains, vm);
> + vm = NULL;
> + }
> +
> +cleanup:
> + virURIFree(uri_p);
> + if (vm)
> + virObjectUnlock(vm);
> + if (event)
> + libxlDomainEventQueue(driver, event);
> + virObjectUnref(cfg);
> + return dom;
> +}
> +
> +static int
> +libxlDomainMigrateConfirm3(virDomainPtr domain,
> + const char *cookiein ATTRIBUTE_UNUSED,
> + int cookieinlen ATTRIBUTE_UNUSED,
> + unsigned long flags,
> + int cancelled)
> +{
> + libxlDriverPrivatePtr driver = domain->conn->privateData;
> + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
> + virDomainObjPtr vm;
> + libxlDomainObjPrivatePtr priv;
> + virDomainEventPtr event = NULL;
> + int ret = -1;
> +
> + virCheckFlags(LIBXL_MIGRATION_FLAGS, -1);
> +
> + vm = virDomainObjListFindByUUID(driver->domains, domain->uuid);
> + if (!vm) {
> + char uuidstr[VIR_UUID_STRING_BUFLEN];
> + virUUIDFormat(domain->uuid, uuidstr);
> + virReportError(VIR_ERR_NO_DOMAIN,
> + _("no domain with matching uuid '%s'"), uuidstr);
> + goto cleanup;
> + }
here.
> +
> + if (virDomainMigrateConfirm3EnsureACL(domain->conn, vm->def) < 0)
> + goto cleanup;
> +
> + if (cancelled) {
> + priv = vm->privateData;
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("migration failed, try to resume on our end"));
> + if (!libxl_domain_resume(priv->ctx, vm->def->id, 0, 0)) {
> + ret = 0;
> + } else {
> + VIR_DEBUG("Failed to resume domain '%d' with libxenlight",
> + vm->def->id);
> + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,
> VIR_DOMAIN_PAUSED_MIGRATION);
> + event = virDomainEventNewFromObj(vm,
> VIR_DOMAIN_EVENT_SUSPENDED,
> +
> VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED);
> + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
> + goto cleanup;
> + }
> +
> + goto cleanup;
> + }
> +
> + if (libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_SAVED)) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Failed to destroy domain '%d'"), vm->def->id);
> + goto cleanup;
> + }
> +
> + event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED,
> + VIR_DOMAIN_EVENT_STOPPED_SAVED);
> +
> + if (flags & VIR_MIGRATE_UNDEFINE_SOURCE)
> + virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm);
> +
> + if (!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE)) {
> + virDomainObjListRemove(driver->domains, vm);
> + vm = NULL;
> + }
> +
> + VIR_DEBUG("Migration successful.\n");
> + ret = 0;
> +
> +cleanup:
> + if (vm)
> + virObjectUnlock(vm);
> + if (event)
> + libxlDomainEventQueue(driver, event);
> + virObjectUnref(cfg);
> + return ret;
> +}
> +
>
> static virDriver libxlDriver = {
> .no = VIR_DRV_LIBXL,
> @@ -4249,6 +4885,11 @@ static virDriver libxlDriver = {
> #ifdef LIBXL_HAVE_DOMAIN_NODEAFFINITY
> .domainGetNumaParameters = libxlDomainGetNumaParameters, /* 1.1.1 */
> #endif
> + .domainMigrateBegin3 = libxlDomainMigrateBegin3, /* 1.1.3 */
> + .domainMigratePrepare3 = libxlDomainMigratePrepare3, /* 1.1.3 */
> + .domainMigratePerform3 = libxlDomainMigratePerform3, /* 1.1.3 */
> + .domainMigrateFinish3 = libxlDomainMigrateFinish3, /* 1.1.3 */
> + .domainMigrateConfirm3 = libxlDomainMigrateConfirm3, /* 1.1.3 */
> .nodeGetFreeMemory = libxlNodeGetFreeMemory, /* 0.9.0 */
> .nodeGetCellsFreeMemory = libxlNodeGetCellsFreeMemory, /* 1.1.1 */
> .connectDomainEventRegister = libxlConnectDomainEventRegister, /*
> 0.9.0 */
> diff --git a/src/libxl/libxl_driver.h b/src/libxl/libxl_driver.h
> index a33d60c..25ac2b8 100644
> --- a/src/libxl/libxl_driver.h
> +++ b/src/libxl/libxl_driver.h
> @@ -24,6 +24,11 @@
> #ifndef LIBXL_DRIVER_H
> # define LIBXL_DRIVER_H
>
> +# define LIBXL_MIGRATION_FLAGS \
> + (VIR_MIGRATE_LIVE | \
> + VIR_MIGRATE_UNDEFINE_SOURCE | \
> + VIR_MIGRATE_PAUSED)
> +
> int libxlRegister(void);
>
> #endif /* LIBXL_DRIVER_H */
> --
> 1.6.0.2
>
> --
> libvir-list mailing list
> libvir-list(a)redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
>
11 years, 1 month
[libvirt] [PATCH] virsh-volume: Add missing check when calling virStreamNew
by Hongwei Bi
Check return value of virStreamNew when called by
cmdVolUpload and cmdVolDownload.
---
tools/virsh-volume.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
index 7dab532..e8b0d9a 100644
--- a/tools/virsh-volume.c
+++ b/tools/virsh-volume.c
@@ -665,7 +665,9 @@ cmdVolUpload(vshControl *ctl, const vshCmd *cmd)
goto cleanup;
}
- st = virStreamNew(ctl->conn, 0);
+ if (!(st = virStreamNew(ctl->conn, 0)))
+ goto cleanup;
+
if (virStorageVolUpload(vol, st, offset, length, 0) < 0) {
vshError(ctl, _("cannot upload to volume %s"), name);
goto cleanup;
@@ -775,7 +777,9 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd)
created = true;
}
- st = virStreamNew(ctl->conn, 0);
+ if (!(st = virStreamNew(ctl->conn, 0)))
+ goto cleanup;
+
if (virStorageVolDownload(vol, st, offset, length, 0) < 0) {
vshError(ctl, _("cannot download from volume %s"), name);
goto cleanup;
--
1.7.1
11 years, 1 month
[libvirt] [PATCHv3 1/2] VMware: Support more than 2 driver backends
by Doug Goldstein
Currently the VMware version check code only supports two types of
VMware backends, Workstation and Player. But in the near future we will
have an additional one so we need to support more. Additionally, we
discover and cache the path to the vmrun binary so we should use that
path when using the cooresponding binary from the VMware VIX SDK.
---
change from v2:
* No change
change from v1:
* Added default case so we don't potentially pass NULL to virCommand
---
src/vmware/vmware_conf.c | 28 +++++++++++++++++++++++++---
src/vmware/vmware_driver.c | 20 ++++++++++++++++++--
2 files changed, 43 insertions(+), 5 deletions(-)
diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c
index 261a4f6..c11c92d 100644
--- a/src/vmware/vmware_conf.c
+++ b/src/vmware/vmware_conf.c
@@ -257,10 +257,30 @@ vmwareExtractVersion(struct vmware_driver *driver)
{
unsigned long version = 0;
int ret = -1;
- virCommandPtr cmd;
+ virCommandPtr cmd = NULL;
char * outbuf = NULL;
- const char * bin = (driver->type == VMWARE_DRIVER_PLAYER) ?
- "vmplayer" : "vmware";
+ char *bin = NULL;
+ char *vmwarePath = NULL;
+
+ if ((vmwarePath = mdir_name(driver->vmrun)) == NULL)
+ goto cleanup;
+
+ switch (driver->type) {
+ case VMWARE_DRIVER_PLAYER:
+ if (virAsprintf(&bin, "%s/%s", vmwarePath, "vmplayer"))
+ goto cleanup;
+ break;
+
+ case VMWARE_DRIVER_WORKSTATION:
+ if (virAsprintf(&bin, "%s/%s", vmwarePath, "vmware"))
+ goto cleanup;
+ break;
+
+ default:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("invalid driver type for version detection"));
+ goto cleanup;
+ }
cmd = virCommandNewArgList(bin, "-v", NULL);
virCommandSetOutputBuffer(cmd, &outbuf);
@@ -276,6 +296,8 @@ vmwareExtractVersion(struct vmware_driver *driver)
cleanup:
virCommandFree(cmd);
VIR_FREE(outbuf);
+ VIR_FREE(bin);
+ VIR_FREE(vmwarePath);
return ret;
}
diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c
index 4e56971..01d65ed 100644
--- a/src/vmware/vmware_driver.c
+++ b/src/vmware/vmware_driver.c
@@ -93,6 +93,7 @@ vmwareConnectOpen(virConnectPtr conn,
{
struct vmware_driver *driver;
size_t i;
+ char *tmp;
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
@@ -144,8 +145,23 @@ vmwareConnectOpen(virConnectPtr conn,
if (virMutexInit(&driver->lock) < 0)
goto cleanup;
- driver->type = STRNEQ(conn->uri->scheme, "vmwareplayer") ?
- VMWARE_DRIVER_WORKSTATION : VMWARE_DRIVER_PLAYER;
+ if ((tmp = STRSKIP(conn->uri->scheme, "vmware")) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, _("unable to parse URI "
+ "scheme '%s'"), conn->uri->scheme);
+ goto cleanup;
+ }
+
+ driver->type = -1;
+ for (i = 0; i < VMWARE_DRIVER_LAST; i++) {
+ if (STREQ(tmp, vmwareDriverTypeToString(i)))
+ driver->type = i;
+ }
+
+ if (driver->type == -1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, _("unable to find valid "
+ "requested VMware backend '%s'"), tmp);
+ goto cleanup;
+ }
if (!(driver->domains = virDomainObjListNew()))
goto cleanup;
--
1.8.1.5
11 years, 1 month
[libvirt] [PATCH] build: fix build --without-lxc
by Eric Blake
'make distcheck' fails from a directory configured --without-lxc:
GEN virt-login-shell.1
Can't write-open ../../tools/virt-login-shell.1: Permission denied at /usr/bin/pod2man line 69.
* tools/Makefile.am (EXTRA_DIST): Ship pre-built man page.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under the build-breaker rule.
tools/Makefile.am | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 0193140..1d9892c 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -84,7 +84,9 @@ dist_man1_MANS = \
virsh.1
if WITH_LXC
dist_man1_MANS += virt-login-shell.1
-endif WITH_LXC
+else ! WITH_LXC
+EXTRA_DIST += virt-login-shell.1
+endif ! WITH_LXC
if WITH_SANLOCK
dist_man8_MANS = virt-sanlock-cleanup.8
endif WITH_SANLOCK
--
1.8.3.1
11 years, 1 month
[libvirt] [PATCH] build: tweak vpath builds of net_rpc
by Eric Blake
Another case missed by commits 716c7bb and 6973e02.
* src/Makefile.am (VIR_NET_RPC_GENERATED): Drop $(srcdir).
(libvirt_net_rpc_la_SOURCES): List generated files more compactly.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under the trivial rule.
src/Makefile.am | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 2b4549e..8632b18 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2194,19 +2194,18 @@ EXTRA_DIST += \
rpc/virkeepaliveprotocol.x
VIR_NET_RPC_GENERATED = \
- $(srcdir)/rpc/virnetprotocol.h \
- $(srcdir)/rpc/virnetprotocol.c \
- $(srcdir)/rpc/virkeepaliveprotocol.h \
- $(srcdir)/rpc/virkeepaliveprotocol.c
+ rpc/virnetprotocol.h \
+ rpc/virnetprotocol.c \
+ rpc/virkeepaliveprotocol.h \
+ rpc/virkeepaliveprotocol.c
BUILT_SOURCES += $(VIR_NET_RPC_GENERATED)
libvirt_net_rpc_la_SOURCES = \
rpc/virnetmessage.h rpc/virnetmessage.c \
- rpc/virnetprotocol.h rpc/virnetprotocol.c \
rpc/virnetsocket.h rpc/virnetsocket.c \
- rpc/virkeepaliveprotocol.h rpc/virkeepaliveprotocol.c \
- rpc/virkeepalive.h rpc/virkeepalive.c
+ rpc/virkeepalive.h rpc/virkeepalive.c \
+ $(VIR_NET_RPC_GENERATED)
if WITH_SSH2
libvirt_net_rpc_la_SOURCES += \
rpc/virnetsshsession.h rpc/virnetsshsession.c
--
1.8.3.1
11 years, 2 months
[libvirt] [PATCHv2 0/4] Improve passthrough of early errors from qemu log
by Peter Krempa
Version 2 fixed according to review feedback of Jan.
Peter Krempa (4):
qemu_process: Make qemuProcessReadLog() more versatile and reusable
qemu: monitor: Add infrastructure to access VM logs for better err
msgs
qemu: monitor: Produce better errors on monitor hangup
qemu: Wire up better early error reporting
src/qemu/qemu_monitor.c | 93 +++++++++++++++++++++++++++++++++++++++++++++----
src/qemu/qemu_monitor.h | 2 ++
src/qemu/qemu_process.c | 54 +++++++++++++++++++---------
src/qemu/qemu_process.h | 2 ++
4 files changed, 129 insertions(+), 22 deletions(-)
--
1.8.3.2
11 years, 2 months
Re: [libvirt] [PATCH] virsh: Fix domdisplay when domain only uses TLS
by Martin Kletzander
On Fri, Sep 27, 2013 at 05:43:50PM +0200, Christophe Fergeau wrote:
> Hey Martin,
>
> Your reply wasn't sent to the mailing list, I'm assuming this was
> unintentional.
>
Yes, sorry, that happened to me with 2 ACKs today :-(
> On Fri, Sep 27, 2013 at 12:08:27PM +0200, Martin Kletzander wrote:
> > On Wed, Sep 25, 2013 at 05:59:54PM +0200, Christophe Fergeau wrote:
> > > It's possible to create a domain which will only use a TLS port
> > > and will not have a non-TLS port set by using:
> > > <graphics type='spice' autoport='yes' defaultMode='secure'/>
> > > In such a setup, the 'graphics' node for the running domain will be:
> > > <graphics type='spice' tlsPort='5900'
> > > autoport='yes' listen='127.0.0.1'
> > > defaultMode='secure'>
> > >
> > > However, cmdDomDisplay loops over all the 'graphics' node, and it
> > > ignores nodes which don't have a 'port' attribute. This means
> > > 'virsh domdisplay' will only return an empty string for domains
> > > as the one above.
> > >
> > > This commit looks for both 'port' and 'tlsPort' before deciding
> > > to ignore a graphics node. It also makes sure 'port' is not printed
> > > when it's not set.
> > > This makes 'virsh domdisplay' return
> > > 'spice://127.0.0.1?tls-port=5900' for domains using only a TLS
> > > port.
> > >
> > > Signed-off-by: Christophe Fergeau <cfergeau(a)redhat.com>
> > > ---
> > > tools/virsh-domain.c | 28 ++++++++++++++++------------
> > > 1 file changed, 16 insertions(+), 12 deletions(-)
> > >
> >
> > ACK and OK for this release.
>
> Thanks, I've pushed this to master.
>
> This patch would also be a good candidate for the stable branch, is there
> some process to follow to get it in there?
>
IIRC, either let Cole know or, if you have the rights, feel free to
just back-port it when it is a bug (which this is).
Martin
11 years, 2 months