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

Merge remote-tracking branch 'remotes/mdroth/tags/qga-pull-2015-11-25-v2-tag' into staging



qemu-ga patch queue for 2.5

* include additional w32 MSI install components needed for
  guest-exec
* fix 'make install' when compiling with --disable-tools
* fix potential data corruption/loss when accessing files
  bi-directionally via guest-file-{read,write}
* explicitly document how integer args for guest-file-seek map to
  SEEK_SET/SEEK_CUR/etc to avoid platform-specific differences

v2:
* fixed missing SoB

# gpg: Signature made Wed 25 Nov 2015 23:58:45 GMT 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-11-25-v2-tag:
  qga: added another non-interactive gspawn() helper file.
  qga: Better mapping of SEEK_* in guest-file-seek
  tests: add file-write-read test
  qga: flush explicitly when needed
  qga: gspawn() console helper to Windows guest agent msi build
  makefile: fix qemu-ga make install for --disable-tools

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 7ef7ddf3 44c6e00c
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -440,10 +440,7 @@ endif
install: all $(if $(BUILD_DOCS),install-doc) \
install-datadir install-localstatedir
ifneq ($(TOOLS),)
	$(call install-prog,$(filter-out qemu-ga,$(TOOLS)),$(DESTDIR)$(bindir))
ifneq (,$(findstring qemu-ga,$(TOOLS)))
	$(call install-prog,qemu-ga$(EXESUF),$(DESTDIR)$(bindir))
endif
	$(call install-prog,$(subst qemu-ga,qemu-ga$(EXESUF),$(TOOLS)),$(DESTDIR)$(bindir))
endif
ifneq ($(CONFIG_MODULES),)
	$(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)"
+55 −1
Original line number Diff line number Diff line
@@ -216,9 +216,16 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
    }
}

typedef enum {
    RW_STATE_NEW,
    RW_STATE_READING,
    RW_STATE_WRITING,
} RwState;

typedef struct GuestFileHandle {
    uint64_t id;
    FILE *fh;
    RwState state;
    QTAILQ_ENTRY(GuestFileHandle) next;
} GuestFileHandle;

@@ -460,6 +467,17 @@ struct GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,
    }

    fh = gfh->fh;

    /* explicitly flush when switching from writing to reading */
    if (gfh->state == RW_STATE_WRITING) {
        int ret = fflush(fh);
        if (ret == EOF) {
            error_setg_errno(errp, errno, "failed to flush file");
            return NULL;
        }
        gfh->state = RW_STATE_NEW;
    }

    buf = g_malloc0(count+1);
    read_count = fread(buf, 1, count, fh);
    if (ferror(fh)) {
@@ -473,6 +491,7 @@ struct GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,
        if (read_count) {
            read_data->buf_b64 = g_base64_encode(buf, read_count);
        }
        gfh->state = RW_STATE_READING;
    }
    g_free(buf);
    clearerr(fh);
@@ -496,6 +515,16 @@ GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
    }

    fh = gfh->fh;

    if (gfh->state == RW_STATE_READING) {
        int ret = fseek(fh, 0, SEEK_CUR);
        if (ret == -1) {
            error_setg_errno(errp, errno, "failed to seek file");
            return NULL;
        }
        gfh->state = RW_STATE_NEW;
    }

    buf = g_base64_decode(buf_b64, &buf_len);

    if (!has_count) {
@@ -515,6 +544,7 @@ GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
        write_data = g_new0(GuestFileWrite, 1);
        write_data->count = write_count;
        write_data->eof = feof(fh);
        gfh->state = RW_STATE_WRITING;
    }
    g_free(buf);
    clearerr(fh);
@@ -523,25 +553,47 @@ GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
}

struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
                                          int64_t whence, Error **errp)
                                          int64_t whence_code, Error **errp)
{
    GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
    GuestFileSeek *seek_data = NULL;
    FILE *fh;
    int ret;
    int whence;

    if (!gfh) {
        return NULL;
    }

    /* We stupidly exposed 'whence':'int' in our qapi */
    switch (whence_code) {
    case QGA_SEEK_SET:
        whence = SEEK_SET;
        break;
    case QGA_SEEK_CUR:
        whence = SEEK_CUR;
        break;
    case QGA_SEEK_END:
        whence = SEEK_END;
        break;
    default:
        error_setg(errp, "invalid whence code %"PRId64, whence_code);
        return NULL;
    }

    fh = gfh->fh;
    ret = fseek(fh, offset, whence);
    if (ret == -1) {
        error_setg_errno(errp, errno, "failed to seek file");
        if (errno == ESPIPE) {
            /* file is non-seekable, stdio shouldn't be buffering anyways */
            gfh->state = RW_STATE_NEW;
        }
    } else {
        seek_data = g_new0(GuestFileSeek, 1);
        seek_data->position = ftell(fh);
        seek_data->eof = feof(fh);
        gfh->state = RW_STATE_NEW;
    }
    clearerr(fh);

@@ -562,6 +614,8 @@ void qmp_guest_file_flush(int64_t handle, Error **errp)
    ret = fflush(fh);
    if (ret == EOF) {
        error_setg_errno(errp, errno, "failed to flush file");
    } else {
        gfh->state = RW_STATE_NEW;
    }
}

