From a474371fc635934e9b4a987d28d2f677c84f992f Mon Sep 17 00:00:00 2001 From: Erik Skultety Date: Mon, 5 Oct 2015 17:17:51 +0200 Subject: [PATCH] admin: Introduce virAdmConnectGetLibVersion Introduce a new API to get libvirt version. It is worth noting, that libvirt-admin and libvirt share the same version number. Unfortunately, our existing API isn't generic enough to be used with virAdmConnectPtr as well. Also this patch wires up this API to the virt-admin client as a generic cmdVersion command. --- daemon/admin_server.c | 9 +++++ include/libvirt/libvirt-admin.h | 3 ++ po/POTFILES.in | 1 + src/admin/admin_protocol.x | 11 +++++- src/admin_protocol-structs | 4 ++ src/libvirt-admin.c | 31 +++++++++++++++ src/libvirt_admin_private.syms | 1 + src/libvirt_admin_public.syms | 1 + src/rpc/gendispatch.pl | 11 ++++-- tools/virt-admin.c | 67 +++++++++++++++++++++++++++++++++ 10 files changed, 135 insertions(+), 4 deletions(-) diff --git a/daemon/admin_server.c b/daemon/admin_server.c index 712a44beca..189091e75a 100644 --- a/daemon/admin_server.c +++ b/daemon/admin_server.c @@ -114,4 +114,13 @@ adminDispatchConnectClose(virNetServerPtr server ATTRIBUTE_UNUSED, return 0; } +static int +adminConnectGetLibVersion(virNetDaemonPtr dmn ATTRIBUTE_UNUSED, + unsigned long long *libVer) +{ + if (libVer) + *libVer = LIBVIR_VERSION_NUMBER; + return 0; +} + #include "admin_dispatch.h" diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h index a921b2b15c..ab9df96b35 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -61,6 +61,9 @@ int virAdmGetVersion(unsigned long long *libVer); char *virAdmConnectGetURI(virAdmConnectPtr conn); +int virAdmConnectGetLibVersion(virAdmConnectPtr conn, + unsigned long long *libVer); + /** * virAdmConnectCloseFunc: * @conn: virAdmConnect connection diff --git a/po/POTFILES.in b/po/POTFILES.in index 669322858a..9cc129f06f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,3 +1,4 @@ +daemon/admin_dispatch.h daemon/admin_server.c daemon/libvirtd-config.c daemon/libvirtd.c diff --git a/src/admin/admin_protocol.x b/src/admin/admin_protocol.x index d0ca1a3757..878983d2ec 100644 --- a/src/admin/admin_protocol.x +++ b/src/admin/admin_protocol.x @@ -41,6 +41,10 @@ struct admin_connect_open_args { unsigned int flags; }; +struct admin_connect_get_lib_version_ret { + unsigned hyper libVer; +}; + /* Define the program number, protocol version and procedure numbers here. */ const ADMIN_PROGRAM = 0x06900690; const ADMIN_PROTOCOL_VERSION = 1; @@ -71,5 +75,10 @@ enum admin_procedure { /** * @generate: none */ - ADMIN_PROC_CONNECT_CLOSE = 2 + ADMIN_PROC_CONNECT_CLOSE = 2, + + /** + * @generate: both + */ + ADMIN_PROC_CONNECT_GET_LIB_VERSION = 3 }; diff --git a/src/admin_protocol-structs b/src/admin_protocol-structs index 3ac31fa253..809379be34 100644 --- a/src/admin_protocol-structs +++ b/src/admin_protocol-structs @@ -2,7 +2,11 @@ struct admin_connect_open_args { u_int flags; }; +struct admin_connect_get_lib_version_ret { + uint64_t libVer; +}; enum admin_procedure { ADMIN_PROC_CONNECT_OPEN = 1, ADMIN_PROC_CONNECT_CLOSE = 2, + ADMIN_PROC_CONNECT_GET_LIB_VERSION = 3, }; diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c index 9a5ee303f9..6e6da81b3f 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -523,3 +523,34 @@ int virAdmConnectUnregisterCloseCallback(virAdmConnectPtr conn, virDispatchError(NULL); return -1; } + +/** + * virAdmConnectGetLibVersion: + * @conn: pointer to an active admin connection + * @libVer: stores the current remote libvirt version number + * + * Retrieves the remote side libvirt version used by the daemon. Format + * returned in @libVer is of a following pattern: + * major * 1,000,000 + minor * 1,000 + release. + * + * Returns 0 on success, -1 on failure and @libVer follows this format: + */ +int virAdmConnectGetLibVersion(virAdmConnectPtr conn, + unsigned long long *libVer) +{ + VIR_DEBUG("conn=%p, libVir=%p", conn, libVer); + + virResetLastError(); + + virCheckAdmConnectReturn(conn, -1); + virCheckNonNullArgReturn(libVer, -1); + + if (remoteAdminConnectGetLibVersion(conn, libVer) < 0) + goto error; + + return 0; + + error: + virDispatchError(NULL); + return -1; +} diff --git a/src/libvirt_admin_private.syms b/src/libvirt_admin_private.syms index 401cd4e7f4..85380dcb2f 100644 --- a/src/libvirt_admin_private.syms +++ b/src/libvirt_admin_private.syms @@ -6,6 +6,7 @@ # # admin/admin_protocol.x +xdr_admin_connect_get_lib_version_ret; xdr_admin_connect_open_args; # Let emacs know we want case-insensitive sorting diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms index 511f6ad27f..33b1db45a3 100644 --- a/src/libvirt_admin_public.syms +++ b/src/libvirt_admin_public.syms @@ -18,6 +18,7 @@ LIBVIRT_ADMIN_1.3.0 { virAdmGetVersion; virAdmConnectIsAlive; virAdmConnectGetURI; + virAdmConnectGetLibVersion; virAdmConnectRegisterCloseCallback; virAdmConnectUnregisterCloseCallback; }; diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl index b6d50f393b..5cfc5120b2 100755 --- a/src/rpc/gendispatch.pl +++ b/src/rpc/gendispatch.pl @@ -50,7 +50,7 @@ my $protocol = shift or die "missing protocol argument"; my @autogen; my $connect_ptr = $structprefix eq "admin" ? "virAdmConnectPtr" : "virConnectPtr"; -my $prefix = ($structprefix eq "admin") ? "adm" : "vir"; +my $prefix = ($structprefix eq "admin") ? "admin" : "vir"; sub fixup_name { my $name = shift; @@ -1401,8 +1401,13 @@ elsif ($mode eq "client") { my $ret_name = $1; if ($call->{ProcName} =~ m/Get(Lib)?Version/) { - push(@args_list, "unsigned long *$ret_name"); - push(@ret_list, "if ($ret_name) HYPER_TO_ULONG(*$ret_name, ret.$ret_name);"); + if ($structprefix eq "admin") { + push(@args_list, "unsigned long long *$ret_name"); + push(@ret_list, "*$ret_name = ret.$ret_name;"); + } else { + push(@args_list, "unsigned long *$ret_name"); + push(@ret_list, "if ($ret_name) HYPER_TO_ULONG(*$ret_name, ret.$ret_name);"); + } push(@ret_list, "rv = 0;"); $single_ret_var = "int rv = -1"; $single_ret_type = "int"; diff --git a/tools/virt-admin.c b/tools/virt-admin.c index 9afb332a36..137296357d 100644 --- a/tools/virt-admin.c +++ b/tools/virt-admin.c @@ -197,6 +197,67 @@ cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) return true; } +/* + * "version" command + */ + +static const vshCmdInfo info_version[] = { + {.name = "help", + .data = N_("show version") + }, + {.name = "desc", + .data = N_("Display the system and also the daemon version information.") + }, + {.name = NULL} +}; + +static bool +cmdVersion(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) +{ + unsigned long libVersion; + unsigned long long includeVersion; + unsigned long long daemonVersion; + int ret; + unsigned int major; + unsigned int minor; + unsigned int rel; + vshAdmControlPtr priv = ctl->privData; + + includeVersion = LIBVIR_VERSION_NUMBER; + major = includeVersion / 1000000; + includeVersion %= 1000000; + minor = includeVersion / 1000; + rel = includeVersion % 1000; + vshPrint(ctl, _("Compiled against library: libvirt %d.%d.%d\n"), + major, minor, rel); + + ret = virGetVersion(&libVersion, NULL, NULL); + if (ret < 0) { + vshError(ctl, "%s", _("failed to get the library version")); + return false; + } + major = libVersion / 1000000; + libVersion %= 1000000; + minor = libVersion / 1000; + rel = libVersion % 1000; + vshPrint(ctl, _("Using library: libvirt %d.%d.%d\n"), + major, minor, rel); + + ret = virAdmConnectGetLibVersion(priv->conn, &daemonVersion); + if (ret < 0) { + vshError(ctl, "%s", _("failed to get the daemon version")); + } else { + major = daemonVersion / 1000000; + daemonVersion %= 1000000; + minor = daemonVersion / 1000; + rel = daemonVersion % 1000; + vshPrint(ctl, _("Running against daemon: %d.%d.%d\n"), + major, minor, rel); + } + + return true; +} + /* --------------- * Command Connect @@ -516,6 +577,12 @@ static const vshCmdDef vshAdmCmds[] = { .info = info_uri, .flags = 0 }, + {.name = "version", + .handler = cmdVersion, + .opts = NULL, + .info = info_version, + .flags = 0 + }, {.name = "connect", .handler = cmdConnect, .opts = opts_connect, -- GitLab