mirror of https://gitee.com/openkylin/libvirt.git
Remove the xend driver
xend was deprecated in Xen 4.2 and removed from the Xen sources before the Xen 4.5 release. The last Xen release to contain xend was Xen 4.4, which was retired upstream in March 2017. Remove xend support from libvirt since it is unrealistic to use modern libvirt with ancient Xen. Signed-off-by: Jim Fehlig <jfehlig@suse.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
4392d2d49b
commit
1dac5fbbbb
|
@ -224,7 +224,6 @@ fi
|
|||
# Stateful drivers are useful only when building the daemon.
|
||||
if test "$with_libvirtd" = "no" ; then
|
||||
with_qemu=no
|
||||
with_xen=no
|
||||
with_lxc=no
|
||||
with_libxl=no
|
||||
with_uml=no
|
||||
|
@ -402,7 +401,6 @@ dnl
|
|||
dnl Virtualization drivers check
|
||||
dnl
|
||||
|
||||
LIBVIRT_DRIVER_ARG_XEN
|
||||
LIBVIRT_DRIVER_ARG_QEMU
|
||||
LIBVIRT_DRIVER_ARG_OPENVZ
|
||||
LIBVIRT_DRIVER_ARG_VMWARE
|
||||
|
@ -422,7 +420,6 @@ LIBVIRT_DRIVER_ARG_LIBVIRTD
|
|||
LIBVIRT_DRIVER_ARG_NETWORK
|
||||
LIBVIRT_DRIVER_ARG_INTERFACE
|
||||
|
||||
LIBVIRT_DRIVER_CHECK_XEN
|
||||
LIBVIRT_DRIVER_CHECK_QEMU
|
||||
LIBVIRT_DRIVER_CHECK_OPENVZ
|
||||
LIBVIRT_DRIVER_CHECK_VMWARE
|
||||
|
@ -442,7 +439,7 @@ LIBVIRT_DRIVER_CHECK_LIBVIRTD
|
|||
LIBVIRT_DRIVER_CHECK_NETWORK
|
||||
LIBVIRT_DRIVER_CHECK_INTERFACE
|
||||
|
||||
AM_CONDITIONAL([WITH_XENCONFIG], [test "$with_libxl" = "yes" || test "$with_xen" = "yes"])
|
||||
AM_CONDITIONAL([WITH_XENCONFIG], [test "$with_libxl" = "yes"])
|
||||
|
||||
|
||||
dnl
|
||||
|
@ -925,7 +922,6 @@ AC_MSG_NOTICE([=====================])
|
|||
AC_MSG_NOTICE([])
|
||||
AC_MSG_NOTICE([Drivers])
|
||||
AC_MSG_NOTICE([])
|
||||
LIBVIRT_DRIVER_RESULT_XEN
|
||||
LIBVIRT_DRIVER_RESULT_QEMU
|
||||
LIBVIRT_DRIVER_RESULT_UML
|
||||
LIBVIRT_DRIVER_RESULT_OPENVZ
|
||||
|
@ -1009,7 +1005,6 @@ LIBVIRT_RESULT_SSH2
|
|||
LIBVIRT_RESULT_UDEV
|
||||
LIBVIRT_RESULT_VIRTUALPORT
|
||||
LIBVIRT_RESULT_XDR
|
||||
LIBVIRT_RESULT_XEN
|
||||
LIBVIRT_RESULT_XENAPI
|
||||
LIBVIRT_RESULT_YAJL
|
||||
AC_MSG_NOTICE([])
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
dnl The XEN driver
|
||||
dnl
|
||||
dnl Copyright (C) 2016 Red Hat, Inc.
|
||||
dnl
|
||||
dnl This library is free software; you can redistribute it and/or
|
||||
dnl modify it under the terms of the GNU Lesser General Public
|
||||
dnl License as published by the Free Software Foundation; either
|
||||
dnl version 2.1 of the License, or (at your option) any later version.
|
||||
dnl
|
||||
dnl This library is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
dnl Lesser General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU Lesser General Public
|
||||
dnl License along with this library. If not, see
|
||||
dnl <http://www.gnu.org/licenses/>.
|
||||
dnl
|
||||
|
||||
AC_DEFUN([LIBVIRT_DRIVER_ARG_XEN], [
|
||||
LIBVIRT_ARG_WITH_FEATURE([XEN], [XEN], [check])
|
||||
LIBVIRT_ARG_WITH_FEATURE([XEN_INOTIFY], [XEN inotify], [check])
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBVIRT_DRIVER_CHECK_XEN], [
|
||||
old_LIBS="$LIBS"
|
||||
old_CFLAGS="$CFLAGS"
|
||||
XEN_LIBS=""
|
||||
XEN_CFLAGS=""
|
||||
fail=0
|
||||
|
||||
dnl search for the Xen store library
|
||||
dnl Either use the provided path, or make use of pkgconfig
|
||||
dnl Xen versions prior 4.9 had no pkgconfig file
|
||||
if test "$with_xen" != "no" ; then
|
||||
xen_path_provided="no"
|
||||
if test "$with_xen" != "yes" && test "$with_xen" != "check" ; then
|
||||
XEN_CFLAGS="-I$with_xen/include"
|
||||
XEN_LIBS="-L$with_xen/lib64 -L$with_xen/lib"
|
||||
xen_path_provided="yes"
|
||||
fi
|
||||
|
||||
if test "$xen_path_provided" = "no" ; then
|
||||
PKG_CHECK_MODULES([XEN], [xenstore], [
|
||||
with_xen=yes
|
||||
], [
|
||||
fail=1
|
||||
])
|
||||
fi
|
||||
dnl manual check if either path was provided or pkgconfig does not exist
|
||||
if test "$xen_path_provided" = "yes" || test "$fail" = 1 ; then
|
||||
CFLAGS="$CFLAGS $XEN_CFLAGS"
|
||||
LIBS="$LIBS $XEN_LIBS"
|
||||
fail=0
|
||||
AC_CHECK_LIB([xenstore], [xs_read], [
|
||||
with_xen=yes
|
||||
XEN_LIBS="$XEN_LIBS -lxenstore"
|
||||
],[
|
||||
if test "$with_xen" = "yes"; then
|
||||
fail=1
|
||||
fi
|
||||
with_xen=no
|
||||
])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$with_xen" != "no" ; then
|
||||
dnl In Xen 4.2, xs.h is deprecated in favor of xenstore.h.
|
||||
AC_CHECK_HEADERS([xenstore.h])
|
||||
AC_CHECK_HEADERS([xen/xen.h xen/version.h xen/dom0_ops.h],,[
|
||||
if test "$with_xen" = "yes"; then
|
||||
fail=1
|
||||
fi
|
||||
with_xen=no
|
||||
],
|
||||
[#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
])
|
||||
fi
|
||||
|
||||
if test "$with_xen" != "no" ; then
|
||||
dnl Search for the location of <xen/{linux,sys}/privcmd.h>.
|
||||
found=
|
||||
AC_CHECK_HEADERS([xen/sys/privcmd.h xen/linux/privcmd.h], [found=yes; break;], [],
|
||||
[#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <xen/xen.h>
|
||||
])
|
||||
if test "x$found" != "xyes"; then
|
||||
if test "$with_xen" = "yes"; then
|
||||
fail=1
|
||||
fi
|
||||
with_xen=no
|
||||
fi
|
||||
fi
|
||||
|
||||
LIBS="$old_LIBS"
|
||||
CFLAGS="$old_CFLAGS"
|
||||
|
||||
if test $fail = 1; then
|
||||
AC_MSG_ERROR([You must install the Xen development package to compile Xen driver with -lxenstore])
|
||||
fi
|
||||
|
||||
if test "$with_xen" = "yes"; then
|
||||
AC_DEFINE_UNQUOTED([WITH_XEN], 1, [whether Xen driver is enabled])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([WITH_XEN], [test "$with_xen" = "yes"])
|
||||
AC_SUBST([XEN_CFLAGS])
|
||||
AC_SUBST([XEN_LIBS])
|
||||
|
||||
dnl
|
||||
dnl check for kernel headers required by xen_inotify
|
||||
dnl
|
||||
if test "$with_xen" != "yes"; then
|
||||
with_xen_inotify=no
|
||||
fi
|
||||
if test "$with_xen_inotify" != "no"; then
|
||||
AC_CHECK_HEADER([sys/inotify.h], [
|
||||
with_xen_inotify=yes
|
||||
], [
|
||||
if test "$with_xen_inotify" = "check"; then
|
||||
with_xen_inotify=no
|
||||
AC_MSG_NOTICE([Header file <sys/inotify.h> is required for Xen Inotify support, disabling it])
|
||||
else
|
||||
AC_MSG_ERROR([Header file <sys/inotify.h> is required for Xen Inotify support!])
|
||||
fi
|
||||
0])
|
||||
fi
|
||||
if test "$with_xen_inotify" = "yes"; then
|
||||
AC_DEFINE_UNQUOTED([WITH_XEN_INOTIFY], 1, [whether Xen inotify sub-driver is enabled])
|
||||
fi
|
||||
AM_CONDITIONAL([WITH_XEN_INOTIFY], [test "$with_xen_inotify" = "yes"])
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBVIRT_RESULT_XEN], [
|
||||
LIBVIRT_RESULT_LIB([XEN])
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBVIRT_DRIVER_RESULT_XEN], [
|
||||
LIBVIRT_RESULT([XEN], [$with_xen])
|
||||
])
|
|
@ -291,13 +291,6 @@ src/vz/vz_driver.c
|
|||
src/vz/vz_sdk.c
|
||||
src/vz/vz_utils.c
|
||||
src/vz/vz_utils.h
|
||||
src/xen/block_stats.c
|
||||
src/xen/xen_driver.c
|
||||
src/xen/xen_hypervisor.c
|
||||
src/xen/xen_inotify.c
|
||||
src/xen/xend_internal.c
|
||||
src/xen/xm_internal.c
|
||||
src/xen/xs_internal.c
|
||||
src/xenapi/xenapi_driver.c
|
||||
src/xenapi/xenapi_utils.c
|
||||
src/xenconfig/xen_common.c
|
||||
|
|
|
@ -115,7 +115,6 @@ include qemu/Makefile.inc.am
|
|||
include bhyve/Makefile.inc.am
|
||||
include xenconfig/Makefile.inc.am
|
||||
include libxl/Makefile.inc.am
|
||||
include xen/Makefile.inc.am
|
||||
include xenapi/Makefile.inc.am
|
||||
include vz/Makefile.inc.am
|
||||
include lxc/Makefile.inc.am
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
XEN_DRIVER_SOURCES = \
|
||||
xen/block_stats.c \
|
||||
xen/block_stats.h \
|
||||
xen/xen_hypervisor.c \
|
||||
xen/xen_hypervisor.h \
|
||||
xen/xen_driver.c \
|
||||
xen/xen_driver.h \
|
||||
xen/xend_internal.c \
|
||||
xen/xend_internal.h \
|
||||
xen/xm_internal.c \
|
||||
xen/xm_internal.h \
|
||||
xen/xs_internal.c \
|
||||
xen/xs_internal.h \
|
||||
$(NULL)
|
||||
|
||||
XEN_DRIVER_INOTIFY_SOURCES = \
|
||||
xen/xen_inotify.c \
|
||||
xen/xen_inotify.h \
|
||||
$(NULL)
|
||||
|
||||
if WITH_XEN_INOTIFY
|
||||
XEN_DRIVER_SOURCES += $(XEN_DRIVER_INOTIFY_SOURCES)
|
||||
endif WITH_XEN_INOTIFY
|
||||
|
||||
DRIVER_SOURCE_FILES += $(XEN_DRIVER_SOURCES)
|
||||
STATEFUL_DRIVER_SOURCE_FILES += $(XEN_DRIVER_SOURCES)
|
||||
EXTRA_DIST += $(XEN_DRIVER_SOURCES) $(XEN_DRIVER_INOTIFY_SOURCES)
|
||||
|
||||
if WITH_XEN
|
||||
noinst_LTLIBRARIES += libvirt_driver_xen_impl.la
|
||||
libvirt_driver_xen_la_SOURCES =
|
||||
libvirt_driver_xen_la_LIBADD = \
|
||||
libvirt_driver_xen_impl.la \
|
||||
libvirt.la \
|
||||
../gnulib/lib/libgnu.la \
|
||||
$(NULL)
|
||||
mod_LTLIBRARIES += libvirt_driver_xen.la
|
||||
libvirt_driver_xen_la_LDFLAGS = $(AM_LDFLAGS_MOD_NOUNDEF)
|
||||
|
||||
libvirt_driver_xen_impl_la_CFLAGS = \
|
||||
$(XEN_CFLAGS) \
|
||||
-I$(srcdir)/access \
|
||||
-I$(srcdir)/conf \
|
||||
-I$(srcdir)/xenconfig \
|
||||
$(AM_CFLAGS) \
|
||||
$(NULL)
|
||||
libvirt_driver_xen_impl_la_LDFLAGS = $(AM_LDFLAGS)
|
||||
libvirt_driver_xen_impl_la_LIBADD = \
|
||||
$(XEN_LIBS) \
|
||||
libvirt_xenconfig.la \
|
||||
$(NULL)
|
||||
libvirt_driver_xen_impl_la_SOURCES = $(XEN_DRIVER_SOURCES)
|
||||
|
||||
INSTALL_DATA_DIRS += xen
|
||||
|
||||
install-data-xen:
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/xen"
|
||||
|
||||
uninstall-data-xen:
|
||||
rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/xen" ||:
|
||||
|
||||
endif WITH_XEN
|
||||
|
||||
.PHONY: \
|
||||
install-data-xen \
|
||||
uninstall-data-xen \
|
||||
$(NULL)
|
|
@ -1,355 +0,0 @@
|
|||
/*
|
||||
* Linux block and network stats.
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2013 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Richard W.M. Jones <rjones@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* This file only applies on Linux. */
|
||||
#ifdef __linux__
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <fcntl.h>
|
||||
# include <string.h>
|
||||
# include <unistd.h>
|
||||
# include <regex.h>
|
||||
|
||||
# if HAVE_XENSTORE_H
|
||||
# include <xenstore.h>
|
||||
# else
|
||||
# include <xs.h>
|
||||
# endif
|
||||
|
||||
# include "virerror.h"
|
||||
# include "datatypes.h"
|
||||
# include "block_stats.h"
|
||||
# include "viralloc.h"
|
||||
# include "virfile.h"
|
||||
# include "virstring.h"
|
||||
|
||||
# define VIR_FROM_THIS VIR_FROM_STATS_LINUX
|
||||
|
||||
|
||||
/*-------------------- Xen: block stats --------------------*/
|
||||
|
||||
# include <linux/major.h>
|
||||
|
||||
/* This is normally defined in <linux/major.h> but previously we
|
||||
* hard-coded it. So if it's not defined, hard-code again.
|
||||
*/
|
||||
# ifndef XENVBD_MAJOR
|
||||
# define XENVBD_MAJOR 202
|
||||
# endif
|
||||
|
||||
static int64_t
|
||||
read_stat(const char *path)
|
||||
{
|
||||
char str[64];
|
||||
long long r;
|
||||
size_t i;
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(path, "r");
|
||||
if (!fp)
|
||||
return -1;
|
||||
|
||||
/* read, but don't bail out before closing */
|
||||
i = fread(str, 1, sizeof(str) - 1, fp);
|
||||
|
||||
if (VIR_FCLOSE(fp) != 0 /* disk error */
|
||||
|| i < 1) /* ensure we read at least one byte */
|
||||
return -1;
|
||||
|
||||
str[i] = '\0'; /* make sure the string is nul-terminated */
|
||||
if (virStrToLong_ll(str, NULL, 10, &r) < 0)
|
||||
return -1;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int64_t
|
||||
read_bd_stat(int device, int domid, const char *str)
|
||||
{
|
||||
static const char *paths[] = {
|
||||
"/sys/bus/xen-backend/devices/vbd-%d-%d/statistics/%s",
|
||||
"/sys/bus/xen-backend/devices/tap-%d-%d/statistics/%s",
|
||||
"/sys/devices/xen-backend/vbd-%d-%d/statistics/%s",
|
||||
"/sys/devices/xen-backend/tap-%d-%d/statistics/%s"
|
||||
};
|
||||
|
||||
size_t i;
|
||||
char *path;
|
||||
int64_t r;
|
||||
|
||||
for (i = 0; i < ARRAY_CARDINALITY(paths); ++i) {
|
||||
if (virAsprintf(&path, paths[i], domid, device, str) < 0)
|
||||
return -1;
|
||||
|
||||
r = read_stat(path);
|
||||
|
||||
VIR_FREE(path);
|
||||
|
||||
if (r >= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* In Xenstore, /local/domain/0/backend/vbd/<domid>/<device>/state,
|
||||
* if available, must be XenbusStateConnected (= 4), otherwise there
|
||||
* is no connected device.
|
||||
*/
|
||||
static int
|
||||
check_bd_connected(xenUnifiedPrivatePtr priv, int device, int domid)
|
||||
{
|
||||
char s[256], *rs;
|
||||
int r;
|
||||
unsigned len = 0;
|
||||
|
||||
/* This code assumes we're connected if we can't get to
|
||||
* xenstore, etc.
|
||||
*/
|
||||
if (!priv->xshandle) return 1;
|
||||
snprintf(s, sizeof(s), "/local/domain/0/backend/vbd/%d/%d/state",
|
||||
domid, device);
|
||||
s[sizeof(s) - 1] = '\0';
|
||||
|
||||
rs = xs_read(priv->xshandle, 0, s, &len);
|
||||
if (!rs) return 1;
|
||||
if (len == 0) {
|
||||
/* Hmmm ... we can get to xenstore but it returns an empty
|
||||
* string instead of an error. Assume it's not connected
|
||||
* in this case.
|
||||
*/
|
||||
VIR_FREE(rs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = STREQ(rs, "4");
|
||||
VIR_FREE(rs);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
read_bd_stats(xenUnifiedPrivatePtr priv,
|
||||
int device, int domid, virDomainBlockStatsPtr stats)
|
||||
{
|
||||
stats->rd_req = read_bd_stat(device, domid, "rd_req");
|
||||
stats->rd_bytes = read_bd_stat(device, domid, "rd_sect");
|
||||
stats->wr_req = read_bd_stat(device, domid, "wr_req");
|
||||
stats->wr_bytes = read_bd_stat(device, domid, "wr_sect");
|
||||
stats->errs = read_bd_stat(device, domid, "oo_req");
|
||||
|
||||
/* None of the files were found - it's likely that this version
|
||||
* of Xen is an old one which just doesn't support stats collection.
|
||||
*/
|
||||
if (stats->rd_req == -1 && stats->rd_bytes == -1 &&
|
||||
stats->wr_req == -1 && stats->wr_bytes == -1 &&
|
||||
stats->errs == -1) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to read any block statistics for domain %d"),
|
||||
domid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If stats are all zero then either there really isn't any block
|
||||
* device activity, or there is no connected front end device
|
||||
* in which case there are no stats.
|
||||
*/
|
||||
if (stats->rd_req == 0 && stats->rd_bytes == 0 &&
|
||||
stats->wr_req == 0 && stats->wr_bytes == 0 &&
|
||||
stats->errs == 0 &&
|
||||
!check_bd_connected(priv, device, domid)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Frontend block device not connected for domain %d"),
|
||||
domid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 'Bytes' was really sectors when we read it. Scale up by
|
||||
* an assumed sector size.
|
||||
*/
|
||||
if (stats->rd_bytes > 0) {
|
||||
if (stats->rd_bytes >= ((unsigned long long)1)<<(63-9)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("stats->rd_bytes would overflow 64 bit counter for domain %d"),
|
||||
domid);
|
||||
return -1;
|
||||
}
|
||||
stats->rd_bytes *= 512;
|
||||
}
|
||||
if (stats->wr_bytes > 0) {
|
||||
if (stats->wr_bytes >= ((unsigned long long)1)<<(63-9)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("stats->wr_bytes would overflow 64 bit counter for domain %d"),
|
||||
domid);
|
||||
return -1;
|
||||
}
|
||||
stats->wr_bytes *= 512;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
disk_re_match(const char *regex, const char *path, int *part)
|
||||
{
|
||||
regex_t myreg;
|
||||
int err;
|
||||
int retval;
|
||||
regmatch_t pmatch[3];
|
||||
|
||||
retval = 0;
|
||||
|
||||
err = regcomp(&myreg, regex, REG_EXTENDED);
|
||||
if (err != 0)
|
||||
return 0;
|
||||
|
||||
err = regexec(&myreg, path, 3, pmatch, 0);
|
||||
|
||||
if (err == 0) {
|
||||
/* OK, we have a match; see if we have a partition */
|
||||
*part = 0;
|
||||
retval = 1;
|
||||
if (pmatch[1].rm_so != -1) {
|
||||
if (virStrToLong_i(path + pmatch[1].rm_so, NULL, 10, part) < 0)
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
regfree(&myreg);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
xenLinuxDomainDeviceID(int domid, const char *path)
|
||||
{
|
||||
int major, minor;
|
||||
int part;
|
||||
int retval;
|
||||
char *mod_path;
|
||||
|
||||
int const scsi_majors[] = { SCSI_DISK0_MAJOR, SCSI_DISK1_MAJOR,
|
||||
SCSI_DISK2_MAJOR, SCSI_DISK3_MAJOR,
|
||||
SCSI_DISK4_MAJOR, SCSI_DISK5_MAJOR,
|
||||
SCSI_DISK6_MAJOR, SCSI_DISK7_MAJOR,
|
||||
SCSI_DISK8_MAJOR, SCSI_DISK9_MAJOR,
|
||||
SCSI_DISK10_MAJOR, SCSI_DISK11_MAJOR,
|
||||
SCSI_DISK12_MAJOR, SCSI_DISK13_MAJOR,
|
||||
SCSI_DISK14_MAJOR, SCSI_DISK15_MAJOR };
|
||||
int const ide_majors[] = { IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR,
|
||||
IDE4_MAJOR, IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR,
|
||||
IDE8_MAJOR, IDE9_MAJOR };
|
||||
|
||||
/*
|
||||
* Possible block device majors & partition ranges. This
|
||||
* matches the ranges supported in Xend xen/util/blkif.py
|
||||
*
|
||||
* hdNM: N=a-t, M=1-63, major={IDE0_MAJOR -> IDE9_MAJOR}
|
||||
* sdNM: N=a-z,aa-iv, M=1-15, major={SCSI_DISK0_MAJOR -> SCSI_DISK15_MAJOR}
|
||||
* xvdNM: N=a-p M=1-15, major=XENVBD_MAJOR
|
||||
* xvdNM: N=q-z,aa-iz M=1-15, major=(1<<28)
|
||||
*
|
||||
* The path for statistics will be
|
||||
*
|
||||
* /sys/devices/xen-backend/(vbd|tap)-{domid}-{devid}/statistics/{...}
|
||||
*/
|
||||
|
||||
if (strlen(path) >= 5 && STRPREFIX(path, "/dev/")) {
|
||||
if (VIR_STRDUP(mod_path, path) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
if (virAsprintf(&mod_path, "/dev/%s", path) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = -1;
|
||||
|
||||
if (disk_re_match("/dev/sd[a-z]([1-9]|1[0-5])?$", mod_path, &part)) {
|
||||
major = scsi_majors[(mod_path[7] - 'a') / 16];
|
||||
minor = ((mod_path[7] - 'a') % 16) * 16 + part;
|
||||
retval = major * 256 + minor;
|
||||
}
|
||||
else if (disk_re_match("/dev/sd[a-h][a-z]([1-9]|1[0-5])?$",
|
||||
mod_path, &part) ||
|
||||
disk_re_match("/dev/sdi[a-v]([1-9]|1[0-5])?$",
|
||||
mod_path, &part)) {
|
||||
major = scsi_majors[((mod_path[7] - 'a' + 1) * 26 + (mod_path[8] - 'a')) / 16];
|
||||
minor = (((mod_path[7] - 'a' + 1) * 26 + (mod_path[8] - 'a')) % 16)
|
||||
* 16 + part;
|
||||
retval = major * 256 + minor;
|
||||
}
|
||||
else if (disk_re_match("/dev/hd[a-t]([1-9]|[1-5][0-9]|6[0-3])?$",
|
||||
mod_path, &part)) {
|
||||
major = ide_majors[(mod_path[7] - 'a') / 2];
|
||||
minor = ((mod_path[7] - 'a') % 2) * 64 + part;
|
||||
retval = major * 256 + minor;
|
||||
}
|
||||
else if (disk_re_match("/dev/xvd[a-p]([1-9]|1[0-5])?$", mod_path, &part))
|
||||
retval = (202 << 8) + ((mod_path[8] - 'a') << 4) + part;
|
||||
else if (disk_re_match("/dev/xvd[q-z]([1-9]|1[0-5])?$", mod_path, &part))
|
||||
retval = (1 << 28) + ((mod_path[8] - 'a') << 8) + part;
|
||||
else if (disk_re_match("/dev/xvd[a-i][a-z]([1-9]|1[0-5])?$",
|
||||
mod_path, &part))
|
||||
retval = (1 << 28) + (((mod_path[8] - 'a' + 1) * 26 + (mod_path[9] - 'a')) << 8) + part;
|
||||
/*
|
||||
* OK, we've now checked the common case (things that work); check the
|
||||
* beginning of the strings for better error messages
|
||||
*/
|
||||
else if (strlen(mod_path) >= 7 && STRPREFIX(mod_path, "/dev/sd"))
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("invalid path, device names must be in the range "
|
||||
"sda[1-15] - sdiv[1-15] for domain %d"), domid);
|
||||
else if (strlen(mod_path) >= 7 && STRPREFIX(mod_path, "/dev/hd"))
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("invalid path, device names must be in the range "
|
||||
"hda[1-63] - hdt[1-63] for domain %d"), domid);
|
||||
else if (strlen(mod_path) >= 8 && STRPREFIX(mod_path, "/dev/xvd"))
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("invalid path, device names must be in the range "
|
||||
"xvda[1-15] - xvdiz[1-15] for domain %d"), domid);
|
||||
else
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("unsupported path, use xvdN, hdN, or sdN for domain %d"),
|
||||
domid);
|
||||
|
||||
VIR_FREE(mod_path);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
xenLinuxDomainBlockStats(xenUnifiedPrivatePtr priv,
|
||||
virDomainDefPtr def,
|
||||
const char *path,
|
||||
virDomainBlockStatsPtr stats)
|
||||
{
|
||||
int device = xenLinuxDomainDeviceID(def->id, path);
|
||||
|
||||
if (device < 0)
|
||||
return -1;
|
||||
|
||||
return read_bd_stats(priv, device, def->id, stats);
|
||||
}
|
||||
|
||||
#endif /* __linux__ */
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Linux block and network stats.
|
||||
*
|
||||
* Copyright (C) 2007 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Richard W.M. Jones <rjones@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __BLOCK_STATS_H__
|
||||
# define __BLOCK_STATS_H__
|
||||
|
||||
# ifdef __linux__
|
||||
|
||||
# include "xen_driver.h"
|
||||
|
||||
int xenLinuxDomainBlockStats (xenUnifiedPrivatePtr priv,
|
||||
virDomainDefPtr def, const char *path,
|
||||
virDomainBlockStatsPtr stats);
|
||||
|
||||
int xenLinuxDomainDeviceID(int domid, const char *dev);
|
||||
|
||||
# endif /* __linux__ */
|
||||
|
||||
#endif /* __STATS_LINUX_H__ */
|
2845
src/xen/xen_driver.c
2845
src/xen/xen_driver.c
File diff suppressed because it is too large
Load Diff
|
@ -1,204 +0,0 @@
|
|||
/*
|
||||
* xen_driver.h: Unified Xen driver.
|
||||
*
|
||||
* Copyright (C) 2007, 2010-2011 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Richard W.M. Jones <rjones@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIR_XEN_UNIFIED_H__
|
||||
# define __VIR_XEN_UNIFIED_H__
|
||||
|
||||
# include "internal.h"
|
||||
# include "capabilities.h"
|
||||
# include "driver.h"
|
||||
# include "domain_conf.h"
|
||||
# include "xs_internal.h"
|
||||
# if WITH_XEN_INOTIFY
|
||||
# include "xen_inotify.h"
|
||||
# endif
|
||||
# include "domain_event.h"
|
||||
# include "virhash.h"
|
||||
|
||||
# ifndef HAVE_WINSOCK2_H
|
||||
# include <sys/un.h>
|
||||
# include <netinet/in.h>
|
||||
# else
|
||||
# include <winsock2.h>
|
||||
# endif
|
||||
|
||||
# include <xen/xen.h>
|
||||
|
||||
/* xen-unstable changeset 19788 removed MAX_VIRT_CPUS from public
|
||||
* headers. Its semantic was retained with XEN_LEGACY_MAX_VCPUS.
|
||||
* Ensure MAX_VIRT_CPUS is defined accordingly.
|
||||
*/
|
||||
# if !defined(MAX_VIRT_CPUS) && defined(XEN_LEGACY_MAX_VCPUS)
|
||||
# define MAX_VIRT_CPUS XEN_LEGACY_MAX_VCPUS
|
||||
# endif
|
||||
|
||||
int xenRegister (void);
|
||||
|
||||
# define XEN_UNIFIED_HYPERVISOR_OFFSET 0
|
||||
# define XEN_UNIFIED_XEND_OFFSET 1
|
||||
# define XEN_UNIFIED_XS_OFFSET 2
|
||||
# define XEN_UNIFIED_XM_OFFSET 3
|
||||
|
||||
# if WITH_XEN_INOTIFY
|
||||
# define XEN_UNIFIED_INOTIFY_OFFSET 4
|
||||
# define XEN_UNIFIED_NR_DRIVERS 5
|
||||
# else
|
||||
# define XEN_UNIFIED_NR_DRIVERS 4
|
||||
# endif
|
||||
|
||||
# define MIN_XEN_GUEST_SIZE 64 /* 64 megabytes */
|
||||
|
||||
# define XEND_DOMAINS_DIR "/var/lib/xend/domains"
|
||||
|
||||
# define XEN_SCHED_SEDF_NPARAM 6
|
||||
# define XEN_SCHED_CRED_NPARAM 2
|
||||
|
||||
/* The set of migration flags explicitly supported by xen. */
|
||||
# define XEN_MIGRATION_FLAGS \
|
||||
(VIR_MIGRATE_LIVE | \
|
||||
VIR_MIGRATE_UNDEFINE_SOURCE | \
|
||||
VIR_MIGRATE_PAUSED | \
|
||||
VIR_MIGRATE_PERSIST_DEST)
|
||||
|
||||
|
||||
typedef struct xenXMConfCache *xenXMConfCachePtr;
|
||||
typedef struct xenXMConfCache {
|
||||
time_t refreshedAt;
|
||||
char *filename;
|
||||
virDomainDefPtr def;
|
||||
} xenXMConfCache;
|
||||
|
||||
/* xenUnifiedDomainInfoPtr:
|
||||
* The minimal state we have about active domains
|
||||
* This is the minmal info necessary to still get a
|
||||
* virDomainPtr when the domain goes away
|
||||
*/
|
||||
struct _xenUnifiedDomainInfo {
|
||||
int id;
|
||||
char *name;
|
||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||
};
|
||||
typedef struct _xenUnifiedDomainInfo xenUnifiedDomainInfo;
|
||||
typedef xenUnifiedDomainInfo *xenUnifiedDomainInfoPtr;
|
||||
|
||||
struct _xenUnifiedDomainInfoList {
|
||||
size_t count;
|
||||
xenUnifiedDomainInfoPtr *doms;
|
||||
};
|
||||
typedef struct _xenUnifiedDomainInfoList xenUnifiedDomainInfoList;
|
||||
typedef xenUnifiedDomainInfoList *xenUnifiedDomainInfoListPtr;
|
||||
|
||||
/* xenUnifiedPrivatePtr:
|
||||
*
|
||||
* Per-connection private data, stored in conn->privateData. All Xen
|
||||
* low-level drivers access parts of this structure.
|
||||
*/
|
||||
struct _xenUnifiedPrivate {
|
||||
virMutex lock;
|
||||
|
||||
/* These initial vars are initialized in Open method
|
||||
* and readonly thereafter, so can be used without
|
||||
* holding the lock
|
||||
*/
|
||||
virCapsPtr caps;
|
||||
virDomainXMLOptionPtr xmlopt;
|
||||
int handle; /* Xen hypervisor handle */
|
||||
|
||||
/* connection to xend */
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
int addrfamily;
|
||||
int addrprotocol;
|
||||
|
||||
/* Keep track of the drivers which opened. We keep a yes/no flag
|
||||
* here for each driver, corresponding to the array drivers in
|
||||
* xen_unified.c.
|
||||
*/
|
||||
int opened[XEN_UNIFIED_NR_DRIVERS];
|
||||
|
||||
|
||||
/*
|
||||
* Everything from this point onwards must be protected
|
||||
* by the lock when used
|
||||
*/
|
||||
|
||||
struct xs_handle *xshandle; /* handle to talk to the xenstore */
|
||||
|
||||
|
||||
/* A list of xenstore watches */
|
||||
xenStoreWatchListPtr xsWatchList;
|
||||
int xsWatch;
|
||||
/* A list of active domain name/uuids */
|
||||
xenUnifiedDomainInfoListPtr activeDomainList;
|
||||
|
||||
/* NUMA topology info cache */
|
||||
int nbNodeCells;
|
||||
int nbNodeCpus;
|
||||
|
||||
virObjectEventStatePtr domainEvents;
|
||||
|
||||
/* Location of config files, either /etc
|
||||
* or /var/lib/xen */
|
||||
const char *configDir;
|
||||
/* Location of managed save dir, default /var/lib/libvirt/xen/save */
|
||||
char *saveDir;
|
||||
|
||||
# if WITH_XEN_INOTIFY
|
||||
/* The inotify fd */
|
||||
int inotifyFD;
|
||||
int inotifyWatch;
|
||||
|
||||
int useXenConfigCache;
|
||||
xenUnifiedDomainInfoListPtr configInfoList;
|
||||
# endif
|
||||
|
||||
/* For the 'xm' driver */
|
||||
/* Primary config file name -> virDomainDef map */
|
||||
virHashTablePtr configCache;
|
||||
/* Domain name to config file name */
|
||||
virHashTablePtr nameConfigMap;
|
||||
/* So we don't refresh too often */
|
||||
time_t lastRefresh;
|
||||
};
|
||||
|
||||
typedef struct _xenUnifiedPrivate *xenUnifiedPrivatePtr;
|
||||
|
||||
char *xenDomainUsedCpus(virDomainPtr dom, virDomainDefPtr def);
|
||||
|
||||
virDomainXMLOptionPtr xenDomainXMLConfInit(void);
|
||||
|
||||
void xenUnifiedDomainInfoListFree(xenUnifiedDomainInfoListPtr info);
|
||||
int xenUnifiedAddDomainInfo(xenUnifiedDomainInfoListPtr info,
|
||||
int id, char *name,
|
||||
unsigned char *uuid);
|
||||
int xenUnifiedRemoveDomainInfo(xenUnifiedDomainInfoListPtr info,
|
||||
int id, char *name,
|
||||
unsigned char *uuid);
|
||||
void xenUnifiedDomainEventDispatch (xenUnifiedPrivatePtr priv,
|
||||
virObjectEventPtr event);
|
||||
unsigned long xenUnifiedVersion(void);
|
||||
int xenUnifiedConnectGetMaxVcpus(virConnectPtr conn, const char *type);
|
||||
|
||||
void xenUnifiedLock(xenUnifiedPrivatePtr priv);
|
||||
void xenUnifiedUnlock(xenUnifiedPrivatePtr priv);
|
||||
|
||||
#endif /* __VIR_XEN_UNIFIED_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,142 +0,0 @@
|
|||
/*
|
||||
* xen_hypervisor.h: internal API for direct access to Xen hypervisor level
|
||||
*
|
||||
* Copyright (C) 2005, 2010-2011 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Daniel Veillard <veillard@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIR_XEN_INTERNAL_H__
|
||||
# define __VIR_XEN_INTERNAL_H__
|
||||
|
||||
# include "internal.h"
|
||||
# include "capabilities.h"
|
||||
# include "driver.h"
|
||||
# include "viruri.h"
|
||||
# include "domain_conf.h"
|
||||
|
||||
/* See xenHypervisorInit() for details. */
|
||||
struct xenHypervisorVersions {
|
||||
int hv; /* u16 major,minor hypervisor version */
|
||||
int hypervisor; /* -1,0,1,2,3 */
|
||||
int sys_interface; /* -1,2,3,4,6,7,8 */
|
||||
int dom_interface; /* -1,3,4,5,6,7 */
|
||||
};
|
||||
|
||||
int xenHypervisorInit(struct xenHypervisorVersions *override_versions);
|
||||
|
||||
virCapsPtr xenHypervisorMakeCapabilities (virConnectPtr conn);
|
||||
|
||||
int
|
||||
xenHypervisorHasDomain(virConnectPtr conn,
|
||||
int id);
|
||||
virDomainDefPtr
|
||||
xenHypervisorLookupDomainByID (virConnectPtr conn, int id);
|
||||
virDomainDefPtr
|
||||
xenHypervisorLookupDomainByUUID (virConnectPtr conn,
|
||||
const unsigned char *uuid);
|
||||
char *
|
||||
xenHypervisorDomainGetOSType (virConnectPtr conn,
|
||||
virDomainDefPtr def);
|
||||
|
||||
int
|
||||
xenHypervisorOpen (virConnectPtr conn,
|
||||
virConnectAuthPtr auth,
|
||||
unsigned int flags);
|
||||
int xenHypervisorClose (virConnectPtr conn);
|
||||
int xenHypervisorGetVersion (virConnectPtr conn,
|
||||
unsigned long *hvVer);
|
||||
virCapsPtr
|
||||
xenHypervisorMakeCapabilitiesInternal(virConnectPtr conn,
|
||||
virArch hostarch,
|
||||
FILE *cpuinfo,
|
||||
FILE *capabilities);
|
||||
char * xenHypervisorGetCapabilities (virConnectPtr conn);
|
||||
unsigned long
|
||||
xenHypervisorGetMaxMemory(virConnectPtr conn,
|
||||
virDomainDefPtr def);
|
||||
int xenHypervisorGetMaxVcpus (virConnectPtr conn,
|
||||
const char *type);
|
||||
int xenHypervisorGetDomainInfo (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
virDomainInfoPtr info)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
int xenHypervisorGetDomainState (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
int *state,
|
||||
int *reason)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
int xenHypervisorGetDomInfo (virConnectPtr conn,
|
||||
int id,
|
||||
virDomainInfoPtr info);
|
||||
int xenHypervisorSetMaxMemory (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned long memory)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
int xenHypervisorCheckID (virConnectPtr conn,
|
||||
int id);
|
||||
int xenHypervisorPinVcpu (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned int vcpu,
|
||||
unsigned char *cpumap,
|
||||
int maplen)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
int xenHypervisorGetVcpus (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
virVcpuInfoPtr info,
|
||||
int maxinfo,
|
||||
unsigned char *cpumaps,
|
||||
int maplen)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
int xenHypervisorGetVcpuMax (virConnectPtr conn,
|
||||
virDomainDefPtr def)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
|
||||
char * xenHypervisorGetSchedulerType (virConnectPtr conn,
|
||||
int *nparams)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
|
||||
int xenHypervisorGetSchedulerParameters(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
virTypedParameterPtr params,
|
||||
int *nparams)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
|
||||
int xenHypervisorSetSchedulerParameters(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
virTypedParameterPtr params,
|
||||
int nparams)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
|
||||
int xenHypervisorDomainBlockStats (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *path,
|
||||
virDomainBlockStatsPtr stats)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
int xenHypervisorDomainInterfaceStats (virDomainDefPtr def,
|
||||
const char *path,
|
||||
virDomainInterfaceStatsPtr stats)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
|
||||
int xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn,
|
||||
unsigned long long *freeMems,
|
||||
int startCell,
|
||||
int maxCells);
|
||||
|
||||
int xenHavePrivilege(void);
|
||||
|
||||
#endif /* __VIR_XEN_INTERNAL_H__ */
|
|
@ -1,447 +0,0 @@
|
|||
/*
|
||||
* xen_inotify.c: Xen notification of xml file activity in the
|
||||
* following dirs:
|
||||
* /etc/xen
|
||||
* /var/lib/xend/domains
|
||||
*
|
||||
* Copyright (C) 2010-2014 Red Hat, Inc.
|
||||
* Copyright (C) 2008 VirtualIron
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Ben Guthro
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/inotify.h>
|
||||
|
||||
#include "virerror.h"
|
||||
#include "datatypes.h"
|
||||
#include "driver.h"
|
||||
#include "viralloc.h"
|
||||
#include "xen_driver.h"
|
||||
#include "virconf.h"
|
||||
#include "domain_conf.h"
|
||||
#include "xen_inotify.h"
|
||||
#include "xend_internal.h"
|
||||
#include "virlog.h"
|
||||
#include "viruuid.h"
|
||||
#include "virfile.h"
|
||||
#include "virstring.h"
|
||||
#include "xm_internal.h" /* for xenXMDomainConfigParse */
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_XEN_INOTIFY
|
||||
|
||||
VIR_LOG_INIT("xen.xen_inotify");
|
||||
|
||||
static int
|
||||
xenInotifyXenCacheLookup(virConnectPtr conn,
|
||||
const char *filename,
|
||||
char **name,
|
||||
unsigned char *uuid)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
xenXMConfCachePtr entry;
|
||||
|
||||
if (!(entry = virHashLookup(priv->configCache, filename))) {
|
||||
VIR_DEBUG("No config found for %s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(uuid, entry->def->uuid, VIR_UUID_BUFLEN);
|
||||
if (VIR_STRDUP(*name, entry->def->name) < 0) {
|
||||
VIR_DEBUG("Error getting dom from def");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xenInotifyXendDomainsDirLookup(virConnectPtr conn,
|
||||
const char *filename,
|
||||
char **name,
|
||||
unsigned char *uuid)
|
||||
{
|
||||
size_t i;
|
||||
virDomainDefPtr def;
|
||||
const char *uuid_str;
|
||||
unsigned char rawuuid[VIR_UUID_BUFLEN];
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
/* xend is managing domains. we will get
|
||||
* a filename in the manner:
|
||||
* /var/lib/xend/domains/<uuid>/
|
||||
*/
|
||||
uuid_str = filename + strlen(XEND_DOMAINS_DIR) + 1;
|
||||
|
||||
if (virUUIDParse(uuid_str, rawuuid) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("parsing uuid %s"), uuid_str);
|
||||
return -1;
|
||||
}
|
||||
/* call directly into xend here, as driver may not yet
|
||||
be set during open while we are building our
|
||||
initial list of domains */
|
||||
VIR_DEBUG("Looking for dom with uuid: %s", uuid_str);
|
||||
|
||||
if (!(def = xenDaemonLookupByUUID(conn, rawuuid))) {
|
||||
/* If we are here, the domain has gone away.
|
||||
search for, and create a domain from the stored
|
||||
list info */
|
||||
for (i = 0; i < priv->configInfoList->count; i++) {
|
||||
if (!memcmp(rawuuid, priv->configInfoList->doms[i]->uuid, VIR_UUID_BUFLEN)) {
|
||||
if (VIR_STRDUP(*name, priv->configInfoList->doms[i]->name) < 0)
|
||||
return -1;
|
||||
memcpy(uuid, priv->configInfoList->doms[i]->uuid, VIR_UUID_BUFLEN);
|
||||
VIR_DEBUG("Found dom on list");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("finding dom on config list"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (VIR_STRDUP(*name, def->name) < 0) {
|
||||
virDomainDefFree(def);
|
||||
return -1;
|
||||
}
|
||||
memcpy(uuid, def->uuid, VIR_UUID_BUFLEN);
|
||||
virDomainDefFree(def);
|
||||
/* succeeded too find domain by uuid */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xenInotifyDomainLookup(virConnectPtr conn,
|
||||
const char *filename,
|
||||
char **name,
|
||||
unsigned char *uuid)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
if (priv->useXenConfigCache)
|
||||
return xenInotifyXenCacheLookup(conn, filename, name, uuid);
|
||||
else
|
||||
return xenInotifyXendDomainsDirLookup(conn, filename, name, uuid);
|
||||
}
|
||||
|
||||
static virObjectEventPtr
|
||||
xenInotifyDomainEventFromFile(virConnectPtr conn,
|
||||
const char *filename,
|
||||
int type,
|
||||
int detail)
|
||||
{
|
||||
virObjectEventPtr event;
|
||||
char *name = NULL;
|
||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||
|
||||
if (xenInotifyDomainLookup(conn, filename, &name, uuid) < 0)
|
||||
return NULL;
|
||||
|
||||
event = virDomainEventLifecycleNew(-1, name, uuid, type, detail);
|
||||
VIR_FREE(name);
|
||||
return event;
|
||||
}
|
||||
|
||||
static int
|
||||
xenInotifyXendDomainsDirRemoveEntry(virConnectPtr conn, const char *fname)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
const char *uuidstr = fname + strlen(XEND_DOMAINS_DIR) + 1;
|
||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||
size_t i;
|
||||
|
||||
if (virUUIDParse(uuidstr, uuid) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("parsing uuid %s"), uuidstr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* match and remove on uuid */
|
||||
for (i = 0; i < priv->configInfoList->count; i++) {
|
||||
if (!memcmp(uuid, priv->configInfoList->doms[i]->uuid, VIR_UUID_BUFLEN)) {
|
||||
VIR_FREE(priv->configInfoList->doms[i]->name);
|
||||
VIR_FREE(priv->configInfoList->doms[i]);
|
||||
|
||||
VIR_DELETE_ELEMENT(priv->configInfoList->doms, i,
|
||||
priv->configInfoList->count);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
xenInotifyXendDomainsDirAddEntry(virConnectPtr conn, const char *fname)
|
||||
{
|
||||
char *name = NULL;
|
||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
if (xenInotifyDomainLookup(conn, fname, &name, uuid) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("Error looking up domain"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (xenUnifiedAddDomainInfo(priv->configInfoList,
|
||||
-1, name, uuid) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("Error adding file to config cache"));
|
||||
VIR_FREE(name);
|
||||
return -1;
|
||||
}
|
||||
VIR_FREE(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xenInotifyRemoveDomainConfigInfo(virConnectPtr conn, const char *fname)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
return priv->useXenConfigCache ?
|
||||
xenXMConfigCacheRemoveFile(conn, fname) :
|
||||
xenInotifyXendDomainsDirRemoveEntry(conn, fname);
|
||||
}
|
||||
|
||||
static int
|
||||
xenInotifyAddDomainConfigInfo(virConnectPtr conn, const char *fname, time_t now)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
return priv->useXenConfigCache ?
|
||||
xenXMConfigCacheAddFile(conn, fname, now) :
|
||||
xenInotifyXendDomainsDirAddEntry(conn, fname);
|
||||
}
|
||||
|
||||
static void
|
||||
xenInotifyEvent(int watch ATTRIBUTE_UNUSED,
|
||||
int fd,
|
||||
int events ATTRIBUTE_UNUSED,
|
||||
void *data)
|
||||
{
|
||||
char buf[1024];
|
||||
char fname[1024];
|
||||
struct inotify_event *e;
|
||||
int got;
|
||||
char *tmp, *name;
|
||||
virConnectPtr conn = data;
|
||||
xenUnifiedPrivatePtr priv = NULL;
|
||||
time_t now = time(NULL);
|
||||
|
||||
VIR_DEBUG("got inotify event");
|
||||
|
||||
if (conn && conn->privateData) {
|
||||
priv = conn->privateData;
|
||||
} else {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("conn, or private data is NULL"));
|
||||
return;
|
||||
}
|
||||
|
||||
xenUnifiedLock(priv);
|
||||
|
||||
reread:
|
||||
got = read(fd, buf, sizeof(buf));
|
||||
if (got == -1) {
|
||||
if (errno == EINTR)
|
||||
goto reread;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
tmp = buf;
|
||||
while (got) {
|
||||
if (got < sizeof(struct inotify_event))
|
||||
goto cleanup; /* bad */
|
||||
|
||||
VIR_WARNINGS_NO_CAST_ALIGN
|
||||
e = (struct inotify_event *)tmp;
|
||||
VIR_WARNINGS_RESET
|
||||
|
||||
tmp += sizeof(struct inotify_event);
|
||||
got -= sizeof(struct inotify_event);
|
||||
|
||||
if (got < e->len)
|
||||
goto cleanup;
|
||||
|
||||
tmp += e->len;
|
||||
got -= e->len;
|
||||
|
||||
name = (char *)&(e->name);
|
||||
|
||||
snprintf(fname, 1024, "%s/%s",
|
||||
priv->configDir, name);
|
||||
|
||||
if (e->mask & (IN_DELETE | IN_MOVED_FROM)) {
|
||||
virObjectEventPtr event =
|
||||
xenInotifyDomainEventFromFile(conn, fname,
|
||||
VIR_DOMAIN_EVENT_UNDEFINED,
|
||||
VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
|
||||
if (event)
|
||||
xenUnifiedDomainEventDispatch(conn->privateData, event);
|
||||
else
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("looking up dom"));
|
||||
|
||||
if (xenInotifyRemoveDomainConfigInfo(conn, fname) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("Error adding file to config cache"));
|
||||
goto cleanup;
|
||||
}
|
||||
} else if (e->mask & (IN_CREATE | IN_CLOSE_WRITE | IN_MOVED_TO)) {
|
||||
virObjectEventPtr event;
|
||||
if (xenInotifyAddDomainConfigInfo(conn, fname, now) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("Error adding file to config cache"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
event = xenInotifyDomainEventFromFile(conn, fname,
|
||||
VIR_DOMAIN_EVENT_DEFINED,
|
||||
VIR_DOMAIN_EVENT_DEFINED_ADDED);
|
||||
|
||||
if (event)
|
||||
xenUnifiedDomainEventDispatch(conn->privateData, event);
|
||||
else
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("looking up dom"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cleanup:
|
||||
xenUnifiedUnlock(priv);
|
||||
}
|
||||
|
||||
/**
|
||||
* xenInotifyOpen:
|
||||
* @conn: pointer to the connection block
|
||||
* @name: URL for the target, NULL for local
|
||||
* @flags: combination of virDrvOpenFlag(s)
|
||||
*
|
||||
* Connects and starts listening for inotify events
|
||||
*
|
||||
* Returns 0 or -1 in case of error.
|
||||
*/
|
||||
int
|
||||
xenInotifyOpen(virConnectPtr conn,
|
||||
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
||||
unsigned int flags)
|
||||
{
|
||||
DIR *dh;
|
||||
struct dirent *ent;
|
||||
char *path;
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
int direrr;
|
||||
time_t now = time(NULL);
|
||||
|
||||
virCheckFlags(VIR_CONNECT_RO, -1);
|
||||
|
||||
if (priv->configDir) {
|
||||
priv->useXenConfigCache = 1;
|
||||
} else {
|
||||
/* /var/lib/xend/domains/<uuid>/config.sxp */
|
||||
priv->configDir = XEND_DOMAINS_DIR;
|
||||
priv->useXenConfigCache = 0;
|
||||
|
||||
if (VIR_ALLOC(priv->configInfoList) < 0)
|
||||
return -1;
|
||||
|
||||
/* populate initial list */
|
||||
if (virDirOpen(&dh, priv->configDir) < 0)
|
||||
return -1;
|
||||
|
||||
while ((direrr = virDirRead(dh, &ent, priv->configDir)) > 0) {
|
||||
if (STRPREFIX(ent->d_name, "."))
|
||||
continue;
|
||||
|
||||
/* Build the full file path */
|
||||
if (!(path = virFileBuildPath(priv->configDir, ent->d_name, NULL))) {
|
||||
VIR_DIR_CLOSE(dh);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (xenInotifyAddDomainConfigInfo(conn, path, now) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("Error adding file to config list"));
|
||||
VIR_DIR_CLOSE(dh);
|
||||
VIR_FREE(path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
VIR_FREE(path);
|
||||
}
|
||||
VIR_DIR_CLOSE(dh);
|
||||
if (direrr < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((priv->inotifyFD = inotify_init()) < 0) {
|
||||
virReportSystemError(errno,
|
||||
"%s", _("initializing inotify"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
VIR_DEBUG("Adding a watch on %s", priv->configDir);
|
||||
if (inotify_add_watch(priv->inotifyFD,
|
||||
priv->configDir,
|
||||
IN_CREATE |
|
||||
IN_CLOSE_WRITE | IN_DELETE |
|
||||
IN_MOVED_TO | IN_MOVED_FROM) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("adding watch on %s"),
|
||||
priv->configDir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
VIR_DEBUG("Building initial config cache");
|
||||
if (priv->useXenConfigCache &&
|
||||
xenXMConfigCacheRefresh(conn) < 0) {
|
||||
VIR_DEBUG("Failed to enable XM config cache %s", conn->err.message);
|
||||
return -1;
|
||||
}
|
||||
|
||||
VIR_DEBUG("Registering with event loop");
|
||||
/* Add the handle for monitoring */
|
||||
if ((priv->inotifyWatch = virEventAddHandle(priv->inotifyFD, VIR_EVENT_HANDLE_READABLE,
|
||||
xenInotifyEvent, conn, NULL)) < 0) {
|
||||
VIR_DEBUG("Failed to add inotify handle, disabling events");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* xenInotifyClose:
|
||||
* @conn: pointer to the connection block
|
||||
*
|
||||
* Close and stop listening for inotify events
|
||||
*
|
||||
* Returns 0 in case of success or -1 in case of error.
|
||||
*/
|
||||
int
|
||||
xenInotifyClose(virConnectPtr conn)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
if (priv->configInfoList)
|
||||
xenUnifiedDomainInfoListFree(priv->configInfoList);
|
||||
|
||||
if (priv->inotifyWatch != -1)
|
||||
virEventRemoveHandle(priv->inotifyWatch);
|
||||
VIR_FORCE_CLOSE(priv->inotifyFD);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* xen_inotify.h: Xen notification of xml files
|
||||
*
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
* Copyright (C) 2008 VirtualIron
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Ben Guthro
|
||||
*/
|
||||
#ifndef __VIR_XEN_INOTIFY_H__
|
||||
# define __VIR_XEN_INOTIFY_H__
|
||||
|
||||
# include "internal.h"
|
||||
|
||||
int xenInotifyOpen(virConnectPtr conn,
|
||||
virConnectAuthPtr auth,
|
||||
unsigned int flags);
|
||||
int xenInotifyClose(virConnectPtr conn);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
* xend_internal.h
|
||||
*
|
||||
* Copyright (C) 2006-2008, 2010-2013 Red Hat, Inc.
|
||||
* Copyright (C) 2005,2006 Anthony Liguori <aliguori@us.ibm.com>
|
||||
* and Daniel Veillard <veillard@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __XEND_INTERNAL_H_
|
||||
# define __XEND_INTERNAL_H_
|
||||
|
||||
# include <sys/types.h>
|
||||
# include <stdint.h>
|
||||
|
||||
# include "internal.h"
|
||||
# include "capabilities.h"
|
||||
# include "domain_conf.h"
|
||||
# include "driver.h"
|
||||
# include "virbuffer.h"
|
||||
# include "viruri.h"
|
||||
|
||||
int
|
||||
xenDaemonOpen_unix(virConnectPtr conn, const char *path);
|
||||
|
||||
/**
|
||||
* \brief Blocks until a domain's devices are initialized
|
||||
* \param xend A xend instance
|
||||
* \param name The domain's name
|
||||
* \return 0 for success; -1 (with errno) on error
|
||||
*
|
||||
* xen_create() returns after a domain has been allocated including
|
||||
* its memory. This does not guarantee, though, that the devices
|
||||
* have come up properly. For instance, if you create a VBD with an
|
||||
* invalid filename, the error won't occur until after this function
|
||||
* returns.
|
||||
*/
|
||||
int xend_wait_for_devices(virConnectPtr xend, const char *name);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Create a new domain
|
||||
* \param xend A xend instance
|
||||
* \param sexpr An S-Expr defining the domain
|
||||
* \return 0 for success; -1 (with errno) on error
|
||||
*
|
||||
* This method will create a domain based the passed in description. The
|
||||
* domain will be paused after creation and must be unpaused with
|
||||
* xenDaemonResumeDomain() to begin execution.
|
||||
*/
|
||||
int xenDaemonDomainCreateXML(virConnectPtr xend, const char *sexpr);
|
||||
|
||||
/**
|
||||
* \brief Lookup the id of a domain
|
||||
* \param xend A xend instance
|
||||
* \param name The name of the domain
|
||||
* \param uuid pointer to store a copy of the uuid
|
||||
* \return the id number on success; -1 (with errno) on error
|
||||
*
|
||||
* This method looks up the ids of a domain
|
||||
*/
|
||||
int xenDaemonDomainLookupByName_ids(virConnectPtr xend,
|
||||
const char *name, unsigned char *uuid);
|
||||
|
||||
|
||||
|
||||
virDomainDefPtr
|
||||
xenDaemonDomainFetch(virConnectPtr xend,
|
||||
int domid,
|
||||
const char *name,
|
||||
const char *cpus);
|
||||
|
||||
|
||||
/* refactored ones */
|
||||
int xenDaemonOpen(virConnectPtr conn, virConnectAuthPtr auth,
|
||||
unsigned int flags);
|
||||
int xenDaemonClose(virConnectPtr conn);
|
||||
int xenDaemonNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info);
|
||||
int xenDaemonNodeGetTopology(virConnectPtr conn, virCapsPtr caps);
|
||||
int xenDaemonDomainSuspend(virConnectPtr conn, virDomainDefPtr def);
|
||||
int xenDaemonDomainResume(virConnectPtr conn, virDomainDefPtr def);
|
||||
int xenDaemonDomainShutdown(virConnectPtr conn, virDomainDefPtr def);
|
||||
int xenDaemonDomainReboot(virConnectPtr conn, virDomainDefPtr def);
|
||||
int xenDaemonDomainDestroy(virConnectPtr conn, virDomainDefPtr def);
|
||||
int xenDaemonDomainSave(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *filename);
|
||||
int xenDaemonDomainCoreDump(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *filename,
|
||||
unsigned int flags);
|
||||
int xenDaemonDomainRestore(virConnectPtr conn, const char *filename);
|
||||
int xenDaemonDomainSetMemory(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned long memory);
|
||||
int xenDaemonDomainSetMaxMemory(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned long memory);
|
||||
int xenDaemonDomainGetInfo(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
virDomainInfoPtr info);
|
||||
int xenDaemonDomainGetState(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
int *state,
|
||||
int *reason);
|
||||
virDomainDefPtr xenDaemonDomainGetXMLDesc(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *cpus);
|
||||
unsigned long long xenDaemonDomainGetMaxMemory(virConnectPtr conn,
|
||||
virDomainDefPtr def);
|
||||
char **xenDaemonListDomainsOld(virConnectPtr xend);
|
||||
|
||||
char *xenDaemonDomainGetOSType(virConnectPtr conn,
|
||||
virDomainDefPtr def);
|
||||
|
||||
int xenDaemonNumOfDefinedDomains(virConnectPtr conn);
|
||||
int xenDaemonListDefinedDomains(virConnectPtr conn,
|
||||
char **const names,
|
||||
int maxnames);
|
||||
|
||||
int xenDaemonAttachDeviceFlags(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *xml,
|
||||
unsigned int flags);
|
||||
int xenDaemonDetachDeviceFlags(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *xml,
|
||||
unsigned int flags);
|
||||
|
||||
int xenDaemonDomainDefineXML(virConnectPtr conn,
|
||||
virDomainDefPtr def);
|
||||
int xenDaemonDomainCreate(virConnectPtr conn,
|
||||
virDomainDefPtr def);
|
||||
int xenDaemonDomainUndefine(virConnectPtr conn,
|
||||
virDomainDefPtr def);
|
||||
|
||||
int xenDaemonDomainSetVcpus (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned int vcpus);
|
||||
int xenDaemonDomainSetVcpusFlags (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned int vcpus,
|
||||
unsigned int flags);
|
||||
int xenDaemonDomainPinVcpu (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned int vcpu,
|
||||
unsigned char *cpumap,
|
||||
int maplen);
|
||||
int xenDaemonDomainGetVcpusFlags (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned int flags);
|
||||
int xenDaemonDomainGetVcpus (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
virVcpuInfoPtr info,
|
||||
int maxinfo,
|
||||
unsigned char *cpumaps,
|
||||
int maplen);
|
||||
int xenDaemonUpdateDeviceFlags(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *xml,
|
||||
unsigned int flags);
|
||||
int xenDaemonDomainGetAutostart(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
int *autostart);
|
||||
int xenDaemonDomainSetAutostart(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
int autostart);
|
||||
|
||||
int xenDaemonCreateXML(virConnectPtr conn, virDomainDefPtr def);
|
||||
virDomainDefPtr xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid);
|
||||
virDomainDefPtr xenDaemonLookupByName(virConnectPtr conn, const char *domname);
|
||||
int xenDaemonDomainMigratePrepare (virConnectPtr dconn,
|
||||
char **cookie, int *cookielen,
|
||||
const char *uri_in, char **uri_out,
|
||||
unsigned long flags, const char *dname, unsigned long resource);
|
||||
int xenDaemonDomainMigratePerform (virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *cookie, int cookielen,
|
||||
const char *uri, unsigned long flags,
|
||||
const char *dname, unsigned long resource);
|
||||
|
||||
int xenDaemonDomainBlockPeek(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *path,
|
||||
unsigned long long offset,
|
||||
size_t size,
|
||||
void *buffer);
|
||||
|
||||
char * xenDaemonGetSchedulerType(virConnectPtr conn,
|
||||
int *nparams);
|
||||
int xenDaemonGetSchedulerParameters(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
virTypedParameterPtr params,
|
||||
int *nparams);
|
||||
int xenDaemonSetSchedulerParameters(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
virTypedParameterPtr params,
|
||||
int nparams);
|
||||
|
||||
#endif /* __XEND_INTERNAL_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* xm_internal.h: helper routines for dealing with inactive domains
|
||||
*
|
||||
* Copyright (C) 2006-2007, 2010-2012 Red Hat, Inc.
|
||||
* Copyright (C) 2006 Daniel P. Berrange
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LIBVIRT_XM_INTERNAL_H_
|
||||
# define _LIBVIRT_XM_INTERNAL_H_
|
||||
|
||||
# include "internal.h"
|
||||
# include "driver.h"
|
||||
# include "virconf.h"
|
||||
# include "domain_conf.h"
|
||||
|
||||
int xenXMConfigCacheRefresh (virConnectPtr conn);
|
||||
int xenXMConfigCacheAddFile(virConnectPtr conn, const char *filename, time_t now);
|
||||
int xenXMConfigCacheRemoveFile(virConnectPtr conn, const char *filename);
|
||||
|
||||
int xenXMOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags);
|
||||
int xenXMClose(virConnectPtr conn);
|
||||
const char *xenXMGetType(virConnectPtr conn);
|
||||
int xenXMDomainGetInfo(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
virDomainInfoPtr info);
|
||||
int xenXMDomainGetState(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
int *state,
|
||||
int *reason);
|
||||
virDomainDefPtr xenXMDomainGetXMLDesc(virConnectPtr conn,
|
||||
virDomainDefPtr def);
|
||||
int xenXMDomainSetMemory(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned long memory);
|
||||
int xenXMDomainSetMaxMemory(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned long memory);
|
||||
unsigned long long xenXMDomainGetMaxMemory(virConnectPtr conn,
|
||||
virDomainDefPtr def);
|
||||
int xenXMDomainSetVcpus(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned int vcpus);
|
||||
int xenXMDomainSetVcpusFlags(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned int vcpus,
|
||||
unsigned int flags);
|
||||
int xenXMDomainGetVcpusFlags(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned int flags);
|
||||
int xenXMDomainPinVcpu(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
unsigned int vcpu,
|
||||
unsigned char *cpumap,
|
||||
int maplen);
|
||||
virDomainDefPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname);
|
||||
virDomainDefPtr xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid);
|
||||
|
||||
int xenXMListDefinedDomains(virConnectPtr conn, char ** const names, int maxnames);
|
||||
int xenXMNumOfDefinedDomains(virConnectPtr conn);
|
||||
|
||||
int xenXMDomainCreate(virConnectPtr conn,
|
||||
virDomainDefPtr def);
|
||||
int xenXMDomainDefineXML(virConnectPtr con, virDomainDefPtr def);
|
||||
int xenXMDomainUndefine(virConnectPtr conn, virDomainDefPtr def);
|
||||
|
||||
int xenXMDomainBlockPeek(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *path,
|
||||
unsigned long long offset,
|
||||
size_t size,
|
||||
void *buffer);
|
||||
|
||||
int xenXMDomainGetAutostart(virDomainDefPtr def,
|
||||
int *autostart);
|
||||
int xenXMDomainSetAutostart(virDomainDefPtr def,
|
||||
int autostart);
|
||||
|
||||
int xenXMDomainAttachDeviceFlags(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *xml,
|
||||
unsigned int flags);
|
||||
|
||||
int xenXMDomainDetachDeviceFlags(virConnectPtr conn,
|
||||
virDomainDefPtr def,
|
||||
const char *xml,
|
||||
unsigned int flags);
|
||||
|
||||
#endif
|
|
@ -1,920 +0,0 @@
|
|||
/*
|
||||
* xs_internal.c: access to Xen Store
|
||||
*
|
||||
* Copyright (C) 2006, 2009-2013 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Daniel Veillard <veillard@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#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>
|
||||
|
||||
#include <xen/dom0_ops.h>
|
||||
#include <xen/version.h>
|
||||
|
||||
#if HAVE_XENSTORE_H
|
||||
# include <xenstore.h>
|
||||
#else
|
||||
# include <xs.h>
|
||||
#endif
|
||||
|
||||
#include "virerror.h"
|
||||
#include "datatypes.h"
|
||||
#include "driver.h"
|
||||
#include "viralloc.h"
|
||||
#include "virlog.h"
|
||||
#include "viruuid.h"
|
||||
#include "xen_driver.h"
|
||||
#include "xs_internal.h"
|
||||
#include "xen_hypervisor.h"
|
||||
#include "virstring.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_XENSTORE
|
||||
|
||||
VIR_LOG_INIT("xen.xs_internal");
|
||||
|
||||
static void xenStoreWatchEvent(int watch, int fd, int events, void *data);
|
||||
static void xenStoreWatchListFree(xenStoreWatchListPtr list);
|
||||
|
||||
|
||||
/**
|
||||
* virDomainDoStoreQuery:
|
||||
* @conn: pointer to the hypervisor connection
|
||||
* @domid: id of the domain
|
||||
* @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 *
|
||||
virDomainDoStoreQuery(virConnectPtr conn, int domid, const char *path)
|
||||
{
|
||||
char s[256];
|
||||
unsigned int len = 0;
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
if (priv->xshandle == NULL)
|
||||
return NULL;
|
||||
|
||||
snprintf(s, 255, "/local/domain/%d/%s", domid, path);
|
||||
s[255] = 0;
|
||||
|
||||
return xs_read(priv->xshandle, 0, &s[0], &len);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
int
|
||||
xenStoreOpen(virConnectPtr conn,
|
||||
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
||||
unsigned int flags)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
virCheckFlags(VIR_CONNECT_RO, -1);
|
||||
|
||||
if (flags & VIR_CONNECT_RO)
|
||||
priv->xshandle = xs_daemon_open_readonly();
|
||||
else
|
||||
priv->xshandle = xs_daemon_open();
|
||||
|
||||
if (priv->xshandle == NULL) {
|
||||
/*
|
||||
* not being able to connect via the socket as an unprivileged
|
||||
* user is rather normal, this should fallback to the proxy (or
|
||||
* remote) mechanism.
|
||||
*/
|
||||
if (xenHavePrivilege()) {
|
||||
virReportError(VIR_ERR_NO_XEN,
|
||||
"%s", _("failed to connect to Xen Store"));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Init activeDomainList */
|
||||
if (VIR_ALLOC(priv->activeDomainList) < 0)
|
||||
return -1;
|
||||
|
||||
/* Init watch list before filling in domInfoList,
|
||||
so we can know if it is the first time through
|
||||
when the callback fires */
|
||||
if (VIR_ALLOC(priv->xsWatchList) < 0)
|
||||
return -1;
|
||||
|
||||
/* This will get called once at start */
|
||||
if (xenStoreAddWatch(conn, "@releaseDomain",
|
||||
"releaseDomain", xenStoreDomainReleased, priv) < 0)
|
||||
{
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("adding watch @releaseDomain"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The initial call of this will fill domInfoList */
|
||||
if (xenStoreAddWatch(conn, "@introduceDomain",
|
||||
"introduceDomain", xenStoreDomainIntroduced, priv) < 0)
|
||||
{
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("adding watch @introduceDomain"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Add an event handle */
|
||||
if ((priv->xsWatch = virEventAddHandle(xs_fileno(priv->xshandle),
|
||||
VIR_EVENT_HANDLE_READABLE,
|
||||
xenStoreWatchEvent,
|
||||
conn,
|
||||
NULL)) < 0)
|
||||
VIR_DEBUG("Failed to add event handle, disabling events");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
if (xenStoreRemoveWatch(conn, "@introduceDomain", "introduceDomain") < 0) {
|
||||
VIR_DEBUG("Warning, could not remove @introduceDomain watch");
|
||||
/* not fatal */
|
||||
}
|
||||
|
||||
if (xenStoreRemoveWatch(conn, "@releaseDomain", "releaseDomain") < 0) {
|
||||
VIR_DEBUG("Warning, could not remove @releaseDomain watch");
|
||||
/* not fatal */
|
||||
}
|
||||
|
||||
xenStoreWatchListFree(priv->xsWatchList);
|
||||
priv->xsWatchList = NULL;
|
||||
xenUnifiedDomainInfoListFree(priv->activeDomainList);
|
||||
priv->activeDomainList = NULL;
|
||||
|
||||
if (priv->xshandle == NULL)
|
||||
return -1;
|
||||
|
||||
if (priv->xsWatch != -1)
|
||||
virEventRemoveHandle(priv->xsWatch);
|
||||
|
||||
xs_daemon_close(priv->xshandle);
|
||||
priv->xshandle = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
char **idlist = NULL;
|
||||
size_t i;
|
||||
int ret = -1, realnum = 0;
|
||||
long id;
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
idlist = xs_directory(priv->xshandle, 0, "/local/domain", &num);
|
||||
if (idlist) {
|
||||
for (i = 0; i < num; i++) {
|
||||
if (virStrToLong_l(idlist[i], NULL, 10, &id) < 0)
|
||||
goto out;
|
||||
|
||||
/* Sometimes xenstore has stale domain IDs, so filter
|
||||
against the hypervisor's info */
|
||||
if (xenHypervisorHasDomain(conn, (int)id))
|
||||
realnum++;
|
||||
}
|
||||
out:
|
||||
VIR_FREE(idlist);
|
||||
ret = realnum;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* xenStoreDoListDomains:
|
||||
* @conn: pointer to the hypervisor connection
|
||||
* @ids: array to collect the list of IDs of active domains
|
||||
* @maxids: size of @ids
|
||||
*
|
||||
* Internal API: collect the list of active domains, and store
|
||||
* their ID in @maxids. The driver lock must be held.
|
||||
*
|
||||
* Returns the number of domain found or -1 in case of error
|
||||
*/
|
||||
static int
|
||||
xenStoreDoListDomains(virConnectPtr conn,
|
||||
xenUnifiedPrivatePtr priv,
|
||||
int *ids,
|
||||
int maxids)
|
||||
{
|
||||
char **idlist = NULL;
|
||||
unsigned int num;
|
||||
size_t i;
|
||||
int ret = -1;
|
||||
long id;
|
||||
|
||||
idlist = xs_directory(priv->xshandle, 0, "/local/domain", &num);
|
||||
if (idlist == NULL)
|
||||
goto out;
|
||||
|
||||
for (ret = 0, i = 0; (i < num) && (ret < maxids); i++) {
|
||||
if (virStrToLong_l(idlist[i], NULL, 10, &id) < 0)
|
||||
goto out;
|
||||
|
||||
/* Sometimes xenstore has stale domain IDs, so filter
|
||||
against the hypervisor's info */
|
||||
if (xenHypervisorHasDomain(conn, (int)id))
|
||||
ids[ret++] = (int) id;
|
||||
}
|
||||
|
||||
out:
|
||||
VIR_FREE(idlist);
|
||||
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)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
int ret;
|
||||
|
||||
xenUnifiedLock(priv);
|
||||
ret = xenStoreDoListDomains(conn, priv, ids, maxids);
|
||||
xenUnifiedUnlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* xenStoreDomainGetVNCPort:
|
||||
* @conn: the hypervisor connection
|
||||
* @domid: id of the domain
|
||||
*
|
||||
* Return the port number on which the domain is listening for VNC
|
||||
* connections.
|
||||
*
|
||||
* The caller must hold the lock on the privateData
|
||||
* associated with the 'conn' parameter.
|
||||
*
|
||||
* Returns the port number, -1 in case of error
|
||||
*/
|
||||
int
|
||||
xenStoreDomainGetVNCPort(virConnectPtr conn, int domid)
|
||||
{
|
||||
char *tmp;
|
||||
int ret = -1;
|
||||
|
||||
tmp = virDomainDoStoreQuery(conn, domid, "console/vnc-port");
|
||||
if (tmp != NULL) {
|
||||
ignore_value(virStrToLong_i(tmp, NULL, 10, &ret));
|
||||
VIR_FREE(tmp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* xenStoreDomainGetConsolePath:
|
||||
* @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
|
||||
* responsibility to free() the return string. Returns NULL
|
||||
* on error
|
||||
*
|
||||
* The caller must hold the lock on the privateData
|
||||
* associated with the 'conn' parameter.
|
||||
*/
|
||||
char *
|
||||
xenStoreDomainGetConsolePath(virConnectPtr conn, int domid)
|
||||
{
|
||||
return virDomainDoStoreQuery(conn, domid, "console/tty");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* responsibility to free() the return string. Returns NULL
|
||||
* on error
|
||||
*
|
||||
* The caller must hold the lock on the privateData
|
||||
* associated with the 'conn' parameter.
|
||||
*/
|
||||
char *
|
||||
xenStoreDomainGetSerialConsolePath(virConnectPtr conn, int domid)
|
||||
{
|
||||
return virDomainDoStoreQuery(conn, domid, "serial/0/tty");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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 *
|
||||
xenStoreDomainGetNetworkID(virConnectPtr conn, int id, const char *mac)
|
||||
{
|
||||
char dir[80], path[128], **list = NULL, *val = NULL;
|
||||
unsigned int len, num;
|
||||
size_t i;
|
||||
char *ret = NULL;
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
if (id < 0 || priv->xshandle == NULL || mac == NULL)
|
||||
return NULL;
|
||||
|
||||
snprintf(dir, sizeof(dir), "/local/domain/0/backend/vif/%d", id);
|
||||
list = xs_directory(priv->xshandle, 0, dir, &num);
|
||||
if (list == NULL)
|
||||
return NULL;
|
||||
for (i = 0; i < num; i++) {
|
||||
snprintf(path, sizeof(path), "%s/%s/%s", dir, list[i], "mac");
|
||||
if ((val = xs_read(priv->xshandle, 0, path, &len)) == NULL)
|
||||
break;
|
||||
|
||||
bool match = (virMacAddrCompare(val, mac) == 0);
|
||||
|
||||
VIR_FREE(val);
|
||||
|
||||
if (match) {
|
||||
ignore_value(VIR_STRDUP(ret, list[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VIR_FREE(list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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 *
|
||||
xenStoreDomainGetDiskID(virConnectPtr conn, int id, const char *dev)
|
||||
{
|
||||
char dir[80], path[128], **list = NULL, *val = NULL;
|
||||
unsigned int devlen, len, num;
|
||||
size_t i;
|
||||
char *ret = NULL;
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
if (id < 0 || priv->xshandle == NULL || dev == NULL)
|
||||
return NULL;
|
||||
devlen = strlen(dev);
|
||||
if (devlen <= 0)
|
||||
return NULL;
|
||||
|
||||
snprintf(dir, sizeof(dir), "/local/domain/0/backend/vbd/%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)) {
|
||||
VIR_FREE(val);
|
||||
} else {
|
||||
ignore_value(VIR_STRDUP(ret, list[i]));
|
||||
|
||||
VIR_FREE(val);
|
||||
VIR_FREE(list);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
VIR_FREE(list);
|
||||
}
|
||||
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)) {
|
||||
VIR_FREE(val);
|
||||
} else {
|
||||
ignore_value(VIR_STRDUP(ret, list[i]));
|
||||
|
||||
VIR_FREE(val);
|
||||
VIR_FREE(list);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
VIR_FREE(list);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
unsigned int len, num;
|
||||
size_t i;
|
||||
char *ret = NULL;
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
if (id < 0 || priv->xshandle == NULL || bdf == NULL)
|
||||
return NULL;
|
||||
|
||||
snprintf(dir, sizeof(dir), "/local/domain/0/backend/pci/%d", id);
|
||||
list = xs_directory(priv->xshandle, 0, dir, &num);
|
||||
if (list == NULL)
|
||||
return NULL;
|
||||
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) {
|
||||
ignore_value(VIR_STRDUP(ret, list[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VIR_FREE(list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller must hold the lock on the privateData
|
||||
* associated with the 'conn' parameter.
|
||||
*/
|
||||
char *
|
||||
xenStoreDomainGetName(virConnectPtr conn, int id)
|
||||
{
|
||||
char prop[200];
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
unsigned int len;
|
||||
|
||||
if (priv->xshandle == NULL)
|
||||
return NULL;
|
||||
|
||||
snprintf(prop, 199, "/local/domain/%d/name", id);
|
||||
prop[199] = 0;
|
||||
return xs_read(priv->xshandle, 0, prop, &len);
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller must hold the lock on the privateData
|
||||
* associated with the 'conn' parameter.
|
||||
*/
|
||||
int
|
||||
xenStoreDomainGetUUID(virConnectPtr conn, int id, unsigned char *uuid)
|
||||
{
|
||||
char prop[200];
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
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;
|
||||
/* This will return something like
|
||||
* /vm/00000000-0000-0000-0000-000000000000[-*] */
|
||||
uuidstr = xs_read(priv->xshandle, 0, prop, &len);
|
||||
/* Strip optional version suffix when VM was renamed */
|
||||
if (len > 40) /* strlen('/vm/') + VIR_UUID_STRING_BUFLEN - sizeof('\0') */
|
||||
uuidstr[40] = '\0';
|
||||
|
||||
/* remove "/vm/" */
|
||||
ret = virUUIDParse(uuidstr + 4, uuid);
|
||||
|
||||
VIR_FREE(uuidstr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
xenStoreWatchListFree(xenStoreWatchListPtr list)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < list->count; i++) {
|
||||
VIR_FREE(list->watches[i]->path);
|
||||
VIR_FREE(list->watches[i]->token);
|
||||
VIR_FREE(list->watches[i]);
|
||||
}
|
||||
VIR_FREE(list);
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller must hold the lock on the privateData
|
||||
* associated with the 'conn' parameter.
|
||||
*/
|
||||
int
|
||||
xenStoreAddWatch(virConnectPtr conn,
|
||||
const char *path,
|
||||
const char *token,
|
||||
xenStoreWatchCallback cb,
|
||||
void *opaque)
|
||||
{
|
||||
xenStoreWatchPtr watch = NULL;
|
||||
int n;
|
||||
xenStoreWatchListPtr list;
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
if (priv->xshandle == NULL)
|
||||
return -1;
|
||||
|
||||
list = priv->xsWatchList;
|
||||
if (!list)
|
||||
return -1;
|
||||
|
||||
/* check if we already have this callback on our list */
|
||||
for (n = 0; n < list->count; n++) {
|
||||
if (STREQ(list->watches[n]->path, path) &&
|
||||
STREQ(list->watches[n]->token, token)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("watch already tracked"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (VIR_ALLOC(watch) < 0)
|
||||
goto error;
|
||||
|
||||
watch->cb = cb;
|
||||
watch->opaque = opaque;
|
||||
if (VIR_STRDUP(watch->path, path) < 0 ||
|
||||
VIR_STRDUP(watch->token, token) < 0)
|
||||
goto error;
|
||||
|
||||
if (VIR_APPEND_ELEMENT_COPY(list->watches, list->count, watch) < 0)
|
||||
goto error;
|
||||
|
||||
return xs_watch(priv->xshandle, watch->path, watch->token);
|
||||
|
||||
error:
|
||||
if (watch) {
|
||||
VIR_FREE(watch->path);
|
||||
VIR_FREE(watch->token);
|
||||
VIR_FREE(watch);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller must hold the lock on the privateData
|
||||
* associated with the 'conn' parameter.
|
||||
*/
|
||||
int
|
||||
xenStoreRemoveWatch(virConnectPtr conn, const char *path, const char *token)
|
||||
{
|
||||
size_t i;
|
||||
xenStoreWatchListPtr list;
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
if (priv->xshandle == NULL)
|
||||
return -1;
|
||||
|
||||
list = priv->xsWatchList;
|
||||
if (!list)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < list->count; i++) {
|
||||
if (STREQ(list->watches[i]->path, path) &&
|
||||
STREQ(list->watches[i]->token, token)) {
|
||||
|
||||
if (!xs_unwatch(priv->xshandle,
|
||||
list->watches[i]->path,
|
||||
list->watches[i]->token))
|
||||
{
|
||||
VIR_DEBUG("WARNING: Could not remove watch");
|
||||
/* Not fatal, continue */
|
||||
}
|
||||
|
||||
VIR_FREE(list->watches[i]->path);
|
||||
VIR_FREE(list->watches[i]->token);
|
||||
VIR_FREE(list->watches[i]);
|
||||
|
||||
VIR_DELETE_ELEMENT(list->watches, i, list->count);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static xenStoreWatchPtr
|
||||
xenStoreFindWatch(xenStoreWatchListPtr list,
|
||||
const char *path,
|
||||
const char *token)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < list->count; i++)
|
||||
if (STREQ(path, list->watches[i]->path) &&
|
||||
STREQ(token, list->watches[i]->token))
|
||||
return list->watches[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
xenStoreWatchEvent(int watch ATTRIBUTE_UNUSED,
|
||||
int fd ATTRIBUTE_UNUSED,
|
||||
int events, void *data)
|
||||
{
|
||||
char **event;
|
||||
char *path;
|
||||
char *token;
|
||||
unsigned int stringCount;
|
||||
xenStoreWatchPtr sw;
|
||||
|
||||
virConnectPtr conn = data;
|
||||
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||
|
||||
if (!priv) return;
|
||||
|
||||
/* only set a watch on read and write events */
|
||||
if (events & (VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP)) return;
|
||||
|
||||
xenUnifiedLock(priv);
|
||||
|
||||
if (!priv->xshandle)
|
||||
goto cleanup;
|
||||
|
||||
event = xs_read_watch(priv->xshandle, &stringCount);
|
||||
if (!event)
|
||||
goto cleanup;
|
||||
|
||||
path = event[XS_WATCH_PATH];
|
||||
token = event[XS_WATCH_TOKEN];
|
||||
|
||||
sw = xenStoreFindWatch(priv->xsWatchList, path, token);
|
||||
if (sw)
|
||||
sw->cb(conn, path, token, sw->opaque);
|
||||
VIR_FREE(event);
|
||||
|
||||
cleanup:
|
||||
xenUnifiedUnlock(priv);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The domain callback for the @introduceDomain watch
|
||||
*
|
||||
* The lock on 'priv' is held when calling this
|
||||
*/
|
||||
int
|
||||
xenStoreDomainIntroduced(virConnectPtr conn,
|
||||
const char *path ATTRIBUTE_UNUSED,
|
||||
const char *token ATTRIBUTE_UNUSED,
|
||||
void *opaque)
|
||||
{
|
||||
size_t i, j;
|
||||
int found, missing = 0, retries = 20;
|
||||
int new_domain_cnt;
|
||||
int *new_domids;
|
||||
int nread;
|
||||
|
||||
xenUnifiedPrivatePtr priv = opaque;
|
||||
|
||||
retry:
|
||||
new_domain_cnt = xenStoreNumOfDomains(conn);
|
||||
if (new_domain_cnt < 0)
|
||||
return -1;
|
||||
|
||||
if (VIR_ALLOC_N(new_domids, new_domain_cnt) < 0)
|
||||
return -1;
|
||||
nread = xenStoreDoListDomains(conn, priv, new_domids, new_domain_cnt);
|
||||
if (nread != new_domain_cnt) {
|
||||
/* mismatch. retry this read */
|
||||
VIR_FREE(new_domids);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
missing = 0;
|
||||
for (i = 0; i < new_domain_cnt; i++) {
|
||||
found = 0;
|
||||
for (j = 0; j < priv->activeDomainList->count; j++) {
|
||||
if (priv->activeDomainList->doms[j]->id == new_domids[i]) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
virObjectEventPtr event;
|
||||
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;
|
||||
}
|
||||
|
||||
event = virDomainEventLifecycleNew(new_domids[i], name, uuid,
|
||||
VIR_DOMAIN_EVENT_STARTED,
|
||||
VIR_DOMAIN_EVENT_STARTED_BOOTED);
|
||||
if (event)
|
||||
xenUnifiedDomainEventDispatch(priv, event);
|
||||
|
||||
/* Add to the list */
|
||||
xenUnifiedAddDomainInfo(priv->activeDomainList,
|
||||
new_domids[i], name, uuid);
|
||||
|
||||
VIR_FREE(name);
|
||||
}
|
||||
}
|
||||
VIR_FREE(new_domids);
|
||||
|
||||
if (missing && retries--) {
|
||||
VIR_DEBUG("Some domains were missing, trying again");
|
||||
usleep(100 * 1000);
|
||||
goto retry;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The domain callback for the @destroyDomain watch
|
||||
*
|
||||
* The lock on 'priv' is held when calling this
|
||||
*/
|
||||
int
|
||||
xenStoreDomainReleased(virConnectPtr conn,
|
||||
const char *path ATTRIBUTE_UNUSED,
|
||||
const char *token ATTRIBUTE_UNUSED,
|
||||
void *opaque)
|
||||
{
|
||||
size_t i, j;
|
||||
int found, removed, retries = 20;
|
||||
int new_domain_cnt;
|
||||
int *new_domids;
|
||||
int nread;
|
||||
|
||||
xenUnifiedPrivatePtr priv = opaque;
|
||||
|
||||
if (!priv->activeDomainList->count) return 0;
|
||||
|
||||
retry:
|
||||
new_domain_cnt = xenStoreNumOfDomains(conn);
|
||||
if (new_domain_cnt < 0)
|
||||
return -1;
|
||||
|
||||
if (VIR_ALLOC_N(new_domids, new_domain_cnt) < 0)
|
||||
return -1;
|
||||
nread = xenStoreDoListDomains(conn, priv, new_domids, new_domain_cnt);
|
||||
if (nread != new_domain_cnt) {
|
||||
/* mismatch. retry this read */
|
||||
VIR_FREE(new_domids);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
removed = 0;
|
||||
for (j = 0; j < priv->activeDomainList->count; j++) {
|
||||
found = 0;
|
||||
for (i = 0; i < new_domain_cnt; i++) {
|
||||
if (priv->activeDomainList->doms[j]->id == new_domids[i]) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
virObjectEventPtr event =
|
||||
virDomainEventLifecycleNew(-1,
|
||||
priv->activeDomainList->doms[j]->name,
|
||||
priv->activeDomainList->doms[j]->uuid,
|
||||
VIR_DOMAIN_EVENT_STOPPED,
|
||||
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
|
||||
if (event)
|
||||
xenUnifiedDomainEventDispatch(priv, event);
|
||||
|
||||
/* Remove from the list */
|
||||
xenUnifiedRemoveDomainInfo(priv->activeDomainList,
|
||||
priv->activeDomainList->doms[j]->id,
|
||||
priv->activeDomainList->doms[j]->name,
|
||||
priv->activeDomainList->doms[j]->uuid);
|
||||
|
||||
removed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
VIR_FREE(new_domids);
|
||||
|
||||
if (!removed && retries--) {
|
||||
VIR_DEBUG("No domains removed, retrying");
|
||||
usleep(100 * 1000);
|
||||
goto retry;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* xs_internal.h: internal API for access to XenStore
|
||||
*
|
||||
* Copyright (C) 2006, 2010-2012 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Daniel Veillard <veillard@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIR_XS_INTERNAL_H__
|
||||
# define __VIR_XS_INTERNAL_H__
|
||||
|
||||
# include "internal.h"
|
||||
# include "driver.h"
|
||||
|
||||
int xenStoreOpen (virConnectPtr conn,
|
||||
virConnectAuthPtr auth,
|
||||
unsigned int flags);
|
||||
int xenStoreClose (virConnectPtr conn);
|
||||
int xenStoreNumOfDomains (virConnectPtr conn);
|
||||
int xenStoreListDomains (virConnectPtr conn,
|
||||
int *ids,
|
||||
int maxids);
|
||||
|
||||
int xenStoreDomainGetVNCPort(virConnectPtr conn,
|
||||
int domid);
|
||||
char * xenStoreDomainGetConsolePath(virConnectPtr conn,
|
||||
int domid);
|
||||
char * xenStoreDomainGetSerialConsolePath(virConnectPtr conn,
|
||||
int domid);
|
||||
char * xenStoreDomainGetNetworkID(virConnectPtr conn,
|
||||
int id,
|
||||
const char *mac);
|
||||
char * xenStoreDomainGetDiskID(virConnectPtr conn,
|
||||
int id,
|
||||
const char *dev);
|
||||
char * xenStoreDomainGetPCIID(virConnectPtr conn,
|
||||
int domid,
|
||||
const char *bdf);
|
||||
char * xenStoreDomainGetName(virConnectPtr conn,
|
||||
int id);
|
||||
int xenStoreDomainGetUUID(virConnectPtr conn,
|
||||
int id,
|
||||
unsigned char *uuid);
|
||||
|
||||
typedef int (*xenStoreWatchCallback)(virConnectPtr conn,
|
||||
const char *path,
|
||||
const char *token,
|
||||
void *opaque);
|
||||
|
||||
struct _xenStoreWatch {
|
||||
char *path;
|
||||
char *token;
|
||||
xenStoreWatchCallback cb;
|
||||
void *opaque;
|
||||
};
|
||||
typedef struct _xenStoreWatch xenStoreWatch;
|
||||
typedef xenStoreWatch *xenStoreWatchPtr;
|
||||
|
||||
struct _xenStoreWatchList {
|
||||
size_t count;
|
||||
xenStoreWatchPtr *watches;
|
||||
};
|
||||
typedef struct _xenStoreWatchList xenStoreWatchList;
|
||||
typedef xenStoreWatchList *xenStoreWatchListPtr;
|
||||
|
||||
|
||||
int xenStoreAddWatch(virConnectPtr conn,
|
||||
const char *path,
|
||||
const char *token,
|
||||
xenStoreWatchCallback cb,
|
||||
void *opaque);
|
||||
int xenStoreRemoveWatch(virConnectPtr conn,
|
||||
const char *path,
|
||||
const char *token);
|
||||
|
||||
/* domain events */
|
||||
int xenStoreDomainIntroduced(virConnectPtr conn,
|
||||
const char *path,
|
||||
const char *token,
|
||||
void *opaque);
|
||||
int xenStoreDomainReleased(virConnectPtr conn,
|
||||
const char *path,
|
||||
const char *token,
|
||||
void *opaque);
|
||||
|
||||
int xenStoreDomainEventEmitted(virDomainEventType evt);
|
||||
#endif /* __VIR_XS_INTERNAL_H__ */
|
Loading…
Reference in New Issue