+19 −1
Original line number Diff line number Diff line
@@ -382,7 +382,7 @@ done:
}

GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
                                   int64_t whence, Error **errp)
                                   int64_t whence_code, Error **errp)
{
    GuestFileHandle *gfh;
    GuestFileSeek *seek_data;
@@ -390,11 +390,29 @@ GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
    LARGE_INTEGER new_pos, off_pos;
    off_pos.QuadPart = offset;
    BOOL res;
    int whence;

    gfh = guest_file_handle_find(handle, errp);
    if (!gfh) {
        return NULL;
    }

    /* We stupidly exposed 'whence':'int' in our qapi */
    switch (whence_code) {
    case QGA_SEEK_SET:
        whence = SEEK_SET;
        break;
    case QGA_SEEK_CUR:
        whence = SEEK_CUR;
        break;
    case QGA_SEEK_END:
        whence = SEEK_END;
        break;
    default:
        error_setg(errp, "invalid whence code %"PRId64, whence_code);
        return NULL;
    }

    fh = gfh->fh;
    res = SetFilePointerEx(fh, off_pos, &new_pos, whence);
    if (!res) {
+7 −0
Original line number Diff line number Diff line
@@ -15,6 +15,13 @@

#define QGA_READ_COUNT_DEFAULT 4096

/* Mapping of whence codes used by guest-file-seek. */
enum {
    QGA_SEEK_SET = 0,
    QGA_SEEK_CUR = 1,
    QGA_SEEK_END = 2,
};

typedef struct GAState GAState;
typedef struct GACommandState GACommandState;
extern GAState *ga_state;
+18 −0
Original line number Diff line number Diff line
@@ -91,6 +91,22 @@
            <File Id="qga_vss.tlb" Name="qga-vss.tlb" Source="$(env.BUILD_DIR)/qga/vss-win32/qga-vss.tlb" KeyPath="yes" DiskId="1"/>
          </Component>
          <?endif?>
          <?if $(var.Arch) = "32"?>
          <Component Id="gspawn-helper-console" Guid="{446185B3-87BE-43D2-96B8-0FEFD9E8696D}">
            <File Id="gspawn-win32-helper-console.exe" Name="gspawn-win32-helper-console.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper-console.exe" KeyPath="yes" DiskId="1"/>
          </Component>
          <Component Id="gspawn-helper" Guid="{CD67A5A3-2DB1-4DA1-A67A-8D71E797B466}">
            <File Id="gspawn-win32-helper.exe" Name="gspawn-win32-helper.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper.exe" KeyPath="yes" DiskId="1"/>
          </Component>
          <?endif?>
          <?if $(var.Arch) = "64"?>
          <Component Id="gspawn-helper-console" Guid="{9E615A9F-349A-4992-A5C2-C10BAD173660}">
            <File Id="gspawn-win64-helper-console.exe" Name="gspawn-win64-helper-console.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper-console.exe" KeyPath="yes" DiskId="1"/>
          </Component>
          <Component Id="gspawn-helper" Guid="{D201AD22-1846-4E4F-B6E1-C7A908ED2457}">
            <File Id="gspawn-win64-helper.exe" Name="gspawn-win64-helper.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper.exe" KeyPath="yes" DiskId="1"/>
          </Component>
          <?endif?>
          <Component Id="iconv" Guid="{35EE3558-D34B-4F0A-B8BD-430FF0775246}">
            <File Id="iconv.dll" Name="iconv.dll" Source="$(var.Mingw_bin)/iconv.dll" KeyPath="yes" DiskId="1"/>
          </Component>
@@ -148,6 +164,8 @@
      <ComponentRef Id="qga_vss_dll" />
      <ComponentRef Id="qga_vss_tlb" />
      <?endif?>
      <ComponentRef Id="gspawn-helper-console" />
      <ComponentRef Id="gspawn-helper" />
      <ComponentRef Id="iconv" />
      <ComponentRef Id="libgcc_arch_lib" />
      <ComponentRef Id="libglib" />
Loading