[libvirt] [PATCH] Don't squash file format on volume refresh

Daniel P. Berrange berrange at redhat.com
Thu Apr 2 18:45:29 UTC 2009


On Thu, Apr 02, 2009 at 02:01:02PM -0400, Cole Robinson wrote:
> A while back, code was added to
> storage_backend.c:virStorageBackendUpdateVolTargetInfoFD to try to
> determine the volume format for iscsi volumes. Unfortunately this
> function is also called for refreshing file volumes, which has the
> effect of setting the format as 'raw' whenever a volume is refreshed
> (ex. after calling virsh vol-info).
> 
> The attached patch moves the offending code into a wrapper function in
> the scsi driver. I haven't played with the scsi support yet so this is
> untested though it's largely code movement.

Ahhh, this is also what breaks the storage_backend_disk driver
with it blowing away the partition types for each partition.

ACK


> commit eda7654e5e63aa4a64cdcc7f38d8e40c14197af1
> Author: Cole Robinson <crobinso at redhat.com>
> Date:   Thu Apr 2 13:37:40 2009 -0400
> 
>     Don't lose file format info on volume refresh.
> 
> diff --git a/src/storage_backend.c b/src/storage_backend.c
> index d9ffaee..b154140 100644
> --- a/src/storage_backend.c
> +++ b/src/storage_backend.c
> @@ -156,37 +156,6 @@ virStorageBackendUpdateVolInfo(virConnectPtr conn,
>      return 0;
>  }
>  
> -struct diskType {
> -    int part_table_type;
> -    unsigned short offset;
> -    unsigned short length;
> -    unsigned long long magic;
> -};
> -
> -static struct diskType const disk_types[] = {
> -    { VIR_STORAGE_POOL_DISK_LVM2, 0x218, 8, 0x31303020324D564CULL },
> -    { VIR_STORAGE_POOL_DISK_GPT,  0x200, 8, 0x5452415020494645ULL },
> -    { VIR_STORAGE_POOL_DISK_DVH,  0x0,   4, 0x41A9E50BULL },
> -    { VIR_STORAGE_POOL_DISK_MAC,  0x0,   2, 0x5245ULL },
> -    { VIR_STORAGE_POOL_DISK_BSD,  0x40,  4, 0x82564557ULL },
> -    { VIR_STORAGE_POOL_DISK_SUN,  0x1fc, 2, 0xBEDAULL },
> -    /*
> -     * NOTE: pc98 is funky; the actual signature is 0x55AA (just like dos), so
> -     * we can't use that.  At the moment I'm relying on the "dummy" IPL
> -     * bootloader data that comes from parted.  Luckily, the chances of running
> -     * into a pc98 machine running libvirt are approximately nil.
> -     */
> -    /*{ 0x1fe, 2, 0xAA55UL },*/
> -    { VIR_STORAGE_POOL_DISK_PC98, 0x0,   8, 0x314C5049000000CBULL },
> -    /*
> -     * NOTE: the order is important here; some other disk types (like GPT and
> -     * and PC98) also have 0x55AA at this offset.  For that reason, the DOS
> -     * one must be the last one.
> -     */
> -    { VIR_STORAGE_POOL_DISK_DOS,  0x1fe, 2, 0xAA55ULL },
> -    { -1,                         0x0,   0, 0x0ULL },
> -};
> -
>  int
>  virStorageBackendUpdateVolTargetInfoFD(virConnectPtr conn,
>                                         virStorageVolTargetPtr target,
> @@ -244,41 +213,6 @@ virStorageBackendUpdateVolTargetInfoFD(virConnectPtr conn,
>          }
>      }
>  
> -    if (S_ISBLK(sb.st_mode)) {
> -        off_t start;
> -        int i;
> -        unsigned char buffer[1024];
> -        ssize_t bytes;
> -
> -        /* make sure to set the target format "unknown" to begin with */
> -        target->format = VIR_STORAGE_POOL_DISK_UNKNOWN;
> -
> -        start = lseek(fd, 0, SEEK_SET);
> -        if (start < 0) {
> -            virReportSystemError(conn, errno,
> -                                 _("cannot seek to beginning of file '%s'"),
> -                                 target->path);
> -            return -1;
> -        }
> -        bytes = saferead(fd, buffer, sizeof(buffer));
> -        if (bytes < 0) {
> -            virReportSystemError(conn, errno,
> -                                 _("cannot read beginning of file '%s'"),
> -                                 target->path);
> -            return -1;
> -        }
> -
> -        for (i = 0; disk_types[i].part_table_type != -1; i++) {
> -            if (disk_types[i].offset + disk_types[i].length > bytes)
> -                continue;
> -            if (memcmp(buffer+disk_types[i].offset, &disk_types[i].magic,
> -                disk_types[i].length) == 0) {
> -                target->format = disk_types[i].part_table_type;
> -                break;
> -            }
> -        }
> -    }
> -
>      target->perms.mode = sb.st_mode & S_IRWXUGO;
>      target->perms.uid = sb.st_uid;
>      target->perms.gid = sb.st_gid;
> diff --git a/src/storage_backend_scsi.c b/src/storage_backend_scsi.c
> index a962d1c..b3e6180 100644
> --- a/src/storage_backend_scsi.c
> +++ b/src/storage_backend_scsi.c
> @@ -100,6 +100,92 @@ out:
>      return retval;
>  }
>  
> +struct diskType {
> +    int part_table_type;
> +    unsigned short offset;
> +    unsigned short length;
> +    unsigned long long magic;
> +};
> +
> +static struct diskType const disk_types[] = {
> +    { VIR_STORAGE_POOL_DISK_LVM2, 0x218, 8, 0x31303020324D564CULL },
> +    { VIR_STORAGE_POOL_DISK_GPT,  0x200, 8, 0x5452415020494645ULL },
> +    { VIR_STORAGE_POOL_DISK_DVH,  0x0,   4, 0x41A9E50BULL },
> +    { VIR_STORAGE_POOL_DISK_MAC,  0x0,   2, 0x5245ULL },
> +    { VIR_STORAGE_POOL_DISK_BSD,  0x40,  4, 0x82564557ULL },
> +    { VIR_STORAGE_POOL_DISK_SUN,  0x1fc, 2, 0xBEDAULL },
> +    /*
> +     * NOTE: pc98 is funky; the actual signature is 0x55AA (just like dos), so
> +     * we can't use that.  At the moment I'm relying on the "dummy" IPL
> +     * bootloader data that comes from parted.  Luckily, the chances of running
> +     * into a pc98 machine running libvirt are approximately nil.
> +     */
> +    /*{ 0x1fe, 2, 0xAA55UL },*/
> +    { VIR_STORAGE_POOL_DISK_PC98, 0x0,   8, 0x314C5049000000CBULL },
> +    /*
> +     * NOTE: the order is important here; some other disk types (like GPT and
> +     * and PC98) also have 0x55AA at this offset.  For that reason, the DOS
> +     * one must be the last one.
> +     */
> +    { VIR_STORAGE_POOL_DISK_DOS,  0x1fe, 2, 0xAA55ULL },
> +    { -1,                         0x0,   0, 0x0ULL },
> +};
> +
> +static int
> +virStorageBackendSCSIUpdateVolTargetInfo(virConnectPtr conn,
> +                                         virStorageVolTargetPtr target,
> +                                         unsigned long long *allocation,
> +                                         unsigned long long *capacity)
> +{
> +    int fd, i;
> +    off_t start;
> +    unsigned char buffer[1024];
> +    ssize_t bytes;
> +
> +    if ((fd = open(target->path, O_RDONLY)) < 0) {
> +        virReportSystemError(conn, errno,
> +                             _("cannot open volume '%s'"),
> +                             target->path);
> +        return -1;
> +    }
> +
> +    if (virStorageBackendUpdateVolTargetInfoFD(conn,
> +                                               target,
> +                                               fd,
> +                                               allocation,
> +                                               capacity) < 0)
> +        return -1;
> +
> +    /* make sure to set the target format "unknown" to begin with */
> +    target->format = VIR_STORAGE_POOL_DISK_UNKNOWN;
> +
> +    start = lseek(fd, 0, SEEK_SET);
> +    if (start < 0) {
> +        virReportSystemError(conn, errno,
> +                             _("cannot seek to beginning of file '%s'"),
> +                             target->path);
> +        return -1;
> +    }
> +    bytes = saferead(fd, buffer, sizeof(buffer));
> +    if (bytes < 0) {
> +        virReportSystemError(conn, errno,
> +                             _("cannot read beginning of file '%s'"),
> +                             target->path);
> +        return -1;
> +    }
> +
> +    for (i = 0; disk_types[i].part_table_type != -1; i++) {
> +        if (disk_types[i].offset + disk_types[i].length > bytes)
> +            continue;
> +        if (memcmp(buffer+disk_types[i].offset, &disk_types[i].magic,
> +            disk_types[i].length) == 0) {
> +            target->format = disk_types[i].part_table_type;
> +            break;
> +        }
> +    }
> +
> +    return 0;
> +}
>  
>  static int
>  virStorageBackendSCSINewLun(virConnectPtr conn,
> @@ -160,10 +246,10 @@ virStorageBackendSCSINewLun(virConnectPtr conn,
>          goto free_vol;
>      }
>  
> -    if (virStorageBackendUpdateVolTargetInfo(conn,
> -                                             &vol->target,
> -                                             &vol->allocation,
> -                                             &vol->capacity) < 0) {
> +    if (virStorageBackendSCSIUpdateVolTargetInfo(conn,
> +                                                 &vol->target,
> +                                                 &vol->allocation,
> +                                                 &vol->capacity) < 0) {
>  
>          virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
>                                _("Failed to update volume for '%s'"),


Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list