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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list