mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 03:12:22 +00:00
virDomainBlockPeek call
* configure.in: Document AC_SYS_LARGEFILE. * docs/hvsupport.html.in: Document HV support for virDomainBlockPeek. * include/libvirt/libvirt.h.in, src/driver.h, src/libvirt.c, src/libvirt_sym.version: Add virDomainBlockPeek infrastructure. * src/qemu_driver.c, src/test.c: Null versions of this call. * src/xen_unified.c, src/xend_internal.c, src/xend_internal.h, src/xm_internal.c, src/xm_internal.h: Xen implementation. * tests/sexpr2xmldata/sexpr2xml-curmem.xml, tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml: XML output has been reordered slightly in the Xen driver, but should be functionally the same.
This commit is contained in:
parent
0bd57cdbe1
commit
8354895e68
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
Thu Jun 5 14:10:00 BST 2008 Richard W.M. Jones <rjones@redhat.com>
|
||||||
|
|
||||||
|
virDomainBlockPeek call
|
||||||
|
* configure.in: Document AC_SYS_LARGEFILE.
|
||||||
|
* docs/hvsupport.html.in: Document HV support for virDomainBlockPeek.
|
||||||
|
* include/libvirt/libvirt.h.in, src/driver.h, src/libvirt.c,
|
||||||
|
src/libvirt_sym.version: Add virDomainBlockPeek infrastructure.
|
||||||
|
* src/qemu_driver.c, src/test.c: Null versions of this call.
|
||||||
|
* src/xen_unified.c, src/xend_internal.c, src/xend_internal.h,
|
||||||
|
src/xm_internal.c, src/xm_internal.h: Xen implementation.
|
||||||
|
* tests/sexpr2xmldata/sexpr2xml-curmem.xml,
|
||||||
|
tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml: XML output
|
||||||
|
has been reordered slightly in the Xen driver, but should be
|
||||||
|
functionally the same.
|
||||||
|
|
||||||
Wed Jun 4 23:02:21 PST 2008 David L. Leskovec <dlesko@linux.vnet.ibm.com>
|
Wed Jun 4 23:02:21 PST 2008 David L. Leskovec <dlesko@linux.vnet.ibm.com>
|
||||||
|
|
||||||
* src/lxc_driver.c: Add sanity of tty pid before kill()
|
* src/lxc_driver.c: Add sanity of tty pid before kill()
|
||||||
|
@ -60,6 +60,10 @@ AM_PROG_CC_C_O
|
|||||||
|
|
||||||
LIBVIRT_COMPILE_WARNINGS([maximum])
|
LIBVIRT_COMPILE_WARNINGS([maximum])
|
||||||
|
|
||||||
|
dnl Support large files / 64 bit seek offsets.
|
||||||
|
dnl Use --disable-largefile if you don't want this.
|
||||||
|
AC_SYS_LARGEFILE
|
||||||
|
|
||||||
dnl Availability of various common functions (non-fatal if missing).
|
dnl Availability of various common functions (non-fatal if missing).
|
||||||
AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity])
|
AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity])
|
||||||
|
|
||||||
@ -982,8 +986,6 @@ AC_SUBST([CYGWIN_EXTRA_LIBADD])
|
|||||||
AC_SUBST([CYGWIN_EXTRA_PYTHON_LIBADD])
|
AC_SUBST([CYGWIN_EXTRA_PYTHON_LIBADD])
|
||||||
AC_SUBST([MINGW_EXTRA_LDFLAGS])
|
AC_SUBST([MINGW_EXTRA_LDFLAGS])
|
||||||
|
|
||||||
AC_SYS_LARGEFILE
|
|
||||||
|
|
||||||
# Set LV_LIBTOOL_OBJDIR to "." or $lt_cv_objdir, depending on whether
|
# Set LV_LIBTOOL_OBJDIR to "." or $lt_cv_objdir, depending on whether
|
||||||
# we're building shared libraries. This is the name of the directory
|
# we're building shared libraries. This is the name of the directory
|
||||||
# in which .o files will be created.
|
# in which .o files will be created.
|
||||||
|
@ -137,7 +137,7 @@ in.
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
This information changes frequently. This page was last checked or
|
This information changes frequently. This page was last checked or
|
||||||
updated on <i>2007-08-20</i>.
|
updated on <i>2008-06-05</i>.
|
||||||
</p>
|
</p>
|
||||||
<h3>Domain functions</h3>
|
<h3>Domain functions</h3>
|
||||||
<p> x = not supported; empty cell means no information </p>
|
<p> x = not supported; empty cell means no information </p>
|
||||||
@ -254,6 +254,14 @@ updated on <i>2007-08-20</i>.
|
|||||||
<td> ≥ 0.2.0 </td>
|
<td> ≥ 0.2.0 </td>
|
||||||
<td> ≥ 0.3.0 </td>
|
<td> ≥ 0.3.0 </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> virConnectOpenAuth </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td> virConnectOpenReadOnly </td>
|
<td> virConnectOpenReadOnly </td>
|
||||||
<td> All </td>
|
<td> All </td>
|
||||||
@ -270,6 +278,14 @@ updated on <i>2007-08-20</i>.
|
|||||||
<td> x </td>
|
<td> x </td>
|
||||||
<td> ≥ 0.3.0 </td>
|
<td> ≥ 0.3.0 </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> virDomainBlockPeek </td>
|
||||||
|
<td> 0.4.3 </td>
|
||||||
|
<td> x </td>
|
||||||
|
<td> x </td>
|
||||||
|
<td> x </td>
|
||||||
|
<td> x </td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td> virDomainBlockStats </td>
|
<td> virDomainBlockStats </td>
|
||||||
<td> 0.3.2 </td>
|
<td> 0.3.2 </td>
|
||||||
|
@ -9,7 +9,7 @@ in.
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
This information changes frequently. This page was last checked or
|
This information changes frequently. This page was last checked or
|
||||||
updated on <i>2007-08-20</i>.
|
updated on <i>2008-06-05</i>.
|
||||||
</p>
|
</p>
|
||||||
<h3>Domain functions</h3>
|
<h3>Domain functions</h3>
|
||||||
<p> x = not supported; empty cell means no information </p>
|
<p> x = not supported; empty cell means no information </p>
|
||||||
@ -118,6 +118,14 @@ updated on <i>2007-08-20</i>.
|
|||||||
<td> ≥ 0.2.0 </td>
|
<td> ≥ 0.2.0 </td>
|
||||||
<td> ≥ 0.3.0 </td>
|
<td> ≥ 0.3.0 </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> virConnectOpenAuth </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td> virConnectOpenReadOnly </td>
|
<td> virConnectOpenReadOnly </td>
|
||||||
<td> All </td>
|
<td> All </td>
|
||||||
@ -134,6 +142,14 @@ updated on <i>2007-08-20</i>.
|
|||||||
<td> x </td>
|
<td> x </td>
|
||||||
<td> ≥ 0.3.0 </td>
|
<td> ≥ 0.3.0 </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> virDomainBlockPeek </td>
|
||||||
|
<td> 0.4.3 </td>
|
||||||
|
<td> x </td>
|
||||||
|
<td> x </td>
|
||||||
|
<td> x </td>
|
||||||
|
<td> x </td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td> virDomainBlockStats </td>
|
<td> virDomainBlockStats </td>
|
||||||
<td> 0.3.2 </td>
|
<td> 0.3.2 </td>
|
||||||
|
@ -530,7 +530,12 @@ int virDomainInterfaceStats (virDomainPtr dom,
|
|||||||
const char *path,
|
const char *path,
|
||||||
virDomainInterfaceStatsPtr stats,
|
virDomainInterfaceStatsPtr stats,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
int virDomainBlockPeek (virDomainPtr dom,
|
||||||
|
const char *path,
|
||||||
|
unsigned long long offset,
|
||||||
|
size_t size,
|
||||||
|
void *buffer,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* defined but not running domains
|
* defined but not running domains
|
||||||
|
@ -530,7 +530,12 @@ int virDomainInterfaceStats (virDomainPtr dom,
|
|||||||
const char *path,
|
const char *path,
|
||||||
virDomainInterfaceStatsPtr stats,
|
virDomainInterfaceStatsPtr stats,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
int virDomainBlockPeek (virDomainPtr dom,
|
||||||
|
const char *path,
|
||||||
|
unsigned long long offset,
|
||||||
|
size_t size,
|
||||||
|
void *buffer,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* defined but not running domains
|
* defined but not running domains
|
||||||
|
@ -225,6 +225,13 @@ typedef int
|
|||||||
const char *path,
|
const char *path,
|
||||||
struct _virDomainInterfaceStats *stats);
|
struct _virDomainInterfaceStats *stats);
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(*virDrvDomainBlockPeek)
|
||||||
|
(virDomainPtr domain,
|
||||||
|
const char *path,
|
||||||
|
unsigned long long offset, size_t size,
|
||||||
|
void *buffer);
|
||||||
|
|
||||||
typedef int
|
typedef int
|
||||||
(*virDrvDomainMigratePrepare)
|
(*virDrvDomainMigratePrepare)
|
||||||
(virConnectPtr dconn,
|
(virConnectPtr dconn,
|
||||||
@ -337,6 +344,7 @@ struct _virDriver {
|
|||||||
virDrvDomainMigrateFinish domainMigrateFinish;
|
virDrvDomainMigrateFinish domainMigrateFinish;
|
||||||
virDrvDomainBlockStats domainBlockStats;
|
virDrvDomainBlockStats domainBlockStats;
|
||||||
virDrvDomainInterfaceStats domainInterfaceStats;
|
virDrvDomainInterfaceStats domainInterfaceStats;
|
||||||
|
virDrvDomainBlockPeek domainBlockPeek;
|
||||||
virDrvNodeGetCellsFreeMemory nodeGetCellsFreeMemory;
|
virDrvNodeGetCellsFreeMemory nodeGetCellsFreeMemory;
|
||||||
virDrvNodeGetFreeMemory getFreeMemory;
|
virDrvNodeGetFreeMemory getFreeMemory;
|
||||||
};
|
};
|
||||||
|
@ -2586,7 +2586,84 @@ virDomainInterfaceStats (virDomainPtr dom, const char *path,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainBlockPeek:
|
||||||
|
* @dom: pointer to the domain object
|
||||||
|
* @path: path to the block device
|
||||||
|
* @offset: offset within block device
|
||||||
|
* @size: size to read
|
||||||
|
* @buffer: return buffer (must be at least size bytes)
|
||||||
|
* @flags: unused, always pass 0
|
||||||
|
*
|
||||||
|
* This function allows you to read the contents of a domain's
|
||||||
|
* disk device.
|
||||||
|
*
|
||||||
|
* Typical uses for this are to determine if the domain has
|
||||||
|
* written a Master Boot Record (indicating that the domain
|
||||||
|
* has completed installation), or to try to work out the state
|
||||||
|
* of the domain's filesystems.
|
||||||
|
*
|
||||||
|
* (Note that in the local case you might try to open the
|
||||||
|
* block device or file directly, but that won't work in the
|
||||||
|
* remote case, nor if you don't have sufficient permission.
|
||||||
|
* Hence the need for this call).
|
||||||
|
*
|
||||||
|
* 'path' must be a device or file corresponding to the domain.
|
||||||
|
* In other words it must be the precise string returned in
|
||||||
|
* a <disk><source dev='...'/></disk> from
|
||||||
|
* virDomainGetXMLDesc.
|
||||||
|
*
|
||||||
|
* 'offset' and 'size' represent an area which must lie entirely
|
||||||
|
* within the device or file. 'size' may be 0 to test if the
|
||||||
|
* call would succeed.
|
||||||
|
*
|
||||||
|
* 'buffer' is the return buffer and must be at least 'size' bytes.
|
||||||
|
*
|
||||||
|
* Returns: 0 in case of success or -1 in case of failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virDomainBlockPeek (virDomainPtr dom,
|
||||||
|
const char *path,
|
||||||
|
unsigned long long offset /* really 64 bits */,
|
||||||
|
size_t size,
|
||||||
|
void *buffer,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
virConnectPtr conn;
|
||||||
|
DEBUG("domain=%p, path=%s, offset=%lld, size=%zi, buffer=%p",
|
||||||
|
dom, path, offset, size, buffer);
|
||||||
|
|
||||||
|
if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
|
||||||
|
virLibDomainError (NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
conn = dom->conn;
|
||||||
|
|
||||||
|
if (!path) {
|
||||||
|
virLibDomainError (dom, VIR_ERR_INVALID_ARG,
|
||||||
|
_("path is NULL"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags != 0) {
|
||||||
|
virLibDomainError (dom, VIR_ERR_INVALID_ARG,
|
||||||
|
_("flags must be zero"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow size == 0 as an access test. */
|
||||||
|
if (size > 0 && !buffer) {
|
||||||
|
virLibDomainError (dom, VIR_ERR_INVALID_ARG,
|
||||||
|
_("buffer is NULL"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn->driver->domainBlockPeek)
|
||||||
|
return conn->driver->domainBlockPeek (dom, path, offset, size, buffer);
|
||||||
|
|
||||||
|
virLibDomainError (dom, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
virDomainSetSchedulerParameters;
|
virDomainSetSchedulerParameters;
|
||||||
virDomainBlockStats;
|
virDomainBlockStats;
|
||||||
virDomainInterfaceStats;
|
virDomainInterfaceStats;
|
||||||
|
virDomainBlockPeek;
|
||||||
virDomainAttachDevice;
|
virDomainAttachDevice;
|
||||||
virDomainDetachDevice;
|
virDomainDetachDevice;
|
||||||
|
|
||||||
|
@ -3521,6 +3521,7 @@ static virDriver qemuDriver = {
|
|||||||
NULL, /* domainMigrateFinish */
|
NULL, /* domainMigrateFinish */
|
||||||
qemudDomainBlockStats, /* domainBlockStats */
|
qemudDomainBlockStats, /* domainBlockStats */
|
||||||
qemudDomainInterfaceStats, /* domainInterfaceStats */
|
qemudDomainInterfaceStats, /* domainInterfaceStats */
|
||||||
|
NULL, /* domainBlockPeek */
|
||||||
#if HAVE_NUMACTL
|
#if HAVE_NUMACTL
|
||||||
qemudNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
|
qemudNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
|
||||||
qemudNodeGetFreeMemory, /* getFreeMemory */
|
qemudNodeGetFreeMemory, /* getFreeMemory */
|
||||||
|
@ -2060,6 +2060,7 @@ static virDriver testDriver = {
|
|||||||
NULL, /* domainMigrateFinish */
|
NULL, /* domainMigrateFinish */
|
||||||
NULL, /* domainBlockStats */
|
NULL, /* domainBlockStats */
|
||||||
NULL, /* domainInterfaceStats */
|
NULL, /* domainInterfaceStats */
|
||||||
|
NULL, /* domainBlockPeek */
|
||||||
testNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
|
testNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
|
||||||
NULL, /* getFreeMemory */
|
NULL, /* getFreeMemory */
|
||||||
};
|
};
|
||||||
|
@ -1234,6 +1234,29 @@ xenUnifiedDomainInterfaceStats (virDomainPtr dom, const char *path,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xenUnifiedDomainBlockPeek (virDomainPtr dom, const char *path,
|
||||||
|
unsigned long long offset, size_t size,
|
||||||
|
void *buffer)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
GET_PRIVATE (dom->conn);
|
||||||
|
|
||||||
|
if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
|
||||||
|
r = xenDaemonDomainBlockPeek (dom, path, offset, size, buffer);
|
||||||
|
if (r != -2) return r;
|
||||||
|
/* r == -2 means declined, so fall through to XM driver ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
|
||||||
|
if (xenXMDomainBlockPeek (dom, path, offset, size, buffer) == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
xenUnifiedError (dom->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xenUnifiedNodeGetCellsFreeMemory (virConnectPtr conn, unsigned long long *freeMems,
|
xenUnifiedNodeGetCellsFreeMemory (virConnectPtr conn, unsigned long long *freeMems,
|
||||||
int startCell, int maxCells)
|
int startCell, int maxCells)
|
||||||
@ -1329,6 +1352,7 @@ static virDriver xenUnifiedDriver = {
|
|||||||
.domainMigrateFinish = xenUnifiedDomainMigrateFinish,
|
.domainMigrateFinish = xenUnifiedDomainMigrateFinish,
|
||||||
.domainBlockStats = xenUnifiedDomainBlockStats,
|
.domainBlockStats = xenUnifiedDomainBlockStats,
|
||||||
.domainInterfaceStats = xenUnifiedDomainInterfaceStats,
|
.domainInterfaceStats = xenUnifiedDomainInterfaceStats,
|
||||||
|
.domainBlockPeek = xenUnifiedDomainBlockPeek,
|
||||||
.nodeGetCellsFreeMemory = xenUnifiedNodeGetCellsFreeMemory,
|
.nodeGetCellsFreeMemory = xenUnifiedNodeGetCellsFreeMemory,
|
||||||
.getFreeMemory = xenUnifiedNodeGetFreeMemory,
|
.getFreeMemory = xenUnifiedNodeGetFreeMemory,
|
||||||
};
|
};
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/errno.h>
|
#include <sys/errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -1705,6 +1707,219 @@ error:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(*sexp_blockdevs_cb)
|
||||||
|
(virConnectPtr conn, void *data,
|
||||||
|
int isBlock, int cdrom, int isNoSrcCdrom, int hvm,
|
||||||
|
const char *drvName, const char *drvType,
|
||||||
|
const char *src, const char *dst,
|
||||||
|
const char *mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xend_parse_sexp_blockdevs:
|
||||||
|
* @conn: connection
|
||||||
|
* @root: root sexpr
|
||||||
|
* @xendConfigVersion: version of xend
|
||||||
|
* @fn: callback function
|
||||||
|
* @data: optional data for callback function
|
||||||
|
*
|
||||||
|
* This parses out block devices from the domain sexpr and calls
|
||||||
|
* fn (conn, data, ...) for each block device found.
|
||||||
|
*
|
||||||
|
* Returns 0 if successful or -1 if failed.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xend_parse_sexp_blockdevs (virConnectPtr conn, struct sexpr *root,
|
||||||
|
int xendConfigVersion,
|
||||||
|
sexp_blockdevs_cb fn, void *data)
|
||||||
|
{
|
||||||
|
struct sexpr *cur, *node;
|
||||||
|
int hvm;
|
||||||
|
|
||||||
|
hvm = sexpr_lookup(root, "domain/image/hvm") ? 1 : 0;
|
||||||
|
|
||||||
|
for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
|
||||||
|
node = cur->u.s.car;
|
||||||
|
/* Normally disks are in a (device (vbd ...)) block
|
||||||
|
but blktap disks ended up in a differently named
|
||||||
|
(device (tap ....)) block.... */
|
||||||
|
if (sexpr_lookup(node, "device/vbd") ||
|
||||||
|
sexpr_lookup(node, "device/tap")) {
|
||||||
|
char *offset;
|
||||||
|
int ret = -1;
|
||||||
|
int isBlock = 0;
|
||||||
|
int cdrom = 0;
|
||||||
|
int isNoSrcCdrom = 0;
|
||||||
|
char *drvName = NULL;
|
||||||
|
char *drvType = NULL;
|
||||||
|
const char *src = NULL;
|
||||||
|
const char *dst = NULL;
|
||||||
|
const char *mode = NULL;
|
||||||
|
|
||||||
|
/* Again dealing with (vbd...) vs (tap ...) differences */
|
||||||
|
if (sexpr_lookup(node, "device/vbd")) {
|
||||||
|
src = sexpr_node(node, "device/vbd/uname");
|
||||||
|
dst = sexpr_node(node, "device/vbd/dev");
|
||||||
|
mode = sexpr_node(node, "device/vbd/mode");
|
||||||
|
} else {
|
||||||
|
src = sexpr_node(node, "device/tap/uname");
|
||||||
|
dst = sexpr_node(node, "device/tap/dev");
|
||||||
|
mode = sexpr_node(node, "device/tap/mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst == NULL) {
|
||||||
|
virXendError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("domain information incomplete, vbd has no dev"));
|
||||||
|
goto bad_parse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src == NULL) {
|
||||||
|
/* There is a case without the uname to the CD-ROM device */
|
||||||
|
offset = strchr(dst, ':');
|
||||||
|
if (offset) {
|
||||||
|
if (hvm && STREQ(offset, ":cdrom")) {
|
||||||
|
isNoSrcCdrom = 1;
|
||||||
|
}
|
||||||
|
offset[0] = '\0';
|
||||||
|
}
|
||||||
|
if (!isNoSrcCdrom) {
|
||||||
|
virXendError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("domain information incomplete, vbd has no src"));
|
||||||
|
goto bad_parse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNoSrcCdrom) {
|
||||||
|
offset = strchr(src, ':');
|
||||||
|
if (!offset) {
|
||||||
|
virXendError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("cannot parse vbd filename, missing driver name"));
|
||||||
|
goto bad_parse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(drvName, (offset-src)+1) < 0) {
|
||||||
|
virXendError(conn, VIR_ERR_NO_MEMORY,
|
||||||
|
_("allocate new buffer"));
|
||||||
|
goto bad_parse;
|
||||||
|
}
|
||||||
|
strncpy(drvName, src, (offset-src));
|
||||||
|
drvName[offset-src] = '\0';
|
||||||
|
|
||||||
|
src = offset + 1;
|
||||||
|
|
||||||
|
if (STREQ (drvName, "tap")) {
|
||||||
|
offset = strchr(src, ':');
|
||||||
|
if (!offset) {
|
||||||
|
virXendError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("cannot parse vbd filename, missing driver type"));
|
||||||
|
goto bad_parse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(drvType, (offset-src)+1)< 0) {
|
||||||
|
virXendError(conn, VIR_ERR_NO_MEMORY,
|
||||||
|
_("allocate new buffer"));
|
||||||
|
goto bad_parse;
|
||||||
|
}
|
||||||
|
strncpy(drvType, src, (offset-src));
|
||||||
|
drvType[offset-src] = '\0';
|
||||||
|
src = offset + 1;
|
||||||
|
/* Its possible to use blktap driver for block devs
|
||||||
|
too, but kinda pointless because blkback is better,
|
||||||
|
so we assume common case here. If blktap becomes
|
||||||
|
omnipotent, we can revisit this, perhaps stat()'ing
|
||||||
|
the src file in question */
|
||||||
|
isBlock = 0;
|
||||||
|
} else if (STREQ(drvName, "phy")) {
|
||||||
|
isBlock = 1;
|
||||||
|
} else if (STREQ(drvName, "file")) {
|
||||||
|
isBlock = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STREQLEN (dst, "ioemu:", 6))
|
||||||
|
dst += 6;
|
||||||
|
|
||||||
|
/* New style disk config from Xen >= 3.0.3 */
|
||||||
|
if (xendConfigVersion > 1) {
|
||||||
|
offset = strrchr(dst, ':');
|
||||||
|
if (offset) {
|
||||||
|
if (STREQ (offset, ":cdrom")) {
|
||||||
|
cdrom = 1;
|
||||||
|
} else if (STREQ (offset, ":disk")) {
|
||||||
|
/* The default anyway */
|
||||||
|
} else {
|
||||||
|
/* Unknown, lets pretend its a disk too */
|
||||||
|
}
|
||||||
|
offset[0] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the callback function. */
|
||||||
|
ret = fn (conn, data, isBlock, cdrom, isNoSrcCdrom, hvm,
|
||||||
|
drvName, drvType, src, dst, mode);
|
||||||
|
|
||||||
|
bad_parse:
|
||||||
|
VIR_FREE(drvName);
|
||||||
|
VIR_FREE(drvType);
|
||||||
|
|
||||||
|
if (ret == -1) return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xend_parse_sexp_desc_blockdev (virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
|
void *data,
|
||||||
|
int isBlock, int cdrom, int isNoSrcCdrom,
|
||||||
|
int hvm,
|
||||||
|
const char *drvName, const char *drvType,
|
||||||
|
const char *src, const char *dst,
|
||||||
|
const char *mode)
|
||||||
|
{
|
||||||
|
virBuffer *buf = (virBuffer *) data;
|
||||||
|
const char *bus = NULL;
|
||||||
|
|
||||||
|
if (!isNoSrcCdrom) {
|
||||||
|
virBufferVSprintf(buf, " <disk type='%s' device='%s'>\n",
|
||||||
|
isBlock ? "block" : "file",
|
||||||
|
cdrom ? "cdrom" : "disk");
|
||||||
|
if (drvType) {
|
||||||
|
virBufferVSprintf(buf, " <driver name='%s' type='%s'/>\n", drvName, drvType);
|
||||||
|
} else {
|
||||||
|
virBufferVSprintf(buf, " <driver name='%s'/>\n", drvName);
|
||||||
|
}
|
||||||
|
if (isBlock) {
|
||||||
|
virBufferVSprintf(buf, " <source dev='%s'/>\n", src);
|
||||||
|
} else {
|
||||||
|
virBufferVSprintf(buf, " <source file='%s'/>\n", src);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* This case is the cdrom device only */
|
||||||
|
virBufferAddLit(buf, " <disk device='cdrom'>\n");
|
||||||
|
}
|
||||||
|
if (STRPREFIX(dst, "xvd") || !hvm) {
|
||||||
|
bus = "xen";
|
||||||
|
} else if (STRPREFIX(dst, "sd")) {
|
||||||
|
bus = "scsi";
|
||||||
|
} else {
|
||||||
|
bus = "ide";
|
||||||
|
}
|
||||||
|
virBufferVSprintf(buf, " <target dev='%s' bus='%s'/>\n",
|
||||||
|
dst, bus);
|
||||||
|
|
||||||
|
/* XXX should we force mode == r, if cdrom==1, or assume
|
||||||
|
xend has already done this ? */
|
||||||
|
if ((mode != NULL) && (STREQ (mode, "r")))
|
||||||
|
virBufferAddLit(buf, " <readonly/>\n");
|
||||||
|
else if ((mode != NULL) && (STREQ (mode, "w!")))
|
||||||
|
virBufferAddLit(buf, " <shareable/>\n");
|
||||||
|
virBufferAddLit(buf, " </disk>\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xend_parse_sexp_desc:
|
* xend_parse_sexp_desc:
|
||||||
* @conn: the connection associated with the XML
|
* @conn: the connection associated with the XML
|
||||||
@ -1849,164 +2064,15 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root,
|
|||||||
if ((tmp != NULL) && (tmp[0] != 0))
|
if ((tmp != NULL) && (tmp[0] != 0))
|
||||||
virBufferVSprintf(&buf, " <emulator>%s</emulator>\n", tmp);
|
virBufferVSprintf(&buf, " <emulator>%s</emulator>\n", tmp);
|
||||||
|
|
||||||
|
/* append block devices */
|
||||||
|
if (xend_parse_sexp_blockdevs (conn, root, xendConfigVersion,
|
||||||
|
xend_parse_sexp_desc_blockdev, &buf) == -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* append network devices and framebuffer */
|
||||||
for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
|
for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
|
||||||
node = cur->u.s.car;
|
node = cur->u.s.car;
|
||||||
/* Normally disks are in a (device (vbd ...)) block
|
if (sexpr_lookup(node, "device/vif")) {
|
||||||
but blktap disks ended up in a differently named
|
|
||||||
(device (tap ....)) block.... */
|
|
||||||
if (sexpr_lookup(node, "device/vbd") ||
|
|
||||||
sexpr_lookup(node, "device/tap")) {
|
|
||||||
char *offset;
|
|
||||||
int isBlock = 0;
|
|
||||||
int cdrom = 0;
|
|
||||||
int isNoSrcCdrom = 0;
|
|
||||||
char *drvName = NULL;
|
|
||||||
char *drvType = NULL;
|
|
||||||
const char *src = NULL;
|
|
||||||
const char *dst = NULL;
|
|
||||||
const char *mode = NULL;
|
|
||||||
const char *bus = NULL;
|
|
||||||
|
|
||||||
/* Again dealing with (vbd...) vs (tap ...) differences */
|
|
||||||
if (sexpr_lookup(node, "device/vbd")) {
|
|
||||||
src = sexpr_node(node, "device/vbd/uname");
|
|
||||||
dst = sexpr_node(node, "device/vbd/dev");
|
|
||||||
mode = sexpr_node(node, "device/vbd/mode");
|
|
||||||
} else {
|
|
||||||
src = sexpr_node(node, "device/tap/uname");
|
|
||||||
dst = sexpr_node(node, "device/tap/dev");
|
|
||||||
mode = sexpr_node(node, "device/tap/mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst == NULL) {
|
|
||||||
virXendError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("domain information incomplete, vbd has no dev"));
|
|
||||||
goto bad_parse;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src == NULL) {
|
|
||||||
/* There is a case without the uname to the CD-ROM device */
|
|
||||||
offset = strchr(dst, ':');
|
|
||||||
if (offset) {
|
|
||||||
if (hvm && STREQ( offset , ":cdrom")) {
|
|
||||||
isNoSrcCdrom = 1;
|
|
||||||
}
|
|
||||||
offset[0] = '\0';
|
|
||||||
}
|
|
||||||
if (!isNoSrcCdrom) {
|
|
||||||
virXendError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("domain information incomplete, vbd has no src"));
|
|
||||||
goto bad_parse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNoSrcCdrom) {
|
|
||||||
offset = strchr(src, ':');
|
|
||||||
if (!offset) {
|
|
||||||
virXendError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("cannot parse vbd filename, missing driver name"));
|
|
||||||
goto bad_parse;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VIR_ALLOC_N(drvName, (offset-src)+1) < 0) {
|
|
||||||
virXendError(conn, VIR_ERR_NO_MEMORY,
|
|
||||||
_("allocate new buffer"));
|
|
||||||
goto bad_parse;
|
|
||||||
}
|
|
||||||
strncpy(drvName, src, (offset-src));
|
|
||||||
drvName[offset-src] = '\0';
|
|
||||||
|
|
||||||
src = offset + 1;
|
|
||||||
|
|
||||||
if (STREQ(drvName, "tap")) {
|
|
||||||
offset = strchr(src, ':');
|
|
||||||
if (!offset) {
|
|
||||||
virXendError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("cannot parse vbd filename, missing driver type"));
|
|
||||||
goto bad_parse;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VIR_ALLOC_N(drvType, (offset-src)+1)< 0) {
|
|
||||||
virXendError(conn, VIR_ERR_NO_MEMORY,
|
|
||||||
_("allocate new buffer"));
|
|
||||||
goto bad_parse;
|
|
||||||
}
|
|
||||||
strncpy(drvType, src, (offset-src));
|
|
||||||
drvType[offset-src] = '\0';
|
|
||||||
src = offset + 1;
|
|
||||||
/* Its possible to use blktap driver for block devs
|
|
||||||
too, but kinda pointless because blkback is better,
|
|
||||||
so we assume common case here. If blktap becomes
|
|
||||||
omnipotent, we can revisit this, perhaps stat()'ing
|
|
||||||
the src file in question */
|
|
||||||
isBlock = 0;
|
|
||||||
} else if (STREQ(drvName, "phy")) {
|
|
||||||
isBlock = 1;
|
|
||||||
} else if (STREQ(drvName, "file")) {
|
|
||||||
isBlock = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (STRPREFIX(dst, "ioemu:"))
|
|
||||||
dst += 6;
|
|
||||||
|
|
||||||
/* New style disk config from Xen >= 3.0.3 */
|
|
||||||
if (xendConfigVersion > 1) {
|
|
||||||
offset = strrchr(dst, ':');
|
|
||||||
if (offset) {
|
|
||||||
if (STREQ(offset, ":cdrom")) {
|
|
||||||
cdrom = 1;
|
|
||||||
} else if (STREQ(offset, ":disk")) {
|
|
||||||
/* The default anyway */
|
|
||||||
} else {
|
|
||||||
/* Unknown, lets pretend its a disk too */
|
|
||||||
}
|
|
||||||
offset[0] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNoSrcCdrom) {
|
|
||||||
virBufferVSprintf(&buf, " <disk type='%s' device='%s'>\n",
|
|
||||||
isBlock ? "block" : "file",
|
|
||||||
cdrom ? "cdrom" : "disk");
|
|
||||||
if (drvType) {
|
|
||||||
virBufferVSprintf(&buf, " <driver name='%s' type='%s'/>\n", drvName, drvType);
|
|
||||||
} else {
|
|
||||||
virBufferVSprintf(&buf, " <driver name='%s'/>\n", drvName);
|
|
||||||
}
|
|
||||||
if (isBlock) {
|
|
||||||
virBufferVSprintf(&buf, " <source dev='%s'/>\n", src);
|
|
||||||
} else {
|
|
||||||
virBufferVSprintf(&buf, " <source file='%s'/>\n", src);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* This case is the cdrom device only */
|
|
||||||
virBufferAddLit(&buf, " <disk device='cdrom'>\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (STRPREFIX(dst, "xvd") || !hvm) {
|
|
||||||
bus = "xen";
|
|
||||||
} else if (STRPREFIX(dst, "sd")) {
|
|
||||||
bus = "scsi";
|
|
||||||
} else {
|
|
||||||
bus = "ide";
|
|
||||||
}
|
|
||||||
virBufferVSprintf(&buf, " <target dev='%s' bus='%s'/>\n",
|
|
||||||
dst, bus);
|
|
||||||
|
|
||||||
|
|
||||||
/* XXX should we force mode == r, if cdrom==1, or assume
|
|
||||||
xend has already done this ? */
|
|
||||||
if ((mode != NULL) && (STREQ(mode, "r")))
|
|
||||||
virBufferAddLit(&buf, " <readonly/>\n");
|
|
||||||
else if ((mode != NULL) && (STREQ(mode, "w!")))
|
|
||||||
virBufferAddLit(&buf, " <shareable/>\n");
|
|
||||||
virBufferAddLit(&buf, " </disk>\n");
|
|
||||||
|
|
||||||
bad_parse:
|
|
||||||
VIR_FREE(drvName);
|
|
||||||
VIR_FREE(drvType);
|
|
||||||
} else if (sexpr_lookup(node, "device/vif")) {
|
|
||||||
const char *tmp2, *model;
|
const char *tmp2, *model;
|
||||||
tmp2 = sexpr_node(node, "device/vif/script");
|
tmp2 = sexpr_node(node, "device/vif/script");
|
||||||
tmp = sexpr_node(node, "device/vif/bridge");
|
tmp = sexpr_node(node, "device/vif/bridge");
|
||||||
@ -4433,5 +4499,110 @@ error:
|
|||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct check_path_data {
|
||||||
|
const char *path;
|
||||||
|
int ok;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_path (virConnectPtr conn ATTRIBUTE_UNUSED, void *vp,
|
||||||
|
int isBlock ATTRIBUTE_UNUSED,
|
||||||
|
int cdrom, int isNoSrcCdrom,
|
||||||
|
int hvm ATTRIBUTE_UNUSED,
|
||||||
|
const char *drvName ATTRIBUTE_UNUSED,
|
||||||
|
const char *drvType ATTRIBUTE_UNUSED,
|
||||||
|
const char *src, const char *dst ATTRIBUTE_UNUSED,
|
||||||
|
const char *mode ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
struct check_path_data *data = (struct check_path_data *) vp;
|
||||||
|
|
||||||
|
if (!isNoSrcCdrom && !cdrom && src && STREQ (src, data->path))
|
||||||
|
data->ok = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xenDaemonDomainBlockPeek:
|
||||||
|
* @dom: domain object
|
||||||
|
* @path: path to the file or device
|
||||||
|
* @offset: offset
|
||||||
|
* @size: size
|
||||||
|
* @buffer: return buffer
|
||||||
|
*
|
||||||
|
* Returns 0 if successful, -1 if error, -2 if declined.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path,
|
||||||
|
unsigned long long offset, size_t size,
|
||||||
|
void *buffer)
|
||||||
|
{
|
||||||
|
xenUnifiedPrivatePtr priv;
|
||||||
|
struct sexpr *root;
|
||||||
|
struct check_path_data data;
|
||||||
|
int fd, ret = -1;
|
||||||
|
struct stat statbuf;
|
||||||
|
|
||||||
|
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
|
||||||
|
|
||||||
|
if (domain->id < 0 && priv->xendConfigVersion < 3)
|
||||||
|
return -2; /* Decline, allow XM to handle it. */
|
||||||
|
|
||||||
|
/* Security check: The path must correspond to a block device. */
|
||||||
|
if (domain->id > 0)
|
||||||
|
root = sexpr_get (domain->conn, "/xend/domain/%d?detail=1",
|
||||||
|
domain->id);
|
||||||
|
else if (domain->id < 0)
|
||||||
|
root = sexpr_get (domain->conn, "/xend/domain/%s?detail=1",
|
||||||
|
domain->name);
|
||||||
|
else {
|
||||||
|
/* This call always fails for dom0. */
|
||||||
|
virXendError (domain->conn, VIR_ERR_NO_SUPPORT,
|
||||||
|
_("domainBlockPeek is not supported for dom0"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!root) {
|
||||||
|
virXendError (domain->conn, VIR_ERR_XEN_CALL, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.path = path;
|
||||||
|
data.ok = 0;
|
||||||
|
|
||||||
|
if (xend_parse_sexp_blockdevs (domain->conn, root,
|
||||||
|
priv->xendConfigVersion,
|
||||||
|
check_path, &data) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!data.ok) {
|
||||||
|
virXendError (domain->conn, VIR_ERR_INVALID_ARG,
|
||||||
|
_("invalid path"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The path is correct, now try to open it and get its size. */
|
||||||
|
fd = open (path, O_RDONLY);
|
||||||
|
if (fd == -1 || fstat (fd, &statbuf) == -1) {
|
||||||
|
virXendError (domain->conn, VIR_ERR_SYSTEM_ERROR, strerror (errno));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Seek and read. */
|
||||||
|
/* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
|
||||||
|
* be 64 bits on all platforms.
|
||||||
|
*/
|
||||||
|
if (lseek (fd, offset, SEEK_SET) == (off_t) -1 ||
|
||||||
|
saferead (fd, buffer, size) == (ssize_t) -1) {
|
||||||
|
virXendError (domain->conn, VIR_ERR_SYSTEM_ERROR, strerror (errno));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
done:
|
||||||
|
if (fd >= 0) close (fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* ! PROXY */
|
#endif /* ! PROXY */
|
||||||
#endif /* WITH_XEN */
|
#endif /* WITH_XEN */
|
||||||
|
@ -244,6 +244,8 @@ virDomainPtr 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 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 (virDomainPtr domain, const char *cookie, int cookielen, const char *uri, unsigned long flags, const char *dname, unsigned long resource);
|
int xenDaemonDomainMigratePerform (virDomainPtr domain, const char *cookie, int cookielen, const char *uri, unsigned long flags, const char *dname, unsigned long resource);
|
||||||
|
|
||||||
|
int xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path, unsigned long long offset, size_t size, void *buffer);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3241,4 +3241,15 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) {
|
|||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xenXMDomainBlockPeek (virDomainPtr dom,
|
||||||
|
const char *path ATTRIBUTE_UNUSED,
|
||||||
|
unsigned long long offset ATTRIBUTE_UNUSED,
|
||||||
|
size_t size ATTRIBUTE_UNUSED,
|
||||||
|
void *buffer ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
xenXMError (dom->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* WITH_XEN */
|
#endif /* WITH_XEN */
|
||||||
|
@ -60,6 +60,7 @@ int xenXMDomainUndefine(virDomainPtr domain);
|
|||||||
|
|
||||||
virConfPtr xenXMParseXMLToConfig(virConnectPtr conn, const char *xml);
|
virConfPtr xenXMParseXMLToConfig(virConnectPtr conn, const char *xml);
|
||||||
char *xenXMDomainFormatXML(virConnectPtr conn, virConfPtr conf);
|
char *xenXMDomainFormatXML(virConnectPtr conn, virConfPtr conf);
|
||||||
|
int xenXMDomainBlockPeek (virDomainPtr dom, const char *path, unsigned long long offset, size_t size, void *buffer);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -15,17 +15,17 @@
|
|||||||
<on_reboot>restart</on_reboot>
|
<on_reboot>restart</on_reboot>
|
||||||
<on_crash>restart</on_crash>
|
<on_crash>restart</on_crash>
|
||||||
<devices>
|
<devices>
|
||||||
|
<disk type='file' device='disk'>
|
||||||
|
<driver name='tap' type='aio'/>
|
||||||
|
<source file='/xen/rhel5.img'/>
|
||||||
|
<target dev='xvda' bus='xen'/>
|
||||||
|
</disk>
|
||||||
<interface type='bridge'>
|
<interface type='bridge'>
|
||||||
<source bridge='xenbr0'/>
|
<source bridge='xenbr0'/>
|
||||||
<target dev='vif5.0'/>
|
<target dev='vif5.0'/>
|
||||||
<mac address='00:16:3e:1d:06:15'/>
|
<mac address='00:16:3e:1d:06:15'/>
|
||||||
<script path='vif-bridge'/>
|
<script path='vif-bridge'/>
|
||||||
</interface>
|
</interface>
|
||||||
<disk type='file' device='disk'>
|
|
||||||
<driver name='tap' type='aio'/>
|
|
||||||
<source file='/xen/rhel5.img'/>
|
|
||||||
<target dev='xvda' bus='xen'/>
|
|
||||||
</disk>
|
|
||||||
<input type='mouse' bus='xen'/>
|
<input type='mouse' bus='xen'/>
|
||||||
<graphics type='vnc' port='-1'/>
|
<graphics type='vnc' port='-1'/>
|
||||||
<console type='pty'>
|
<console type='pty'>
|
||||||
|
@ -20,11 +20,6 @@
|
|||||||
<clock offset='utc'/>
|
<clock offset='utc'/>
|
||||||
<devices>
|
<devices>
|
||||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||||
<interface type='bridge'>
|
|
||||||
<source bridge='xenbr0'/>
|
|
||||||
<target dev='vif6.0'/>
|
|
||||||
<mac address='00:16:3e:0a:7b:39'/>
|
|
||||||
</interface>
|
|
||||||
<disk type='block' device='disk'>
|
<disk type='block' device='disk'>
|
||||||
<driver name='phy'/>
|
<driver name='phy'/>
|
||||||
<source dev='/dev/sda8'/>
|
<source dev='/dev/sda8'/>
|
||||||
@ -34,6 +29,11 @@
|
|||||||
<target dev='hdc' bus='ide'/>
|
<target dev='hdc' bus='ide'/>
|
||||||
<readonly/>
|
<readonly/>
|
||||||
</disk>
|
</disk>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<source bridge='xenbr0'/>
|
||||||
|
<target dev='vif6.0'/>
|
||||||
|
<mac address='00:16:3e:0a:7b:39'/>
|
||||||
|
</interface>
|
||||||
<input type='mouse' bus='ps2'/>
|
<input type='mouse' bus='ps2'/>
|
||||||
<graphics type='vnc' port='-1'/>
|
<graphics type='vnc' port='-1'/>
|
||||||
<serial type='pty'>
|
<serial type='pty'>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user