[libvirt] [PATCH RFC 01/48] util: Introduce virFileInData

Daniel P. Berrange berrange at redhat.com
Mon Jun 27 16:55:39 UTC 2016


On Wed, Jun 22, 2016 at 04:43:18PM +0200, Michal Privoznik wrote:
> This function takes a FD and determines whether the current
> position is in data section or in a hole. In addition to that,
> it also determines how much bytes are there remaining till the
> current section ends.
> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  src/libvirt_private.syms |  1 +
>  src/util/virfile.c       | 70 ++++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/virfile.h       |  4 +++
>  3 files changed, 75 insertions(+)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 501c23e..f476eae 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1513,6 +1513,7 @@ virFileGetHugepageSize;
>  virFileGetMountReverseSubtree;
>  virFileGetMountSubtree;
>  virFileHasSuffix;
> +virFileInData;
>  virFileIsAbsPath;
>  virFileIsDir;
>  virFileIsExecutable;
> diff --git a/src/util/virfile.c b/src/util/virfile.c
> index f47bf39..05b709a 100644
> --- a/src/util/virfile.c
> +++ b/src/util/virfile.c
> @@ -3443,3 +3443,73 @@ int virFileIsSharedFS(const char *path)
>                                   VIR_FILE_SHFS_SMB |
>                                   VIR_FILE_SHFS_CIFS);
>  }
> +
> +
> +int virFileInData(int fd,
> +                  int *inData,
> +                  unsigned long long *length)
> +{
> +    int ret = -1;
> +    off_t cur, data, hole;
> +
> +    /* Get current position */
> +    cur = lseek(fd, 0, SEEK_CUR);
> +    if (cur == (off_t) -1) {
> +        virReportSystemError(errno, "%s",
> +                             _("Unable to get current position in file"));
> +        goto cleanup;
> +    }
> +
> +    /* Now try to get data and hole offsets */
> +    data = lseek(fd, cur, SEEK_DATA);
> +
> +    /* There are four options:
> +     * 1) data == cur;  @cur is in data
> +     * 2) data > cur; @cur is in a hole, next data at @data
> +     * 3) data < 0, errno = ENXIO; either @cur is in trailing hole, or @cur is beyond EOF.
> +     * 4) data < 0, errno != ENXIO; we learned nothing
> +     */
> +
> +    if (data == (off_t) -1) {
> +        /* cases 3 and 4 */
> +        if (errno != ENXIO) {
> +            virReportSystemError(errno, "%s",
> +                                 _("Unable to seek to data"));
> +            goto cleanup;
> +        }
> +        *inData = 0;
> +        *length = 0;
> +    } else if (data > cur) {
> +        /* case 2 */
> +        *inData = 0;
> +        *length = data - cur;
> +    } else {
> +        /* case 1 */
> +        *inData = 1;
> +
> +        /* We don't know where does the next hole start. Let's
> +         * find out. Here we get the same 4 possibilities as
> +         * described above.*/
> +        hole = lseek(fd, data, SEEK_HOLE);
> +        if (hole == (off_t) -1 || hole == data) {
> +            /* cases 1, 3 and 4 */
> +            /* Wait a second. The reason why we are here is
> +             * because we are in data. But at the same time we
> +             * are in a trailing hole? Wut!? Do the best what we
> +             * can do here. */
> +            virReportSystemError(errno, "%s",
> +                                 _("unable to seek to hole"));
> +            goto cleanup;
> +        } else {
> +            /* case 2 */
> +            *length = (hole - data);
> +        }
> +    }
> +
> +    ret = 0;
> + cleanup:
> +    /* At any rate, reposition back to where we started. */
> +    if (cur != (off_t) -1)
> +        ignore_value(lseek(fd, cur, SEEK_SET));

Is it really safe to ignore the value here ?  IIUC, callers of this
function would be justified in thinking it would *not* have a side
effect on file position. IOW, I think we'd probably want to treat
this error as fatal too.

I think it'd be desirable to have a unit test written explicitly
for this function, since there's a few fun edge cases to worry
about here.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list