2006-03-23 15:42:10 +00:00
|
|
|
/*
|
|
|
|
* xs_internal.c: access to Xen Store
|
|
|
|
*
|
2013-01-28 22:22:28 +00:00
|
|
|
* Copyright (C) 2006, 2009-2013 Red Hat, Inc.
|
2006-03-23 15:42:10 +00:00
|
|
|
*
|
2012-07-27 09:39:53 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-27 09:39:53 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2006-03-23 15:42:10 +00:00
|
|
|
*
|
|
|
|
* Daniel Veillard <veillard@redhat.com>
|
|
|
|
*/
|
|
|
|
|
2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
2007-12-05 21:40:15 +00:00
|
|
|
|
2006-03-23 15:42:10 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
2008-02-05 19:27:37 +00:00
|
|
|
#include <xen/dom0_ops.h>
|
2006-03-23 15:42:10 +00:00
|
|
|
#include <xen/version.h>
|
|
|
|
|
2012-09-26 21:20:35 +00:00
|
|
|
#if HAVE_XENSTORE_H
|
|
|
|
# include <xenstore.h>
|
|
|
|
#else
|
|
|
|
# include <xs.h>
|
|
|
|
#endif
|
2006-03-23 15:42:10 +00:00
|
|
|
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2008-11-04 23:22:06 +00:00
|
|
|
#include "datatypes.h"
|
2006-03-23 15:42:10 +00:00
|
|
|
#include "driver.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2012-12-12 17:59:27 +00:00
|
|
|
#include "virlog.h"
|
2012-12-13 18:01:25 +00:00
|
|
|
#include "viruuid.h"
|
Move xen driver code into src/xen/ directory
* src/Makefile.am, src/proxy_internal.c, src/proxy_internal.h
src/sexpr.c, src/sexpr.h, src/xen_unified.c, src/xen_unified.h,
src/xen_internal.c, src/xen_internal.h, src/xen_inotify.c,
src/xen_inotify.h, src/xend_internal.c, src/xend_internal.h,
src/xm_internal.c, src/xm_internal.h, src/xs_internal.c,
src/xs_internal.h: Move to src/xen/ directory
* proxy/Makefile.am, proxy/libvirt_proxy.c, src/Makefile.am,
src/libvirt.c, tests/sexpr2xmltest.c, tests/statstest.c,
tests/xencapstest.c, tests/xmconfigtest.c, tests/xml2sexprtest.c:
Adapt to changed xen location
* src/stats_linux.h, src/stats_linux.c: Remove xen specific block
stats APIs
* src/qemu_driver.c, src/uml_driver.c: Add missing sys/un.h include
uncovered after change to stats_linux.h
* src/xen/block_stats.h, src/xen/block_stats.c: Add xen specific
block stats APIs
2009-09-15 15:38:33 +00:00
|
|
|
#include "xen_driver.h"
|
2006-03-23 15:42:10 +00:00
|
|
|
#include "xs_internal.h"
|
Move xen driver code into src/xen/ directory
* src/Makefile.am, src/proxy_internal.c, src/proxy_internal.h
src/sexpr.c, src/sexpr.h, src/xen_unified.c, src/xen_unified.h,
src/xen_internal.c, src/xen_internal.h, src/xen_inotify.c,
src/xen_inotify.h, src/xend_internal.c, src/xend_internal.h,
src/xm_internal.c, src/xm_internal.h, src/xs_internal.c,
src/xs_internal.h: Move to src/xen/ directory
* proxy/Makefile.am, proxy/libvirt_proxy.c, src/Makefile.am,
src/libvirt.c, tests/sexpr2xmltest.c, tests/statstest.c,
tests/xencapstest.c, tests/xmconfigtest.c, tests/xml2sexprtest.c:
Adapt to changed xen location
* src/stats_linux.h, src/stats_linux.c: Remove xen specific block
stats APIs
* src/qemu_driver.c, src/uml_driver.c: Add missing sys/un.h include
uncovered after change to stats_linux.h
* src/xen/block_stats.h, src/xen/block_stats.c: Add xen specific
block stats APIs
2009-09-15 15:38:33 +00:00
|
|
|
#include "xen_hypervisor.h"
|
2013-05-03 12:51:25 +00:00
|
|
|
#include "virstring.h"
|
2006-03-23 15:42:10 +00:00
|
|
|
|
2016-01-20 18:36:26 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_XENSTORE
|
2009-01-29 12:10:32 +00:00
|
|
|
|
2014-02-28 12:16:17 +00:00
|
|
|
VIR_LOG_INIT("xen.xs_internal");
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
static void xenStoreWatchEvent(int watch, int fd, int events, void *data);
|
|
|
|
static void xenStoreWatchListFree(xenStoreWatchListPtr list);
|
2006-11-07 16:28:16 +00:00
|
|
|
|
2006-03-23 15:42:10 +00:00
|
|
|
/************************************************************************
|
|
|
|
* *
|
|
|
|
* Helper internal APIs *
|
|
|
|
* *
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virDomainDoStoreQuery:
|
2006-08-09 15:21:16 +00:00
|
|
|
* @conn: pointer to the hypervisor connection
|
|
|
|
* @domid: id of the domain
|
2006-03-23 15:42:10 +00:00
|
|
|
* @path: the relative path of the data in the store to retrieve
|
|
|
|
*
|
|
|
|
* Internal API querying the Xenstore for a string value.
|
|
|
|
*
|
|
|
|
* Returns a string which must be freed by the caller or NULL in case of error
|
|
|
|
*/
|
|
|
|
static char *
|
2006-08-09 15:21:16 +00:00
|
|
|
virDomainDoStoreQuery(virConnectPtr conn, int domid, const char *path)
|
2006-03-23 15:42:10 +00:00
|
|
|
{
|
|
|
|
char s[256];
|
|
|
|
unsigned int len = 0;
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2006-03-23 15:42:10 +00:00
|
|
|
|
2007-04-04 14:19:49 +00:00
|
|
|
if (priv->xshandle == NULL)
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2006-03-23 15:42:10 +00:00
|
|
|
|
2006-08-09 15:21:16 +00:00
|
|
|
snprintf(s, 255, "/local/domain/%d/%s", domid, path);
|
2006-03-23 15:42:10 +00:00
|
|
|
s[255] = 0;
|
|
|
|
|
2007-04-04 14:19:49 +00:00
|
|
|
return xs_read(priv->xshandle, 0, &s[0], &len);
|
2006-03-23 15:42:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* *
|
|
|
|
* Canonical internal APIs *
|
|
|
|
* *
|
|
|
|
************************************************************************/
|
|
|
|
/**
|
|
|
|
* xenStoreOpen:
|
|
|
|
* @conn: pointer to the connection block
|
|
|
|
* @name: URL for the target, NULL for local
|
|
|
|
* @flags: combination of virDrvOpenFlag(s)
|
|
|
|
*
|
|
|
|
* Connects to the Xen hypervisor.
|
|
|
|
*
|
|
|
|
* Returns 0 or -1 in case of error.
|
|
|
|
*/
|
2013-04-30 13:41:48 +00:00
|
|
|
int
|
2007-04-04 14:19:49 +00:00
|
|
|
xenStoreOpen(virConnectPtr conn,
|
2007-12-05 18:28:05 +00:00
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
unsigned int flags)
|
2006-03-23 15:42:10 +00:00
|
|
|
{
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2006-03-23 15:42:10 +00:00
|
|
|
|
2013-04-30 13:41:48 +00:00
|
|
|
virCheckFlags(VIR_CONNECT_RO, -1);
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
|
2007-12-05 18:28:05 +00:00
|
|
|
if (flags & VIR_CONNECT_RO)
|
2008-04-10 16:54:54 +00:00
|
|
|
priv->xshandle = xs_daemon_open_readonly();
|
2006-03-23 15:42:10 +00:00
|
|
|
else
|
2008-04-10 16:54:54 +00:00
|
|
|
priv->xshandle = xs_daemon_open();
|
2006-03-23 15:42:10 +00:00
|
|
|
|
2007-04-04 14:19:49 +00:00
|
|
|
if (priv->xshandle == NULL) {
|
2008-04-10 16:54:54 +00:00
|
|
|
/*
|
2009-01-22 17:49:41 +00:00
|
|
|
* not being able to connect via the socket as an unprivileged
|
|
|
|
* user is rather normal, this should fallback to the proxy (or
|
2007-11-27 14:39:42 +00:00
|
|
|
* remote) mechanism.
|
2008-04-10 16:54:54 +00:00
|
|
|
*/
|
2009-01-22 17:49:41 +00:00
|
|
|
if (xenHavePrivilege()) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_NO_XEN,
|
|
|
|
"%s", _("failed to connect to Xen Store"));
|
2008-04-10 16:54:54 +00:00
|
|
|
}
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2006-03-23 15:42:10 +00:00
|
|
|
}
|
2008-11-25 10:44:52 +00:00
|
|
|
|
|
|
|
/* Init activeDomainList */
|
2013-07-04 10:18:49 +00:00
|
|
|
if (VIR_ALLOC(priv->activeDomainList) < 0)
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* Init watch list before filling in domInfoList,
|
|
|
|
so we can know if it is the first time through
|
|
|
|
when the callback fires */
|
2013-07-04 10:18:49 +00:00
|
|
|
if (VIR_ALLOC(priv->xsWatchList) < 0)
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* This will get called once at start */
|
2012-10-17 09:23:12 +00:00
|
|
|
if (xenStoreAddWatch(conn, "@releaseDomain",
|
|
|
|
"releaseDomain", xenStoreDomainReleased, priv) < 0)
|
2008-11-25 10:44:52 +00:00
|
|
|
{
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("adding watch @releaseDomain"));
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The initial call of this will fill domInfoList */
|
2012-10-17 09:23:12 +00:00
|
|
|
if (xenStoreAddWatch(conn, "@introduceDomain",
|
|
|
|
"introduceDomain", xenStoreDomainIntroduced, priv) < 0)
|
2008-11-25 10:44:52 +00:00
|
|
|
{
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("adding watch @introduceDomain"));
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add an event handle */
|
|
|
|
if ((priv->xsWatch = virEventAddHandle(xs_fileno(priv->xshandle),
|
|
|
|
VIR_EVENT_HANDLE_READABLE,
|
|
|
|
xenStoreWatchEvent,
|
|
|
|
conn,
|
|
|
|
NULL)) < 0)
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("Failed to add event handle, disabling events");
|
2008-11-25 10:44:52 +00:00
|
|
|
|
|
|
|
return 0;
|
2006-03-23 15:42:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* xenStoreClose:
|
|
|
|
* @conn: pointer to the connection block
|
|
|
|
*
|
|
|
|
* Close the connection to the Xen hypervisor.
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success or -1 in case of error.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
xenStoreClose(virConnectPtr conn)
|
|
|
|
{
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2008-11-25 10:44:52 +00:00
|
|
|
|
|
|
|
if (xenStoreRemoveWatch(conn, "@introduceDomain", "introduceDomain") < 0) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("Warning, could not remove @introduceDomain watch");
|
2008-11-25 10:44:52 +00:00
|
|
|
/* not fatal */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xenStoreRemoveWatch(conn, "@releaseDomain", "releaseDomain") < 0) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("Warning, could not remove @releaseDomain watch");
|
2008-11-25 10:44:52 +00:00
|
|
|
/* not fatal */
|
|
|
|
}
|
|
|
|
|
|
|
|
xenStoreWatchListFree(priv->xsWatchList);
|
2009-01-15 01:21:36 +00:00
|
|
|
priv->xsWatchList = NULL;
|
2009-01-20 17:19:23 +00:00
|
|
|
xenUnifiedDomainInfoListFree(priv->activeDomainList);
|
|
|
|
priv->activeDomainList = NULL;
|
2010-11-08 16:32:02 +00:00
|
|
|
|
2007-04-04 14:19:49 +00:00
|
|
|
if (priv->xshandle == NULL)
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2007-04-04 14:19:49 +00:00
|
|
|
|
2008-11-25 10:44:52 +00:00
|
|
|
if (priv->xsWatch != -1)
|
|
|
|
virEventRemoveHandle(priv->xsWatch);
|
2010-11-08 16:32:02 +00:00
|
|
|
|
2007-04-04 14:19:49 +00:00
|
|
|
xs_daemon_close(priv->xshandle);
|
2008-11-25 10:44:52 +00:00
|
|
|
priv->xshandle = NULL;
|
|
|
|
|
2012-03-22 11:33:35 +00:00
|
|
|
return 0;
|
2006-03-23 15:42:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* xenStoreNumOfDomains:
|
|
|
|
* @conn: pointer to the hypervisor connection
|
|
|
|
*
|
|
|
|
* Provides the number of active domains.
|
|
|
|
*
|
|
|
|
* Returns the number of domain found or -1 in case of error
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
xenStoreNumOfDomains(virConnectPtr conn)
|
|
|
|
{
|
|
|
|
unsigned int num;
|
2014-07-18 07:46:39 +00:00
|
|
|
char **idlist = NULL;
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int ret = -1, realnum = 0;
|
2009-10-09 09:32:37 +00:00
|
|
|
long id;
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2006-03-23 15:42:10 +00:00
|
|
|
|
2007-04-04 14:19:49 +00:00
|
|
|
idlist = xs_directory(priv->xshandle, 0, "/local/domain", &num);
|
2006-03-23 15:42:10 +00:00
|
|
|
if (idlist) {
|
2009-10-09 09:32:37 +00:00
|
|
|
for (i = 0; i < num; i++) {
|
2014-07-18 07:46:39 +00:00
|
|
|
if (virStrToLong_l(idlist[i], NULL, 10, &id) < 0)
|
2009-10-09 09:32:37 +00:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
/* Sometimes xenstore has stale domain IDs, so filter
|
|
|
|
against the hypervisor's info */
|
|
|
|
if (xenHypervisorHasDomain(conn, (int)id))
|
|
|
|
realnum++;
|
|
|
|
}
|
2014-03-25 06:54:51 +00:00
|
|
|
out:
|
2012-10-17 09:23:12 +00:00
|
|
|
VIR_FREE(idlist);
|
2009-10-09 09:32:37 +00:00
|
|
|
ret = realnum;
|
2006-03-23 15:42:10 +00:00
|
|
|
}
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2006-03-23 15:42:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2009-01-23 19:18:24 +00:00
|
|
|
* xenStoreDoListDomains:
|
2006-03-23 15:42:10 +00:00
|
|
|
* @conn: pointer to the hypervisor connection
|
|
|
|
* @ids: array to collect the list of IDs of active domains
|
|
|
|
* @maxids: size of @ids
|
|
|
|
*
|
2009-01-23 19:18:24 +00:00
|
|
|
* Internal API: collect the list of active domains, and store
|
|
|
|
* their ID in @maxids. The driver lock must be held.
|
2006-03-23 15:42:10 +00:00
|
|
|
*
|
|
|
|
* Returns the number of domain found or -1 in case of error
|
|
|
|
*/
|
2009-01-23 19:18:24 +00:00
|
|
|
static int
|
2013-01-28 22:22:28 +00:00
|
|
|
xenStoreDoListDomains(virConnectPtr conn,
|
|
|
|
xenUnifiedPrivatePtr priv,
|
|
|
|
int *ids,
|
|
|
|
int maxids)
|
2006-03-23 15:42:10 +00:00
|
|
|
{
|
2014-07-18 07:46:39 +00:00
|
|
|
char **idlist = NULL;
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
unsigned int num;
|
|
|
|
size_t i;
|
2009-01-23 19:18:24 +00:00
|
|
|
int ret = -1;
|
2006-03-23 15:42:10 +00:00
|
|
|
long id;
|
2009-01-21 18:11:14 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
idlist = xs_directory(priv->xshandle, 0, "/local/domain", &num);
|
2006-03-23 15:42:10 +00:00
|
|
|
if (idlist == NULL)
|
2009-01-23 19:18:24 +00:00
|
|
|
goto out;
|
2006-03-23 15:42:10 +00:00
|
|
|
|
|
|
|
for (ret = 0, i = 0; (i < num) && (ret < maxids); i++) {
|
2014-07-18 07:46:39 +00:00
|
|
|
if (virStrToLong_l(idlist[i], NULL, 10, &id) < 0)
|
2009-01-23 19:18:24 +00:00
|
|
|
goto out;
|
2009-10-09 09:32:37 +00:00
|
|
|
|
|
|
|
/* Sometimes xenstore has stale domain IDs, so filter
|
|
|
|
against the hypervisor's info */
|
|
|
|
if (xenHypervisorHasDomain(conn, (int)id))
|
|
|
|
ids[ret++] = (int) id;
|
2006-03-23 15:42:10 +00:00
|
|
|
}
|
2009-01-23 19:18:24 +00:00
|
|
|
|
2014-03-25 06:54:51 +00:00
|
|
|
out:
|
2012-10-17 09:23:12 +00:00
|
|
|
VIR_FREE(idlist);
|
2009-01-23 19:18:24 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* xenStoreListDomains:
|
|
|
|
* @conn: pointer to the hypervisor connection
|
|
|
|
* @ids: array to collect the list of IDs of active domains
|
|
|
|
* @maxids: size of @ids
|
|
|
|
*
|
|
|
|
* Collect the list of active domains, and store their ID in @maxids
|
|
|
|
*
|
|
|
|
* Returns the number of domain found or -1 in case of error
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
xenStoreListDomains(virConnectPtr conn, int *ids, int maxids)
|
|
|
|
{
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2009-01-23 19:18:24 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
xenUnifiedLock(priv);
|
2009-10-09 09:32:37 +00:00
|
|
|
ret = xenStoreDoListDomains(conn, priv, ids, maxids);
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedUnlock(priv);
|
2009-01-23 19:18:24 +00:00
|
|
|
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2006-03-23 15:42:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-08 20:14:40 +00:00
|
|
|
/**
|
|
|
|
* xenStoreDomainGetVNCPort:
|
2006-08-09 15:21:16 +00:00
|
|
|
* @conn: the hypervisor connection
|
|
|
|
* @domid: id of the domain
|
2006-08-08 20:14:40 +00:00
|
|
|
*
|
|
|
|
* Return the port number on which the domain is listening for VNC
|
2008-02-05 19:27:37 +00:00
|
|
|
* connections.
|
2006-08-08 20:14:40 +00:00
|
|
|
*
|
2009-01-21 18:11:14 +00:00
|
|
|
* The caller must hold the lock on the privateData
|
|
|
|
* associated with the 'conn' parameter.
|
|
|
|
*
|
2006-08-08 20:14:40 +00:00
|
|
|
* Returns the port number, -1 in case of error
|
|
|
|
*/
|
2013-01-28 22:22:28 +00:00
|
|
|
int
|
|
|
|
xenStoreDomainGetVNCPort(virConnectPtr conn, int domid)
|
|
|
|
{
|
2006-08-08 20:14:40 +00:00
|
|
|
char *tmp;
|
|
|
|
int ret = -1;
|
|
|
|
|
2006-08-09 15:21:16 +00:00
|
|
|
tmp = virDomainDoStoreQuery(conn, domid, "console/vnc-port");
|
2006-08-08 20:14:40 +00:00
|
|
|
if (tmp != NULL) {
|
2014-07-21 08:17:02 +00:00
|
|
|
ignore_value(virStrToLong_i(tmp, NULL, 10, &ret));
|
2009-12-09 23:00:50 +00:00
|
|
|
VIR_FREE(tmp);
|
2006-08-08 20:14:40 +00:00
|
|
|
}
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2006-08-08 20:14:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* xenStoreDomainGetConsolePath:
|
2006-08-09 15:21:16 +00:00
|
|
|
* @conn: the hypervisor connection
|
|
|
|
* @domid: id of the domain
|
2006-08-08 20:14:40 +00:00
|
|
|
*
|
2010-01-25 14:58:40 +00:00
|
|
|
* Return the path to the pseudo TTY on which the guest domain's
|
2006-08-08 20:14:40 +00:00
|
|
|
* serial console is attached.
|
|
|
|
*
|
|
|
|
* Returns the path to the serial console. It is the callers
|
2014-04-20 20:07:46 +00:00
|
|
|
* responsibility to free() the return string. Returns NULL
|
2006-08-08 20:14:40 +00:00
|
|
|
* on error
|
2009-01-21 18:11:14 +00:00
|
|
|
*
|
|
|
|
* The caller must hold the lock on the privateData
|
|
|
|
* associated with the 'conn' parameter.
|
2006-08-08 20:14:40 +00:00
|
|
|
*/
|
2013-01-28 22:22:28 +00:00
|
|
|
char *
|
|
|
|
xenStoreDomainGetConsolePath(virConnectPtr conn, int domid)
|
|
|
|
{
|
2006-08-09 15:21:16 +00:00
|
|
|
return virDomainDoStoreQuery(conn, domid, "console/tty");
|
2006-08-08 20:14:40 +00:00
|
|
|
}
|
2006-11-07 16:28:16 +00:00
|
|
|
|
2012-01-03 22:39:59 +00:00
|
|
|
/**
|
|
|
|
* xenStoreDomainGetSerailConsolePath:
|
|
|
|
* @conn: the hypervisor connection
|
|
|
|
* @domid: id of the domain
|
|
|
|
*
|
|
|
|
* Return the path to the pseudo TTY on which the guest domain's
|
|
|
|
* serial console is attached.
|
|
|
|
*
|
|
|
|
* Returns the path to the serial console. It is the callers
|
2014-04-20 20:07:46 +00:00
|
|
|
* responsibility to free() the return string. Returns NULL
|
2012-01-03 22:39:59 +00:00
|
|
|
* on error
|
|
|
|
*
|
|
|
|
* The caller must hold the lock on the privateData
|
|
|
|
* associated with the 'conn' parameter.
|
|
|
|
*/
|
2013-01-28 22:22:28 +00:00
|
|
|
char *
|
|
|
|
xenStoreDomainGetSerialConsolePath(virConnectPtr conn, int domid)
|
|
|
|
{
|
2012-01-03 22:39:59 +00:00
|
|
|
return virDomainDoStoreQuery(conn, domid, "serial/0/tty");
|
|
|
|
}
|
|
|
|
|
2006-11-20 16:42:16 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* xenStoreDomainGetNetworkID:
|
|
|
|
* @conn: pointer to the connection.
|
|
|
|
* @id: the domain id
|
|
|
|
* @mac: the mac address
|
|
|
|
*
|
|
|
|
* Get the reference (i.e. the string number) for the device on that domain
|
|
|
|
* which uses the given mac address
|
|
|
|
*
|
2009-01-21 18:11:14 +00:00
|
|
|
* The caller must hold the lock on the privateData
|
|
|
|
* associated with the 'conn' parameter.
|
|
|
|
*
|
2006-11-20 16:42:16 +00:00
|
|
|
* Returns the new string or NULL in case of error, the string must be
|
|
|
|
* freed by the caller.
|
|
|
|
*/
|
|
|
|
char *
|
2013-01-28 22:22:28 +00:00
|
|
|
xenStoreDomainGetNetworkID(virConnectPtr conn, int id, const char *mac)
|
|
|
|
{
|
2006-11-20 16:42:16 +00:00
|
|
|
char dir[80], path[128], **list = NULL, *val = NULL;
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
unsigned int len, num;
|
|
|
|
size_t i;
|
2006-11-20 16:42:16 +00:00
|
|
|
char *ret = NULL;
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2006-11-20 16:42:16 +00:00
|
|
|
|
2013-01-28 22:22:28 +00:00
|
|
|
if (id < 0 || priv->xshandle == NULL || mac == NULL)
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2006-11-20 16:42:16 +00:00
|
|
|
|
2007-03-23 16:15:07 +00:00
|
|
|
snprintf(dir, sizeof(dir), "/local/domain/0/backend/vif/%d", id);
|
2007-04-04 14:19:49 +00:00
|
|
|
list = xs_directory(priv->xshandle, 0, dir, &num);
|
2006-11-20 16:42:16 +00:00
|
|
|
if (list == NULL)
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2006-11-20 16:42:16 +00:00
|
|
|
for (i = 0; i < num; i++) {
|
2008-04-10 16:54:54 +00:00
|
|
|
snprintf(path, sizeof(path), "%s/%s/%s", dir, list[i], "mac");
|
2009-02-05 18:14:00 +00:00
|
|
|
if ((val = xs_read(priv->xshandle, 0, path, &len)) == NULL)
|
2008-04-10 16:54:54 +00:00
|
|
|
break;
|
2009-02-05 18:14:00 +00:00
|
|
|
|
|
|
|
bool match = (virMacAddrCompare(val, mac) == 0);
|
|
|
|
|
|
|
|
VIR_FREE(val);
|
|
|
|
|
|
|
|
if (match) {
|
2013-05-03 12:51:25 +00:00
|
|
|
ignore_value(VIR_STRDUP(ret, list[i]));
|
2008-04-10 16:54:54 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-11-20 16:42:16 +00:00
|
|
|
}
|
2009-02-05 18:14:00 +00:00
|
|
|
|
|
|
|
VIR_FREE(list);
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2006-11-20 16:42:16 +00:00
|
|
|
}
|
2007-03-15 07:43:16 +00:00
|
|
|
|
2007-11-06 11:49:01 +00:00
|
|
|
/*
|
|
|
|
* xenStoreDomainGetDiskID:
|
|
|
|
* @conn: pointer to the connection.
|
|
|
|
* @id: the domain id
|
|
|
|
* @dev: the virtual block device name
|
|
|
|
*
|
|
|
|
* Get the reference (i.e. the string number) for the device on that domain
|
|
|
|
* which uses the given virtual block device name
|
|
|
|
*
|
2009-01-21 18:11:14 +00:00
|
|
|
* The caller must hold the lock on the privateData
|
|
|
|
* associated with the 'conn' parameter.
|
|
|
|
*
|
2007-11-06 11:49:01 +00:00
|
|
|
* Returns the new string or NULL in case of error, the string must be
|
|
|
|
* freed by the caller.
|
|
|
|
*/
|
|
|
|
char *
|
2013-01-28 22:22:28 +00:00
|
|
|
xenStoreDomainGetDiskID(virConnectPtr conn, int id, const char *dev)
|
|
|
|
{
|
2007-11-06 11:49:01 +00:00
|
|
|
char dir[80], path[128], **list = NULL, *val = NULL;
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
unsigned int devlen, len, num;
|
|
|
|
size_t i;
|
2007-11-06 11:49:01 +00:00
|
|
|
char *ret = NULL;
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2007-11-06 11:49:01 +00:00
|
|
|
|
2013-01-28 22:22:28 +00:00
|
|
|
if (id < 0 || priv->xshandle == NULL || dev == NULL)
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2007-11-06 11:49:01 +00:00
|
|
|
devlen = strlen(dev);
|
|
|
|
if (devlen <= 0)
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2007-11-06 11:49:01 +00:00
|
|
|
|
|
|
|
snprintf(dir, sizeof(dir), "/local/domain/0/backend/vbd/%d", id);
|
|
|
|
list = xs_directory(priv->xshandle, 0, dir, &num);
|
2007-12-14 15:38:02 +00:00
|
|
|
if (list != NULL) {
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
snprintf(path, sizeof(path), "%s/%s/%s", dir, list[i], "dev");
|
|
|
|
val = xs_read(priv->xshandle, 0, path, &len);
|
|
|
|
if (val == NULL)
|
|
|
|
break;
|
|
|
|
if ((devlen != len) || memcmp(val, dev, len)) {
|
2012-10-17 09:23:12 +00:00
|
|
|
VIR_FREE(val);
|
2007-12-14 15:38:02 +00:00
|
|
|
} else {
|
2013-05-03 12:51:25 +00:00
|
|
|
ignore_value(VIR_STRDUP(ret, list[i]));
|
2009-11-08 21:08:54 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
VIR_FREE(val);
|
|
|
|
VIR_FREE(list);
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2007-12-14 15:38:02 +00:00
|
|
|
}
|
2007-11-06 11:49:01 +00:00
|
|
|
}
|
2012-10-17 09:23:12 +00:00
|
|
|
VIR_FREE(list);
|
2007-11-06 11:49:01 +00:00
|
|
|
}
|
2007-12-14 15:38:02 +00:00
|
|
|
snprintf(dir, sizeof(dir), "/local/domain/0/backend/tap/%d", id);
|
|
|
|
list = xs_directory(priv->xshandle, 0, dir, &num);
|
|
|
|
if (list != NULL) {
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
snprintf(path, sizeof(path), "%s/%s/%s", dir, list[i], "dev");
|
|
|
|
val = xs_read(priv->xshandle, 0, path, &len);
|
|
|
|
if (val == NULL)
|
|
|
|
break;
|
|
|
|
if ((devlen != len) || memcmp(val, dev, len)) {
|
2012-10-17 09:23:12 +00:00
|
|
|
VIR_FREE(val);
|
2007-12-14 15:38:02 +00:00
|
|
|
} else {
|
2013-05-03 12:51:25 +00:00
|
|
|
ignore_value(VIR_STRDUP(ret, list[i]));
|
2009-11-08 21:08:54 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
VIR_FREE(val);
|
|
|
|
VIR_FREE(list);
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2007-12-14 15:38:02 +00:00
|
|
|
}
|
|
|
|
}
|
2012-10-17 09:23:12 +00:00
|
|
|
VIR_FREE(list);
|
2007-12-14 15:38:02 +00:00
|
|
|
}
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2007-11-06 11:49:01 +00:00
|
|
|
}
|
|
|
|
|
2009-12-22 09:53:51 +00:00
|
|
|
/*
|
|
|
|
* xenStoreDomainGetPCIID:
|
|
|
|
* @conn: pointer to the connection.
|
|
|
|
* @id: the domain id
|
|
|
|
* @bdf: the PCI BDF
|
|
|
|
*
|
|
|
|
* Get the reference (i.e. the string number) for the device on that domain
|
|
|
|
* which uses the given PCI address
|
|
|
|
*
|
|
|
|
* The caller must hold the lock on the privateData
|
|
|
|
* associated with the 'conn' parameter.
|
|
|
|
*
|
|
|
|
* Returns the new string or NULL in case of error, the string must be
|
|
|
|
* freed by the caller.
|
|
|
|
*/
|
|
|
|
char *
|
|
|
|
xenStoreDomainGetPCIID(virConnectPtr conn, int id, const char *bdf)
|
|
|
|
{
|
|
|
|
char dir[80], path[128], **list = NULL, *val = NULL;
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
unsigned int len, num;
|
|
|
|
size_t i;
|
2009-12-22 09:53:51 +00:00
|
|
|
char *ret = NULL;
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2009-12-22 09:53:51 +00:00
|
|
|
|
2013-01-28 22:22:28 +00:00
|
|
|
if (id < 0 || priv->xshandle == NULL || bdf == NULL)
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2009-12-22 09:53:51 +00:00
|
|
|
|
|
|
|
snprintf(dir, sizeof(dir), "/local/domain/0/backend/pci/%d", id);
|
|
|
|
list = xs_directory(priv->xshandle, 0, dir, &num);
|
|
|
|
if (list == NULL)
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2009-12-22 09:53:51 +00:00
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
snprintf(path, sizeof(path), "%s/%s/%s", dir, list[i], "dev-0");
|
|
|
|
if ((val = xs_read(priv->xshandle, 0, path, &len)) == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
bool match = STREQ(val, bdf);
|
|
|
|
|
|
|
|
VIR_FREE(val);
|
|
|
|
|
|
|
|
if (match) {
|
2013-05-03 12:51:25 +00:00
|
|
|
ignore_value(VIR_STRDUP(ret, list[i]));
|
2009-12-22 09:53:51 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(list);
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2009-12-22 09:53:51 +00:00
|
|
|
}
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
/*
|
|
|
|
* The caller must hold the lock on the privateData
|
|
|
|
* associated with the 'conn' parameter.
|
|
|
|
*/
|
2013-01-28 22:22:28 +00:00
|
|
|
char *
|
|
|
|
xenStoreDomainGetName(virConnectPtr conn, int id)
|
|
|
|
{
|
2007-08-10 18:25:15 +00:00
|
|
|
char prop[200];
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2007-08-10 18:25:15 +00:00
|
|
|
unsigned int len;
|
|
|
|
|
|
|
|
if (priv->xshandle == NULL)
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2007-08-10 18:25:15 +00:00
|
|
|
|
|
|
|
snprintf(prop, 199, "/local/domain/%d/name", id);
|
|
|
|
prop[199] = 0;
|
|
|
|
return xs_read(priv->xshandle, 0, prop, &len);
|
|
|
|
}
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
/*
|
|
|
|
* The caller must hold the lock on the privateData
|
|
|
|
* associated with the 'conn' parameter.
|
|
|
|
*/
|
2013-01-28 22:22:28 +00:00
|
|
|
int
|
|
|
|
xenStoreDomainGetUUID(virConnectPtr conn, int id, unsigned char *uuid)
|
|
|
|
{
|
2008-11-25 10:44:52 +00:00
|
|
|
char prop[200];
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2008-11-25 10:44:52 +00:00
|
|
|
unsigned int len;
|
|
|
|
char *uuidstr;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (priv->xshandle == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
snprintf(prop, 199, "/local/domain/%d/vm", id);
|
|
|
|
prop[199] = 0;
|
2011-01-28 21:38:06 +00:00
|
|
|
/* This will return something like
|
2012-08-24 12:58:52 +00:00
|
|
|
* /vm/00000000-0000-0000-0000-000000000000[-*] */
|
2008-11-25 10:44:52 +00:00
|
|
|
uuidstr = xs_read(priv->xshandle, 0, prop, &len);
|
2012-08-24 12:58:52 +00:00
|
|
|
/* Strip optional version suffix when VM was renamed */
|
|
|
|
if (len > 40) /* strlen('/vm/') + VIR_UUID_STRING_BUFLEN - sizeof('\0') */
|
|
|
|
uuidstr[40] = '\0';
|
2008-11-25 10:44:52 +00:00
|
|
|
|
2011-01-28 21:38:06 +00:00
|
|
|
/* remove "/vm/" */
|
2008-11-25 10:44:52 +00:00
|
|
|
ret = virUUIDParse(uuidstr + 4, uuid);
|
|
|
|
|
|
|
|
VIR_FREE(uuidstr);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
static void
|
|
|
|
xenStoreWatchListFree(xenStoreWatchListPtr list)
|
2008-11-25 10:44:52 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2014-01-20 11:27:29 +00:00
|
|
|
for (i = 0; i < list->count; i++) {
|
2008-11-25 10:44:52 +00:00
|
|
|
VIR_FREE(list->watches[i]->path);
|
|
|
|
VIR_FREE(list->watches[i]->token);
|
|
|
|
VIR_FREE(list->watches[i]);
|
|
|
|
}
|
|
|
|
VIR_FREE(list);
|
|
|
|
}
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
/*
|
|
|
|
* The caller must hold the lock on the privateData
|
|
|
|
* associated with the 'conn' parameter.
|
|
|
|
*/
|
2013-01-28 22:22:28 +00:00
|
|
|
int
|
|
|
|
xenStoreAddWatch(virConnectPtr conn,
|
|
|
|
const char *path,
|
|
|
|
const char *token,
|
|
|
|
xenStoreWatchCallback cb,
|
|
|
|
void *opaque)
|
2008-11-25 10:44:52 +00:00
|
|
|
{
|
2009-11-08 21:08:54 +00:00
|
|
|
xenStoreWatchPtr watch = NULL;
|
2008-11-25 10:44:52 +00:00
|
|
|
int n;
|
|
|
|
xenStoreWatchListPtr list;
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2008-11-25 10:44:52 +00:00
|
|
|
|
|
|
|
if (priv->xshandle == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
list = priv->xsWatchList;
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!list)
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* check if we already have this callback on our list */
|
2014-01-20 11:27:29 +00:00
|
|
|
for (n = 0; n < list->count; n++) {
|
2012-10-17 09:23:12 +00:00
|
|
|
if (STREQ(list->watches[n]->path, path) &&
|
2008-11-25 10:44:52 +00:00
|
|
|
STREQ(list->watches[n]->token, token)) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("watch already tracked"));
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-04 10:18:49 +00:00
|
|
|
if (VIR_ALLOC(watch) < 0)
|
2013-05-03 12:51:25 +00:00
|
|
|
goto error;
|
2009-11-08 21:08:54 +00:00
|
|
|
|
2013-05-03 12:51:25 +00:00
|
|
|
watch->cb = cb;
|
2008-11-25 10:44:52 +00:00
|
|
|
watch->opaque = opaque;
|
2013-05-03 12:51:25 +00:00
|
|
|
if (VIR_STRDUP(watch->path, path) < 0 ||
|
|
|
|
VIR_STRDUP(watch->token, token) < 0)
|
|
|
|
goto error;
|
2009-11-08 21:08:54 +00:00
|
|
|
|
2014-03-07 08:33:31 +00:00
|
|
|
if (VIR_APPEND_ELEMENT_COPY(list->watches, list->count, watch) < 0)
|
2013-05-03 12:51:25 +00:00
|
|
|
goto error;
|
2008-11-25 10:44:52 +00:00
|
|
|
|
|
|
|
return xs_watch(priv->xshandle, watch->path, watch->token);
|
2009-11-08 21:08:54 +00:00
|
|
|
|
2014-03-25 06:54:51 +00:00
|
|
|
error:
|
2009-11-08 21:08:54 +00:00
|
|
|
if (watch) {
|
|
|
|
VIR_FREE(watch->path);
|
|
|
|
VIR_FREE(watch->token);
|
|
|
|
VIR_FREE(watch);
|
|
|
|
}
|
|
|
|
return -1;
|
2008-11-25 10:44:52 +00:00
|
|
|
}
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
/*
|
|
|
|
* The caller must hold the lock on the privateData
|
|
|
|
* associated with the 'conn' parameter.
|
|
|
|
*/
|
2013-01-28 22:22:28 +00:00
|
|
|
int
|
|
|
|
xenStoreRemoveWatch(virConnectPtr conn, const char *path, const char *token)
|
2008-11-25 10:44:52 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2008-11-25 10:44:52 +00:00
|
|
|
xenStoreWatchListPtr list;
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2008-11-25 10:44:52 +00:00
|
|
|
|
|
|
|
if (priv->xshandle == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
list = priv->xsWatchList;
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!list)
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
|
|
|
|
2013-05-21 07:21:21 +00:00
|
|
|
for (i = 0; i < list->count; i++) {
|
2012-10-17 09:23:12 +00:00
|
|
|
if (STREQ(list->watches[i]->path, path) &&
|
2008-11-25 10:44:52 +00:00
|
|
|
STREQ(list->watches[i]->token, token)) {
|
|
|
|
|
|
|
|
if (!xs_unwatch(priv->xshandle,
|
|
|
|
list->watches[i]->path,
|
2009-01-15 01:23:32 +00:00
|
|
|
list->watches[i]->token))
|
2008-11-25 10:44:52 +00:00
|
|
|
{
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("WARNING: Could not remove watch");
|
2008-11-25 10:44:52 +00:00
|
|
|
/* Not fatal, continue */
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(list->watches[i]->path);
|
|
|
|
VIR_FREE(list->watches[i]->token);
|
|
|
|
VIR_FREE(list->watches[i]);
|
|
|
|
|
2014-03-07 08:33:31 +00:00
|
|
|
VIR_DELETE_ELEMENT(list->watches, i, list->count);
|
2008-11-25 10:44:52 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
static xenStoreWatchPtr
|
|
|
|
xenStoreFindWatch(xenStoreWatchListPtr list,
|
|
|
|
const char *path,
|
|
|
|
const char *token)
|
2008-11-25 10:44:52 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2013-05-21 07:21:21 +00:00
|
|
|
for (i = 0; i < list->count; i++)
|
2012-10-17 09:23:12 +00:00
|
|
|
if (STREQ(path, list->watches[i]->path) &&
|
|
|
|
STREQ(token, list->watches[i]->token))
|
2008-11-25 10:44:52 +00:00
|
|
|
return list->watches[i];
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
static void
|
|
|
|
xenStoreWatchEvent(int watch ATTRIBUTE_UNUSED,
|
|
|
|
int fd ATTRIBUTE_UNUSED,
|
2013-01-28 22:22:28 +00:00
|
|
|
int events, void *data)
|
2008-11-25 10:44:52 +00:00
|
|
|
{
|
|
|
|
char **event;
|
|
|
|
char *path;
|
|
|
|
char *token;
|
|
|
|
unsigned int stringCount;
|
|
|
|
xenStoreWatchPtr sw;
|
|
|
|
|
|
|
|
virConnectPtr conn = data;
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2009-03-11 13:43:24 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!priv) return;
|
2009-01-21 18:11:14 +00:00
|
|
|
|
2009-03-11 13:43:24 +00:00
|
|
|
/* only set a watch on read and write events */
|
|
|
|
if (events & (VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP)) return;
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!priv->xshandle)
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2008-11-25 10:44:52 +00:00
|
|
|
|
|
|
|
event = xs_read_watch(priv->xshandle, &stringCount);
|
|
|
|
if (!event)
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2008-11-25 10:44:52 +00:00
|
|
|
|
|
|
|
path = event[XS_WATCH_PATH];
|
|
|
|
token = event[XS_WATCH_TOKEN];
|
|
|
|
|
|
|
|
sw = xenStoreFindWatch(priv->xsWatchList, path, token);
|
2012-10-17 09:23:12 +00:00
|
|
|
if (sw)
|
2008-11-25 10:44:52 +00:00
|
|
|
sw->cb(conn, path, token, sw->opaque);
|
|
|
|
VIR_FREE(event);
|
2009-01-21 18:11:14 +00:00
|
|
|
|
2014-03-25 06:54:51 +00:00
|
|
|
cleanup:
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedUnlock(priv);
|
2008-11-25 10:44:52 +00:00
|
|
|
}
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The domain callback for the @introduceDomain watch
|
|
|
|
*
|
|
|
|
* The lock on 'priv' is held when calling this
|
|
|
|
*/
|
2013-01-28 22:22:28 +00:00
|
|
|
int
|
|
|
|
xenStoreDomainIntroduced(virConnectPtr conn,
|
|
|
|
const char *path ATTRIBUTE_UNUSED,
|
|
|
|
const char *token ATTRIBUTE_UNUSED,
|
|
|
|
void *opaque)
|
2008-11-25 10:44:52 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i, j;
|
|
|
|
int found, missing = 0, retries = 20;
|
2008-11-25 10:44:52 +00:00
|
|
|
int new_domain_cnt;
|
|
|
|
int *new_domids;
|
|
|
|
int nread;
|
|
|
|
|
2009-01-20 17:19:23 +00:00
|
|
|
xenUnifiedPrivatePtr priv = opaque;
|
2008-11-25 10:44:52 +00:00
|
|
|
|
2014-03-25 06:54:51 +00:00
|
|
|
retry:
|
2008-11-25 10:44:52 +00:00
|
|
|
new_domain_cnt = xenStoreNumOfDomains(conn);
|
2010-02-02 11:22:17 +00:00
|
|
|
if (new_domain_cnt < 0)
|
|
|
|
return -1;
|
|
|
|
|
2013-11-19 22:32:34 +00:00
|
|
|
if (VIR_ALLOC_N(new_domids, new_domain_cnt) < 0)
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
2009-10-09 09:32:37 +00:00
|
|
|
nread = xenStoreDoListDomains(conn, priv, new_domids, new_domain_cnt);
|
2008-11-25 10:44:52 +00:00
|
|
|
if (nread != new_domain_cnt) {
|
2011-01-28 21:38:06 +00:00
|
|
|
/* mismatch. retry this read */
|
2008-11-25 10:44:52 +00:00
|
|
|
VIR_FREE(new_domids);
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
|
|
|
|
missing = 0;
|
2014-01-20 11:27:29 +00:00
|
|
|
for (i = 0; i < new_domain_cnt; i++) {
|
2008-11-25 10:44:52 +00:00
|
|
|
found = 0;
|
2013-05-21 07:21:21 +00:00
|
|
|
for (j = 0; j < priv->activeDomainList->count; j++) {
|
2009-01-20 17:19:23 +00:00
|
|
|
if (priv->activeDomainList->doms[j]->id == new_domids[i]) {
|
2008-11-25 10:44:52 +00:00
|
|
|
found = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found) {
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event;
|
2008-11-25 10:44:52 +00:00
|
|
|
char *name;
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
|
|
|
|
if (!(name = xenStoreDomainGetName(conn, new_domids[i]))) {
|
|
|
|
missing = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (xenStoreDomainGetUUID(conn, new_domids[i], uuid) < 0) {
|
|
|
|
missing = 1;
|
|
|
|
VIR_FREE(name);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-11-21 17:03:26 +00:00
|
|
|
event = virDomainEventLifecycleNew(new_domids[i], name, uuid,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED_BOOTED);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
xenUnifiedDomainEventDispatch(priv, event);
|
2008-11-25 10:44:52 +00:00
|
|
|
|
2008-12-04 21:09:20 +00:00
|
|
|
/* Add to the list */
|
2009-01-20 17:19:23 +00:00
|
|
|
xenUnifiedAddDomainInfo(priv->activeDomainList,
|
2008-12-04 21:09:20 +00:00
|
|
|
new_domids[i], name, uuid);
|
2008-11-25 10:44:52 +00:00
|
|
|
|
|
|
|
VIR_FREE(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(new_domids);
|
|
|
|
|
|
|
|
if (missing && retries--) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("Some domains were missing, trying again");
|
2008-11-25 10:44:52 +00:00
|
|
|
usleep(100 * 1000);
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
/*
|
|
|
|
* The domain callback for the @destroyDomain watch
|
|
|
|
*
|
|
|
|
* The lock on 'priv' is held when calling this
|
|
|
|
*/
|
2013-01-28 22:22:28 +00:00
|
|
|
int
|
|
|
|
xenStoreDomainReleased(virConnectPtr conn,
|
|
|
|
const char *path ATTRIBUTE_UNUSED,
|
|
|
|
const char *token ATTRIBUTE_UNUSED,
|
|
|
|
void *opaque)
|
2008-11-25 10:44:52 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i, j;
|
|
|
|
int found, removed, retries = 20;
|
2008-11-25 10:44:52 +00:00
|
|
|
int new_domain_cnt;
|
|
|
|
int *new_domids;
|
|
|
|
int nread;
|
|
|
|
|
2013-01-28 22:22:28 +00:00
|
|
|
xenUnifiedPrivatePtr priv = opaque;
|
2008-11-25 10:44:52 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!priv->activeDomainList->count) return 0;
|
2008-11-25 10:44:52 +00:00
|
|
|
|
2014-03-25 06:54:51 +00:00
|
|
|
retry:
|
2008-11-25 10:44:52 +00:00
|
|
|
new_domain_cnt = xenStoreNumOfDomains(conn);
|
2010-02-02 11:22:17 +00:00
|
|
|
if (new_domain_cnt < 0)
|
|
|
|
return -1;
|
2008-11-25 10:44:52 +00:00
|
|
|
|
2013-11-19 22:32:34 +00:00
|
|
|
if (VIR_ALLOC_N(new_domids, new_domain_cnt) < 0)
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
2009-10-09 09:32:37 +00:00
|
|
|
nread = xenStoreDoListDomains(conn, priv, new_domids, new_domain_cnt);
|
2008-11-25 10:44:52 +00:00
|
|
|
if (nread != new_domain_cnt) {
|
2011-01-28 21:38:06 +00:00
|
|
|
/* mismatch. retry this read */
|
2008-11-25 10:44:52 +00:00
|
|
|
VIR_FREE(new_domids);
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
|
|
|
|
removed = 0;
|
2014-01-20 11:27:29 +00:00
|
|
|
for (j = 0; j < priv->activeDomainList->count; j++) {
|
2008-11-25 10:44:52 +00:00
|
|
|
found = 0;
|
2014-01-20 11:27:29 +00:00
|
|
|
for (i = 0; i < new_domain_cnt; i++) {
|
2009-01-20 17:19:23 +00:00
|
|
|
if (priv->activeDomainList->doms[j]->id == new_domids[i]) {
|
2008-11-25 10:44:52 +00:00
|
|
|
found = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found) {
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr event =
|
2013-11-21 17:03:26 +00:00
|
|
|
virDomainEventLifecycleNew(-1,
|
|
|
|
priv->activeDomainList->doms[j]->name,
|
|
|
|
priv->activeDomainList->doms[j]->uuid,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
|
2008-12-04 21:09:20 +00:00
|
|
|
if (event)
|
|
|
|
xenUnifiedDomainEventDispatch(priv, event);
|
|
|
|
|
|
|
|
/* Remove from the list */
|
2009-01-20 17:19:23 +00:00
|
|
|
xenUnifiedRemoveDomainInfo(priv->activeDomainList,
|
|
|
|
priv->activeDomainList->doms[j]->id,
|
|
|
|
priv->activeDomainList->doms[j]->name,
|
|
|
|
priv->activeDomainList->doms[j]->uuid);
|
2008-12-04 21:09:20 +00:00
|
|
|
|
|
|
|
removed = 1;
|
2008-11-25 10:44:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(new_domids);
|
|
|
|
|
|
|
|
if (!removed && retries--) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("No domains removed, retrying");
|
2008-11-25 10:44:52 +00:00
|
|
|
usleep(100 * 1000);
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|