From: mdroth <mdroth@linux.vnet.ibm.com>
To: Joel Schopp <jschopp@linux.vnet.ibm.com>
Cc: qemu-devel@nongnu.org, Stefan Berger <stefanb@linux.vnet.ibm.com>
Subject: Re: [Qemu-devel] [PATCH 4/9] qemu_qsb.diff
Date: Wed, 13 Mar 2013 16:11:35 -0500 [thread overview]
Message-ID: <20130313211135.GB6188@vm> (raw)
In-Reply-To: <1363200988-17865-5-git-send-email-jschopp@linux.vnet.ibm.com>
On Wed, Mar 13, 2013 at 01:56:23PM -0500, Joel Schopp wrote:
> This patch adds support functions for operating on in memory sized file buffers.
There's been some past refactorings to remove non-migration users of
QEMUFile, and AFAIK that's still the case today. QEMUFile satisfies
funky requirements like rate-limiting, buffering, etc that were specific
to migration.
IIUC all we want here is an abstraction on top of write()/memcpy(),
and access to qemu_{put|get}_be* utility functions.
Have you considered rolling those abstractions in the visitor
implementations as opposed to extending QEMUFile, and using
be*_to_cpus/cpus_to_be* helpers directly instead (like block/qcow2.c
does, for example)?
>
> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
> Signed-off-by: Joel Schopp <jschopp@linux.vnet.ibm.com>
> ---
> include/migration/qemu-file.h | 12 +++
> include/qemu-common.h | 15 ++++
> util/qemu-file.c | 184 +++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 211 insertions(+)
>
> diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
> index 07d8362..2bc77b1 100644
> --- a/include/migration/qemu-file.h
> +++ b/include/migration/qemu-file.h
> @@ -24,6 +24,8 @@
> #ifndef QEMU_FILE_H
> #define QEMU_FILE_H 1
>
> +#include <stdint.h>
> +
> /* This function writes a chunk of data to a file at the given position.
> * The pos argument can be ignored if the file is only being used for
> * streaming. The handler should try to write all of the data it can.
> @@ -58,6 +60,14 @@ typedef struct QEMUFileOps {
> QEMUFileGetFD *get_fd;
> } QEMUFileOps;
>
> +struct QEMUSizedBuffer {
> + unsigned char *buffer;
> + uint64_t size;
> + uint64_t used;
> +};
> +
> +typedef struct QEMUSizedBuffer QEMUSizedBuffer;
> +
> QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops);
> QEMUFile *qemu_fopen(const char *filename, const char *mode);
> QEMUFile *qemu_fdopen(int fd, const char *mode);
> @@ -71,6 +81,8 @@ void qemu_put_byte(QEMUFile *f, int v);
> int qemu_read_bytes(QEMUFile *f, uint8_t *buf, int size);
> int qemu_peek_bytes(QEMUFile *f, uint8_t *buf, int size, size_t offset);
> int qemu_write_bytes(QEMUFile *f, const uint8_t *buf, int size);
> +QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input);
> +const QEMUSizedBuffer *qemu_buf_get(QEMUFile *f);
>
> static inline void qemu_put_ubyte(QEMUFile *f, unsigned int v)
> {
> diff --git a/include/qemu-common.h b/include/qemu-common.h
> index 5e13708..de1cdc0 100644
> --- a/include/qemu-common.h
> +++ b/include/qemu-common.h
> @@ -442,4 +442,19 @@ int64_t pow2floor(int64_t value);
> int uleb128_encode_small(uint8_t *out, uint32_t n);
> int uleb128_decode_small(const uint8_t *in, uint32_t *n);
>
> +/* QEMU Sized Buffer */
> +#include "include/migration/qemu-file.h"
> +QEMUSizedBuffer *qsb_create(const uint8_t *buffer, uint64_t len);
> +QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *);
> +void qsb_free(QEMUSizedBuffer *);
> +uint64_t qsb_set_length(QEMUSizedBuffer *qsb, uint64_t length);
> +uint64_t qsb_get_length(const QEMUSizedBuffer *qsb);
> +const unsigned char *qsb_get_buffer(const QEMUSizedBuffer *, int64_t pos);
> +int qsb_write_at(QEMUSizedBuffer *qsb, const uint8_t *buf,
> + int64_t pos, int size);
> +int qsb_append_qsb(QEMUSizedBuffer *dest, const QEMUSizedBuffer *src);
> +int qsb_append(QEMUSizedBuffer *dest, const uint8_t *buffer, uint64_t len);
> +
> +
> +
> #endif
> diff --git a/util/qemu-file.c b/util/qemu-file.c
> index e698713..4442dcc 100644
> --- a/util/qemu-file.c
> +++ b/util/qemu-file.c
> @@ -710,3 +710,187 @@ int qemu_write_bytes(QEMUFile *f, const uint8_t *buf, int size)
>
> return size;
> }
> +
> +
> +QEMUSizedBuffer *qsb_create(const uint8_t *buffer, uint64_t len)
> +{
> + QEMUSizedBuffer *qsb;
> + uint64_t alloc_len;
> +
> + alloc_len = (len > 1024) ? len : 1024;
> +
> + qsb = g_new0(QEMUSizedBuffer, 1);
> + if (!qsb) {
> + return NULL;
> + }
> +
> + qsb->buffer = g_malloc(alloc_len);
> + if (!qsb->buffer) {
> + g_free(qsb);
> + return NULL;
> + }
> + qsb->size = alloc_len;
> +
> + if (buffer) {
> + memcpy(qsb->buffer, buffer, len);
> + qsb->used = len;
> + }
> +
> + return qsb;
> +}
> +
> +void qsb_free(QEMUSizedBuffer *qsb)
> +{
> + if (!qsb) {
> + return;
> + }
> + g_free(qsb->buffer);
> + g_free(qsb);
> +}
> +
> +uint64_t qsb_get_length(const QEMUSizedBuffer *qsb)
> +{
> + return qsb->used;
> +}
> +
> +uint64_t qsb_set_length(QEMUSizedBuffer *qsb, uint64_t new_len)
> +{
> + if (new_len <= qsb->size) {
> + qsb->used = new_len;
> + } else {
> + qsb->used = qsb->size;
> + }
> + return qsb->used;
> +}
> +
> +const unsigned char *qsb_get_buffer(const QEMUSizedBuffer *qsb, int64_t pos)
> +{
> + if (pos < qsb->used) {
> + return &qsb->buffer[pos];
> + }
> + return NULL;
> +}
> +
> +int qsb_write_at(QEMUSizedBuffer *qsb, const uint8_t *buf,
> + int64_t pos, int size)
> +{
> + if (pos + size > qsb->size) {
> + qsb->buffer = g_realloc(qsb->buffer, pos + size + 1024);
> + if (qsb->buffer == NULL) {
> + return -ENOMEM;
> + }
> + qsb->size = pos + size;
> + }
> + memcpy(&qsb->buffer[pos], buf, size);
> + if (pos + size > qsb->used) {
> + qsb->used = pos + size;
> + }
> +
> + return size;
> +}
> +
> +int qsb_append_qsb(QEMUSizedBuffer *dest, const QEMUSizedBuffer *src)
> +{
> + return qsb_write_at(dest, qsb_get_buffer(src, 0),
> + qsb_get_length(dest), qsb_get_length(src));
> +}
> +
> +int qsb_append(QEMUSizedBuffer *dest, const uint8_t *buf, uint64_t len)
> +{
> + return qsb_write_at(dest, buf,
> + qsb_get_length(dest), len);
> +}
> +
> +QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *in)
> +{
> + return qsb_create(qsb_get_buffer(in, 0),
> + qsb_get_length(in));
> +}
> +
> +typedef struct QEMUBuffer {
> + QEMUSizedBuffer *qsb;
> + QEMUFile *file;
> +} QEMUBuffer;
> +
> +static int buf_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
> +{
> + QEMUBuffer *s = opaque;
> + ssize_t len = qsb_get_length(s->qsb) - pos;
> +
> + if (len <= 0) {
> + return 0;
> + }
> +
> + if (len > size) {
> + len = size;
> + }
> + memcpy(buf, qsb_get_buffer(s->qsb, pos), len);
> +
> + return len;
> +}
> +
> +static int buf_put_buffer(void *opaque, const uint8_t *buf,
> + int64_t pos, int size)
> +{
> + QEMUBuffer *s = opaque;
> +
> + return qsb_write_at(s->qsb, buf, pos, size);
> +}
> +
> +static int buf_close(void *opaque)
> +{
> + QEMUBuffer *s = opaque;
> +
> + qsb_free(s->qsb);
> +
> + g_free(s);
> +
> + return 0;
> +}
> +
> +const QEMUSizedBuffer *qemu_buf_get(QEMUFile *f)
> +{
> + QEMUBuffer *p;
> +
> + qemu_fflush(f);
> +
> + p = (QEMUBuffer *)f->opaque;
> +
> + return p->qsb;
> +}
> +
> +static const QEMUFileOps buf_read_ops = {
> + .get_buffer = buf_get_buffer,
> + .close = buf_close
> +};
> +
> +static const QEMUFileOps buf_write_ops = {
> + .put_buffer = buf_put_buffer,
> + .close = buf_close
> +};
> +
> +QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input)
> +{
> + QEMUBuffer *s;
> +
> + if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
> + fprintf(stderr, "qemu_bufopen: Argument validity check failed\n");
> + return NULL;
> + }
> +
> + s = g_malloc0(sizeof(QEMUBuffer));
> + if (mode[0] == 'r') {
> + s->qsb = input;
> + }
> +
> + if (s->qsb == NULL) {
> + s->qsb = qsb_create(NULL, 0);
> + }
> +
> + if (mode[0] == 'r') {
> + s->file = qemu_fopen_ops(s, &buf_read_ops);
> + } else {
> + s->file = qemu_fopen_ops(s, &buf_write_ops);
> + }
> + return s->file;
> +}
> --
> 1.7.10.4
>
>
next prev parent reply other threads:[~2013-03-13 21:15 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-13 18:56 [Qemu-devel] [PATCH 0/9 v3] Implement and test asn1 ber visitors Joel Schopp
2013-03-13 18:56 ` [Qemu-devel] [PATCH 1/9] qemu-file Joel Schopp
2013-03-13 18:56 ` [Qemu-devel] [PATCH 2/9] qapi_c_arrays.diff Joel Schopp
2013-03-13 19:11 ` Anthony Liguori
2013-03-13 22:54 ` Stefan Berger
2013-03-13 18:56 ` [Qemu-devel] [PATCH 3/9] two new file wrappers Joel Schopp
2013-03-13 21:04 ` Eric Blake
2013-03-14 10:49 ` Stefan Berger
2013-03-13 18:56 ` [Qemu-devel] [PATCH 4/9] qemu_qsb.diff Joel Schopp
2013-03-13 21:11 ` mdroth [this message]
2013-03-13 21:28 ` Stefan Berger
2013-03-13 22:41 ` mdroth
2013-03-13 22:47 ` mdroth
2013-03-13 23:11 ` Stefan Berger
2013-03-13 18:56 ` [Qemu-devel] [PATCH 5/9] qapi_sized_buffer Joel Schopp
2013-03-13 20:52 ` mdroth
2013-03-13 22:00 ` Stefan Berger
2013-03-13 23:18 ` mdroth
2013-03-14 1:48 ` Stefan Berger
2013-03-14 12:18 ` mdroth
2013-03-14 13:39 ` Stefan Berger
2013-03-14 14:28 ` mdroth
2013-03-14 14:51 ` Stefan Berger
2013-03-14 15:11 ` mdroth
2013-03-14 15:24 ` Stefan Berger
2013-03-14 21:06 ` mdroth
2013-03-15 2:05 ` Stefan Berger
2013-03-13 18:56 ` [Qemu-devel] [PATCH 6/9] asn1_output-visitor.diff Joel Schopp
2013-03-13 18:56 ` [Qemu-devel] [PATCH 7/9] asn1_input-visitor.diff Joel Schopp
2013-03-13 18:56 ` [Qemu-devel] [PATCH 8/9] asn1_test_visitor_serialization.diff Joel Schopp
2013-03-13 18:56 ` [Qemu-devel] [PATCH 9/9] update_maintainers.diff Joel Schopp
-- strict thread matches above, loose matches on Subject: below --
2013-03-13 3:09 [Qemu-devel] [PATCH 0/9 v2] Implement and test asn1 ber visitors Joel Schopp
2013-03-13 3:09 ` [Qemu-devel] [PATCH 4/9] qemu_qsb.diff Joel Schopp
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130313211135.GB6188@vm \
--to=mdroth@linux.vnet.ibm.com \
--cc=jschopp@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanb@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.