Patchwork Add guest-get-hostname to retrieve the guests current hostname

login
register
mail settings
Submitter Guido Günther
Date Aug. 21, 2012, 11:57 a.m.
Message ID <20120821115754.GA5855@bogon.sigxcpu.org>
Download mbox | patch
Permalink /patch/179103/
State New
Headers show

Comments

Guido Günther - Aug. 21, 2012, 11:57 a.m.
This allows to retrieve the guest's hostname via gethostname(2).

This can be useful to identify a VM e.g. one without network.

Signed-off-by: Guido Günther <agx@sigxcpu.org>
---
We have an API in libvirt for that (virDomainGetHostname).
Cheers
 -- Guido

 qapi-schema-guest.json |   12 ++++++++++++
 qga/commands-posix.c   |   12 ++++++++++++
 qga/commands-win32.c   |    6 ++++++
 3 files changed, 30 insertions(+)
Daniel P. Berrange - Aug. 21, 2012, 6:31 p.m.
On Tue, Aug 21, 2012 at 01:57:54PM +0200, Guido Günther wrote:
> This allows to retrieve the guest's hostname via gethostname(2).
> 
> This can be useful to identify a VM e.g. one without network.
> 
> Signed-off-by: Guido Günther <agx@sigxcpu.org>
> ---
> We have an API in libvirt for that (virDomainGetHostname).
> Cheers
>  -- Guido
> 
>  qapi-schema-guest.json |   12 ++++++++++++
>  qga/commands-posix.c   |   12 ++++++++++++
>  qga/commands-win32.c   |    6 ++++++
>  3 files changed, 30 insertions(+)
> 
> diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json
> index d955cf1..8c7a4a5 100644
> --- a/qapi-schema-guest.json
> +++ b/qapi-schema-guest.json
> @@ -515,3 +515,15 @@
>  ##
>  { 'command': 'guest-network-get-interfaces',
>    'returns': ['GuestNetworkInterface'] }
> +
> +##
> +# @guest-get-hostname:
> +#
> +# Get the guest's hostname
> +#
> +# Returns: The guest's hostname
> +#
> +# Since: 1.2
> +##
> +{ 'command': 'guest-get-hostname',
> +  'returns': 'str' }
> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index ce90421..9223f18 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c
> @@ -15,6 +15,7 @@
>  #include <sys/types.h>
>  #include <sys/ioctl.h>
>  #include <sys/wait.h>
> +#include <unistd.h>
>  #include "qga/guest-agent-core.h"
>  #include "qga-qmp-commands.h"
>  #include "qerror.h"
> @@ -993,6 +994,17 @@ void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err)
>  }
>  #endif
>  
> +char *qmp_guest_get_hostname(Error **err)
> +{
> +    char hostname[HOST_NAME_MAX];
> +
> +    if (gethostname(hostname, HOST_NAME_MAX)) {
> +        error_set(err, QERR_QGA_COMMAND_FAILED, strerror(errno));
> +        return NULL;
> +    }
> +    return g_strdup(hostname);
> +}
> +
>  /* register init/cleanup routines for stateful command groups */
>  void ga_command_state_init(GAState *s, GACommandState *cs)
>  {
> diff --git a/qga/commands-win32.c b/qga/commands-win32.c
> index 54bc546..55e8162 100644
> --- a/qga/commands-win32.c
> +++ b/qga/commands-win32.c
> @@ -280,6 +280,12 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **err)
>      return NULL;
>  }
>  
> +char *qmp_guest_get_hostname(Error **err)
> +{
> +    error_set(err, QERR_UNSUPPORTED);
> +    return NULL;
> +}

Why no impl ?  Winsock has the gethostname() API too

