pr-manager: add query-pr-managers QMP command
This command lets you query the connection status of each pr-manager-helper object. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
58b3017f7f
commit
5f64089416
@ -33,8 +33,10 @@ typedef struct PRManagerClass {
|
||||
|
||||
/* <public> */
|
||||
int (*run)(PRManager *pr_mgr, int fd, struct sg_io_hdr *hdr);
|
||||
bool (*is_connected)(PRManager *pr_mgr);
|
||||
} PRManagerClass;
|
||||
|
||||
bool pr_manager_is_connected(PRManager *pr_mgr);
|
||||
BlockAIOCB *pr_manager_execute(PRManager *pr_mgr,
|
||||
AioContext *ctx, int fd,
|
||||
struct sg_io_hdr *hdr,
|
||||
|
@ -77,6 +77,34 @@
|
||||
{ 'struct': 'BlockdevSnapshotInternal',
|
||||
'data': { 'device': 'str', 'name': 'str' } }
|
||||
|
||||
##
|
||||
# @PRManagerInfo:
|
||||
#
|
||||
# Information about a persistent reservation manager
|
||||
#
|
||||
# @id: the identifier of the persistent reservation manager
|
||||
#
|
||||
# @connected: true if the persistent reservation manager is connected to
|
||||
# the underlying storage or helper
|
||||
#
|
||||
# Since: 3.0
|
||||
##
|
||||
{ 'struct': 'PRManagerInfo',
|
||||
'data': {'id': 'str', 'connected': 'bool'} }
|
||||
|
||||
##
|
||||
# @query-pr-managers:
|
||||
#
|
||||
# Returns a list of information about each persistent reservation manager.
|
||||
#
|
||||
# Returns: a list of @PRManagerInfo for each persistent reservation manager
|
||||
#
|
||||
# Since: 3.0
|
||||
##
|
||||
{ 'command': 'query-pr-managers', 'returns': ['PRManagerInfo'],
|
||||
'allow-preconfig': true }
|
||||
|
||||
|
||||
##
|
||||
# @blockdev-snapshot-internal-sync:
|
||||
#
|
||||
|
@ -235,6 +235,18 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool pr_manager_helper_is_connected(PRManager *p)
|
||||
{
|
||||
PRManagerHelper *pr_mgr = PR_MANAGER_HELPER(p);
|
||||
bool result;
|
||||
|
||||
qemu_mutex_lock(&pr_mgr->lock);
|
||||
result = (pr_mgr->ioc != NULL);
|
||||
qemu_mutex_unlock(&pr_mgr->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void pr_manager_helper_complete(UserCreatable *uc, Error **errp)
|
||||
{
|
||||
PRManagerHelper *pr_mgr = PR_MANAGER_HELPER(uc);
|
||||
@ -284,6 +296,7 @@ static void pr_manager_helper_class_init(ObjectClass *klass,
|
||||
&error_abort);
|
||||
uc_klass->complete = pr_manager_helper_complete;
|
||||
prmgr_klass->run = pr_manager_helper_run;
|
||||
prmgr_klass->is_connected = pr_manager_helper_is_connected;
|
||||
}
|
||||
|
||||
static const TypeInfo pr_manager_helper_info = {
|
||||
|
@ -22,3 +22,9 @@ PRManager *pr_manager_lookup(const char *id, Error **errp)
|
||||
error_setg(errp, "No persistent reservation manager with id '%s'", id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
PRManagerInfoList *qmp_query_pr_managers(Error **errp)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -17,6 +17,10 @@
|
||||
#include "block/thread-pool.h"
|
||||
#include "scsi/pr-manager.h"
|
||||
#include "trace.h"
|
||||
#include "qapi/qapi-types-block.h"
|
||||
#include "qapi/qapi-commands-block.h"
|
||||
|
||||
#define PR_MANAGER_PATH "/objects"
|
||||
|
||||
typedef struct PRManagerData {
|
||||
PRManager *pr_mgr;
|
||||
@ -64,6 +68,14 @@ BlockAIOCB *pr_manager_execute(PRManager *pr_mgr,
|
||||
data, complete, opaque);
|
||||
}
|
||||
|
||||
bool pr_manager_is_connected(PRManager *pr_mgr)
|
||||
{
|
||||
PRManagerClass *pr_mgr_class =
|
||||
PR_MANAGER_GET_CLASS(pr_mgr);
|
||||
|
||||
return !pr_mgr_class->is_connected || pr_mgr_class->is_connected(pr_mgr);
|
||||
}
|
||||
|
||||
static const TypeInfo pr_manager_info = {
|
||||
.parent = TYPE_OBJECT,
|
||||
.name = TYPE_PR_MANAGER,
|
||||
@ -105,5 +117,38 @@ pr_manager_register_types(void)
|
||||
type_register_static(&pr_manager_info);
|
||||
}
|
||||
|
||||
static int query_one_pr_manager(Object *object, void *opaque)
|
||||
{
|
||||
PRManagerInfoList ***prev = opaque;
|
||||
PRManagerInfoList *elem;
|
||||
PRManagerInfo *info;
|
||||
PRManager *pr_mgr;
|
||||
|
||||
pr_mgr = (PRManager *)object_dynamic_cast(object, TYPE_PR_MANAGER);
|
||||
if (!pr_mgr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
elem = g_new0(PRManagerInfoList, 1);
|
||||
info = g_new0(PRManagerInfo, 1);
|
||||
info->id = object_get_canonical_path_component(object);
|
||||
info->connected = pr_manager_is_connected(pr_mgr);
|
||||
elem->value = info;
|
||||
elem->next = NULL;
|
||||
|
||||
**prev = elem;
|
||||
*prev = &elem->next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRManagerInfoList *qmp_query_pr_managers(Error **errp)
|
||||
{
|
||||
PRManagerInfoList *head = NULL;
|
||||
PRManagerInfoList **prev = &head;
|
||||
Object *container = container_get(object_get_root(), PR_MANAGER_PATH);
|
||||
|
||||
object_child_foreach(container, query_one_pr_manager, &prev);
|
||||
return head;
|
||||
}
|
||||
|
||||
type_init(pr_manager_register_types);
|
||||
|
Loading…
Reference in New Issue
Block a user