Message ID | 20190725032321.12721-7-alxndr@bu.edu (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add virtual device fuzzing support | expand |
On Thu, Jul 25, 2019 at 03:23:49AM +0000, Oleinik, Alexander wrote: > The ramfile allows vmstate to be saved and restored directly onto the > heap. > > Signed-off-by: Alexander Oleinik <alxndr@bu.edu> > --- > tests/fuzz/ramfile.c | 127 +++++++++++++++++++++++++++++++++++++++++++ > tests/fuzz/ramfile.h | 20 +++++++ > 2 files changed, 147 insertions(+) > create mode 100644 tests/fuzz/ramfile.c > create mode 100644 tests/fuzz/ramfile.h > > diff --git a/tests/fuzz/ramfile.c b/tests/fuzz/ramfile.c > new file mode 100644 > index 0000000000..8da242e9ee > --- /dev/null > +++ b/tests/fuzz/ramfile.c Please put this in migration/. This code doesn't do fuzzing and is general-purpose enough to be used by other parts of QEMU dealing with live migration. > @@ -0,0 +1,127 @@ > +/* > + * ===================================================================================== > + * > + * Filename: ramfile.c > + * > + * Description: QEMUFile stored in dynamically allocated RAM for fast VMRestore > + * > + * Author: Alexander Oleinik (), alxndr@bu.edu > + * Organization: > + * > + * ===================================================================================== > + */ Please use license headers with all new files that are created. Fine-grained filename and authorship information is already kept by git so it's not necessary to duplicate it here. > +#include <stdlib.h> > +#include "qemu/osdep.h" osdep.h already includes stdlib.h. > +#include "qemu-common.h" > +#include "exec/memory.h" > +#include "migration/qemu-file.h" > +#include "migration/migration.h" > +#include "migration/savevm.h" > +#include "ramfile.h" > + > +#define INCREMENT 10240 > +#define IO_BUF_SIZE 32768 > +#define MAX_IOV_SIZE MIN(IOV_MAX, 64) > + > +struct QEMUFile { > + const QEMUFileOps *ops; > + const QEMUFileHooks *hooks; > + void *opaque; > + > + int64_t bytes_xfer; > + int64_t xfer_limit; > + > + int64_t pos; /* start of buffer when writing, end of buffer > + when reading */ > + int buf_index; > + int buf_size; /* 0 when writing */ > + uint8_t buf[IO_BUF_SIZE]; > + > + DECLARE_BITMAP(may_free, MAX_IOV_SIZE); > + struct iovec iov[MAX_IOV_SIZE]; > + unsigned int iovcnt; > + > + int last_error; > +}; Wait, what?! :) Please add the ram file to qemu-file.c instead of duplicating QEMUFile.
On 7/26/19 8:47 AM, Stefan Hajnoczi wrote: > On Thu, Jul 25, 2019 at 03:23:49AM +0000, Oleinik, Alexander wrote: >> The ramfile allows vmstate to be saved and restored directly onto the >> heap. >> >> Signed-off-by: Alexander Oleinik <alxndr@bu.edu> >> --- >> tests/fuzz/ramfile.c | 127 +++++++++++++++++++++++++++++++++++++++++++ >> tests/fuzz/ramfile.h | 20 +++++++ >> 2 files changed, 147 insertions(+) >> create mode 100644 tests/fuzz/ramfile.c >> create mode 100644 tests/fuzz/ramfile.h >> >> diff --git a/tests/fuzz/ramfile.c b/tests/fuzz/ramfile.c >> new file mode 100644 >> index 0000000000..8da242e9ee >> --- /dev/null >> +++ b/tests/fuzz/ramfile.c > > Please put this in migration/. This code doesn't do fuzzing and is > general-purpose enough to be used by other parts of QEMU dealing with > live migration. > >> @@ -0,0 +1,127 @@ >> +/* >> + * ===================================================================================== >> + * >> + * Filename: ramfile.c >> + * >> + * Description: QEMUFile stored in dynamically allocated RAM for fast VMRestore >> + * >> + * Author: Alexander Oleinik (), alxndr@bu.edu >> + * Organization: >> + * >> + * ===================================================================================== >> + */ > > Please use license headers with all new files that are created. > Fine-grained filename and authorship information is already kept by git > so it's not necessary to duplicate it here. > >> +#include <stdlib.h> >> +#include "qemu/osdep.h" > > osdep.h already includes stdlib.h. > >> +#include "qemu-common.h" >> +#include "exec/memory.h" >> +#include "migration/qemu-file.h" >> +#include "migration/migration.h" >> +#include "migration/savevm.h" >> +#include "ramfile.h" >> + >> +#define INCREMENT 10240 >> +#define IO_BUF_SIZE 32768 >> +#define MAX_IOV_SIZE MIN(IOV_MAX, 64) >> + >> +struct QEMUFile { >> + const QEMUFileOps *ops; >> + const QEMUFileHooks *hooks; >> + void *opaque; >> + >> + int64_t bytes_xfer; >> + int64_t xfer_limit; >> + >> + int64_t pos; /* start of buffer when writing, end of buffer >> + when reading */ >> + int buf_index; >> + int buf_size; /* 0 when writing */ >> + uint8_t buf[IO_BUF_SIZE]; >> + >> + DECLARE_BITMAP(may_free, MAX_IOV_SIZE); >> + struct iovec iov[MAX_IOV_SIZE]; >> + unsigned int iovcnt; >> + >> + int last_error; >> +}; > > Wait, what?! :) > > Please add the ram file to qemu-file.c instead of duplicating QEMUFile. > I think we should be able to replace all of this simply by using memfd_create. Since it acts as a regular file, it will work with the existing code (likely with performance gains).
On 26/07/19 21:36, Oleinik, Alexander wrote: >> >> Please add the ram file to qemu-file.c instead of duplicating QEMUFile. >> > I think we should be able to replace all of this simply by using > memfd_create. Since it acts as a regular file, it will work with the > existing code (likely with performance gains). That wouldn't be portable to non-Linux, so having RAMFile is better. Paolo
diff --git a/tests/fuzz/ramfile.c b/tests/fuzz/ramfile.c new file mode 100644 index 0000000000..8da242e9ee --- /dev/null +++ b/tests/fuzz/ramfile.c @@ -0,0 +1,127 @@ +/* + * ===================================================================================== + * + * Filename: ramfile.c + * + * Description: QEMUFile stored in dynamically allocated RAM for fast VMRestore + * + * Author: Alexander Oleinik (), alxndr@bu.edu + * Organization: + * + * ===================================================================================== + */ +#include <stdlib.h> +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "exec/memory.h" +#include "migration/qemu-file.h" +#include "migration/migration.h" +#include "migration/savevm.h" +#include "ramfile.h" + +#define INCREMENT 10240 +#define IO_BUF_SIZE 32768 +#define MAX_IOV_SIZE MIN(IOV_MAX, 64) + +struct QEMUFile { + const QEMUFileOps *ops; + const QEMUFileHooks *hooks; + void *opaque; + + int64_t bytes_xfer; + int64_t xfer_limit; + + int64_t pos; /* start of buffer when writing, end of buffer + when reading */ + int buf_index; + int buf_size; /* 0 when writing */ + uint8_t buf[IO_BUF_SIZE]; + + DECLARE_BITMAP(may_free, MAX_IOV_SIZE); + struct iovec iov[MAX_IOV_SIZE]; + unsigned int iovcnt; + + int last_error; +}; + +static ssize_t ram_writev_buffer(void *opaque, struct iovec *iov, int iovcnt, + int64_t pos) +{ + ram_disk *rd = (ram_disk*)opaque; + gsize newsize; + ssize_t total_size = 0; + int i; + if(!rd->base) { + rd->base = g_malloc(INCREMENT); + rd->len = INCREMENT; + } + for(i = 0; i< iovcnt; i++) + { + if(pos+iov[i].iov_len >= rd->len ){ + newsize = ((pos + iov[i].iov_len)/INCREMENT + 1) * INCREMENT; + rd->base = g_realloc(rd->base, newsize); + rd->len = newsize; + } + /* for(int j =0; j<iov[i].iov_len; j++){ */ + /* printf("%hhx",*((char*)iov[i].iov_base+j)); */ + /* } */ + memcpy(rd->base + pos, iov[i].iov_base, iov[i].iov_len); + pos += iov[i].iov_len; + total_size += iov[i].iov_len; + } + return total_size; +} + +static ssize_t ram_get_buffer(void *opaque, uint8_t *buf, int64_t pos, + size_t size) +{ + ram_disk *rd = (ram_disk*)opaque; + if(pos+size>rd->len){ + if(rd->len-pos>=0){ + memcpy(buf, rd->base + pos, rd->len-pos); + size = rd->len-pos; + } + } + else + memcpy(buf, rd->base + pos, size); + return size; +} + +static int ram_fclose(void *opaque) +{ + return 0; +} + +static const QEMUFileOps ram_read_ops = { + .get_buffer = ram_get_buffer, + .close = ram_fclose +}; + +static const QEMUFileOps ram_write_ops = { + .writev_buffer = ram_writev_buffer, + .close = ram_fclose +}; + +QEMUFile *qemu_fopen_ram(ram_disk **return_rd) { + ram_disk *rd = g_new0(ram_disk, 1); + *return_rd=rd; + return qemu_fopen_ops(rd, &ram_write_ops); +} + +QEMUFile *qemu_fopen_ro_ram(ram_disk* rd) { + return qemu_fopen_ops(rd, &ram_read_ops); +} + +void qemu_freopen_ro_ram(QEMUFile* f) { + void *rd = f->opaque; + f->bytes_xfer=0; + f->xfer_limit=0; + f->last_error=0; + f->iovcnt=0; + f->buf_index=0; + f->buf_size=0; + f->pos=0; + f->ops = &ram_read_ops; + f->opaque = rd; + return; +} diff --git a/tests/fuzz/ramfile.h b/tests/fuzz/ramfile.h new file mode 100644 index 0000000000..b51cc72950 --- /dev/null +++ b/tests/fuzz/ramfile.h @@ -0,0 +1,20 @@ +#ifndef RAMFILE_H +#define RAMFILE_H + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qemu/iov.h" +#include "exec/memory.h" +#include "exec/address-spaces.h" +#include "migration/qemu-file.h" + +typedef struct ram_disk { + void *base; + gsize len; +} ram_disk; + +QEMUFile *qemu_fopen_ram(ram_disk **rd); +QEMUFile *qemu_fopen_ro_ram(ram_disk* rd); +void qemu_freopen_ro_ram(QEMUFile* f); + +#endif
The ramfile allows vmstate to be saved and restored directly onto the heap. Signed-off-by: Alexander Oleinik <alxndr@bu.edu> --- tests/fuzz/ramfile.c | 127 +++++++++++++++++++++++++++++++++++++++++++ tests/fuzz/ramfile.h | 20 +++++++ 2 files changed, 147 insertions(+) create mode 100644 tests/fuzz/ramfile.c create mode 100644 tests/fuzz/ramfile.h