Just like with server-related APIs, before any of client-based APIs can be
called, a reference to a client-side client object needs to be obtained. For
this purpose, a lookup method should exist. Apart from the client retrieval
logic, a new error code for non-existent client had to be added as well.
Signed-off-by: Erik Skultety <eskultet(a)redhat.com>
---
daemon/admin_server.c | 10 ++++++++++
daemon/admin_server.h | 4 ++++
include/libvirt/libvirt-admin.h | 5 +++++
include/libvirt/virterror.h | 1 +
src/admin/admin_protocol.x | 17 ++++++++++++++++-
src/admin_protocol-structs | 9 +++++++++
src/libvirt-admin.c | 36 ++++++++++++++++++++++++++++++++++++
src/libvirt_admin_private.syms | 2 ++
src/libvirt_admin_public.syms | 1 +
src/rpc/virnetserver.c | 23 +++++++++++++++++++++++
src/rpc/virnetserver.h | 3 +++
src/util/virerror.c | 6 ++++++
12 files changed, 116 insertions(+), 1 deletion(-)
diff --git a/daemon/admin_server.c b/daemon/admin_server.c
index 0bd142c..9ea1164 100644
--- a/daemon/admin_server.c
+++ b/daemon/admin_server.c
@@ -201,3 +201,13 @@ adminServerListClients(virNetServerPtr srv,
virObjectListFreeCount(clts, ret);
return ret;
}
+
+virNetServerClientPtr
+adminServerLookupClient(virNetServerPtr srv,
+ unsigned long long id,
+ unsigned int flags)
+{
+ virCheckFlags(0, NULL);
+
+ return virNetServerGetClient(srv, id);
+}
diff --git a/daemon/admin_server.h b/daemon/admin_server.h
index 3e4786e..a593251 100644
--- a/daemon/admin_server.h
+++ b/daemon/admin_server.h
@@ -50,4 +50,8 @@ int adminServerListClients(virNetServerPtr srv,
virNetServerClientPtr **clients,
unsigned int flags);
+virNetServerClientPtr adminServerLookupClient(virNetServerPtr srv,
+ unsigned long long id,
+ unsigned int flags);
+
#endif /* __LIBVIRTD_ADMIN_SERVER_H__ */
diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h
index 20768e2..e51f2ba 100644
--- a/include/libvirt/libvirt-admin.h
+++ b/include/libvirt/libvirt-admin.h
@@ -219,6 +219,11 @@ int virAdmServerListClients(virAdmServerPtr srv,
virAdmClientPtr **clients,
unsigned int flags);
+virAdmClientPtr
+virAdmServerLookupClient(virAdmServerPtr srv,
+ unsigned long long id,
+ unsigned int flags);
+
# ifdef __cplusplus
}
# endif
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index c6abdf7..2ec560e 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -314,6 +314,7 @@ typedef enum {
VIR_ERR_MIGRATE_FINISH_OK = 93, /* Finish API succeeded but it is expected to
return NULL */
VIR_ERR_AUTH_UNAVAILABLE = 94, /* authentication unavailable */
VIR_ERR_NO_SERVER = 95, /* Server was not found */
+ VIR_ERR_NO_CLIENT = 96, /* Client was not found */
} virErrorNumber;
/**
diff --git a/src/admin/admin_protocol.x b/src/admin/admin_protocol.x
index e77ce9e..da21db8 100644
--- a/src/admin/admin_protocol.x
+++ b/src/admin/admin_protocol.x
@@ -138,6 +138,16 @@ struct admin_server_list_clients_ret { /* insert@1 */
unsigned int ret;
};
+struct admin_server_lookup_client_args {
+ admin_nonnull_server srv;
+ unsigned hyper id;
+ unsigned int flags;
+};
+
+struct admin_server_lookup_client_ret {
+ admin_nonnull_client clnt;
+};
+
/* Define the program number, protocol version and procedure numbers here. */
const ADMIN_PROGRAM = 0x06900690;
const ADMIN_PROTOCOL_VERSION = 1;
@@ -198,5 +208,10 @@ enum admin_procedure {
/**
* @generate: both
*/
- ADMIN_PROC_SERVER_LIST_CLIENTS = 8
+ ADMIN_PROC_SERVER_LIST_CLIENTS = 8,
+
+ /**
+ * @generate: both
+ */
+ ADMIN_PROC_SERVER_LOOKUP_CLIENT = 9
};
diff --git a/src/admin_protocol-structs b/src/admin_protocol-structs
index 055ddd5..dc2220e 100644
--- a/src/admin_protocol-structs
+++ b/src/admin_protocol-structs
@@ -87,6 +87,14 @@ struct admin_server_list_clients_ret {
} clients;
u_int ret;
};
+struct admin_server_lookup_client_args {
+ admin_nonnull_server srv;
+ uint64_t id;
+ u_int flags;
+};
+struct admin_server_lookup_client_ret {
+ admin_nonnull_client clnt;
+};
enum admin_procedure {
ADMIN_PROC_CONNECT_OPEN = 1,
ADMIN_PROC_CONNECT_CLOSE = 2,
@@ -96,4 +104,5 @@ enum admin_procedure {
ADMIN_PROC_SERVER_GET_THREADPOOL_PARAMETERS = 6,
ADMIN_PROC_SERVER_SET_THREADPOOL_PARAMETERS = 7,
ADMIN_PROC_SERVER_LIST_CLIENTS = 8,
+ ADMIN_PROC_SERVER_LOOKUP_CLIENT = 9,
};
diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c
index d4143e4..5d0755f 100644
--- a/src/libvirt-admin.c
+++ b/src/libvirt-admin.c
@@ -889,3 +889,39 @@ virAdmServerListClients(virAdmServerPtr srv,
virDispatchError(NULL);
return -1;
}
+
+/**
+ * virAdmServerLookupClient:
+ * @srv: a valid server object reference
+ * @id: ID of the client to lookup on server @srv
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Try to lookup a client on the given server based on @id.
+ *
+ * virAdmClientFree() should be used to free the resources after the
+ * client object is no longer needed.
+ *
+ * Returns the requested client or NULL in case of failure. If the
+ * client could not be found, then VIR_ERR_NO_CLIENT error is raised.
+ */
+virAdmClientPtr
+virAdmServerLookupClient(virAdmServerPtr srv,
+ unsigned long long id,
+ unsigned int flags)
+{
+ virAdmClientPtr ret = NULL;
+
+ VIR_DEBUG("srv=%p, id=%llu, flags=%x", srv, id, flags);
+ virResetLastError();
+
+ virCheckAdmServerGoto(srv, error);
+ virCheckFlagsGoto(0, error);
+
+ if (!(ret = remoteAdminServerLookupClient(srv, id, flags)))
+ goto error;
+
+ return ret;
+ error:
+ virDispatchError(NULL);
+ return NULL;
+}
diff --git a/src/libvirt_admin_private.syms b/src/libvirt_admin_private.syms
index 621b502..3d7ecbc 100644
--- a/src/libvirt_admin_private.syms
+++ b/src/libvirt_admin_private.syms
@@ -16,6 +16,8 @@ xdr_admin_server_get_threadpool_parameters_args;
xdr_admin_server_get_threadpool_parameters_ret;
xdr_admin_server_list_clients_args;
xdr_admin_server_list_clients_ret;
+xdr_admin_server_lookup_client_args;
+xdr_admin_server_lookup_client_ret;
xdr_admin_server_set_threadpool_parameters_args;
# datatypes.h
diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms
index bf6643a..066ae0c 100644
--- a/src/libvirt_admin_public.syms
+++ b/src/libvirt_admin_public.syms
@@ -29,6 +29,7 @@ LIBVIRT_ADMIN_1.3.0 {
virAdmServerGetName;
virAdmServerGetThreadPoolParameters;
virAdmServerFree;
+ virAdmServerLookupClient;
virAdmConnectLookupServer;
virAdmServerSetThreadPoolParameters;
virAdmServerListClients;
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index fcc79f4..60541cb 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -972,3 +972,26 @@ virNetServerGetClients(virNetServerPtr srv,
virObjectUnlock(srv);
return ret;
}
+
+virNetServerClientPtr
+virNetServerGetClient(virNetServerPtr srv,
+ unsigned long long id)
+{
+ size_t i;
+ virNetServerClientPtr ret = NULL;
+
+ virObjectLock(srv);
+
+ for (i = 0; i < srv->nclients; i++) {
+ virNetServerClientPtr client = srv->clients[i];
+ if (virNetServerClientGetID(client) == id)
+ ret = virObjectRef(client);
+ }
+
+ virObjectUnlock(srv);
+
+ if (!ret)
+ virReportError(VIR_ERR_NO_CLIENT,
+ _("No client with matching ID '%llu'"), id);
+ return ret;
+}
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
index f5bb200..993bda7 100644
--- a/src/rpc/virnetserver.h
+++ b/src/rpc/virnetserver.h
@@ -105,6 +105,9 @@ int virNetServerSetThreadPoolParameters(virNetServerPtr srv,
unsigned long long virNetServerNextClientID(virNetServerPtr srv);
+virNetServerClientPtr virNetServerGetClient(virNetServerPtr srv,
+ unsigned long long id);
+
int virNetServerGetClients(virNetServerPtr srv,
virNetServerClientPtr **clients);
diff --git a/src/util/virerror.c b/src/util/virerror.c
index 4766e13..5d875e3 100644
--- a/src/util/virerror.c
+++ b/src/util/virerror.c
@@ -1388,6 +1388,12 @@ virErrorMsg(virErrorNumber error, const char *info)
else
errmsg = _("Server not found: %s");
break;
+ case VIR_ERR_NO_CLIENT:
+ if (info == NULL)
+ errmsg = _("Client not found");
+ else
+ errmsg = _("Client not found: %s");
+ break;
}
return errmsg;
}
--
2.4.11