From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34974) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bwT7a-0002GE-K9 for qemu-devel@nongnu.org; Tue, 18 Oct 2016 08:03:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bwT7U-0000aq-I1 for qemu-devel@nongnu.org; Tue, 18 Oct 2016 08:03:54 -0400 Date: Tue, 18 Oct 2016 13:03:36 +0100 From: "Daniel P. Berrange" Message-ID: <20161018120335.GO4349@redhat.com> Reply-To: "Daniel P. Berrange" References: <528780a9a2fd3f7cd759231bba30d3a48901f8be.1476741489.git.tgolembi@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <528780a9a2fd3f7cd759231bba30d3a48901f8be.1476741489.git.tgolembi@redhat.com> Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH v2] raw_bsd: add offset and size options List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: =?utf-8?B?VG9tw6HFoSBHb2xlbWJpb3Zza8O9?= Cc: qemu-devel@nongnu.org, Kevin Wolf , qemu-block@nongnu.org, Markus Armbruster , Max Reitz On Tue, Oct 18, 2016 at 12:25:17AM +0200, Tom=C3=A1=C5=A1 Golembiovsk=C3=BD= wrote: > Added two new options 'offset' and 'size'. This makes it possible to us= e > only part of the file as a device. This can be used e.g. to limit the > access only to single partition in a disk image or use a disk inside a > tar archive (like OVA). >=20 > When 'size' is specified we do our best to honour it. >=20 > Signed-off-by: Tom=C3=A1=C5=A1 Golembiovsk=C3=BD > --- > block/raw_bsd.c | 169 +++++++++++++++++++++++++++++++++++++++++++= +++++++- > qapi/block-core.json | 16 ++++- > 2 files changed, 181 insertions(+), 4 deletions(-) >=20 > diff --git a/block/raw_bsd.c b/block/raw_bsd.c > index 588d408..3fb3f13 100644 > --- a/block/raw_bsd.c > +++ b/block/raw_bsd.c > @@ -31,6 +31,30 @@ > #include "qapi/error.h" > #include "qemu/option.h" > =20 > +typedef struct BDRVRawState { > + uint64_t offset; > + uint64_t size; > + bool has_size; > +} BDRVRawState; > + > +static QemuOptsList raw_runtime_opts =3D { > + .name =3D "raw", > + .head =3D QTAILQ_HEAD_INITIALIZER(raw_runtime_opts.head), > + .desc =3D { > + { > + .name =3D "offset", > + .type =3D QEMU_OPT_SIZE, > + .help =3D "offset in the disk where the image starts", > + }, > + { > + .name =3D "size", > + .type =3D QEMU_OPT_SIZE, > + .help =3D "virtual disk size", > + }, > + { /* end of list */ } > + }, > +}; > + > static QemuOptsList raw_create_opts =3D { > .name =3D "raw-create-opts", > .head =3D QTAILQ_HEAD_INITIALIZER(raw_create_opts.head), > @@ -44,17 +68,107 @@ static QemuOptsList raw_create_opts =3D { > } > }; > =20 > +static int raw_read_options(QDict *options, BlockDriverState *bs, > + BDRVRawState *s, Error **errp) > +{ > + Error *local_err =3D NULL; > + QemuOpts *opts =3D NULL; > + int64_t real_size =3D 0; > + int ret; > + > + real_size =3D bdrv_getlength(bs->file->bs); > + if (real_size < 0) { > + error_setg_errno(errp, -real_size, "Could not get image size")= ; > + return real_size; > + } > + > + opts =3D qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort= ); > + qemu_opts_absorb_qdict(opts, options, &local_err); > + if (local_err) { > + error_propagate(errp, local_err); > + ret =3D -EINVAL; > + goto fail; > + } > + > + s->offset =3D qemu_opt_get_size(opts, "offset", 0); > + if (qemu_opt_find(opts, "size") !=3D NULL) { > + s->size =3D qemu_opt_get_size(opts, "size", 0); > + s->has_size =3D true; > + } else { > + s->has_size =3D false; > + s->size =3D real_size; > + } > + > + /* Check size and offset */ > + if (real_size < s->offset || (real_size - s->offset) < s->size) { > + error_setg(errp, "The sum of offset (%"PRIu64") and size " > + "(%"PRIu64") has to be smaller or equal to the " > + " actual size of the containing file (%"PRId64").", > + s->offset, s->size, real_size); > + ret =3D -EINVAL; > + goto fail; > + } > + > + /* Make sure size is multiple of BDRV_SECTOR_SIZE to prevent round= ing > + * up and leaking out of the specified area. */ > + if (s->size !=3D QEMU_ALIGN_DOWN(s->size, BDRV_SECTOR_SIZE)) { > + s->size =3D QEMU_ALIGN_DOWN(s->size, BDRV_SECTOR_SIZE); > + fprintf(stderr, > + "WARNING: Specified size is not multiple of %llu! " > + "Rounding down to %"PRIu64 ". (End of the image will be " > + "ignored.)\n", > + BDRV_SECTOR_SIZE, s->size); IMHO you should be using error_setg here - I don't see a compelling reason to let execution continue with incorrect values set. Regards, Daniel --=20 |: http://berrange.com -o- http://www.flickr.com/photos/dberrange= / :| |: http://libvirt.org -o- http://virt-manager.or= g :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr= / :|