Message ID | 1358842372-16344-3-git-send-email-lilei@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
On Tue, 22 Jan 2013 16:12:51 +0800 Lei Li <lilei@linux.vnet.ibm.com> wrote: > Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com> > --- > hmp-commands.hx | 16 ++++++++++++++++ > hmp.c | 13 +++++++++++++ > hmp.h | 1 + > qapi-schema.json | 41 +++++++++++++++++++++++++++++++++++++++++ > qemu-char.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ > qmp-commands.hx | 34 ++++++++++++++++++++++++++++++++++ > 6 files changed, 153 insertions(+), 0 deletions(-) > > diff --git a/hmp-commands.hx b/hmp-commands.hx > index 0934b9b..e546c76 100644 > --- a/hmp-commands.hx > +++ b/hmp-commands.hx > @@ -837,6 +837,22 @@ STEXI > @item nmi @var{cpu} > @findex nmi > Inject an NMI on the given CPU (x86 only). > + > +ETEXI > + > + { > + .name = "memchar_write", > + .args_type = "chardev:s,data:s", > + .params = "chardev data", This is missing .help. Please look at the other entries for examples. > + .mhandler.cmd = hmp_memchar_write, > + }, > + > +STEXI > +@item memchar_write @var{chardev} @var{data} > +@findex memchar_write > +Provide writing interface for CirMemCharDriver. Write @var{data} > +to char device 'memory'. > + > ETEXI > > { > diff --git a/hmp.c b/hmp.c > index c7b6ba0..546d687 100644 > --- a/hmp.c > +++ b/hmp.c > @@ -684,6 +684,19 @@ void hmp_pmemsave(Monitor *mon, const QDict *qdict) > hmp_handle_error(mon, &errp); > } > > +void hmp_memchar_write(Monitor *mon, const QDict *qdict) > +{ > + uint32_t size; > + const char *chardev = qdict_get_str(qdict, "chardev"); > + const char *data = qdict_get_str(qdict, "data"); > + Error *errp = NULL; > + > + size = strlen(data); > + qmp_memchar_write(chardev, size, data, false, 0, &errp); > + > + hmp_handle_error(mon, &errp); > +} > + > static void hmp_cont_cb(void *opaque, int err) > { > if (!err) { > diff --git a/hmp.h b/hmp.h > index 44be683..06d6ea2 100644 > --- a/hmp.h > +++ b/hmp.h > @@ -43,6 +43,7 @@ void hmp_system_powerdown(Monitor *mon, const QDict *qdict); > void hmp_cpu(Monitor *mon, const QDict *qdict); > void hmp_memsave(Monitor *mon, const QDict *qdict); > void hmp_pmemsave(Monitor *mon, const QDict *qdict); > +void hmp_memchar_write(Monitor *mon, const QDict *qdict); > void hmp_cont(Monitor *mon, const QDict *qdict); > void hmp_system_wakeup(Monitor *mon, const QDict *qdict); > void hmp_inject_nmi(Monitor *mon, const QDict *qdict); > diff --git a/qapi-schema.json b/qapi-schema.json > index 6d7252b..c34e9ac 100644 > --- a/qapi-schema.json > +++ b/qapi-schema.json > @@ -325,6 +325,47 @@ > { 'command': 'query-chardev', 'returns': ['ChardevInfo'] } > > ## > +# @DataFormat: > +# > +# An enumeration of data format. > +# > +# @utf8: The data format is 'utf8'. > +# > +# @base64: The data format is 'base64'. > +# > +# Since: 1.4 > +## > +{ 'enum': 'DataFormat' > + 'data': [ 'utf8', 'base64' ] } > + > +## > +# @memchar-write: > +# > +# Provide writing interface for memchardev. Write data to char > +# device 'memory'. > +# > +# @chardev: the name of the memory char device. I wonder if this should be 'device' instead. > +# > +# @size: the size to write in bytes. > +# > +# @data: the source data write to memchar. > +# > +# @format: #optional the format of the data write to chardev 'memory', > +# by default is 'utf8'. > +# > +# Returns: Nothing on success > +# If @chardev is not a valid char device, DeviceNotFound > +# > +# Notes: For now assume 'drop' behaver, which would result in writes > +# dropping queued data. I agree this is the desired interface, but it's not what it does, see below. > +# > +# Since: 1.4 > +## > +{ 'command': 'memchar-write', > + 'data': {'chardev': 'str', 'size': 'int', 'data': 'str', > + '*format': 'DataFormat'} } > + > +## > # @CommandInfo: > # > # Information about a QMP command > diff --git a/qemu-char.c b/qemu-char.c > index b323e94..c3bb6ec 100644 > --- a/qemu-char.c > +++ b/qemu-char.c > @@ -2754,6 +2754,54 @@ fail: > return NULL; > } > > +static bool qemu_is_chr(const CharDriverState *chr, const char *filename) > +{ > + return strcmp(chr->filename, filename); > +} > + > +void qmp_memchar_write(const char *chardev, int64_t size, > + const char *data, bool has_format, > + enum DataFormat format, > + Error **errp) > +{ > + CharDriverState *chr; > + guchar *write_data; > + int ret; > + gsize write_count; > + > + chr = qemu_chr_find(chardev); > + if (!chr) { > + error_set(errp, QERR_DEVICE_NOT_FOUND, chardev); > + return; > + } > + > + if (qemu_is_chr(chr, "memory")) { > + error_setg(errp,"%s is not memory char device\n", chardev); Please, drop the trailing '\n'. > + return; > + } > + > + /* XXX: Drop the coming data when the buffer is full. */ > + if (cirmem_chr_is_full(chr)) { > + error_setg(errp, "Memory device %s is full", chardev); > + return; > + } This is where the code contradicts the doc, and we can't fix this later because we'd change the interface. Why can't you just drop this check? > + > + write_count = (gsize)size; > + > + if (has_format && (format == DATA_FORMAT_BASE64)) { > + write_data = g_base64_decode(data, &write_count); > + } else { > + write_data = (uint8_t *)data; > + } > + > + ret = cirmem_chr_write(chr, write_data, write_count); > + > + if (ret < 0) { > + error_setg(errp, "Failed to write to device %s", chardev); > + return; > + } > +} > + > QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename) > { > char host[65], port[33], width[8], height[8]; > diff --git a/qmp-commands.hx b/qmp-commands.hx > index cbf1280..8ad06d0 100644 > --- a/qmp-commands.hx > +++ b/qmp-commands.hx > @@ -466,6 +466,40 @@ Note: inject-nmi fails when the guest doesn't support injecting. > EQMP > > { > + .name = "memchar-write", > + .args_type = "chardev:s,size:i,data:s,format:s?", > + .help = "write size of data to memory chardev", Please, drop .help. We only use it for hmp commands. > + .mhandler.cmd_new = qmp_marshal_input_memchar_write, > + }, > + > +SQMP > +memchar-write > +------------- > + > +Provide writing interface for CirMemCharDriver. Write data to memory > +char device. > + > +Arguments: > + > +- "chardev": the name of the char device, must be unique (json-string) > +- "size": the memory size, in bytes, should be power of 2 (json-int) > +- "data": the source data write to memory (json-string) > +- "format": the data format write to memory, default is > + utf8. (json-string, optional) > + - Possible values: "utf8", "base64" > + > +Example: > + > +-> { "execute": "memchar-write", > + "arguments": { "chardev": foo, > + "size": 8, > + "data": "abcdefgh", > + "format": "utf8" } } > +<- { "return": {} } > + > +EQMP > + > + { > .name = "xen-save-devices-state", > .args_type = "filename:F", > .mhandler.cmd_new = qmp_marshal_input_xen_save_devices_state,
On 01/23/2013 12:27 AM, Luiz Capitulino wrote: > On Tue, 22 Jan 2013 16:12:51 +0800 > Lei Li <lilei@linux.vnet.ibm.com> wrote: > >> Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com> >> --- >> hmp-commands.hx | 16 ++++++++++++++++ >> hmp.c | 13 +++++++++++++ >> hmp.h | 1 + >> qapi-schema.json | 41 +++++++++++++++++++++++++++++++++++++++++ >> qemu-char.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ >> qmp-commands.hx | 34 ++++++++++++++++++++++++++++++++++ >> 6 files changed, 153 insertions(+), 0 deletions(-) >> >> diff --git a/hmp-commands.hx b/hmp-commands.hx >> index 0934b9b..e546c76 100644 >> --- a/hmp-commands.hx >> +++ b/hmp-commands.hx >> @@ -837,6 +837,22 @@ STEXI >> @item nmi @var{cpu} >> @findex nmi >> Inject an NMI on the given CPU (x86 only). >> + >> +ETEXI >> + >> + { >> + .name = "memchar_write", >> + .args_type = "chardev:s,data:s", >> + .params = "chardev data", > This is missing .help. Please look at the other entries for examples. Hmm, I did add .help here before version 5, and I get rid of them based on your comments "Help doesn't make sense for HMP."... So I guess it's misunderstanding here? > >> + .mhandler.cmd = hmp_memchar_write, >> + }, >> + >> +STEXI >> +@item memchar_write @var{chardev} @var{data} >> +@findex memchar_write >> +Provide writing interface for CirMemCharDriver. Write @var{data} >> +to char device 'memory'. >> + >> ETEXI >> >> { >> diff --git a/hmp.c b/hmp.c >> index c7b6ba0..546d687 100644 >> --- a/hmp.c >> +++ b/hmp.c >> @@ -684,6 +684,19 @@ void hmp_pmemsave(Monitor *mon, const QDict *qdict) >> hmp_handle_error(mon, &errp); >> } >> >> +void hmp_memchar_write(Monitor *mon, const QDict *qdict) >> +{ >> + uint32_t size; >> + const char *chardev = qdict_get_str(qdict, "chardev"); >> + const char *data = qdict_get_str(qdict, "data"); >> + Error *errp = NULL; >> + >> + size = strlen(data); >> + qmp_memchar_write(chardev, size, data, false, 0, &errp); >> + >> + hmp_handle_error(mon, &errp); >> +} >> + >> static void hmp_cont_cb(void *opaque, int err) >> { >> if (!err) { >> diff --git a/hmp.h b/hmp.h >> index 44be683..06d6ea2 100644 >> --- a/hmp.h >> +++ b/hmp.h >> @@ -43,6 +43,7 @@ void hmp_system_powerdown(Monitor *mon, const QDict *qdict); >> void hmp_cpu(Monitor *mon, const QDict *qdict); >> void hmp_memsave(Monitor *mon, const QDict *qdict); >> void hmp_pmemsave(Monitor *mon, const QDict *qdict); >> +void hmp_memchar_write(Monitor *mon, const QDict *qdict); >> void hmp_cont(Monitor *mon, const QDict *qdict); >> void hmp_system_wakeup(Monitor *mon, const QDict *qdict); >> void hmp_inject_nmi(Monitor *mon, const QDict *qdict); >> diff --git a/qapi-schema.json b/qapi-schema.json >> index 6d7252b..c34e9ac 100644 >> --- a/qapi-schema.json >> +++ b/qapi-schema.json >> @@ -325,6 +325,47 @@ >> { 'command': 'query-chardev', 'returns': ['ChardevInfo'] } >> >> ## >> +# @DataFormat: >> +# >> +# An enumeration of data format. >> +# >> +# @utf8: The data format is 'utf8'. >> +# >> +# @base64: The data format is 'base64'. >> +# >> +# Since: 1.4 >> +## >> +{ 'enum': 'DataFormat' >> + 'data': [ 'utf8', 'base64' ] } >> + >> +## >> +# @memchar-write: >> +# >> +# Provide writing interface for memchardev. Write data to char >> +# device 'memory'. >> +# >> +# @chardev: the name of the memory char device. > I wonder if this should be 'device' instead. ok. >> +# >> +# @size: the size to write in bytes. >> +# >> +# @data: the source data write to memchar. >> +# >> +# @format: #optional the format of the data write to chardev 'memory', >> +# by default is 'utf8'. >> +# >> +# Returns: Nothing on success >> +# If @chardev is not a valid char device, DeviceNotFound >> +# >> +# Notes: For now assume 'drop' behaver, which would result in writes >> +# dropping queued data. > I agree this is the desired interface, but it's not what it does, see > below. > >> +# >> +# Since: 1.4 >> +## >> +{ 'command': 'memchar-write', >> + 'data': {'chardev': 'str', 'size': 'int', 'data': 'str', >> + '*format': 'DataFormat'} } >> + >> +## >> # @CommandInfo: >> # >> # Information about a QMP command >> diff --git a/qemu-char.c b/qemu-char.c >> index b323e94..c3bb6ec 100644 >> --- a/qemu-char.c >> +++ b/qemu-char.c >> @@ -2754,6 +2754,54 @@ fail: >> return NULL; >> } >> >> +static bool qemu_is_chr(const CharDriverState *chr, const char *filename) >> +{ >> + return strcmp(chr->filename, filename); >> +} >> + >> +void qmp_memchar_write(const char *chardev, int64_t size, >> + const char *data, bool has_format, >> + enum DataFormat format, >> + Error **errp) >> +{ >> + CharDriverState *chr; >> + guchar *write_data; >> + int ret; >> + gsize write_count; >> + >> + chr = qemu_chr_find(chardev); >> + if (!chr) { >> + error_set(errp, QERR_DEVICE_NOT_FOUND, chardev); >> + return; >> + } >> + >> + if (qemu_is_chr(chr, "memory")) { >> + error_setg(errp,"%s is not memory char device\n", chardev); > Please, drop the trailing '\n'. > Ah, sorry for this.. >> + return; >> + } >> + >> + /* XXX: Drop the coming data when the buffer is full. */ >> + if (cirmem_chr_is_full(chr)) { >> + error_setg(errp, "Memory device %s is full", chardev); >> + return; >> + } > This is where the code contradicts the doc, and we can't fix this > later because we'd change the interface. > > Why can't you just drop this check? > >> + >> + write_count = (gsize)size; >> + >> + if (has_format && (format == DATA_FORMAT_BASE64)) { >> + write_data = g_base64_decode(data, &write_count); >> + } else { >> + write_data = (uint8_t *)data; >> + } >> + >> + ret = cirmem_chr_write(chr, write_data, write_count); >> + >> + if (ret < 0) { >> + error_setg(errp, "Failed to write to device %s", chardev); >> + return; >> + } >> +} >> + >> QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename) >> { >> char host[65], port[33], width[8], height[8]; >> diff --git a/qmp-commands.hx b/qmp-commands.hx >> index cbf1280..8ad06d0 100644 >> --- a/qmp-commands.hx >> +++ b/qmp-commands.hx >> @@ -466,6 +466,40 @@ Note: inject-nmi fails when the guest doesn't support injecting. >> EQMP >> >> { >> + .name = "memchar-write", >> + .args_type = "chardev:s,size:i,data:s,format:s?", >> + .help = "write size of data to memory chardev", > Please, drop .help. We only use it for hmp commands. > >> + .mhandler.cmd_new = qmp_marshal_input_memchar_write, >> + }, >> + >> +SQMP >> +memchar-write >> +------------- >> + >> +Provide writing interface for CirMemCharDriver. Write data to memory >> +char device. >> + >> +Arguments: >> + >> +- "chardev": the name of the char device, must be unique (json-string) >> +- "size": the memory size, in bytes, should be power of 2 (json-int) >> +- "data": the source data write to memory (json-string) >> +- "format": the data format write to memory, default is >> + utf8. (json-string, optional) >> + - Possible values: "utf8", "base64" >> + >> +Example: >> + >> +-> { "execute": "memchar-write", >> + "arguments": { "chardev": foo, >> + "size": 8, >> + "data": "abcdefgh", >> + "format": "utf8" } } >> +<- { "return": {} } >> + >> +EQMP >> + >> + { >> .name = "xen-save-devices-state", >> .args_type = "filename:F", >> .mhandler.cmd_new = qmp_marshal_input_xen_save_devices_state, >
On Wed, 23 Jan 2013 11:30:23 +0800 Lei Li <lilei@linux.vnet.ibm.com> wrote: > On 01/23/2013 12:27 AM, Luiz Capitulino wrote: > > On Tue, 22 Jan 2013 16:12:51 +0800 > > Lei Li <lilei@linux.vnet.ibm.com> wrote: > > > >> Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com> > >> --- > >> hmp-commands.hx | 16 ++++++++++++++++ > >> hmp.c | 13 +++++++++++++ > >> hmp.h | 1 + > >> qapi-schema.json | 41 +++++++++++++++++++++++++++++++++++++++++ > >> qemu-char.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ > >> qmp-commands.hx | 34 ++++++++++++++++++++++++++++++++++ > >> 6 files changed, 153 insertions(+), 0 deletions(-) > >> > >> diff --git a/hmp-commands.hx b/hmp-commands.hx > >> index 0934b9b..e546c76 100644 > >> --- a/hmp-commands.hx > >> +++ b/hmp-commands.hx > >> @@ -837,6 +837,22 @@ STEXI > >> @item nmi @var{cpu} > >> @findex nmi > >> Inject an NMI on the given CPU (x86 only). > >> + > >> +ETEXI > >> + > >> + { > >> + .name = "memchar_write", > >> + .args_type = "chardev:s,data:s", > >> + .params = "chardev data", > > This is missing .help. Please look at the other entries for examples. > > Hmm, I did add .help here before version 5, and I get rid of them > based on your comments "Help doesn't make sense for HMP."... Did I really say that? The help text makes sense _only_ for HMP. I may have quoted the wrong .hx file. If I did that I'm sorry, but it's also just a matter of checking other entries in the file to see if yours is correct.
diff --git a/hmp-commands.hx b/hmp-commands.hx index 0934b9b..e546c76 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -837,6 +837,22 @@ STEXI @item nmi @var{cpu} @findex nmi Inject an NMI on the given CPU (x86 only). + +ETEXI + + { + .name = "memchar_write", + .args_type = "chardev:s,data:s", + .params = "chardev data", + .mhandler.cmd = hmp_memchar_write, + }, + +STEXI +@item memchar_write @var{chardev} @var{data} +@findex memchar_write +Provide writing interface for CirMemCharDriver. Write @var{data} +to char device 'memory'. + ETEXI { diff --git a/hmp.c b/hmp.c index c7b6ba0..546d687 100644 --- a/hmp.c +++ b/hmp.c @@ -684,6 +684,19 @@ void hmp_pmemsave(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &errp); } +void hmp_memchar_write(Monitor *mon, const QDict *qdict) +{ + uint32_t size; + const char *chardev = qdict_get_str(qdict, "chardev"); + const char *data = qdict_get_str(qdict, "data"); + Error *errp = NULL; + + size = strlen(data); + qmp_memchar_write(chardev, size, data, false, 0, &errp); + + hmp_handle_error(mon, &errp); +} + static void hmp_cont_cb(void *opaque, int err) { if (!err) { diff --git a/hmp.h b/hmp.h index 44be683..06d6ea2 100644 --- a/hmp.h +++ b/hmp.h @@ -43,6 +43,7 @@ void hmp_system_powerdown(Monitor *mon, const QDict *qdict); void hmp_cpu(Monitor *mon, const QDict *qdict); void hmp_memsave(Monitor *mon, const QDict *qdict); void hmp_pmemsave(Monitor *mon, const QDict *qdict); +void hmp_memchar_write(Monitor *mon, const QDict *qdict); void hmp_cont(Monitor *mon, const QDict *qdict); void hmp_system_wakeup(Monitor *mon, const QDict *qdict); void hmp_inject_nmi(Monitor *mon, const QDict *qdict); diff --git a/qapi-schema.json b/qapi-schema.json index 6d7252b..c34e9ac 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -325,6 +325,47 @@ { 'command': 'query-chardev', 'returns': ['ChardevInfo'] } ## +# @DataFormat: +# +# An enumeration of data format. +# +# @utf8: The data format is 'utf8'. +# +# @base64: The data format is 'base64'. +# +# Since: 1.4 +## +{ 'enum': 'DataFormat' + 'data': [ 'utf8', 'base64' ] } + +## +# @memchar-write: +# +# Provide writing interface for memchardev. Write data to char +# device 'memory'. +# +# @chardev: the name of the memory char device. +# +# @size: the size to write in bytes. +# +# @data: the source data write to memchar. +# +# @format: #optional the format of the data write to chardev 'memory', +# by default is 'utf8'. +# +# Returns: Nothing on success +# If @chardev is not a valid char device, DeviceNotFound +# +# Notes: For now assume 'drop' behaver, which would result in writes +# dropping queued data. +# +# Since: 1.4 +## +{ 'command': 'memchar-write', + 'data': {'chardev': 'str', 'size': 'int', 'data': 'str', + '*format': 'DataFormat'} } + +## # @CommandInfo: # # Information about a QMP command diff --git a/qemu-char.c b/qemu-char.c index b323e94..c3bb6ec 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2754,6 +2754,54 @@ fail: return NULL; } +static bool qemu_is_chr(const CharDriverState *chr, const char *filename) +{ + return strcmp(chr->filename, filename); +} + +void qmp_memchar_write(const char *chardev, int64_t size, + const char *data, bool has_format, + enum DataFormat format, + Error **errp) +{ + CharDriverState *chr; + guchar *write_data; + int ret; + gsize write_count; + + chr = qemu_chr_find(chardev); + if (!chr) { + error_set(errp, QERR_DEVICE_NOT_FOUND, chardev); + return; + } + + if (qemu_is_chr(chr, "memory")) { + error_setg(errp,"%s is not memory char device\n", chardev); + return; + } + + /* XXX: Drop the coming data when the buffer is full. */ + if (cirmem_chr_is_full(chr)) { + error_setg(errp, "Memory device %s is full", chardev); + return; + } + + write_count = (gsize)size; + + if (has_format && (format == DATA_FORMAT_BASE64)) { + write_data = g_base64_decode(data, &write_count); + } else { + write_data = (uint8_t *)data; + } + + ret = cirmem_chr_write(chr, write_data, write_count); + + if (ret < 0) { + error_setg(errp, "Failed to write to device %s", chardev); + return; + } +} + QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename) { char host[65], port[33], width[8], height[8]; diff --git a/qmp-commands.hx b/qmp-commands.hx index cbf1280..8ad06d0 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -466,6 +466,40 @@ Note: inject-nmi fails when the guest doesn't support injecting. EQMP { + .name = "memchar-write", + .args_type = "chardev:s,size:i,data:s,format:s?", + .help = "write size of data to memory chardev", + .mhandler.cmd_new = qmp_marshal_input_memchar_write, + }, + +SQMP +memchar-write +------------- + +Provide writing interface for CirMemCharDriver. Write data to memory +char device. + +Arguments: + +- "chardev": the name of the char device, must be unique (json-string) +- "size": the memory size, in bytes, should be power of 2 (json-int) +- "data": the source data write to memory (json-string) +- "format": the data format write to memory, default is + utf8. (json-string, optional) + - Possible values: "utf8", "base64" + +Example: + +-> { "execute": "memchar-write", + "arguments": { "chardev": foo, + "size": 8, + "data": "abcdefgh", + "format": "utf8" } } +<- { "return": {} } + +EQMP + + { .name = "xen-save-devices-state", .args_type = "filename:F", .mhandler.cmd_new = qmp_marshal_input_xen_save_devices_state,
Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com> --- hmp-commands.hx | 16 ++++++++++++++++ hmp.c | 13 +++++++++++++ hmp.h | 1 + qapi-schema.json | 41 +++++++++++++++++++++++++++++++++++++++++ qemu-char.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ qmp-commands.hx | 34 ++++++++++++++++++++++++++++++++++ 6 files changed, 153 insertions(+), 0 deletions(-)