mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 02:51:16 +00:00
virDomainBlockPeek QEMU and remote support
* qemud/remote.c, qemud/remote_protocol.x, src/remote_internal.c: Remote support. * qemud/remote_dispatch_localvars.h, qemud/remote_dispatch_proc_switch.h, qemud/remote_dispatch_prototypes.h, qemud/remote_protocol.c, qemud/remote_protocol.h: Generated files for remote support. * src/xen_unified.c, src/driver.h, src/libvirt.c: Small fix - pass flags around internally. * src/qemu_driver.c: Support for QEMU. * src/xend_internal.c: Remove redundant fstat call from Xen.
This commit is contained in:
parent
8354895e68
commit
a73a88a19f
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
||||
Thu Jun 5 22:08:00 BST 2008 Richard W.M. Jones <rjones@redhat.com>
|
||||
|
||||
virDomainBlockPeek QEMU and remote support
|
||||
* qemud/remote.c, qemud/remote_protocol.x, src/remote_internal.c:
|
||||
Remote support.
|
||||
* qemud/remote_dispatch_localvars.h,
|
||||
qemud/remote_dispatch_proc_switch.h,
|
||||
qemud/remote_dispatch_prototypes.h,
|
||||
qemud/remote_protocol.c,
|
||||
qemud/remote_protocol.h:
|
||||
Generated files for remote support.
|
||||
* src/xen_unified.c, src/driver.h, src/libvirt.c: Small fix -
|
||||
pass flags around internally.
|
||||
* src/qemu_driver.c: Support for QEMU.
|
||||
* src/xend_internal.c: Remove redundant fstat call from Xen.
|
||||
|
||||
Thu Jun 5 14:10:00 BST 2008 Richard W.M. Jones <rjones@redhat.com>
|
||||
|
||||
virDomainBlockPeek call
|
||||
|
@ -889,6 +889,54 @@ remoteDispatchDomainInterfaceStats (struct qemud_server *server ATTRIBUTE_UNUSED
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
remoteDispatchDomainBlockPeek (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
struct qemud_client *client,
|
||||
remote_message_header *req,
|
||||
remote_domain_block_peek_args *args,
|
||||
remote_domain_block_peek_ret *ret)
|
||||
{
|
||||
virDomainPtr dom;
|
||||
char *path;
|
||||
unsigned long long offset;
|
||||
size_t size;
|
||||
unsigned int flags;
|
||||
CHECK_CONN (client);
|
||||
|
||||
dom = get_nonnull_domain (client->conn, args->dom);
|
||||
if (dom == NULL) {
|
||||
remoteDispatchError (client, req, "%s", _("domain not found"));
|
||||
return -2;
|
||||
}
|
||||
path = args->path;
|
||||
offset = args->offset;
|
||||
size = args->size;
|
||||
flags = args->flags;
|
||||
|
||||
if (size > REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX) {
|
||||
remoteDispatchError (client, req,
|
||||
"%s", _("size > maximum buffer size"));
|
||||
return -2;
|
||||
}
|
||||
|
||||
ret->buffer.buffer_len = size;
|
||||
ret->buffer.buffer_val = malloc (size);
|
||||
if (!ret->buffer.buffer_val) {
|
||||
remoteDispatchError (client, req, "%s", strerror (errno));
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (virDomainBlockPeek (dom, path, offset, size,
|
||||
ret->buffer.buffer_val, flags) == -1) {
|
||||
/* free (ret->buffer.buffer_val); - caller frees */
|
||||
virDomainFree (dom);
|
||||
return -1;
|
||||
}
|
||||
virDomainFree (dom);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
remoteDispatchDomainAttachDevice (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
struct qemud_client *client,
|
||||
|
@ -41,6 +41,8 @@ remote_list_domains_ret lv_remote_list_domains_ret;
|
||||
remote_network_define_xml_args lv_remote_network_define_xml_args;
|
||||
remote_network_define_xml_ret lv_remote_network_define_xml_ret;
|
||||
remote_get_type_ret lv_remote_get_type_ret;
|
||||
remote_domain_block_peek_args lv_remote_domain_block_peek_args;
|
||||
remote_domain_block_peek_ret lv_remote_domain_block_peek_ret;
|
||||
remote_storage_vol_delete_args lv_remote_storage_vol_delete_args;
|
||||
remote_network_dump_xml_args lv_remote_network_dump_xml_args;
|
||||
remote_network_dump_xml_ret lv_remote_network_dump_xml_ret;
|
||||
|
@ -47,6 +47,15 @@ case REMOTE_PROC_DOMAIN_ATTACH_DEVICE:
|
||||
args = (char *) &lv_remote_domain_attach_device_args;
|
||||
memset (&lv_remote_domain_attach_device_args, 0, sizeof lv_remote_domain_attach_device_args);
|
||||
break;
|
||||
case REMOTE_PROC_DOMAIN_BLOCK_PEEK:
|
||||
fn = (dispatch_fn) remoteDispatchDomainBlockPeek;
|
||||
args_filter = (xdrproc_t) xdr_remote_domain_block_peek_args;
|
||||
args = (char *) &lv_remote_domain_block_peek_args;
|
||||
memset (&lv_remote_domain_block_peek_args, 0, sizeof lv_remote_domain_block_peek_args);
|
||||
ret_filter = (xdrproc_t) xdr_remote_domain_block_peek_ret;
|
||||
ret = (char *) &lv_remote_domain_block_peek_ret;
|
||||
memset (&lv_remote_domain_block_peek_ret, 0, sizeof lv_remote_domain_block_peek_ret);
|
||||
break;
|
||||
case REMOTE_PROC_DOMAIN_BLOCK_STATS:
|
||||
fn = (dispatch_fn) remoteDispatchDomainBlockStats;
|
||||
args_filter = (xdrproc_t) xdr_remote_domain_block_stats_args;
|
||||
|
@ -9,6 +9,7 @@ static int remoteDispatchAuthSaslStart (struct qemud_server *server, struct qemu
|
||||
static int remoteDispatchAuthSaslStep (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_auth_sasl_step_args *args, remote_auth_sasl_step_ret *ret);
|
||||
static int remoteDispatchClose (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, void *ret);
|
||||
static int remoteDispatchDomainAttachDevice (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_domain_attach_device_args *args, void *ret);
|
||||
static int remoteDispatchDomainBlockPeek (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_domain_block_peek_args *args, remote_domain_block_peek_ret *ret);
|
||||
static int remoteDispatchDomainBlockStats (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_domain_block_stats_args *args, remote_domain_block_stats_ret *ret);
|
||||
static int remoteDispatchDomainCoreDump (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_domain_core_dump_args *args, void *ret);
|
||||
static int remoteDispatchDomainCreate (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_domain_create_args *args, void *ret);
|
||||
|
@ -534,6 +534,33 @@ xdr_remote_domain_interface_stats_ret (XDR *xdrs, remote_domain_interface_stats_
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_remote_domain_block_peek_args (XDR *xdrs, remote_domain_block_peek_args *objp)
|
||||
{
|
||||
|
||||
if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
|
||||
return FALSE;
|
||||
if (!xdr_remote_nonnull_string (xdrs, &objp->path))
|
||||
return FALSE;
|
||||
if (!xdr_u_quad_t (xdrs, &objp->offset))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->size))
|
||||
return FALSE;
|
||||
if (!xdr_u_int (xdrs, &objp->flags))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_remote_domain_block_peek_ret (XDR *xdrs, remote_domain_block_peek_ret *objp)
|
||||
{
|
||||
char **objp_cpp0 = (char **) (void *) &objp->buffer.buffer_val;
|
||||
|
||||
if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->buffer.buffer_len, REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_remote_list_domains_args (XDR *xdrs, remote_list_domains_args *objp)
|
||||
{
|
||||
|
@ -33,6 +33,7 @@ typedef remote_nonnull_string *remote_string;
|
||||
#define REMOTE_NODE_MAX_CELLS 1024
|
||||
#define REMOTE_AUTH_SASL_DATA_MAX 65536
|
||||
#define REMOTE_AUTH_TYPE_LIST_MAX 20
|
||||
#define REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX 65536
|
||||
|
||||
typedef char remote_uuid[VIR_UUID_BUFLEN];
|
||||
|
||||
@ -263,6 +264,23 @@ struct remote_domain_interface_stats_ret {
|
||||
};
|
||||
typedef struct remote_domain_interface_stats_ret remote_domain_interface_stats_ret;
|
||||
|
||||
struct remote_domain_block_peek_args {
|
||||
remote_nonnull_domain dom;
|
||||
remote_nonnull_string path;
|
||||
u_quad_t offset;
|
||||
u_int size;
|
||||
u_int flags;
|
||||
};
|
||||
typedef struct remote_domain_block_peek_args remote_domain_block_peek_args;
|
||||
|
||||
struct remote_domain_block_peek_ret {
|
||||
struct {
|
||||
u_int buffer_len;
|
||||
char *buffer_val;
|
||||
} buffer;
|
||||
};
|
||||
typedef struct remote_domain_block_peek_ret remote_domain_block_peek_ret;
|
||||
|
||||
struct remote_list_domains_args {
|
||||
int maxids;
|
||||
};
|
||||
@ -1138,6 +1156,7 @@ enum remote_procedure {
|
||||
REMOTE_PROC_STORAGE_VOL_GET_PATH = 100,
|
||||
REMOTE_PROC_NODE_GET_CELLS_FREE_MEMORY = 101,
|
||||
REMOTE_PROC_NODE_GET_FREE_MEMORY = 102,
|
||||
REMOTE_PROC_DOMAIN_BLOCK_PEEK = 103,
|
||||
};
|
||||
typedef enum remote_procedure remote_procedure;
|
||||
|
||||
@ -1206,6 +1225,8 @@ extern bool_t xdr_remote_domain_block_stats_args (XDR *, remote_domain_block_st
|
||||
extern bool_t xdr_remote_domain_block_stats_ret (XDR *, remote_domain_block_stats_ret*);
|
||||
extern bool_t xdr_remote_domain_interface_stats_args (XDR *, remote_domain_interface_stats_args*);
|
||||
extern bool_t xdr_remote_domain_interface_stats_ret (XDR *, remote_domain_interface_stats_ret*);
|
||||
extern bool_t xdr_remote_domain_block_peek_args (XDR *, remote_domain_block_peek_args*);
|
||||
extern bool_t xdr_remote_domain_block_peek_ret (XDR *, remote_domain_block_peek_ret*);
|
||||
extern bool_t xdr_remote_list_domains_args (XDR *, remote_list_domains_args*);
|
||||
extern bool_t xdr_remote_list_domains_ret (XDR *, remote_list_domains_ret*);
|
||||
extern bool_t xdr_remote_num_of_domains_ret (XDR *, remote_num_of_domains_ret*);
|
||||
@ -1381,6 +1402,8 @@ extern bool_t xdr_remote_domain_block_stats_args ();
|
||||
extern bool_t xdr_remote_domain_block_stats_ret ();
|
||||
extern bool_t xdr_remote_domain_interface_stats_args ();
|
||||
extern bool_t xdr_remote_domain_interface_stats_ret ();
|
||||
extern bool_t xdr_remote_domain_block_peek_args ();
|
||||
extern bool_t xdr_remote_domain_block_peek_ret ();
|
||||
extern bool_t xdr_remote_list_domains_args ();
|
||||
extern bool_t xdr_remote_list_domains_ret ();
|
||||
extern bool_t xdr_remote_num_of_domains_ret ();
|
||||
|
@ -96,6 +96,12 @@ const REMOTE_AUTH_SASL_DATA_MAX = 65536;
|
||||
/* Maximum number of auth types */
|
||||
const REMOTE_AUTH_TYPE_LIST_MAX = 20;
|
||||
|
||||
/* Maximum length of a block or memory peek buffer message.
|
||||
* Note applications need to be aware of this limit and issue multiple
|
||||
* requests for large amounts of data.
|
||||
*/
|
||||
const REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX = 65536;
|
||||
|
||||
/* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */
|
||||
typedef opaque remote_uuid[VIR_UUID_BUFLEN];
|
||||
|
||||
@ -322,6 +328,18 @@ struct remote_domain_interface_stats_ret {
|
||||
hyper tx_drop;
|
||||
};
|
||||
|
||||
struct remote_domain_block_peek_args {
|
||||
remote_nonnull_domain dom;
|
||||
remote_nonnull_string path;
|
||||
unsigned hyper offset;
|
||||
unsigned size;
|
||||
unsigned flags;
|
||||
};
|
||||
|
||||
struct remote_domain_block_peek_ret {
|
||||
opaque buffer<REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX>;
|
||||
};
|
||||
|
||||
struct remote_list_domains_args {
|
||||
int maxids;
|
||||
};
|
||||
@ -1036,7 +1054,9 @@ enum remote_procedure {
|
||||
REMOTE_PROC_STORAGE_VOL_GET_PATH = 100,
|
||||
|
||||
REMOTE_PROC_NODE_GET_CELLS_FREE_MEMORY = 101,
|
||||
REMOTE_PROC_NODE_GET_FREE_MEMORY = 102
|
||||
REMOTE_PROC_NODE_GET_FREE_MEMORY = 102,
|
||||
|
||||
REMOTE_PROC_DOMAIN_BLOCK_PEEK = 103
|
||||
};
|
||||
|
||||
/* Custom RPC structure. */
|
||||
|
@ -230,7 +230,8 @@ typedef int
|
||||
(virDomainPtr domain,
|
||||
const char *path,
|
||||
unsigned long long offset, size_t size,
|
||||
void *buffer);
|
||||
void *buffer,
|
||||
unsigned int flags);
|
||||
|
||||
typedef int
|
||||
(*virDrvDomainMigratePrepare)
|
||||
|
@ -2659,7 +2659,8 @@ virDomainBlockPeek (virDomainPtr dom,
|
||||
}
|
||||
|
||||
if (conn->driver->domainBlockPeek)
|
||||
return conn->driver->domainBlockPeek (dom, path, offset, size, buffer);
|
||||
return conn->driver->domainBlockPeek (dom, path, offset, size,
|
||||
buffer, flags);
|
||||
|
||||
virLibDomainError (dom, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
return -1;
|
||||
|
@ -3163,6 +3163,64 @@ qemudDomainInterfaceStats (virDomainPtr dom,
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
qemudDomainBlockPeek (virDomainPtr dom,
|
||||
const char *path,
|
||||
unsigned long long offset, size_t size,
|
||||
void *buffer,
|
||||
unsigned int flags ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
|
||||
struct qemud_vm *vm = qemudFindVMByUUID (driver, dom->uuid);
|
||||
int i;
|
||||
int fd, ret = -1;
|
||||
|
||||
if (!vm) {
|
||||
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
|
||||
_("no domain with matching uuid"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!path || path[0] == '\0') {
|
||||
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
||||
_("NULL or empty path"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check the path belongs to this domain. */
|
||||
for (i = 0; i < vm->def->ndisks; ++i) {
|
||||
if (STREQ (vm->def->disks[i].src, path)) goto found;
|
||||
}
|
||||
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
|
||||
_("invalid path"));
|
||||
return -1;
|
||||
|
||||
found:
|
||||
/* The path is correct, now try to open it and get its size. */
|
||||
fd = open (path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
|
||||
"%s", 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) {
|
||||
qemudReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
|
||||
"%s", strerror (errno));
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
done:
|
||||
if (fd >= 0) close (fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static virNetworkPtr qemudNetworkLookupByUUID(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
const unsigned char *uuid) {
|
||||
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
||||
@ -3521,7 +3579,7 @@ static virDriver qemuDriver = {
|
||||
NULL, /* domainMigrateFinish */
|
||||
qemudDomainBlockStats, /* domainBlockStats */
|
||||
qemudDomainInterfaceStats, /* domainInterfaceStats */
|
||||
NULL, /* domainBlockPeek */
|
||||
qemudDomainBlockPeek, /* domainBlockPeek */
|
||||
#if HAVE_NUMACTL
|
||||
qemudNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
|
||||
qemudNodeGetFreeMemory, /* getFreeMemory */
|
||||
|
@ -2374,6 +2374,52 @@ remoteDomainInterfaceStats (virDomainPtr domain, const char *path,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
remoteDomainBlockPeek (virDomainPtr domain,
|
||||
const char *path,
|
||||
unsigned long long offset,
|
||||
size_t size,
|
||||
void *buffer,
|
||||
unsigned int flags)
|
||||
{
|
||||
remote_domain_block_peek_args args;
|
||||
remote_domain_block_peek_ret ret;
|
||||
GET_PRIVATE (domain->conn, -1);
|
||||
|
||||
if (size > REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX) {
|
||||
errorf (domain->conn, VIR_ERR_RPC,
|
||||
_("block peek request too large for remote protocol, %zi > %d"),
|
||||
size, REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX);
|
||||
return -1;
|
||||
}
|
||||
|
||||
make_nonnull_domain (&args.dom, domain);
|
||||
args.path = (char *) path;
|
||||
args.offset = offset;
|
||||
args.size = size;
|
||||
args.flags = flags;
|
||||
|
||||
memset (&ret, 0, sizeof ret);
|
||||
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_PEEK,
|
||||
(xdrproc_t) xdr_remote_domain_block_peek_args,
|
||||
(char *) &args,
|
||||
(xdrproc_t) xdr_remote_domain_block_peek_ret,
|
||||
(char *) &ret) == -1)
|
||||
return -1;
|
||||
|
||||
if (ret.buffer.buffer_len != size) {
|
||||
errorf (domain->conn, VIR_ERR_RPC,
|
||||
_("returned buffer is not same size as requested"));
|
||||
free (ret.buffer.buffer_val);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy (buffer, ret.buffer.buffer_val, size);
|
||||
free (ret.buffer.buffer_val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
static int
|
||||
@ -4784,6 +4830,7 @@ static virDriver driver = {
|
||||
.domainMigrateFinish = remoteDomainMigrateFinish,
|
||||
.domainBlockStats = remoteDomainBlockStats,
|
||||
.domainInterfaceStats = remoteDomainInterfaceStats,
|
||||
.domainBlockPeek = remoteDomainBlockPeek,
|
||||
.nodeGetCellsFreeMemory = remoteNodeGetCellsFreeMemory,
|
||||
.getFreeMemory = remoteNodeGetFreeMemory,
|
||||
};
|
||||
|
@ -1237,7 +1237,7 @@ xenUnifiedDomainInterfaceStats (virDomainPtr dom, const char *path,
|
||||
static int
|
||||
xenUnifiedDomainBlockPeek (virDomainPtr dom, const char *path,
|
||||
unsigned long long offset, size_t size,
|
||||
void *buffer)
|
||||
void *buffer, unsigned int flags ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int r;
|
||||
GET_PRIVATE (dom->conn);
|
||||
|
@ -4541,7 +4541,6 @@ xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path,
|
||||
struct sexpr *root;
|
||||
struct check_path_data data;
|
||||
int fd, ret = -1;
|
||||
struct stat statbuf;
|
||||
|
||||
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
|
||||
|
||||
@ -4583,7 +4582,7 @@ xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path,
|
||||
|
||||
/* 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) {
|
||||
if (fd == -1) {
|
||||
virXendError (domain->conn, VIR_ERR_SYSTEM_ERROR, strerror (errno));
|
||||
goto done;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user