Commit f52dd72d authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/mdroth/tags/qga-pull-2015-10-14-v4-tag' into staging



qemu-ga patch queue

* add unit tests for qemu-ga
* add guest-exec support for posix/w32 guests
* added 'qemu-ga' target for w32. this allows us to do full MSI build,
  without overloading 'qemu-ga.exe' target with uneeded dependencies.
* number of s/g_new/g_malloc/ conversions for qga

v2:
* commit message and qapi documentation spelling fixes
* rename 'inp-data' guest-exec param to 'input-data'

v3:
* fix OSX build errors for test-qga by using PRId64
  format in place of glib's, and dropping use of G_SPAWN_DEFAULT
  macro for glib 2.22 compat
* fix win32 build warnings for 32-bit builds by avoid int casts
  of process HANDLEs

v4:
* assert connect_qga() doesn't fail
* only enable test-qga for linux hosts
* allow get-memory-block-info* to fail if memory blocks aren't exposed in
  sysfs

# gpg: Signature made Tue 20 Oct 2015 00:33:43 BST using RSA key ID F108B584
# gpg: Good signature from "Michael Roth <flukshun@gmail.com>"
# gpg:                 aka "Michael Roth <mdroth@utexas.edu>"
# gpg:                 aka "Michael Roth <mdroth@linux.vnet.ibm.com>"

* remotes/mdroth/tags/qga-pull-2015-10-14-v4-tag:
  qga: fix uninitialized value warning for win32
  qga: guest-exec simple stdin/stdout/stderr redirection
  qga: handle G_IO_STATUS_AGAIN in ga_channel_write_all()
  qga: handle possible SIGPIPE in guest-file-write
  qga: guest exec functionality
  qga: drop guest_file_init helper and replace it with static initializers
  tests: add a local test for guest agent
  qga: guest-get-memory-blocks shouldn't fail for unexposed memory blocks
  glib-compat: add 2.38/2.40/2.46 asserts
  qtest: add a few fd-level qmp helpers
  qga: do not override configuration verbosity
  qga: add QGA_CONF environment variable
  qga: Use g_new() & friends where that makes obvious sense
  build: qemu-ga: add 'qemu-ga' build target for w32

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 26c7be84 e853ea1c
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -298,18 +298,15 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)

# we require QGA_VSS_PROVIDER files to be built alongside qemu-ga
# executable since they are shipped together, but we don't want to actually
# link against them
qemu-ga$(EXESUF): $(qga-obj-y) libqemuutil.a libqemustub.a $(QGA_VSS_PROVIDER)
	$(call LINK, $(filter-out $(QGA_VSS_PROVIDER), $^))
qemu-ga$(EXESUF): $(qga-obj-y) libqemuutil.a libqemustub.a
	$(call LINK, $^)

ifdef QEMU_GA_MSI_ENABLED
QEMU_GA_MSI=qemu-ga-$(ARCH).msi

msi: $(QEMU_GA_MSI)

$(QEMU_GA_MSI): qemu-ga.exe
$(QEMU_GA_MSI): qemu-ga.exe $(QGA_VSS_PROVIDER)

$(QEMU_GA_MSI): config-host.mak

@@ -321,6 +318,11 @@ msi:
	@echo "MSI build not configured or dependency resolution failed (reconfigure with --enable-guest-agent-msi option)"
endif

ifneq ($(EXESUF),)
.PHONY: qemu-ga
qemu-ga: qemu-ga$(EXESUF) $(QGA_VSS_PROVIDER) $(QEMU_GA_MSI)
endif

clean:
# avoid old build problems by removing potentially incorrect old files
	rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
+1 −1
Original line number Diff line number Diff line
@@ -4437,7 +4437,7 @@ fi

if [ "$guest_agent" != "no" ]; then
  if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" -o "$mingw32" = "yes" ] ; then
      tools="qemu-ga\$(EXESUF) $tools"
      tools="qemu-ga $tools"
      guest_agent=yes
  elif [ "$guest_agent" != yes ]; then
      guest_agent=no
