diff --git a/ChangeLog b/ChangeLog index b80ef0b113..8cc8e4bab9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,12 @@ +Thu Dec 8 14:25:09 CET 2005 Daniel Veillard + + * configure.in: activate pedantic flags + * src/libvir.c src/libvir_sym.version src/xen_internal.[ch] + include/libvir.h: implementing hypervisor Version and Type interfaces + * src/virsh.c: adding a version command, WIP + Thu Dec 8 11:19:48 CET 2005 Karel Zak + * src/Makefile.am src/virsh.c configure.in: adding readline support, and implement basic commands to virsh. diff --git a/configure.in b/configure.in index 78148e0abe..d735b1b85c 100644 --- a/configure.in +++ b/configure.in @@ -65,15 +65,19 @@ dnl dnl specific tests to setup DV devel environments with debug etc ... dnl if [[ "${LOGNAME}" = "veillard" -a "`pwd`" = "/u/veillard/libvir" ]] ; then - if test "${GCC}" = "yes" ; then - CFLAGS="-g -O -W -Wformat -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls -Wall" - fi STATIC_BINARIES="-static" else STATIC_BINARIES= fi AC_SUBST(STATIC_BINARIES) +dnl +dnl make CFLAGS very pedantic at least during the devel phase for everybody +dnl + if test "${GCC}" = "yes" ; then + CFLAGS="-g -O -W -Wformat -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls -Wall" + fi + dnl search for the low level Xen library AC_SEARCH_LIBS(xs_read, [xenstore], [], [AC_MSG_ERROR([Xen store library not found])]) diff --git a/include/libvir.h b/include/libvir.h index 86d0e60875..581d57ed1f 100644 --- a/include/libvir.h +++ b/include/libvir.h @@ -115,6 +115,7 @@ typedef enum { virConnectPtr virConnectOpen (const char *name); virConnectPtr virConnectOpenReadOnly (const char *name); int virConnectClose (virConnectPtr conn); +const char * virConnectGetType (virConnectPtr conn); unsigned long virConnectGetVersion (virConnectPtr conn); /* diff --git a/src/libvir.c b/src/libvir.c index 52c82fbcd7..5bfca607de 100644 --- a/src/libvir.c +++ b/src/libvir.c @@ -193,20 +193,47 @@ virConnectClose(virConnectPtr conn) { return(0); } +/** + * virConnectGetType: + * @conn: pointer to the hypervisor connection + * + * Get the name of the Hypervisor software used. + * + * Returns NULL in case of error, a static zero terminated string otherwise. + */ +const char * +virConnectGetType(virConnectPtr conn) { + if (conn == NULL) + return(NULL); + + return("Xen"); +} + /** * virConnectGetVersion: * @conn: pointer to the hypervisor connection * - * Get the version level of the Hypervisor running. + * Get the version level of the Hypervisor running. This may work only with + * hypervisor call, i.e. with priviledged access to the hypervisor, not + * with a Read-Only connection. * - * Returns -1 in case of error or major * 10,000 + minor * 100 + rev otherwise + * Returns -1 in case of error, 0 if the version can't be extracted by lack + * of capacities otherwise major * 1,000,000 + minor * 1,000 + release */ unsigned long virConnectGetVersion(virConnectPtr conn) { + unsigned long ver, ret; + if (conn == NULL) return(-1); - TODO - return(-1); + + /* this can't be extracted from the Xenstore */ + if (conn->handle < 0) + return(0); + + ver = xenHypervisorGetVersion(conn->handle); + ret = (ver >> 16) * 1000000 + (ver & 0xFFFF) * 1000; + return(ret); } /** diff --git a/src/libvir_sym.version b/src/libvir_sym.version index fb312815f2..7fa7d7c3bd 100644 --- a/src/libvir_sym.version +++ b/src/libvir_sym.version @@ -12,6 +12,7 @@ virDomainGetInfo; virDomainGetMaxMemory; virDomainGetName; + virConnectGetType; virDomainLookupByID; virDomainLookupByName; virDomainResume; diff --git a/src/virsh.c b/src/virsh.c index 0ea7721aff..a9659a6eaa 100644 --- a/src/virsh.c +++ b/src/virsh.c @@ -191,6 +191,7 @@ static vshCmdInfo info_help[] = { { "syntax", "help []" }, { "help", "print help" }, { "desc", "Prints global help or command specific help." }, + { "version", "Prints versionning informations." }, { NULL, NULL } }; @@ -490,6 +491,55 @@ cmdIdof(vshControl *ctl, vshCmd *cmd) { return TRUE; } +/* + * "version" command + */ +static vshCmdInfo info_version[] = { + { "syntax", "version" }, + { "help", "show versions" }, + { "desc", "Display the version informations available" }, + { NULL, NULL } +}; + + +static int +cmdVersion(vshControl *ctl, vshCmd *cmd) { + unsigned long hvVersion; + const char *hvType; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; + + hvType = virConnectGetType(ctl->conn); + if (hvType == NULL) { + vshError(ctl, FALSE, "Failed to get hypervisor type\n"); + return FALSE; + } + + hvVersion = virConnectGetVersion(ctl->conn); + if (hvVersion < 0) { + vshError(ctl, FALSE, "failed get hypervisor version"); + return FALSE; + } + if (hvVersion == 0) { + vshPrint(ctl, VSH_MESG, + "Cannot extract running %s hypervisor version\n", + hvType); + } else { + unsigned int major = hvVersion / 1000000; + unsigned int minor; + unsigned int rel; + + hvVersion %= 1000000; + minor = hvVersion / 1000000; + rel = hvVersion % 1000000; + + vshPrint(ctl, VSH_MESG, "Running hypervisor: %s %d.%d.%d\n", hvType, + major, minor, rel); + } + return TRUE; +} + /* * "quit" command */ @@ -516,6 +566,7 @@ static vshCmdDef commands[] = { { "idof", cmdIdof, opts_idof, info_idof }, { "list", cmdList, NULL, info_list }, { "nameof", cmdNameof, opts_nameof, info_nameof }, + { "version", cmdVersion, NULL, info_version }, { "quit", cmdQuit, NULL, info_quit }, { NULL, NULL, NULL, NULL } }; diff --git a/src/xen_internal.c b/src/xen_internal.c index 0eb49b6dda..0119dac544 100644 --- a/src/xen_internal.c +++ b/src/xen_internal.c @@ -19,6 +19,7 @@ #include #include +#include #include #ifndef __LINUX_PUBLIC_PRIVCMD_H__ @@ -106,6 +107,36 @@ xenHypervisorDoOp(int handle, dom0_op_t *op) { return(0); } +/** + * xenHypervisorGetVersion: + * @handle: the handle to the Xen hypervisor + * + * Call the hypervisor to extracts his own internal API version + * + * Returns the hypervisor running version or 0 in case of error. + */ +unsigned long +xenHypervisorGetVersion(int handle) { + int ret; + unsigned int cmd; + hypercall_t hc; + + hc.op = __HYPERVISOR_xen_version; + hc.arg[0] = (unsigned long) XENVER_version; + hc.arg[1] = 0; + + cmd = _IOC(_IOC_NONE, 'P', 0, sizeof(hc)); + ret = ioctl(handle, cmd, (unsigned long) &hc); + + if (ret < 0) + return(0); + /* + * use unsigned long in case the version grows behind expectations + * allowed by int + */ + return((unsigned long) ret); +} + /** * xenHypervisorGetDomainInfo: * @handle: the handle to the Xen hypervisor diff --git a/src/xen_internal.h b/src/xen_internal.h index f4bc39d215..ac40a5f4b3 100644 --- a/src/xen_internal.h +++ b/src/xen_internal.h @@ -11,7 +11,9 @@ #ifndef __VIR_XEN_INTERNAL_H__ #define __VIR_XEN_INTERNAL_H__ +/* required for uint8_t, uint32_t, etc ... */ #include +/* required for dom0_getdomaininfo_t */ #include #ifdef __cplusplus @@ -20,6 +22,7 @@ extern "C" { int xenHypervisorOpen (void); int xenHypervisorClose (int handle); +unsigned long xenHypervisorGetVersion (int handle); int xenHypervisorGetDomainInfo (int handle, int domain, dom0_getdomaininfo_t *info);