$ grep gethostname /usr/i686-w64-mingw32/sys-root/mingw/include/*.h
/usr/i686-w64-mingw32/sys-root/mingw/include/winsock2.h:  WINSOCK_API_LINKAGE int WSAAPI gethostname(char *name,int namelen);

Regards,
Daniel
Eric Blake - Aug. 21, 2012, 7:16 p.m.
On 08/21/2012 05:57 AM, Guido Günther wrote:
> This allows to retrieve the guest's hostname via gethostname(2).
> 
> This can be useful to identify a VM e.g. one without network.
> 
> Signed-off-by: Guido Günther <agx@sigxcpu.org>
> ---
> We have an API in libvirt for that (virDomainGetHostname).
> Cheers
>  -- Guido

Still, this feels like a new feature and not a bug fix, so

> +
> +##
> +# @guest-get-hostname:
> +#
> +# Get the guest's hostname
> +#
> +# Returns: The guest's hostname
> +#
> +# Since: 1.2

...this should probably be 1.3.
Guido Günther - Aug. 22, 2012, 8:04 a.m.
On Tue, Aug 21, 2012 at 07:31:17PM +0100, Daniel P. Berrange wrote:
> On Tue, Aug 21, 2012 at 01:57:54PM +0200, Guido Günther wrote:
[..snip..]
> 
> Why no impl ?  Winsock has the gethostname() API too
> 
> $ grep gethostname /usr/i686-w64-mingw32/sys-root/mingw/include/*.h
> /usr/i686-w64-mingw32/sys-root/mingw/include/winsock2.h:  WINSOCK_API_LINKAGE int WSAAPI gethostname(char *name,int namelen);

This was mostly due to the lack of a test system. Are there any pointers
on how to cross compile qemu-qa for Windows?
Cheers,
 -- Guido

> 
> Regards,
> Daniel
> -- 
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
> |: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|
>
Daniel P. Berrange - Aug. 22, 2012, 8:32 a.m.
On Wed, Aug 22, 2012 at 10:04:33AM +0200, Guido Günther wrote:
> On Tue, Aug 21, 2012 at 07:31:17PM +0100, Daniel P. Berrange wrote:
> > On Tue, Aug 21, 2012 at 01:57:54PM +0200, Guido Günther wrote:
> [..snip..]
> > 
> > Why no impl ?  Winsock has the gethostname() API too
> > 
> > $ grep gethostname /usr/i686-w64-mingw32/sys-root/mingw/include/*.h
> > /usr/i686-w64-mingw32/sys-root/mingw/include/winsock2.h:  WINSOCK_API_LINKAGE int WSAAPI gethostname(char *name,int namelen);
> 
> This was mostly due to the lack of a test system. Are there any pointers
> on how to cross compile qemu-qa for Windows?

Assuming you have the Mingw64 toolchain installed, then compilation is just
a case of passing the --cross-prefix arg to configure. eg on Fedora 17 I
would do:

  ./configure --target-list=x86_64-softmmu --cross-prefix=i686-w64-mingw32-

which causes it to use  i686-w64-mingw32-gcc as the compiler

Daniel
Luiz Capitulino - Aug. 23, 2012, 12:48 p.m.
On Tue, 21 Aug 2012 13:57:54 +0200
Guido Günther <agx@sigxcpu.org> wrote:

> This allows to retrieve the guest's hostname via gethostname(2).
> 
> This can be useful to identify a VM e.g. one without network.
> 
> Signed-off-by: Guido Günther <agx@sigxcpu.org>
> ---
> We have an API in libvirt for that (virDomainGetHostname).
> Cheers
>  -- Guido
> 
>  qapi-schema-guest.json |   12 ++++++++++++
>  qga/commands-posix.c   |   12 ++++++++++++
>  qga/commands-win32.c   |    6 ++++++
>  3 files changed, 30 insertions(+)
> 
> diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json
> index d955cf1..8c7a4a5 100644
> --- a/qapi-schema-guest.json
> +++ b/qapi-schema-guest.json
> @@ -515,3 +515,15 @@
>  ##
>  { 'command': 'guest-network-get-interfaces',
>    'returns': ['GuestNetworkInterface'] }
> +
> +##
> +# @guest-get-hostname:
> +#
> +# Get the guest's hostname
> +#
> +# Returns: The guest's hostname
> +#
> +# Since: 1.2

Won't make it for 1.2 because we're in hard-freeze.

> +##
> +{ 'command': 'guest-get-hostname',
> +  'returns': 'str' }
> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index ce90421..9223f18 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c
> @@ -15,6 +15,7 @@
>  #include <sys/types.h>
>  #include <sys/ioctl.h>
>  #include <sys/wait.h>
> +#include <unistd.h>
>  #include "qga/guest-agent-core.h"
>  #include "qga-qmp-commands.h"
>  #include "qerror.h"
> @@ -993,6 +994,17 @@ void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err)
>  }
>  #endif
>  
> +char *qmp_guest_get_hostname(Error **err)
> +{
> +    char hostname[HOST_NAME_MAX];
> +
> +    if (gethostname(hostname, HOST_NAME_MAX)) {
> +        error_set(err, QERR_QGA_COMMAND_FAILED, strerror(errno));

You shouldn't use that macro, you can do something like this instead:

 error_set(err, "can't get hostname: %s", strerror(errno));

Michael, do you think that's fine for new error messages or do you think it's
worth it to add a "guest-agent: " prefix to all guest agent error messages?

> +        return NULL;
> +    }
> +    return g_strdup(hostname);
> +}
> +
>  /* register init/cleanup routines for stateful command groups */
>  void ga_command_state_init(GAState *s, GACommandState *cs)
>  {
> diff --git a/qga/commands-win32.c b/qga/commands-win32.c
> index 54bc546..55e8162 100644
> --- a/qga/commands-win32.c
> +++ b/qga/commands-win32.c
> @@ -280,6 +280,12 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **err)
>      return NULL;
>  }
>  
> +char *qmp_guest_get_hostname(Error **err)
> +{
> +    error_set(err, QERR_UNSUPPORTED);
> +    return NULL;
> +}
> +
>  /* register init/cleanup routines for stateful command groups */
>  void ga_command_state_init(GAState *s, GACommandState *cs)
>  {
Michael Roth - Aug. 23, 2012, 2:08 p.m.
On Thu, Aug 23, 2012 at 09:48:54AM -0300, Luiz Capitulino wrote:
> On Tue, 21 Aug 2012 13:57:54 +0200
> Guido Günther <agx@sigxcpu.org> wrote:
> 
> > This allows to retrieve the guest's hostname via gethostname(2).
> > 
> > This can be useful to identify a VM e.g. one without network.
> > 
> > Signed-off-by: Guido Günther <agx@sigxcpu.org>
> > ---
> > We have an API in libvirt for that (virDomainGetHostname).
> > Cheers
> >  -- Guido
> > 
> >  qapi-schema-guest.json |   12 ++++++++++++
> >  qga/commands-posix.c   |   12 ++++++++++++
> >  qga/commands-win32.c   |    6 ++++++
> >  3 files changed, 30 insertions(+)
> > 
> > diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json
> > index d955cf1..8c7a4a5 100644
> > --- a/qapi-schema-guest.json
> > +++ b/qapi-schema-guest.json
> > @@ -515,3 +515,15 @@
> >  ##
> >  { 'command': 'guest-network-get-interfaces',
> >    'returns': ['GuestNetworkInterface'] }
> > +
> > +##
> > +# @guest-get-hostname:
> > +#
> > +# Get the guest's hostname
> > +#
> > +# Returns: The guest's hostname
> > +#
> > +# Since: 1.2
> 
> Won't make it for 1.2 because we're in hard-freeze.
> 
> > +##
> > +{ 'command': 'guest-get-hostname',
> > +  'returns': 'str' }
> > diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> > index ce90421..9223f18 100644
> > --- a/qga/commands-posix.c
> > +++ b/qga/commands-posix.c
> > @@ -15,6 +15,7 @@
> >  #include <sys/types.h>
> >  #include <sys/ioctl.h>
> >  #include <sys/wait.h>
> > +#include <unistd.h>
> >  #include "qga/guest-agent-core.h"
> >  #include "qga-qmp-commands.h"
> >  #include "qerror.h"
> > @@ -993,6 +994,17 @@ void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err)
> >  }
> >  #endif
> >  
> > +char *qmp_guest_get_hostname(Error **err)
> > +{
> > +    char hostname[HOST_NAME_MAX];
> > +
> > +    if (gethostname(hostname, HOST_NAME_MAX)) {
> > +        error_set(err, QERR_QGA_COMMAND_FAILED, strerror(errno));
> 
> You shouldn't use that macro, you can do something like this instead:
> 
>  error_set(err, "can't get hostname: %s", strerror(errno));
> 
> Michael, do you think that's fine for new error messages or do you think it's
> worth it to add a "guest-agent: " prefix to all guest agent error messages?
> 

I think that's fine. libvirt or QMP (if we integrate the qemu-ga
commands with QMP) can tack on a prefix for cases where we need to distinguish
where in the stack the error occurred, but for direct communication with
qemu-ga it's unambiguous, so might as well save the keystrokes.

> > +        return NULL;
> > +    }
> > +    return g_strdup(hostname);
> > +}
> > +
> >  /* register init/cleanup routines for stateful command groups */
> >  void ga_command_state_init(GAState *s, GACommandState *cs)
> >  {
> > diff --git a/qga/commands-win32.c b/qga/commands-win32.c
> > index 54bc546..55e8162 100644
> > --- a/qga/commands-win32.c
> > +++ b/qga/commands-win32.c
> > @@ -280,6 +280,12 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **err)
> >      return NULL;
> >  }
> >  
> > +char *qmp_guest_get_hostname(Error **err)
> > +{
> > +    error_set(err, QERR_UNSUPPORTED);
> > +    return NULL;
> > +}
> > +
> >  /* register init/cleanup routines for stateful command groups */
> >  void ga_command_state_init(GAState *s, GACommandState *cs)
> >  {
> 
>
Guido Günther - Aug. 24, 2012, 3:31 p.m.
On Wed, Aug 22, 2012 at 09:32:02AM +0100, Daniel P. Berrange wrote:
> On Wed, Aug 22, 2012 at 10:04:33AM +0200, Guido Günther wrote:
> > On Tue, Aug 21, 2012 at 07:31:17PM +0100, Daniel P. Berrange wrote:
> > > On Tue, Aug 21, 2012 at 01:57:54PM +0200, Guido Günther wrote:
> > [..snip..]
> > > 
> > > Why no impl ?  Winsock has the gethostname() API too
> > > 
> > > $ grep gethostname /usr/i686-w64-mingw32/sys-root/mingw/include/*.h
> > > /usr/i686-w64-mingw32/sys-root/mingw/include/winsock2.h:  WINSOCK_API_LINKAGE int WSAAPI gethostname(char *name,int namelen);
> > 
> > This was mostly due to the lack of a test system. Are there any pointers
> > on how to cross compile qemu-qa for Windows?
> 
> Assuming you have the Mingw64 toolchain installed, then compilation is just
> a case of passing the --cross-prefix arg to configure. eg on Fedora 17 I
> would do:
> 
>   ./configure --target-list=x86_64-softmmu --cross-prefix=i686-w64-mingw32-
> 
> which causes it to use  i686-w64-mingw32-gcc as the compiler

That helped! I had to additionally install

mingw32-pkg-config mingw32-zlib mingw32-glib2

to cross build qemu-ga. Howver running this on a win7-pro evaluation
version I get:

.\qemu-ga

<timestamp>: critical: error opening path
<timestamp>: critical: error opening channel
<timestamp>: critical: failed to create guest agent channel
<timestamp>: critical: failed to initialize guest agent channel

qemu-ga is current git while the host is qemu-kvm 1.1.0. The virtio
serial driver is installed in the guest but running the test program
gives errors as well:

.\VIOSER-TEST
Running in non blocking mode.
Cannot find vioserial device \\?\.\{<uuid>}#vioserialport#... , error 5

Libvirt creates the guest agent channel via:

  <channel type='unix'>
      <source mode='bind' path='/var/lib/libvirt/qemu/win7-32.agent'/>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
      <alias name='channel0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
  </channel>

While the same works well with linux guests. Any ideas what I'm missing
on the Windows side?
Cheers,
 -- Guido

> 
> Daniel
> -- 
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
> |: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|
>

Patch

diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json
index d955cf1..8c7a4a5 100644
--- a/qapi-schema-guest.json
+++ b/qapi-schema-guest.json
@@ -515,3 +515,15 @@ 
 ##
 { 'command': 'guest-network-get-interfaces',
   'returns': ['GuestNetworkInterface'] }
+
+##
+# @guest-get-hostname:
+#
+# Get the guest's hostname
+#
+# Returns: The guest's hostname
+#
+# Since: 1.2
+##
+{ 'command': 'guest-get-hostname',
+  'returns': 'str' }
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index ce90421..9223f18 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -15,6 +15,7 @@ 
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/wait.h>
+#include <unistd.h>
 #include "qga/guest-agent-core.h"
 #include "qga-qmp-commands.h"
 #include "qerror.h"
@@ -993,6 +994,17 @@  void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err)
 }
 #endif
 
+char *qmp_guest_get_hostname(Error **err)
+{
+    char hostname[HOST_NAME_MAX];
+
+    if (gethostname(hostname, HOST_NAME_MAX)) {
+        error_set(err, QERR_QGA_COMMAND_FAILED, strerror(errno));
+        return NULL;
+    }
+    return g_strdup(hostname);
+}
+
 /* register init/cleanup routines for stateful command groups */
 void ga_command_state_init(GAState *s, GACommandState *cs)
 {
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 54bc546..55e8162 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -280,6 +280,12 @@  GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **err)
     return NULL;
 }
 
+char *qmp_guest_get_hostname(Error **err)
+{
+    error_set(err, QERR_UNSUPPORTED);
+    return NULL;
+}
+
 /* register init/cleanup routines for stateful command groups */
 void ga_command_state_init(GAState *s, GACommandState *cs)
 {