+61 −0
Original line number Diff line number Diff line
@@ -165,4 +165,65 @@ static inline GThread *g_thread_new(const char *name,
#define CompatGCond GCond
#endif /* glib 2.31 */

#ifndef g_assert_true
#define g_assert_true(expr)                                                    \
    do {                                                                       \
        if (G_LIKELY(expr)) {                                                  \
        } else {                                                               \
            g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC,   \
                                "'" #expr "' should be TRUE");                 \
        }                                                                      \
    } while (0)
#endif

#ifndef g_assert_false
#define g_assert_false(expr)                                                   \
    do {                                                                       \
        if (G_LIKELY(!(expr))) {                                               \
        } else {                                                               \
            g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC,   \
                                "'" #expr "' should be FALSE");                \
        }                                                                      \
    } while (0)
#endif

#ifndef g_assert_null
#define g_assert_null(expr)                                                    \
    do {                                                                       \
        if (G_LIKELY((expr) == NULL)) {                                        \
        } else {                                                               \
            g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC,   \
                                "'" #expr "' should be NULL");                 \
        }                                                                      \
    } while (0)
#endif

#ifndef g_assert_nonnull
#define g_assert_nonnull(expr)                                                 \
    do {                                                                       \
        if (G_LIKELY((expr) != NULL)) {                                        \
        } else {                                                               \
            g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC,   \
                                "'" #expr "' should not be NULL");             \
        }                                                                      \
    } while (0)
#endif

#ifndef g_assert_cmpmem
#define g_assert_cmpmem(m1, l1, m2, l2)                                        \
    do {                                                                       \
        gconstpointer __m1 = m1, __m2 = m2;                                    \
        int __l1 = l1, __l2 = l2;                                              \
        if (__l1 != __l2) {                                                    \
            g_assertion_message_cmpnum(                                        \
                G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC,                   \
                #l1 " (len(" #m1 ")) == " #l2 " (len(" #m2 "))", __l1, "==",   \
                __l2, 'i');                                                    \
        } else if (memcmp(__m1, __m2, __l1) != 0) {                            \
            g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC,   \
                                "assertion failed (" #m1 " == " #m2 ")");      \
        }                                                                      \
    } while (0)
#endif

#endif
+12 −13
Original line number Diff line number Diff line
@@ -217,25 +217,24 @@ GIOStatus ga_channel_write_all(GAChannel *c, const gchar *buf, gsize size)
    GIOStatus status = G_IO_STATUS_NORMAL;

    while (size) {
        g_debug("sending data, count: %d", (int)size);
        status = g_io_channel_write_chars(c->client_channel, buf, size,
                                          &written, &err);
        g_debug("sending data, count: %d", (int)size);
        if (err != NULL) {
        if (status == G_IO_STATUS_NORMAL) {
            size -= written;
            buf += written;
        } else if (status != G_IO_STATUS_AGAIN) {
            g_warning("error writing to channel: %s", err->message);
            return G_IO_STATUS_ERROR;
        }
        if (status != G_IO_STATUS_NORMAL) {
            break;
            return status;
        }
        size -= written;
    }

    if (status == G_IO_STATUS_NORMAL) {
    do {
        status = g_io_channel_flush(c->client_channel, &err);
        if (err != NULL) {
    } while (status == G_IO_STATUS_AGAIN);

    if (status != G_IO_STATUS_NORMAL) {
        g_warning("error flushing channel: %s", err->message);
            return G_IO_STATUS_ERROR;
        }
    }

    return status;
@@ -249,7 +248,7 @@ GIOStatus ga_channel_read(GAChannel *c, gchar *buf, gsize size, gsize *count)
GAChannel *ga_channel_new(GAChannelMethod method, const gchar *path,
                          GAChannelCallback cb, gpointer opaque)
{
    GAChannel *c = g_malloc0(sizeof(GAChannel));
    GAChannel *c = g_new0(GAChannel, 1);
    c->event_cb = cb;
    c->user_data = opaque;

+2 −2
Original line number Diff line number Diff line
@@ -269,7 +269,7 @@ static GIOStatus ga_channel_write(GAChannel *c, const char *buf, size_t size,
GIOStatus ga_channel_write_all(GAChannel *c, const char *buf, size_t size)
{
    GIOStatus status = G_IO_STATUS_NORMAL;
    size_t count;
    size_t count = 0;

    while (size) {
        status = ga_channel_write(c, buf, size, &count);
@@ -322,7 +322,7 @@ static gboolean ga_channel_open(GAChannel *c, GAChannelMethod method,
GAChannel *ga_channel_new(GAChannelMethod method, const gchar *path,
                          GAChannelCallback cb, gpointer opaque)
{
    GAChannel *c = g_malloc0(sizeof(GAChannel));
    GAChannel *c = g_new0(GAChannel, 1);
    SECURITY_ATTRIBUTES sec_attrs;

    if (!ga_channel_open(c, method, path)) {
Loading