mirror of https://gitee.com/openkylin/libvirt.git
Add storage pool source discovery support (patch from David Lively)
This commit is contained in:
parent
406f3ee9e8
commit
39c9354c5c
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
||||||
|
Wed Aug 27 20:50:00 EST 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
Storage pool source discovery from David Lively
|
||||||
|
|
||||||
|
* include/libvirt/libvirt.h, include/libvirt/libvirt.h.in,
|
||||||
|
src/libvirt_sym.version, src/libvirt.c, src/driver.h: Add
|
||||||
|
the virConnectFindStoragePoolSources() API
|
||||||
|
* src/remote_internal.c, qemu/remote.c, src/remote_protocol.{c,h,x}
|
||||||
|
Implement remote protocol support for virConnectFindStoragePoolSources
|
||||||
|
* src/remote_dispatch_*.h: Re-generate from remote_protocol.x
|
||||||
|
* libvirt.spec.in:Add dep on nfs-utils
|
||||||
|
* configure.in: Check for showmount binary
|
||||||
|
* src/storage_backend.h, src/storage_driver.c: Generic impl
|
||||||
|
of storage discovery
|
||||||
|
* src/storage_backend_fs.c, src/storage_backend_logical.c: Add
|
||||||
|
specific impl of storage discovery for NFS and LVM
|
||||||
|
* src/virsh.c: Add command to discover storage pools
|
||||||
|
|
||||||
Wed Aug 27 12:40:00 EST 2008 Daniel P. Berrange <berrange@redhat.com>
|
Wed Aug 27 12:40:00 EST 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
* src/util.h, src/util.c: Allow virExec to take set of FDs
|
* src/util.h, src/util.c: Allow virExec to take set of FDs
|
||||||
|
|
|
@ -671,6 +671,11 @@ if test "$with_storage_fs" = "yes" -o "$with_storage_fs" = "check"; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL([WITH_STORAGE_FS], [test "$with_storage_fs" = "yes"])
|
AM_CONDITIONAL([WITH_STORAGE_FS], [test "$with_storage_fs" = "yes"])
|
||||||
|
if test "$with_storage_fs" = "yes"; then
|
||||||
|
AC_PATH_PROG([SHOWMOUNT], [showmount], [], [$PATH:/sbin:/usr/sbin])
|
||||||
|
AC_DEFINE_UNQUOTED([SHOWMOUNT], ["$SHOWMOUNT"],
|
||||||
|
[Location or name of the showmount program])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_PATH_PROG([QEMU_IMG], [qemu-img], [], [$PATH:/sbin:/usr/sbin:/bin:/usr/bin])
|
AC_PATH_PROG([QEMU_IMG], [qemu-img], [], [$PATH:/sbin:/usr/sbin:/bin:/usr/bin])
|
||||||
if test -n "$QEMU_IMG" ; then
|
if test -n "$QEMU_IMG" ; then
|
||||||
|
|
|
@ -889,6 +889,14 @@ int virConnectListDefinedStoragePools(virConnectPtr conn,
|
||||||
char **const names,
|
char **const names,
|
||||||
int maxnames);
|
int maxnames);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Query a host for storage pools of a particular type
|
||||||
|
*/
|
||||||
|
char * virConnectFindStoragePoolSources(virConnectPtr conn,
|
||||||
|
const char *type,
|
||||||
|
const char *srcSpec,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup pool by name or uuid
|
* Lookup pool by name or uuid
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -889,6 +889,14 @@ int virConnectListDefinedStoragePools(virConnectPtr conn,
|
||||||
char **const names,
|
char **const names,
|
||||||
int maxnames);
|
int maxnames);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Query a host for storage pools of a particular type
|
||||||
|
*/
|
||||||
|
char * virConnectFindStoragePoolSources(virConnectPtr conn,
|
||||||
|
const char *type,
|
||||||
|
const char *srcSpec,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup pool by name or uuid
|
* Lookup pool by name or uuid
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -55,6 +55,9 @@ Requires: PolicyKit >= 0.6
|
||||||
%endif
|
%endif
|
||||||
# For mount/umount in FS driver
|
# For mount/umount in FS driver
|
||||||
BuildRequires: util-linux
|
BuildRequires: util-linux
|
||||||
|
# For showmount in FS driver (netfs discovery)
|
||||||
|
BuildRequires: nfs-utils
|
||||||
|
Requires: nfs-utils
|
||||||
%if %{with_qemu}
|
%if %{with_qemu}
|
||||||
# From QEMU RPMs
|
# From QEMU RPMs
|
||||||
Requires: /usr/bin/qemu-img
|
Requires: /usr/bin/qemu-img
|
||||||
|
|
|
@ -2957,6 +2957,27 @@ remoteDispatchListStoragePools (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
remoteDispatchFindStoragePoolSources (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||||
|
struct qemud_client *client,
|
||||||
|
remote_message_header *req,
|
||||||
|
remote_find_storage_pool_sources_args *args,
|
||||||
|
remote_find_storage_pool_sources_ret *ret)
|
||||||
|
{
|
||||||
|
CHECK_CONN(client);
|
||||||
|
|
||||||
|
ret->xml =
|
||||||
|
virConnectFindStoragePoolSources (client->conn,
|
||||||
|
args->type,
|
||||||
|
args->srcSpec ? *args->srcSpec : NULL,
|
||||||
|
args->flags);
|
||||||
|
if (ret->xml == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
remoteDispatchStoragePoolCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
|
remoteDispatchStoragePoolCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||||
struct qemud_client *client,
|
struct qemud_client *client,
|
||||||
|
|
|
@ -80,6 +80,8 @@ remote_domain_resume_args lv_remote_domain_resume_args;
|
||||||
remote_network_get_bridge_name_args lv_remote_network_get_bridge_name_args;
|
remote_network_get_bridge_name_args lv_remote_network_get_bridge_name_args;
|
||||||
remote_network_get_bridge_name_ret lv_remote_network_get_bridge_name_ret;
|
remote_network_get_bridge_name_ret lv_remote_network_get_bridge_name_ret;
|
||||||
remote_domain_destroy_args lv_remote_domain_destroy_args;
|
remote_domain_destroy_args lv_remote_domain_destroy_args;
|
||||||
|
remote_find_storage_pool_sources_args lv_remote_find_storage_pool_sources_args;
|
||||||
|
remote_find_storage_pool_sources_ret lv_remote_find_storage_pool_sources_ret;
|
||||||
remote_auth_sasl_step_args lv_remote_auth_sasl_step_args;
|
remote_auth_sasl_step_args lv_remote_auth_sasl_step_args;
|
||||||
remote_auth_sasl_step_ret lv_remote_auth_sasl_step_ret;
|
remote_auth_sasl_step_ret lv_remote_auth_sasl_step_ret;
|
||||||
remote_domain_migrate_finish_args lv_remote_domain_migrate_finish_args;
|
remote_domain_migrate_finish_args lv_remote_domain_migrate_finish_args;
|
||||||
|
|
|
@ -335,6 +335,15 @@ case REMOTE_PROC_DOMAIN_UNDEFINE:
|
||||||
args = (char *) &lv_remote_domain_undefine_args;
|
args = (char *) &lv_remote_domain_undefine_args;
|
||||||
memset (&lv_remote_domain_undefine_args, 0, sizeof lv_remote_domain_undefine_args);
|
memset (&lv_remote_domain_undefine_args, 0, sizeof lv_remote_domain_undefine_args);
|
||||||
break;
|
break;
|
||||||
|
case REMOTE_PROC_FIND_STORAGE_POOL_SOURCES:
|
||||||
|
fn = (dispatch_fn) remoteDispatchFindStoragePoolSources;
|
||||||
|
args_filter = (xdrproc_t) xdr_remote_find_storage_pool_sources_args;
|
||||||
|
args = (char *) &lv_remote_find_storage_pool_sources_args;
|
||||||
|
memset (&lv_remote_find_storage_pool_sources_args, 0, sizeof lv_remote_find_storage_pool_sources_args);
|
||||||
|
ret_filter = (xdrproc_t) xdr_remote_find_storage_pool_sources_ret;
|
||||||
|
ret = (char *) &lv_remote_find_storage_pool_sources_ret;
|
||||||
|
memset (&lv_remote_find_storage_pool_sources_ret, 0, sizeof lv_remote_find_storage_pool_sources_ret);
|
||||||
|
break;
|
||||||
case REMOTE_PROC_GET_CAPABILITIES:
|
case REMOTE_PROC_GET_CAPABILITIES:
|
||||||
fn = (dispatch_fn) remoteDispatchGetCapabilities;
|
fn = (dispatch_fn) remoteDispatchGetCapabilities;
|
||||||
ret_filter = (xdrproc_t) xdr_remote_get_capabilities_ret;
|
ret_filter = (xdrproc_t) xdr_remote_get_capabilities_ret;
|
||||||
|
|
|
@ -47,6 +47,7 @@ static int remoteDispatchDomainSetVcpus (struct qemud_server *server, struct qem
|
||||||
static int remoteDispatchDomainShutdown (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_domain_shutdown_args *args, void *ret);
|
static int remoteDispatchDomainShutdown (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_domain_shutdown_args *args, void *ret);
|
||||||
static int remoteDispatchDomainSuspend (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_domain_suspend_args *args, void *ret);
|
static int remoteDispatchDomainSuspend (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_domain_suspend_args *args, void *ret);
|
||||||
static int remoteDispatchDomainUndefine (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_domain_undefine_args *args, void *ret);
|
static int remoteDispatchDomainUndefine (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_domain_undefine_args *args, void *ret);
|
||||||
|
static int remoteDispatchFindStoragePoolSources (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_find_storage_pool_sources_args *args, remote_find_storage_pool_sources_ret *ret);
|
||||||
static int remoteDispatchGetCapabilities (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_get_capabilities_ret *ret);
|
static int remoteDispatchGetCapabilities (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_get_capabilities_ret *ret);
|
||||||
static int remoteDispatchGetHostname (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_get_hostname_ret *ret);
|
static int remoteDispatchGetHostname (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_get_hostname_ret *ret);
|
||||||
static int remoteDispatchGetMaxVcpus (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_get_max_vcpus_args *args, remote_get_max_vcpus_ret *ret);
|
static int remoteDispatchGetMaxVcpus (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_get_max_vcpus_args *args, remote_get_max_vcpus_ret *ret);
|
||||||
|
|
|
@ -1501,6 +1501,28 @@ xdr_remote_list_defined_storage_pools_ret (XDR *xdrs, remote_list_defined_storag
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_remote_find_storage_pool_sources_args (XDR *xdrs, remote_find_storage_pool_sources_args *objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_remote_nonnull_string (xdrs, &objp->type))
|
||||||
|
return FALSE;
|
||||||
|
if (!xdr_remote_string (xdrs, &objp->srcSpec))
|
||||||
|
return FALSE;
|
||||||
|
if (!xdr_u_int (xdrs, &objp->flags))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_remote_find_storage_pool_sources_ret (XDR *xdrs, remote_find_storage_pool_sources_ret *objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_remote_nonnull_string (xdrs, &objp->xml))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
bool_t
|
bool_t
|
||||||
xdr_remote_storage_pool_lookup_by_uuid_args (XDR *xdrs, remote_storage_pool_lookup_by_uuid_args *objp)
|
xdr_remote_storage_pool_lookup_by_uuid_args (XDR *xdrs, remote_storage_pool_lookup_by_uuid_args *objp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -837,6 +837,18 @@ struct remote_list_defined_storage_pools_ret {
|
||||||
};
|
};
|
||||||
typedef struct remote_list_defined_storage_pools_ret remote_list_defined_storage_pools_ret;
|
typedef struct remote_list_defined_storage_pools_ret remote_list_defined_storage_pools_ret;
|
||||||
|
|
||||||
|
struct remote_find_storage_pool_sources_args {
|
||||||
|
remote_nonnull_string type;
|
||||||
|
remote_string srcSpec;
|
||||||
|
u_int flags;
|
||||||
|
};
|
||||||
|
typedef struct remote_find_storage_pool_sources_args remote_find_storage_pool_sources_args;
|
||||||
|
|
||||||
|
struct remote_find_storage_pool_sources_ret {
|
||||||
|
remote_nonnull_string xml;
|
||||||
|
};
|
||||||
|
typedef struct remote_find_storage_pool_sources_ret remote_find_storage_pool_sources_ret;
|
||||||
|
|
||||||
struct remote_storage_pool_lookup_by_uuid_args {
|
struct remote_storage_pool_lookup_by_uuid_args {
|
||||||
remote_uuid uuid;
|
remote_uuid uuid;
|
||||||
};
|
};
|
||||||
|
@ -1146,7 +1158,7 @@ enum remote_procedure {
|
||||||
REMOTE_PROC_LIST_STORAGE_POOLS = 72,
|
REMOTE_PROC_LIST_STORAGE_POOLS = 72,
|
||||||
REMOTE_PROC_NUM_OF_DEFINED_STORAGE_POOLS = 73,
|
REMOTE_PROC_NUM_OF_DEFINED_STORAGE_POOLS = 73,
|
||||||
REMOTE_PROC_LIST_DEFINED_STORAGE_POOLS = 74,
|
REMOTE_PROC_LIST_DEFINED_STORAGE_POOLS = 74,
|
||||||
REMOTE_PROC_DISCOVER_STORAGE_POOLS = 75,
|
REMOTE_PROC_FIND_STORAGE_POOL_SOURCES = 75,
|
||||||
REMOTE_PROC_STORAGE_POOL_CREATE_XML = 76,
|
REMOTE_PROC_STORAGE_POOL_CREATE_XML = 76,
|
||||||
REMOTE_PROC_STORAGE_POOL_DEFINE_XML = 77,
|
REMOTE_PROC_STORAGE_POOL_DEFINE_XML = 77,
|
||||||
REMOTE_PROC_STORAGE_POOL_CREATE = 78,
|
REMOTE_PROC_STORAGE_POOL_CREATE = 78,
|
||||||
|
@ -1337,6 +1349,8 @@ extern bool_t xdr_remote_list_storage_pools_ret (XDR *, remote_list_storage_poo
|
||||||
extern bool_t xdr_remote_num_of_defined_storage_pools_ret (XDR *, remote_num_of_defined_storage_pools_ret*);
|
extern bool_t xdr_remote_num_of_defined_storage_pools_ret (XDR *, remote_num_of_defined_storage_pools_ret*);
|
||||||
extern bool_t xdr_remote_list_defined_storage_pools_args (XDR *, remote_list_defined_storage_pools_args*);
|
extern bool_t xdr_remote_list_defined_storage_pools_args (XDR *, remote_list_defined_storage_pools_args*);
|
||||||
extern bool_t xdr_remote_list_defined_storage_pools_ret (XDR *, remote_list_defined_storage_pools_ret*);
|
extern bool_t xdr_remote_list_defined_storage_pools_ret (XDR *, remote_list_defined_storage_pools_ret*);
|
||||||
|
extern bool_t xdr_remote_find_storage_pool_sources_args (XDR *, remote_find_storage_pool_sources_args*);
|
||||||
|
extern bool_t xdr_remote_find_storage_pool_sources_ret (XDR *, remote_find_storage_pool_sources_ret*);
|
||||||
extern bool_t xdr_remote_storage_pool_lookup_by_uuid_args (XDR *, remote_storage_pool_lookup_by_uuid_args*);
|
extern bool_t xdr_remote_storage_pool_lookup_by_uuid_args (XDR *, remote_storage_pool_lookup_by_uuid_args*);
|
||||||
extern bool_t xdr_remote_storage_pool_lookup_by_uuid_ret (XDR *, remote_storage_pool_lookup_by_uuid_ret*);
|
extern bool_t xdr_remote_storage_pool_lookup_by_uuid_ret (XDR *, remote_storage_pool_lookup_by_uuid_ret*);
|
||||||
extern bool_t xdr_remote_storage_pool_lookup_by_name_args (XDR *, remote_storage_pool_lookup_by_name_args*);
|
extern bool_t xdr_remote_storage_pool_lookup_by_name_args (XDR *, remote_storage_pool_lookup_by_name_args*);
|
||||||
|
@ -1516,6 +1530,8 @@ extern bool_t xdr_remote_list_storage_pools_ret ();
|
||||||
extern bool_t xdr_remote_num_of_defined_storage_pools_ret ();
|
extern bool_t xdr_remote_num_of_defined_storage_pools_ret ();
|
||||||
extern bool_t xdr_remote_list_defined_storage_pools_args ();
|
extern bool_t xdr_remote_list_defined_storage_pools_args ();
|
||||||
extern bool_t xdr_remote_list_defined_storage_pools_ret ();
|
extern bool_t xdr_remote_list_defined_storage_pools_ret ();
|
||||||
|
extern bool_t xdr_remote_find_storage_pool_sources_args ();
|
||||||
|
extern bool_t xdr_remote_find_storage_pool_sources_ret ();
|
||||||
extern bool_t xdr_remote_storage_pool_lookup_by_uuid_args ();
|
extern bool_t xdr_remote_storage_pool_lookup_by_uuid_args ();
|
||||||
extern bool_t xdr_remote_storage_pool_lookup_by_uuid_ret ();
|
extern bool_t xdr_remote_storage_pool_lookup_by_uuid_ret ();
|
||||||
extern bool_t xdr_remote_storage_pool_lookup_by_name_args ();
|
extern bool_t xdr_remote_storage_pool_lookup_by_name_args ();
|
||||||
|
|
|
@ -763,6 +763,16 @@ struct remote_list_defined_storage_pools_ret {
|
||||||
remote_nonnull_string names<REMOTE_STORAGE_POOL_NAME_LIST_MAX>;
|
remote_nonnull_string names<REMOTE_STORAGE_POOL_NAME_LIST_MAX>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct remote_find_storage_pool_sources_args {
|
||||||
|
remote_nonnull_string type;
|
||||||
|
remote_string srcSpec;
|
||||||
|
unsigned flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct remote_find_storage_pool_sources_ret {
|
||||||
|
remote_nonnull_string xml;
|
||||||
|
};
|
||||||
|
|
||||||
struct remote_storage_pool_lookup_by_uuid_args {
|
struct remote_storage_pool_lookup_by_uuid_args {
|
||||||
remote_uuid uuid;
|
remote_uuid uuid;
|
||||||
};
|
};
|
||||||
|
@ -1042,7 +1052,7 @@ enum remote_procedure {
|
||||||
REMOTE_PROC_LIST_STORAGE_POOLS = 72,
|
REMOTE_PROC_LIST_STORAGE_POOLS = 72,
|
||||||
REMOTE_PROC_NUM_OF_DEFINED_STORAGE_POOLS = 73,
|
REMOTE_PROC_NUM_OF_DEFINED_STORAGE_POOLS = 73,
|
||||||
REMOTE_PROC_LIST_DEFINED_STORAGE_POOLS = 74,
|
REMOTE_PROC_LIST_DEFINED_STORAGE_POOLS = 74,
|
||||||
REMOTE_PROC_DISCOVER_STORAGE_POOLS = 75,
|
REMOTE_PROC_FIND_STORAGE_POOL_SOURCES = 75,
|
||||||
REMOTE_PROC_STORAGE_POOL_CREATE_XML = 76,
|
REMOTE_PROC_STORAGE_POOL_CREATE_XML = 76,
|
||||||
REMOTE_PROC_STORAGE_POOL_DEFINE_XML = 77,
|
REMOTE_PROC_STORAGE_POOL_DEFINE_XML = 77,
|
||||||
REMOTE_PROC_STORAGE_POOL_CREATE = 78,
|
REMOTE_PROC_STORAGE_POOL_CREATE = 78,
|
||||||
|
|
|
@ -444,6 +444,11 @@ typedef int
|
||||||
(*virDrvConnectListDefinedStoragePools) (virConnectPtr conn,
|
(*virDrvConnectListDefinedStoragePools) (virConnectPtr conn,
|
||||||
char **const names,
|
char **const names,
|
||||||
int maxnames);
|
int maxnames);
|
||||||
|
typedef char *
|
||||||
|
(*virDrvConnectFindStoragePoolSources) (virConnectPtr conn,
|
||||||
|
const char *type,
|
||||||
|
const char *srcSpec,
|
||||||
|
unsigned int flags);
|
||||||
typedef virStoragePoolPtr
|
typedef virStoragePoolPtr
|
||||||
(*virDrvStoragePoolLookupByName) (virConnectPtr conn,
|
(*virDrvStoragePoolLookupByName) (virConnectPtr conn,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
@ -548,6 +553,7 @@ struct _virStorageDriver {
|
||||||
virDrvConnectListStoragePools listPools;
|
virDrvConnectListStoragePools listPools;
|
||||||
virDrvConnectNumOfDefinedStoragePools numOfDefinedPools;
|
virDrvConnectNumOfDefinedStoragePools numOfDefinedPools;
|
||||||
virDrvConnectListDefinedStoragePools listDefinedPools;
|
virDrvConnectListDefinedStoragePools listDefinedPools;
|
||||||
|
virDrvConnectFindStoragePoolSources findPoolSources;
|
||||||
virDrvStoragePoolLookupByName poolLookupByName;
|
virDrvStoragePoolLookupByName poolLookupByName;
|
||||||
virDrvStoragePoolLookupByUUID poolLookupByUUID;
|
virDrvStoragePoolLookupByUUID poolLookupByUUID;
|
||||||
virDrvStoragePoolLookupByVolume poolLookupByVolume;
|
virDrvStoragePoolLookupByVolume poolLookupByVolume;
|
||||||
|
|
|
@ -362,4 +362,16 @@ int __virDomainMigratePrepare (virConnectPtr dconn, char **cookie, int *cookiele
|
||||||
int __virDomainMigratePerform (virDomainPtr domain, const char *cookie, int cookielen, const char *uri, unsigned long flags, const char *dname, unsigned long bandwidth);
|
int __virDomainMigratePerform (virDomainPtr domain, const char *cookie, int cookielen, const char *uri, unsigned long flags, const char *dname, unsigned long bandwidth);
|
||||||
virDomainPtr __virDomainMigrateFinish (virConnectPtr dconn, const char *dname, const char *cookie, int cookielen, const char *uri, unsigned long flags);
|
virDomainPtr __virDomainMigrateFinish (virConnectPtr dconn, const char *dname, const char *cookie, int cookielen, const char *uri, unsigned long flags);
|
||||||
|
|
||||||
|
typedef struct _virStringList virStringList;
|
||||||
|
|
||||||
|
struct _virStringList {
|
||||||
|
char *val;
|
||||||
|
int len;
|
||||||
|
struct _virStringList *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
char *virStringListJoin(const virStringList *list, const char *pre,
|
||||||
|
const char *post, const char *sep);
|
||||||
|
void virStringListFree(virStringList *list);
|
||||||
|
|
||||||
#endif /* __VIR_INTERNAL_H__ */
|
#endif /* __VIR_INTERNAL_H__ */
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
#ifdef WITH_TEST
|
#ifdef WITH_TEST
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
@ -4124,6 +4125,50 @@ virConnectListDefinedStoragePools(virConnectPtr conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virConnectFindStoragePoolSources:
|
||||||
|
* @conn: pointer to hypervisor connection
|
||||||
|
* @type: type of storage pool sources to discover
|
||||||
|
* @srcSpec: XML document specifying discovery source
|
||||||
|
* @flags: flags for discovery (unused, pass 0)
|
||||||
|
*
|
||||||
|
* Talks to a storage backend and attempts to auto-discover the set of
|
||||||
|
* available storage pool sources. e.g. For iSCSI this would be a set of
|
||||||
|
* iSCSI targets. For NFS this would be a list of exported paths. The
|
||||||
|
* srcSpec (optional for some storage pool types, e.g. local ones) is
|
||||||
|
* an instance of the storage pool's source element specifying where
|
||||||
|
* to look for the pools.
|
||||||
|
*
|
||||||
|
* srcSpec is not required for some types (e.g., those querying
|
||||||
|
* local storage resources only)
|
||||||
|
*
|
||||||
|
* Returns an xml document consisting of a SourceList element
|
||||||
|
* containing a source document appropriate to the given pool
|
||||||
|
* type for each discovered source.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
virConnectFindStoragePoolSources(virConnectPtr conn,
|
||||||
|
const char *type,
|
||||||
|
const char *srcSpec,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
if (!VIR_IS_CONNECT(conn)) {
|
||||||
|
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (type == NULL) {
|
||||||
|
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn->storageDriver && conn->storageDriver->findPoolSources)
|
||||||
|
return conn->storageDriver->findPoolSources(conn, type, srcSpec, flags);
|
||||||
|
|
||||||
|
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virStoragePoolLookupByName:
|
* virStoragePoolLookupByName:
|
||||||
* @conn: pointer to hypervisor connection
|
* @conn: pointer to hypervisor connection
|
||||||
|
@ -5234,3 +5279,45 @@ virStorageVolGetPath(virStorageVolPtr vol)
|
||||||
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Not for public use. Combines the elements of a virStringList
|
||||||
|
* into a single string.
|
||||||
|
*/
|
||||||
|
char *virStringListJoin(const virStringList *list, const char *pre,
|
||||||
|
const char *post, const char *sep)
|
||||||
|
{
|
||||||
|
size_t pre_len = strlen(pre);
|
||||||
|
size_t sep_len = strlen(sep);
|
||||||
|
size_t len = pre_len + strlen(post);
|
||||||
|
const virStringList *p;
|
||||||
|
char *retval;
|
||||||
|
|
||||||
|
for (p = list; p; p = p->next)
|
||||||
|
len += p->len + sep_len;
|
||||||
|
if (VIR_ALLOC_N(retval, len+1) < 0)
|
||||||
|
return NULL;
|
||||||
|
strcpy(retval, pre);
|
||||||
|
len = pre_len;
|
||||||
|
for (p = list; p; p = p->next) {
|
||||||
|
strcpy(retval + len, p->val);
|
||||||
|
len += p->len;
|
||||||
|
strcpy(retval + len, sep);
|
||||||
|
len += sep_len;
|
||||||
|
}
|
||||||
|
strcpy(retval + len, post);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void virStringListFree(virStringList *list)
|
||||||
|
{
|
||||||
|
while (list) {
|
||||||
|
virStringList *p = list->next;
|
||||||
|
VIR_FREE(list);
|
||||||
|
list = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
virConnectNumOfDefinedStoragePools;
|
virConnectNumOfDefinedStoragePools;
|
||||||
virConnectListStoragePools;
|
virConnectListStoragePools;
|
||||||
virConnectListDefinedStoragePools;
|
virConnectListDefinedStoragePools;
|
||||||
virConnectDiscoverStoragePools;
|
virConnectFindStoragePoolSources;
|
||||||
virStoragePoolLookupByName;
|
virStoragePoolLookupByName;
|
||||||
virStoragePoolLookupByUUID;
|
virStoragePoolLookupByUUID;
|
||||||
virStoragePoolLookupByUUIDString;
|
virStoragePoolLookupByUUIDString;
|
||||||
|
|
|
@ -3079,6 +3079,47 @@ remoteListDefinedStoragePools (virConnectPtr conn,
|
||||||
return ret.names.names_len;
|
return ret.names.names_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
remoteFindStoragePoolSources (virConnectPtr conn,
|
||||||
|
const char *type,
|
||||||
|
const char *srcSpec,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
remote_find_storage_pool_sources_args args;
|
||||||
|
remote_find_storage_pool_sources_ret ret;
|
||||||
|
GET_STORAGE_PRIVATE (conn, NULL);
|
||||||
|
const char *emptyString = "";
|
||||||
|
char *retval;
|
||||||
|
|
||||||
|
args.type = (char*)type;
|
||||||
|
/*
|
||||||
|
* I'd think the following would work here:
|
||||||
|
* args.srcSpec = (char**)&srcSpec;
|
||||||
|
* since srcSpec is a remote_string (not a remote_nonnull_string).
|
||||||
|
*
|
||||||
|
* But when srcSpec is NULL, this yields:
|
||||||
|
* libvir: Remote error : marshalling args
|
||||||
|
*
|
||||||
|
* So for now I'm working around this by turning NULL srcSpecs
|
||||||
|
* into empty strings.
|
||||||
|
*/
|
||||||
|
args.srcSpec = srcSpec ? (char **)&srcSpec : (char **)&emptyString;
|
||||||
|
args.flags = flags;
|
||||||
|
|
||||||
|
memset (&ret, 0, sizeof ret);
|
||||||
|
if (call (conn, priv, 0, REMOTE_PROC_FIND_STORAGE_POOL_SOURCES,
|
||||||
|
(xdrproc_t) xdr_remote_find_storage_pool_sources_args, (char *) &args,
|
||||||
|
(xdrproc_t) xdr_remote_find_storage_pool_sources_ret, (char *) &ret) == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
retval = ret.xml;
|
||||||
|
ret.xml = NULL; /* To stop xdr_free free'ing it */
|
||||||
|
|
||||||
|
xdr_free ((xdrproc_t) xdr_remote_find_storage_pool_sources_ret, (char *) &ret);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static virStoragePoolPtr
|
static virStoragePoolPtr
|
||||||
remoteStoragePoolLookupByUUID (virConnectPtr conn,
|
remoteStoragePoolLookupByUUID (virConnectPtr conn,
|
||||||
const unsigned char *uuid)
|
const unsigned char *uuid)
|
||||||
|
@ -4940,6 +4981,7 @@ static virStorageDriver storage_driver = {
|
||||||
.listPools = remoteListStoragePools,
|
.listPools = remoteListStoragePools,
|
||||||
.numOfDefinedPools = remoteNumOfDefinedStoragePools,
|
.numOfDefinedPools = remoteNumOfDefinedStoragePools,
|
||||||
.listDefinedPools = remoteListDefinedStoragePools,
|
.listDefinedPools = remoteListDefinedStoragePools,
|
||||||
|
.findPoolSources = remoteFindStoragePoolSources,
|
||||||
.poolLookupByUUID = remoteStoragePoolLookupByUUID,
|
.poolLookupByUUID = remoteStoragePoolLookupByUUID,
|
||||||
.poolLookupByName = remoteStoragePoolLookupByName,
|
.poolLookupByName = remoteStoragePoolLookupByName,
|
||||||
.poolLookupByVolume = remoteStoragePoolLookupByVolume,
|
.poolLookupByVolume = remoteStoragePoolLookupByVolume,
|
||||||
|
|
|
@ -63,6 +63,10 @@ struct _virStorageBackendPoolOptions {
|
||||||
virStoragePoolFormatFromString formatFromString;
|
virStoragePoolFormatFromString formatFromString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SOURCES_START_TAG "<sources>"
|
||||||
|
#define SOURCES_END_TAG "</sources>"
|
||||||
|
|
||||||
|
typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn, const char *srcSpec, unsigned int flags);
|
||||||
typedef int (*virStorageBackendStartPool)(virConnectPtr conn, virStoragePoolObjPtr pool);
|
typedef int (*virStorageBackendStartPool)(virConnectPtr conn, virStoragePoolObjPtr pool);
|
||||||
typedef int (*virStorageBackendBuildPool)(virConnectPtr conn, virStoragePoolObjPtr pool, unsigned int flags);
|
typedef int (*virStorageBackendBuildPool)(virConnectPtr conn, virStoragePoolObjPtr pool, unsigned int flags);
|
||||||
typedef int (*virStorageBackendRefreshPool)(virConnectPtr conn, virStoragePoolObjPtr pool);
|
typedef int (*virStorageBackendRefreshPool)(virConnectPtr conn, virStoragePoolObjPtr pool);
|
||||||
|
@ -80,6 +84,7 @@ typedef virStorageBackend *virStorageBackendPtr;
|
||||||
struct _virStorageBackend {
|
struct _virStorageBackend {
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
|
virStorageBackendFindPoolSources findPoolSources;
|
||||||
virStorageBackendStartPool startPool;
|
virStorageBackendStartPool startPool;
|
||||||
virStorageBackendBuildPool buildPool;
|
virStorageBackendBuildPool buildPool;
|
||||||
virStorageBackendRefreshPool refreshPool;
|
virStorageBackendRefreshPool refreshPool;
|
||||||
|
|
|
@ -36,11 +36,16 @@
|
||||||
#include <mntent.h>
|
#include <mntent.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
#include <libxml/tree.h>
|
||||||
|
#include <libxml/xpath.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "storage_backend_fs.h"
|
#include "storage_backend_fs.h"
|
||||||
#include "storage_conf.h"
|
#include "storage_conf.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "xml.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VIR_STORAGE_POOL_FS_AUTO = 0,
|
VIR_STORAGE_POOL_FS_AUTO = 0,
|
||||||
|
@ -442,6 +447,129 @@ static int virStorageBackendProbeFile(virConnectPtr conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WITH_STORAGE_FS
|
#if WITH_STORAGE_FS
|
||||||
|
struct _virNetfsDiscoverState {
|
||||||
|
const char *host;
|
||||||
|
virStringList *list;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _virNetfsDiscoverState virNetfsDiscoverState;
|
||||||
|
|
||||||
|
static int
|
||||||
|
virStorageBackendFileSystemNetFindPoolSourcesFunc(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
|
virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
|
||||||
|
char **const groups,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
virNetfsDiscoverState *state = data;
|
||||||
|
virStringList *newItem;
|
||||||
|
const char *name, *path;
|
||||||
|
|
||||||
|
path = groups[0];
|
||||||
|
|
||||||
|
name = strrchr(path, '/');
|
||||||
|
if (name == NULL) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("invalid netfs path (no /): %s"), path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
name += 1;
|
||||||
|
if (*name == '\0') {
|
||||||
|
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("invalid netfs path (ends in /): %s"), path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append new XML desc to list */
|
||||||
|
|
||||||
|
if (VIR_ALLOC(newItem) != 0) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("new xml desc"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asprintf(&newItem->val,
|
||||||
|
"<source><host name='%s'/><dir path='%s'/></source>",
|
||||||
|
state->host, path) <= 0) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", _("asprintf failed"));
|
||||||
|
VIR_FREE(newItem);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
newItem->len = strlen(newItem->val);
|
||||||
|
newItem->next = state->list;
|
||||||
|
state->list = newItem;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
virStorageBackendFileSystemNetFindPoolSources(virConnectPtr conn,
|
||||||
|
const char *srcSpec,
|
||||||
|
unsigned int flags ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* # showmount --no-headers -e HOSTNAME
|
||||||
|
* /tmp *
|
||||||
|
* /A dir demo1.foo.bar,demo2.foo.bar
|
||||||
|
*
|
||||||
|
* Extract directory name (including possible interior spaces ...).
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char *regexes[] = {
|
||||||
|
"^(/.*\\S) +\\S+$"
|
||||||
|
};
|
||||||
|
int vars[] = {
|
||||||
|
1
|
||||||
|
};
|
||||||
|
xmlDocPtr doc = NULL;
|
||||||
|
xmlXPathContextPtr xpath_ctxt = NULL;
|
||||||
|
virNetfsDiscoverState state = { .host = NULL, .list = NULL };
|
||||||
|
const char *prog[] = { SHOWMOUNT, "--no-headers", "--exports", NULL, NULL };
|
||||||
|
int exitstatus;
|
||||||
|
char *retval = NULL;
|
||||||
|
|
||||||
|
doc = xmlReadDoc((const xmlChar *)srcSpec, "srcSpec.xml", NULL,
|
||||||
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
||||||
|
XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
|
||||||
|
if (doc == NULL) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_XML_ERROR, "%s", _("bad <source> spec"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
xpath_ctxt = xmlXPathNewContext(doc);
|
||||||
|
if (xpath_ctxt == NULL) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("xpath_ctxt"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.host = virXPathString(conn, "string(/source/host/@name)", xpath_ctxt);
|
||||||
|
if (!state.host || !state.host[0]) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("missing <host> in <source> spec"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
prog[3] = state.host;
|
||||||
|
|
||||||
|
if (virStorageBackendRunProgRegex(conn, NULL, prog, 1, regexes, vars,
|
||||||
|
virStorageBackendFileSystemNetFindPoolSourcesFunc,
|
||||||
|
&state, &exitstatus) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
retval = virStringListJoin(state.list, SOURCES_START_TAG, SOURCES_END_TAG, "\n");
|
||||||
|
if (retval == NULL) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_NO_MEMORY, _("retval"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
xmlXPathFreeContext(xpath_ctxt);
|
||||||
|
VIR_FREE(state.host);
|
||||||
|
virStringListFree(state.list);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @conn connection to report errors against
|
* @conn connection to report errors against
|
||||||
* @pool storage pool to check for status
|
* @pool storage pool to check for status
|
||||||
|
@ -1114,6 +1242,7 @@ virStorageBackend virStorageBackendNetFileSystem = {
|
||||||
|
|
||||||
.buildPool = virStorageBackendFileSystemBuild,
|
.buildPool = virStorageBackendFileSystemBuild,
|
||||||
.startPool = virStorageBackendFileSystemStart,
|
.startPool = virStorageBackendFileSystemStart,
|
||||||
|
.findPoolSources = virStorageBackendFileSystemNetFindPoolSources,
|
||||||
.refreshPool = virStorageBackendFileSystemRefresh,
|
.refreshPool = virStorageBackendFileSystemRefresh,
|
||||||
.stopPool = virStorageBackendFileSystemStop,
|
.stopPool = virStorageBackendFileSystemStop,
|
||||||
.deletePool = virStorageBackendFileSystemDelete,
|
.deletePool = virStorageBackendFileSystemDelete,
|
||||||
|
|
|
@ -258,6 +258,75 @@ virStorageBackendLogicalRefreshPoolFunc(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virStorageBackendLogicalFindPoolSourcesFunc(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
|
virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
|
||||||
|
char **const groups,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
virStringList **rest = data;
|
||||||
|
virStringList *newItem;
|
||||||
|
const char *name = groups[0];
|
||||||
|
|
||||||
|
/* Append new XML desc to list */
|
||||||
|
|
||||||
|
if (VIR_ALLOC(newItem) != 0) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("new xml desc"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asprintf(&newItem->val, "<source><name>%s</name></source>", name) <= 0) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", _("asprintf failed"));
|
||||||
|
VIR_FREE(newItem);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
newItem->len = strlen(newItem->val);
|
||||||
|
newItem->next = *rest;
|
||||||
|
*rest = newItem;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
virStorageBackendLogicalFindPoolSources(virConnectPtr conn,
|
||||||
|
const char *srcSpec ATTRIBUTE_UNUSED,
|
||||||
|
unsigned int flags ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* # sudo vgs --noheadings -o vg_name
|
||||||
|
* VolGroup00
|
||||||
|
* VolGroup01
|
||||||
|
*/
|
||||||
|
const char *regexes[] = {
|
||||||
|
"^\\s*(\\S+)\\s*$"
|
||||||
|
};
|
||||||
|
int vars[] = {
|
||||||
|
1
|
||||||
|
};
|
||||||
|
virStringList *descs = NULL;
|
||||||
|
const char *prog[] = { VGS, "--noheadings", "-o", "vg_name", NULL };
|
||||||
|
int exitstatus;
|
||||||
|
char *retval = NULL;
|
||||||
|
|
||||||
|
if (virStorageBackendRunProgRegex(conn, NULL, prog, 1, regexes, vars,
|
||||||
|
virStorageBackendLogicalFindPoolSourcesFunc,
|
||||||
|
&descs, &exitstatus) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
retval = virStringListJoin(descs, SOURCES_START_TAG, SOURCES_END_TAG, "\n");
|
||||||
|
if (retval == NULL) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_NO_MEMORY, _("retval"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virStringListFree(descs);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virStorageBackendLogicalStartPool(virConnectPtr conn,
|
virStorageBackendLogicalStartPool(virConnectPtr conn,
|
||||||
virStoragePoolObjPtr pool)
|
virStoragePoolObjPtr pool)
|
||||||
|
@ -537,6 +606,7 @@ virStorageBackendLogicalDeleteVol(virConnectPtr conn,
|
||||||
virStorageBackend virStorageBackendLogical = {
|
virStorageBackend virStorageBackendLogical = {
|
||||||
.type = VIR_STORAGE_POOL_LOGICAL,
|
.type = VIR_STORAGE_POOL_LOGICAL,
|
||||||
|
|
||||||
|
.findPoolSources = virStorageBackendLogicalFindPoolSources,
|
||||||
.startPool = virStorageBackendLogicalStartPool,
|
.startPool = virStorageBackendLogicalStartPool,
|
||||||
.buildPool = virStorageBackendLogicalBuildPool,
|
.buildPool = virStorageBackendLogicalBuildPool,
|
||||||
.refreshPool = virStorageBackendLogicalRefreshPool,
|
.refreshPool = virStorageBackendLogicalRefreshPool,
|
||||||
|
|
|
@ -386,6 +386,30 @@ storageListDefinedPools(virConnectPtr conn,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
storageFindPoolSources(virConnectPtr conn,
|
||||||
|
const char *type,
|
||||||
|
const char *srcSpec,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
int backend_type;
|
||||||
|
virStorageBackendPtr backend;
|
||||||
|
|
||||||
|
backend_type = virStorageBackendFromString(type);
|
||||||
|
if (backend_type < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
backend = virStorageBackendForType(backend_type);
|
||||||
|
if (backend == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (backend->findPoolSources)
|
||||||
|
return backend->findPoolSources(conn, srcSpec, flags);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static virStoragePoolPtr
|
static virStoragePoolPtr
|
||||||
storagePoolCreate(virConnectPtr conn,
|
storagePoolCreate(virConnectPtr conn,
|
||||||
const char *xml,
|
const char *xml,
|
||||||
|
@ -1212,6 +1236,7 @@ static virStorageDriver storageDriver = {
|
||||||
storageListPools,
|
storageListPools,
|
||||||
storageNumDefinedPools,
|
storageNumDefinedPools,
|
||||||
storageListDefinedPools,
|
storageListDefinedPools,
|
||||||
|
storageFindPoolSources,
|
||||||
storagePoolLookupByName,
|
storagePoolLookupByName,
|
||||||
storagePoolLookupByUUID,
|
storagePoolLookupByUUID,
|
||||||
storagePoolLookupByVolume,
|
storagePoolLookupByVolume,
|
||||||
|
|
137
src/virsh.c
137
src/virsh.c
|
@ -3422,6 +3422,139 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "find-storage-pool-sources-as" command
|
||||||
|
*/
|
||||||
|
static const vshCmdInfo info_find_storage_pool_sources_as[] = {
|
||||||
|
{"syntax", "find-storage-pool-sources-as <type> [options]"},
|
||||||
|
{"help", gettext_noop("find potential storage pool sources")},
|
||||||
|
{"desc", gettext_noop("Returns XML <sources> document.")},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const vshCmdOptDef opts_find_storage_pool_sources_as[] = {
|
||||||
|
{"type", VSH_OT_DATA, VSH_OFLAG_REQ,
|
||||||
|
gettext_noop("type of storage pool sources to find")},
|
||||||
|
{"host", VSH_OT_DATA, VSH_OFLAG_NONE, gettext_noop("optional host to query")},
|
||||||
|
{"port", VSH_OT_DATA, VSH_OFLAG_NONE, gettext_noop("optional port to query")},
|
||||||
|
{NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmdPoolDiscoverSourcesAs(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
char *type, *host;
|
||||||
|
char *srcSpec = NULL;
|
||||||
|
char *srcList;
|
||||||
|
int found;
|
||||||
|
|
||||||
|
type = vshCommandOptString(cmd, "type", &found);
|
||||||
|
if (!found)
|
||||||
|
return FALSE;
|
||||||
|
host = vshCommandOptString(cmd, "host", &found);
|
||||||
|
if (!found)
|
||||||
|
host = NULL;
|
||||||
|
|
||||||
|
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (host) {
|
||||||
|
size_t hostlen = strlen(host);
|
||||||
|
char *port = vshCommandOptString(cmd, "port", &found);
|
||||||
|
int ret;
|
||||||
|
if (!found) {
|
||||||
|
port = strrchr(host, ':');
|
||||||
|
if (port) {
|
||||||
|
if (*(++port))
|
||||||
|
hostlen = port - host - 1;
|
||||||
|
else
|
||||||
|
port = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = port ?
|
||||||
|
asprintf(&srcSpec,
|
||||||
|
"<source><host name='%.*s' port='%s'/></source>",
|
||||||
|
(int)hostlen, host, port) :
|
||||||
|
asprintf(&srcSpec,
|
||||||
|
"<source><host name='%.*s'/></source>",
|
||||||
|
(int)hostlen, host);
|
||||||
|
if (ret < 0) {
|
||||||
|
switch (errno) {
|
||||||
|
case ENOMEM:
|
||||||
|
vshError(ctl, FALSE, "%s", _("Out of memory"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vshError(ctl, FALSE, _("asprintf failed (errno %d)"), errno);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
srcList = virConnectFindStoragePoolSources(ctl->conn, type, srcSpec, 0);
|
||||||
|
free(srcSpec);
|
||||||
|
if (srcList == NULL) {
|
||||||
|
vshError(ctl, FALSE, _("Failed to find any %s pool sources"), type);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
vshPrint(ctl, "%s", srcList);
|
||||||
|
free(srcList);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "find-storage-pool-sources" command
|
||||||
|
*/
|
||||||
|
static const vshCmdInfo info_find_storage_pool_sources[] = {
|
||||||
|
{"syntax", "find-storage-pool-sources <type> [srcSpec]"},
|
||||||
|
{"help", gettext_noop("discover potential storage pool sources")},
|
||||||
|
{"desc", gettext_noop("Returns XML <sources> document.")},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const vshCmdOptDef opts_find_storage_pool_sources[] = {
|
||||||
|
{"type", VSH_OT_DATA, VSH_OFLAG_REQ,
|
||||||
|
gettext_noop("type of storage pool sources to discover")},
|
||||||
|
{"srcSpec", VSH_OT_DATA, VSH_OFLAG_NONE,
|
||||||
|
gettext_noop("optional file of source xml to query for pools")},
|
||||||
|
{NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmdPoolDiscoverSources(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
char *type, *srcSpec, *srcSpecFile, *srcList;
|
||||||
|
int found;
|
||||||
|
|
||||||
|
type = vshCommandOptString(cmd, "type", &found);
|
||||||
|
if (!found)
|
||||||
|
return FALSE;
|
||||||
|
srcSpecFile = vshCommandOptString(cmd, "srcSpec", &found);
|
||||||
|
if (!found) {
|
||||||
|
srcSpecFile = NULL;
|
||||||
|
srcSpec = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (srcSpecFile && virFileReadAll(srcSpecFile, VIRSH_MAX_XML_FILE, &srcSpec) < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
srcList = virConnectFindStoragePoolSources(ctl->conn, type, srcSpec, 0);
|
||||||
|
free(srcSpec);
|
||||||
|
if (srcList == NULL) {
|
||||||
|
vshError(ctl, FALSE, _("Failed to find any %s pool sources"), type);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
vshPrint(ctl, "%s", srcList);
|
||||||
|
free(srcList);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static double
|
static double
|
||||||
prettyCapacity(unsigned long long val,
|
prettyCapacity(unsigned long long val,
|
||||||
const char **unit) {
|
const char **unit) {
|
||||||
|
@ -5362,6 +5495,10 @@ static const vshCmdDef commands[] = {
|
||||||
{"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat},
|
{"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat},
|
||||||
{"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml},
|
{"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml},
|
||||||
{"edit", cmdEdit, opts_edit, info_edit},
|
{"edit", cmdEdit, opts_edit, info_edit},
|
||||||
|
{"find-storage-pool-sources", cmdPoolDiscoverSources,
|
||||||
|
opts_find_storage_pool_sources, info_find_storage_pool_sources},
|
||||||
|
{"find-storage-pool-sources-as", cmdPoolDiscoverSourcesAs,
|
||||||
|
opts_find_storage_pool_sources_as, info_find_storage_pool_sources_as},
|
||||||
{"freecell", cmdFreecell, opts_freecell, info_freecell},
|
{"freecell", cmdFreecell, opts_freecell, info_freecell},
|
||||||
{"hostname", cmdHostname, NULL, info_hostname},
|
{"hostname", cmdHostname, NULL, info_hostname},
|
||||||
{"list", cmdList, opts_list, info_list},
|
{"list", cmdList, opts_list, info_list},
|
||||||
|
|
Loading…
Reference in New Issue