manipulating a server requires a client-side server object reference. We cannot
rely on client to call virAdmConnectListAllServers and further stored the
result. Therefore offer a separate API to retrieve a specific server object
for remote-side.
---
daemon/admin.c | 26 ++++++++++++++++++++++++++
daemon/admin_server.c | 17 +++++++++++++++++
daemon/admin_server.h | 4 ++++
include/libvirt/libvirt-admin.h | 2 ++
include/libvirt/virterror.h | 1 +
po/POTFILES.in | 3 ++-
src/admin/admin_protocol.x | 15 ++++++++++++++-
src/admin/admin_remote.c | 27 +++++++++++++++++++++++++++
src/admin_protocol-structs | 7 +++++++
src/libvirt-admin.c | 31 +++++++++++++++++++++++++++++++
src/libvirt_admin_private.syms | 2 ++
src/libvirt_admin_public.syms | 1 +
src/util/virerror.c | 6 ++++++
13 files changed, 140 insertions(+), 2 deletions(-)
diff --git a/daemon/admin.c b/daemon/admin.c
index 0c1ddc0..45b1190 100644
--- a/daemon/admin.c
+++ b/daemon/admin.c
@@ -178,4 +178,30 @@ adminDispatchConnectListServers(virNetServerPtr server
ATTRIBUTE_UNUSED,
VIR_FREE(servers);
return rv;
}
+
+static int
+adminDispatchConnectServerLookupByName(virNetServerPtr server ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client,
+ virNetMessagePtr msg ATTRIBUTE_UNUSED,
+ virNetMessageErrorPtr rerr,
+ struct admin_connect_server_lookup_by_name_args
*args,
+ struct admin_connect_server_lookup_by_name_ret
*ret)
+{
+ int rv = -1;
+ virAdmServerPtr srv = NULL;
+ struct daemonAdmClientPrivate *priv =
+ virNetServerClientGetPrivateData(client);
+
+ if (!(srv = adminDaemonLookupServerByName(priv->dmn, args->name)))
+ goto cleanup;
+
+ make_nonnull_server(&ret->server, srv);
+ rv = 0;
+
+ cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ virObjectUnref(srv);
+ return rv;
+}
#include "admin_dispatch.h"
diff --git a/daemon/admin_server.c b/daemon/admin_server.c
index 0196bfe..de8bc71 100644
--- a/daemon/admin_server.c
+++ b/daemon/admin_server.c
@@ -72,3 +72,20 @@ adminDaemonListServers(virNetDaemonPtr dmn,
virObjectListFree(srvs);
return ret;
}
+
+virAdmServerPtr
+adminDaemonLookupServerByName(virNetDaemonPtr dmn,
+ const char *name)
+{
+ virNetServerPtr srv = NULL;
+
+ if (!(srv = virNetDaemonGetServer(dmn, name))) {
+ virReportError(VIR_ERR_NO_SERVER,
+ _("no server with matching name '%s' found"),
+ name);
+ return NULL;
+ }
+
+ virObjectUnref(srv);
+ return virAdmGetServer(NULL, name);
+}
diff --git a/daemon/admin_server.h b/daemon/admin_server.h
index 2a5aa16..385c3e4 100644
--- a/daemon/admin_server.h
+++ b/daemon/admin_server.h
@@ -31,4 +31,8 @@ adminDaemonListServers(virNetDaemonPtr dmn,
virAdmServerPtr **servers,
unsigned int flags);
+virAdmServerPtr
+adminDaemonLookupServerByName(virNetDaemonPtr dmn,
+ const char *name);
+
#endif /* __LIBVIRTD_ADMIN_SERVER_H__ */
diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h
index e9ec394..1f62a4d 100644
--- a/include/libvirt/libvirt-admin.h
+++ b/include/libvirt/libvirt-admin.h
@@ -106,6 +106,8 @@ int virAdmConnectUnregisterCloseCallback(virAdmConnectPtr conn,
const char *virAdmServerGetName(virAdmServerPtr srv);
+virAdmServerPtr virAdmConnectServerLookupByName(virAdmConnectPtr conn,
+ const char *name);
# ifdef __cplusplus
}
# endif
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index c6d1a76..90621aa 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -310,6 +310,7 @@ typedef enum {
CPU*/
VIR_ERR_XML_INVALID_SCHEMA = 92, /* XML document doesn't validate against
schema */
VIR_ERR_MIGRATE_FINISH_OK = 93, /* Finish API succeeded but it is expected to
return NULL */
+ VIR_ERR_NO_SERVER = 94, /* server with matching name not found */
} virErrorNumber;
/**
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ff207cb..27980df 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,5 +1,6 @@
-daemon/admin_dispatch.h
daemon/admin.c
+daemon/admin_dispatch.h
+daemon/admin_server.c
daemon/libvirtd-config.c
daemon/libvirtd.c
daemon/qemu_dispatch.h
diff --git a/src/admin/admin_protocol.x b/src/admin/admin_protocol.x
index 7b0a3b3..09b9c7d 100644
--- a/src/admin/admin_protocol.x
+++ b/src/admin/admin_protocol.x
@@ -89,6 +89,14 @@ struct admin_connect_list_servers_ret {
unsigned int ret;
};
+struct admin_connect_server_lookup_by_name_args {
+ admin_nonnull_string name;
+};
+
+struct admin_connect_server_lookup_by_name_ret {
+ admin_nonnull_server server;
+};
+
/* Define the program number, protocol version and procedure numbers here. */
const ADMIN_PROGRAM = 0x06900690;
const ADMIN_PROTOCOL_VERSION = 1;
@@ -130,5 +138,10 @@ enum admin_procedure {
* @generate: none
* @priority: high
*/
- ADMIN_PROC_CONNECT_LIST_SERVERS = 4
+ ADMIN_PROC_CONNECT_LIST_SERVERS = 4,
+
+ /**
+ * @generate: none
+ */
+ ADMIN_PROC_CONNECT_SERVER_LOOKUP_BY_NAME = 5
};
diff --git a/src/admin/admin_remote.c b/src/admin/admin_remote.c
index 3745b9e..570dce4 100644
--- a/src/admin/admin_remote.c
+++ b/src/admin/admin_remote.c
@@ -287,3 +287,30 @@ remoteAdminConnectListServers(virAdmConnectPtr conn,
virObjectUnlock(priv);
return rv;
}
+
+static virAdmServerPtr
+remoteAdminConnectServerLookupByName(virAdmConnectPtr conn,
+ const char *srvname)
+{
+ virAdmServerPtr rv = NULL;
+ remoteAdminPrivPtr priv = conn->privateData;
+ admin_connect_server_lookup_by_name_args args;
+ admin_connect_server_lookup_by_name_ret ret;
+
+ args.name = (char *) srvname;
+ memset(&ret, 0, sizeof(ret));
+
+ virObjectLock(priv);
+
+ if (call(conn, 0, ADMIN_PROC_CONNECT_SERVER_LOOKUP_BY_NAME,
+ (xdrproc_t)xdr_admin_connect_server_lookup_by_name_args, (char *)
&args,
+ (xdrproc_t)xdr_admin_connect_server_lookup_by_name_ret, (char *) &ret)
== -1)
+ goto cleanup;
+
+ rv = get_nonnull_server(conn, ret.server);
+ xdr_free((xdrproc_t)xdr_admin_connect_server_lookup_by_name_ret, (char *) &ret);
+
+ cleanup:
+ virObjectUnlock(priv);
+ return rv;
+}
diff --git a/src/admin_protocol-structs b/src/admin_protocol-structs
index 7153a89..141de25 100644
--- a/src/admin_protocol-structs
+++ b/src/admin_protocol-structs
@@ -44,9 +44,16 @@ struct admin_connect_list_servers_ret {
} servers;
u_int ret;
};
+struct admin_connect_server_lookup_by_name_args {
+ admin_nonnull_string name;
+};
+struct admin_connect_server_lookup_by_name_ret {
+ admin_nonnull_server server;
+};
enum admin_procedure {
ADMIN_PROC_CONNECT_OPEN = 1,
ADMIN_PROC_CONNECT_CLOSE = 2,
ADMIN_PROC_CONNECT_GET_LIB_VERSION = 3,
ADMIN_PROC_CONNECT_LIST_SERVERS = 4,
+ ADMIN_PROC_CONNECT_SERVER_LOOKUP_BY_NAME = 5,
};
diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c
index 3667444..d09c015 100644
--- a/src/libvirt-admin.c
+++ b/src/libvirt-admin.c
@@ -633,3 +633,34 @@ virAdmConnectListServers(virAdmConnectPtr conn,
virDispatchError(NULL);
return -1;
}
+
+/**
+ * virAdmConnectServerLookupByName:
+ * @conn: daemon connection reference
+ * @name: name of the server which the method will look for
+ *
+ * Method looks up and returns a server object based on its name.
+ *
+ * Returns handle to server object or NULL in case of an error.
+ */
+virAdmServerPtr
+virAdmConnectServerLookupByName(virAdmConnectPtr conn,
+ const char *name)
+{
+ virAdmServerPtr ret = NULL;
+
+ VIR_DEBUG("conn=%p, name=%s", conn, name);
+
+ virResetLastError();
+
+ virCheckAdmConnectReturn(conn, NULL);
+ virCheckNonNullArgGoto(name, error);
+
+ if (!(ret = remoteAdminConnectServerLookupByName(conn, name)))
+ goto error;
+
+ return ret;
+ error:
+ virDispatchError(NULL);
+ return NULL;
+}
diff --git a/src/libvirt_admin_private.syms b/src/libvirt_admin_private.syms
index f22137b..cdd2203 100644
--- a/src/libvirt_admin_private.syms
+++ b/src/libvirt_admin_private.syms
@@ -10,6 +10,8 @@ xdr_admin_connect_get_lib_version_ret;
xdr_admin_connect_list_servers_args;
xdr_admin_connect_list_servers_ret;
xdr_admin_connect_open_args;
+xdr_admin_connect_server_lookup_by_name_args;
+xdr_admin_connect_server_lookup_by_name_ret;
# datatypes.h
virAdmConnectClass;
diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms
index 52ff2dc..84936c2 100644
--- a/src/libvirt_admin_public.syms
+++ b/src/libvirt_admin_public.syms
@@ -20,6 +20,7 @@ LIBVIRT_ADMIN_1.3.0 {
virAdmConnectGetURI;
virAdmConnectGetLibVersion;
virAdmConnectRegisterCloseCallback;
+ virAdmConnectServerLookupByName;
virAdmConnectUnregisterCloseCallback;
virAdmConnectListServers;
virAdmServerGetName;
diff --git a/src/util/virerror.c b/src/util/virerror.c
index e1bcf52..0acc914 100644
--- a/src/util/virerror.c
+++ b/src/util/virerror.c
@@ -1374,6 +1374,12 @@ virErrorMsg(virErrorNumber error, const char *info)
case VIR_ERR_MIGRATE_FINISH_OK:
errmsg = _("migration successfully aborted");
break;
+ case VIR_ERR_NO_SERVER:
+ if (info == NULL)
+ errmsg = _("Server not found");
+ else
+ errmsg = _("Server not found: %s");
+ break;
}
return errmsg;
}
--
2.4.3