qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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
> 
> 

  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).