[libvirt PATCH v2 06/13] util: extract storage file probe code into virtstoragefileprobe.c

Pavel Hrdina phrdina at redhat.com
Fri Jan 22 09:09:27 UTC 2021


On Fri, Jan 22, 2021 at 09:23:00AM +0100, Peter Krempa wrote:
> On Thu, Jan 21, 2021 at 20:34:20 +0100, Pavel Hrdina wrote:
> > This code is not directly relevant to virStorageSource so move it to
> > separate file.
> > 
> > Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
> > ---
> >  po/POTFILES.in                        |   1 +
> >  src/libvirt_private.syms              |   6 +-
> >  src/qemu/qemu_driver.c                |   1 +
> >  src/storage/storage_backend_gluster.c |   1 +
> >  src/storage/storage_util.c            |   1 +
> >  src/util/meson.build                  |   1 +
> >  src/util/virstoragefile.c             | 939 +------------------------
> >  src/util/virstoragefile.h             |  11 -
> >  src/util/virstoragefileprobe.c        | 967 ++++++++++++++++++++++++++
> >  src/util/virstoragefileprobe.h        |  44 ++
> >  10 files changed, 1026 insertions(+), 946 deletions(-)
> >  create mode 100644 src/util/virstoragefileprobe.c
> >  create mode 100644 src/util/virstoragefileprobe.h
> 
> [...]
> 
> > diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
> > index 13a86f34e5..98a3222d09 100644
> > --- a/src/util/virstoragefile.c
> > +++ b/src/util/virstoragefile.c
> 
> [...]
> 
> > @@ -792,289 +146,6 @@ virStorageIsRelative(const char *backing)
> >  }
> >  
> >  
> > -static int
> > -virStorageFileProbeFormatFromBuf(const char *path,
> > -                                 char *buf,
> > -                                 size_t buflen)
> 
> I'd prefer if this is the function exported from the new module ...
> 
> > -{
> > -    int format = VIR_STORAGE_FILE_RAW;
> > -    size_t i;
> > -    int possibleFormat = VIR_STORAGE_FILE_RAW;
> > -    VIR_DEBUG("path=%s, buf=%p, buflen=%zu", path, buf, buflen);
> > -
> > -    /* First check file magic */
> > -    for (i = 0; i < VIR_STORAGE_FILE_LAST; i++) {
> > -        if (virStorageFileMatchesMagic(fileTypeInfo[i].magicOffset,
> > -                                       fileTypeInfo[i].magic,
> > -                                       buf, buflen)) {
> > -            if (!virStorageFileMatchesVersion(fileTypeInfo[i].versionOffset,
> > -                                              fileTypeInfo[i].versionSize,
> > -                                              fileTypeInfo[i].versionNumbers,
> > -                                              fileTypeInfo[i].endian,
> > -                                              buf, buflen)) {
> > -                possibleFormat = i;
> > -                continue;
> > -            }
> > -            format = i;
> > -            goto cleanup;
> > -        }
> > -    }
> > -
> > -    if (possibleFormat != VIR_STORAGE_FILE_RAW)
> > -        VIR_WARN("File %s matches %s magic, but version is wrong. "
> > -                 "Please report new version to libvir-list at redhat.com",
> > -                 path, virStorageFileFormatTypeToString(possibleFormat));
> > -
> > - cleanup:
> > -    VIR_DEBUG("format=%d", format);
> > -    return format;
> > -}
> 
> [...]
> 
> > -/**
> > - * virStorageFileProbeFormat:
> > - *
> > - * Probe for the format of 'path', returning the detected
> > - * disk format.
> > - *
> > - * Callers are advised never to trust the returned 'format'
> > - * unless it is listed as VIR_STORAGE_FILE_RAW, since a
> > - * malicious guest can turn a raw file into any other non-raw
> > - * format at will.
> > - *
> > - * Best option: Don't use this function
> > - */
> > -int
> > -virStorageFileProbeFormat(const char *path, uid_t uid, gid_t gid)
> > -{
> 
> ... and not this.
> 
> > -    struct stat sb;
> > -    ssize_t len = VIR_STORAGE_MAX_HEADER;
> > -    VIR_AUTOCLOSE fd = -1;
> > -    g_autofree char *header = NULL;
> > -
> > -    if ((fd = virFileOpenAs(path, O_RDONLY, 0, uid, gid, 0)) < 0) {
> 
> Specifically the new module should not ever touch any real storage and
> should just be a self-contained prober of metadata froma buffer.
> 
> > -        virReportSystemError(-fd, _("Failed to open file '%s'"), path);
> > -        return -1;
> > -    }
> > -
> > -    if (fstat(fd, &sb) < 0) {
> > -        virReportSystemError(errno, _("cannot stat file '%s'"), path);
> > -        return -1;
> > -    }
> > -
> > -    /* No header to probe for directories */
> > -    if (S_ISDIR(sb.st_mode))
> > -        return VIR_STORAGE_FILE_DIR;
> > -
> > -    if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
> > -        virReportSystemError(errno, _("cannot set to start of '%s'"), path);
> > -        return -1;
> > -    }
> > -
> > -    if ((len = virFileReadHeaderFD(fd, len, &header)) < 0) {
> > -        virReportSystemError(errno, _("cannot read header '%s'"), path);
> > -        return -1;
> > -    }
> > -
> > -    return virStorageFileProbeFormatFromBuf(path, header, len);
> > -}
> 
> [...]
> 
> > diff --git a/src/util/virstoragefileprobe.h b/src/util/virstoragefileprobe.h
> > new file mode 100644
> > index 0000000000..2b94a4ae51
> > --- /dev/null
> > +++ b/src/util/virstoragefileprobe.h
> > @@ -0,0 +1,44 @@
> > +/*
> > + * virstoragefileprobe.h: file utility functions for FS storage backend
> > + *
> > + * Copyright (C) 2007-2009, 2012-2016 Red Hat, Inc.
> > + * Copyright (C) 2007-2008 Daniel P. Berrange
> > + *
> > + * This library is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU Lesser General Public
> > + * License as published by the Free Software Foundation; either
> > + * version 2.1 of the License, or (at your option) any later version.
> > + *
> > + * This library is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General Public
> > + * License along with this library.  If not, see
> > + * <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#pragma once
> > +
> > +#include <sys/stat.h>
> 
> #include <sys/types.h> for uid_t/gid_t instead, there's no use of the
> stat struct in the header, but that shouldn't be necessary at all if the
> format is probed fromt he buffer directly.
> 
> > +
> > +#include "virstoragefile.h"
> > +
> > +/* Minimum header size required to probe all known formats with
> > + * virStorageFileProbeFormat, or obtain metadata from a known format.
> > + * Rounded to multiple of 512 (ISO has a 5-byte magic at offset
> > + * 32769).  Some formats can be probed with fewer bytes.  Although
> > + * some formats theoretically permit metadata that can rely on offsets
> > + * beyond this size, in practice that doesn't matter.  */
> > +#define VIR_STORAGE_MAX_HEADER 0x8200
> > +
> > +int
> > +virStorageFileProbeGetMetadata(virStorageSourcePtr meta,
> > +                               char *buf,
> > +                               size_t len);
> > +
> > +int
> > +virStorageFileProbeFormat(const char *path,
> > +                          uid_t uid,
> > +                          gid_t gid);
> 
> Reviewed-by: Peter Krempa <pkrempa at redhat.com>
> 
> If you decide that it's too much hassle to shuffle this around, you can
> return the code opening the file back to the appropriate file later.
> 
> (Or I'll do it, if you don't, but virstoragefileprobe.c will not
> 'open()' anything in the end)

Make sense, I'll look into it and post v3.

Thanks,

Pavel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20210122/858e6790/attachment-0001.sig>


More information about the libvir-list mailing list