* [Qemu-devel] [PATCH v2] qga: Support enum names in guest-file-seek
@ 2015-12-18 17:44 Eric Blake
2016-01-19 16:13 ` Eric Blake
0 siblings, 1 reply; 2+ messages in thread
From: Eric Blake @ 2015-12-18 17:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Michael Roth
Magic constants are a pain to use, especially when we run the
risk that our choice of '1' for QGA_SEEK_CUR might differ from
the host or guest's choice of SEEK_CUR. Better is to use an
enum value, via a qapi alternate type for back-compatibility.
With this,
{"command":"guest-file-seek", "arguments":{"handle":1,
"offset":0, "whence":"cur"}}
becomes a synonym for the older
{"command":"guest-file-seek", "arguments":{"handle":1,
"offset":0, "whence":1}}
Signed-off-by: Eric Blake <eblake@redhat.com>
---
v2: rebase on top of qapi work that has now landed
v1 was here: https://lists.gnu.org/archive/html/qemu-devel/2015-11/msg05730.html
---
qga/commands-posix.c | 19 ++++++-------------
qga/commands-win32.c | 19 ++++++-------------
qga/commands.c | 21 +++++++++++++++++++++
qga/guest-agent-core.h | 9 ++-------
qga/qapi-schema.json | 33 +++++++++++++++++++++++++++++++--
tests/test-qga.c | 9 ++++-----
6 files changed, 70 insertions(+), 40 deletions(-)
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index c2ff970..a8c36aa 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -553,31 +553,24 @@ 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_code, Error **errp)
+ GuestFileWhence *whence_code,
+ Error **errp)
{
GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
GuestFileSeek *seek_data = NULL;
FILE *fh;
int ret;
int whence;
+ Error *err = NULL;
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);
+ whence = ga_parse_whence(whence_code, &err);
+ if (err) {
+ error_propagate(errp, err);
return NULL;
}
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 0654fe4..c6fed1e 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -382,7 +382,8 @@ done:
}
GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
- int64_t whence_code, Error **errp)
+ GuestFileWhence *whence_code,
+ Error **errp)
{
GuestFileHandle *gfh;
GuestFileSeek *seek_data;
@@ -391,6 +392,7 @@ GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
off_pos.QuadPart = offset;
BOOL res;
int whence;
+ Error *err = NULL;
gfh = guest_file_handle_find(handle, errp);
if (!gfh) {
@@ -398,18 +400,9 @@ GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
}
/* 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);
+ whence = ga_parse_whence(whence_code, &err);
+ if (err) {
+ error_propagate(errp, err);
return NULL;
}
diff --git a/qga/commands.c b/qga/commands.c
index bb73e7d..b936d93 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -461,3 +461,24 @@ done:
return ge;
}
+
+/* Convert GuestFileWhence (either a raw integer or an enum value) into
+ * the guest's SEEK_ constants. */
+int ga_parse_whence(GuestFileWhence *whence, Error **errp)
+{
+ /* Exploit the fact that we picked values to match QGA_SEEK_*. */
+ if (whence->type == QTYPE_QSTRING) {
+ whence->type = QTYPE_QINT;
+ whence->u.value = whence->u.name;
+ }
+ switch (whence->u.value) {
+ case QGA_SEEK_SET:
+ return SEEK_SET;
+ case QGA_SEEK_CUR:
+ return SEEK_CUR;
+ case QGA_SEEK_END:
+ return SEEK_END;
+ }
+ error_setg(errp, "invalid whence code %"PRId64, whence->u.value);
+ return -1;
+}
diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h
index 238dc6b..0a49516 100644
--- a/qga/guest-agent-core.h
+++ b/qga/guest-agent-core.h
@@ -12,16 +12,10 @@
*/
#include "qapi/qmp/dispatch.h"
#include "qemu-common.h"
+#include "qga-qmp-commands.h"
#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;
@@ -44,6 +38,7 @@ void ga_set_frozen(GAState *s);
void ga_unset_frozen(GAState *s);
const char *ga_fsfreeze_hook(GAState *s);
int64_t ga_get_fd_handle(GAState *s, Error **errp);
+int ga_parse_whence(GuestFileWhence *whence, Error **errp);
#ifndef _WIN32
void reopen_fd_to_null(int fd);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 01c9ee4..c21f308 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -314,6 +314,34 @@
'data': { 'position': 'int', 'eof': 'bool' } }
##
+# @QGASeek:
+#
+# Symbolic names for use in @guest-file-seek
+#
+# @set: Set to the specified offset (same effect as 'whence':0)
+# @cur: Add offset to the current location (same effect as 'whence':1)
+# @end: Add offset to the end of the file (same effect as 'whence':2)
+#
+# Since: 2.6
+##
+{ 'enum': 'QGASeek', 'data': [ 'set', 'cur', 'end' ] }
+
+##
+# @GuestFileWhence:
+#
+# Controls the meaning of offset to @guest-file-seek.
+#
+# @value: Integral value (0 for set, 1 for cur, 2 for end), available
+# for historical reasons, and might differ from the host's or
+# guest's SEEK_* values (since: 0.15)
+# @name: Symbolic name, and preferred interface
+#
+# Since: 2.6
+##
+{ 'alternate': 'GuestFileWhence',
+ 'data': { 'value': 'int', 'name': 'QGASeek' } }
+
+##
# @guest-file-seek:
#
# Seek to a position in the file, as with fseek(), and return the
@@ -324,14 +352,15 @@
#
# @offset: bytes to skip over in the file stream
#
-# @whence: 0 for SEEK_SET, 1 for SEEK_CUR, or 2 for SEEK_END
+# @whence: Symbolic or numeric code for interpreting offset
#
# Returns: @GuestFileSeek on success.
#
# Since: 0.15.0
##
{ 'command': 'guest-file-seek',
- 'data': { 'handle': 'int', 'offset': 'int', 'whence': 'int' },
+ 'data': { 'handle': 'int', 'offset': 'int',
+ 'whence': 'GuestFileWhence' },
'returns': 'GuestFileSeek' }
##
diff --git a/tests/test-qga.c b/tests/test-qga.c
index e6a84d1..d1d3d9f 100644
--- a/tests/test-qga.c
+++ b/tests/test-qga.c
@@ -13,7 +13,6 @@
#include "libqtest.h"
#include "config-host.h"
-#include "qga/guest-agent-core.h"
typedef struct {
char *test_dir;
@@ -457,8 +456,8 @@ static void test_qga_file_ops(gconstpointer fix)
/* seek */
cmd = g_strdup_printf("{'execute': 'guest-file-seek',"
" 'arguments': { 'handle': %" PRId64 ", "
- " 'offset': %d, 'whence': %d } }",
- id, 6, QGA_SEEK_SET);
+ " 'offset': %d, 'whence': '%s' } }",
+ id, 6, "set");
ret = qmp_fd(fixture->fd, cmd);
qmp_assert_no_error(ret);
val = qdict_get_qdict(ret, "return");
@@ -550,8 +549,8 @@ static void test_qga_file_write_read(gconstpointer fix)
/* seek to 0 */
cmd = g_strdup_printf("{'execute': 'guest-file-seek',"
" 'arguments': { 'handle': %" PRId64 ", "
- " 'offset': %d, 'whence': %d } }",
- id, 0, QGA_SEEK_SET);
+ " 'offset': %d, 'whence': '%s' } }",
+ id, 0, "set");
ret = qmp_fd(fixture->fd, cmd);
qmp_assert_no_error(ret);
val = qdict_get_qdict(ret, "return");
--
2.4.3
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [Qemu-devel] [PATCH v2] qga: Support enum names in guest-file-seek
2015-12-18 17:44 [Qemu-devel] [PATCH v2] qga: Support enum names in guest-file-seek Eric Blake
@ 2016-01-19 16:13 ` Eric Blake
0 siblings, 0 replies; 2+ messages in thread
From: Eric Blake @ 2016-01-19 16:13 UTC (permalink / raw)
To: qemu-devel; +Cc: Michael Roth
[-- Attachment #1: Type: text/plain, Size: 9156 bytes --]
ping
On 12/18/2015 10:44 AM, Eric Blake wrote:
> Magic constants are a pain to use, especially when we run the
> risk that our choice of '1' for QGA_SEEK_CUR might differ from
> the host or guest's choice of SEEK_CUR. Better is to use an
> enum value, via a qapi alternate type for back-compatibility.
>
> With this,
> {"command":"guest-file-seek", "arguments":{"handle":1,
> "offset":0, "whence":"cur"}}
> becomes a synonym for the older
> {"command":"guest-file-seek", "arguments":{"handle":1,
> "offset":0, "whence":1}}
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v2: rebase on top of qapi work that has now landed
> v1 was here: https://lists.gnu.org/archive/html/qemu-devel/2015-11/msg05730.html
> ---
> qga/commands-posix.c | 19 ++++++-------------
> qga/commands-win32.c | 19 ++++++-------------
> qga/commands.c | 21 +++++++++++++++++++++
> qga/guest-agent-core.h | 9 ++-------
> qga/qapi-schema.json | 33 +++++++++++++++++++++++++++++++--
> tests/test-qga.c | 9 ++++-----
> 6 files changed, 70 insertions(+), 40 deletions(-)
>
> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index c2ff970..a8c36aa 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c
> @@ -553,31 +553,24 @@ 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_code, Error **errp)
> + GuestFileWhence *whence_code,
> + Error **errp)
> {
> GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
> GuestFileSeek *seek_data = NULL;
> FILE *fh;
> int ret;
> int whence;
> + Error *err = NULL;
>
> 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);
> + whence = ga_parse_whence(whence_code, &err);
> + if (err) {
> + error_propagate(errp, err);
> return NULL;
> }
>
> diff --git a/qga/commands-win32.c b/qga/commands-win32.c
> index 0654fe4..c6fed1e 100644
> --- a/qga/commands-win32.c
> +++ b/qga/commands-win32.c
> @@ -382,7 +382,8 @@ done:
> }
>
> GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
> - int64_t whence_code, Error **errp)
> + GuestFileWhence *whence_code,
> + Error **errp)
> {
> GuestFileHandle *gfh;
> GuestFileSeek *seek_data;
> @@ -391,6 +392,7 @@ GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
> off_pos.QuadPart = offset;
> BOOL res;
> int whence;
> + Error *err = NULL;
>
> gfh = guest_file_handle_find(handle, errp);
> if (!gfh) {
> @@ -398,18 +400,9 @@ GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
> }
>
> /* 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);
> + whence = ga_parse_whence(whence_code, &err);
> + if (err) {
> + error_propagate(errp, err);
> return NULL;
> }
>
> diff --git a/qga/commands.c b/qga/commands.c
> index bb73e7d..b936d93 100644
> --- a/qga/commands.c
> +++ b/qga/commands.c
> @@ -461,3 +461,24 @@ done:
>
> return ge;
> }
> +
> +/* Convert GuestFileWhence (either a raw integer or an enum value) into
> + * the guest's SEEK_ constants. */
> +int ga_parse_whence(GuestFileWhence *whence, Error **errp)
> +{
> + /* Exploit the fact that we picked values to match QGA_SEEK_*. */
> + if (whence->type == QTYPE_QSTRING) {
> + whence->type = QTYPE_QINT;
> + whence->u.value = whence->u.name;
> + }
> + switch (whence->u.value) {
> + case QGA_SEEK_SET:
> + return SEEK_SET;
> + case QGA_SEEK_CUR:
> + return SEEK_CUR;
> + case QGA_SEEK_END:
> + return SEEK_END;
> + }
> + error_setg(errp, "invalid whence code %"PRId64, whence->u.value);
> + return -1;
> +}
> diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h
> index 238dc6b..0a49516 100644
> --- a/qga/guest-agent-core.h
> +++ b/qga/guest-agent-core.h
> @@ -12,16 +12,10 @@
> */
> #include "qapi/qmp/dispatch.h"
> #include "qemu-common.h"
> +#include "qga-qmp-commands.h"
>
> #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;
> @@ -44,6 +38,7 @@ void ga_set_frozen(GAState *s);
> void ga_unset_frozen(GAState *s);
> const char *ga_fsfreeze_hook(GAState *s);
> int64_t ga_get_fd_handle(GAState *s, Error **errp);
> +int ga_parse_whence(GuestFileWhence *whence, Error **errp);
>
> #ifndef _WIN32
> void reopen_fd_to_null(int fd);
> diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
> index 01c9ee4..c21f308 100644
> --- a/qga/qapi-schema.json
> +++ b/qga/qapi-schema.json
> @@ -314,6 +314,34 @@
> 'data': { 'position': 'int', 'eof': 'bool' } }
>
> ##
> +# @QGASeek:
> +#
> +# Symbolic names for use in @guest-file-seek
> +#
> +# @set: Set to the specified offset (same effect as 'whence':0)
> +# @cur: Add offset to the current location (same effect as 'whence':1)
> +# @end: Add offset to the end of the file (same effect as 'whence':2)
> +#
> +# Since: 2.6
> +##
> +{ 'enum': 'QGASeek', 'data': [ 'set', 'cur', 'end' ] }
> +
> +##
> +# @GuestFileWhence:
> +#
> +# Controls the meaning of offset to @guest-file-seek.
> +#
> +# @value: Integral value (0 for set, 1 for cur, 2 for end), available
> +# for historical reasons, and might differ from the host's or
> +# guest's SEEK_* values (since: 0.15)
> +# @name: Symbolic name, and preferred interface
> +#
> +# Since: 2.6
> +##
> +{ 'alternate': 'GuestFileWhence',
> + 'data': { 'value': 'int', 'name': 'QGASeek' } }
> +
> +##
> # @guest-file-seek:
> #
> # Seek to a position in the file, as with fseek(), and return the
> @@ -324,14 +352,15 @@
> #
> # @offset: bytes to skip over in the file stream
> #
> -# @whence: 0 for SEEK_SET, 1 for SEEK_CUR, or 2 for SEEK_END
> +# @whence: Symbolic or numeric code for interpreting offset
> #
> # Returns: @GuestFileSeek on success.
> #
> # Since: 0.15.0
> ##
> { 'command': 'guest-file-seek',
> - 'data': { 'handle': 'int', 'offset': 'int', 'whence': 'int' },
> + 'data': { 'handle': 'int', 'offset': 'int',
> + 'whence': 'GuestFileWhence' },
> 'returns': 'GuestFileSeek' }
>
> ##
> diff --git a/tests/test-qga.c b/tests/test-qga.c
> index e6a84d1..d1d3d9f 100644
> --- a/tests/test-qga.c
> +++ b/tests/test-qga.c
> @@ -13,7 +13,6 @@
>
> #include "libqtest.h"
> #include "config-host.h"
> -#include "qga/guest-agent-core.h"
>
> typedef struct {
> char *test_dir;
> @@ -457,8 +456,8 @@ static void test_qga_file_ops(gconstpointer fix)
> /* seek */
> cmd = g_strdup_printf("{'execute': 'guest-file-seek',"
> " 'arguments': { 'handle': %" PRId64 ", "
> - " 'offset': %d, 'whence': %d } }",
> - id, 6, QGA_SEEK_SET);
> + " 'offset': %d, 'whence': '%s' } }",
> + id, 6, "set");
> ret = qmp_fd(fixture->fd, cmd);
> qmp_assert_no_error(ret);
> val = qdict_get_qdict(ret, "return");
> @@ -550,8 +549,8 @@ static void test_qga_file_write_read(gconstpointer fix)
> /* seek to 0 */
> cmd = g_strdup_printf("{'execute': 'guest-file-seek',"
> " 'arguments': { 'handle': %" PRId64 ", "
> - " 'offset': %d, 'whence': %d } }",
> - id, 0, QGA_SEEK_SET);
> + " 'offset': %d, 'whence': '%s' } }",
> + id, 0, "set");
> ret = qmp_fd(fixture->fd, cmd);
> qmp_assert_no_error(ret);
> val = qdict_get_qdict(ret, "return");
>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-01-19 16:13 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-18 17:44 [Qemu-devel] [PATCH v2] qga: Support enum names in guest-file-seek Eric Blake
2016-01-19 16:13 ` Eric Blake
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.