diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 395c1df948..25206a1044 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -1116,6 +1116,80 @@ virStorageBackendForType(int type) } +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 +virStorageBackendDetectBlockVolFormatFD(virStorageVolTargetPtr target, + int fd) +{ + size_t i; + off_t start; + 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(errno, + _("cannot seek to beginning of file '%s'"), + target->path); + return -1; + } + bytes = saferead(fd, buffer, sizeof(buffer)); + if (bytes < 0) { + virReportSystemError(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; +} + + /* * Allows caller to silently ignore files with improper mode * @@ -1217,22 +1291,30 @@ int virStorageBackendUpdateVolTargetInfo(virStorageVolTargetPtr target, unsigned long long *allocation, unsigned long long *capacity, + bool withBlockVolFormat, unsigned int openflags) { - int ret, fd; + int ret, fd = -1; struct stat sb; if ((ret = virStorageBackendVolOpenCheckMode(target->path, &sb, openflags)) < 0) - return ret; - + goto cleanup; fd = ret; - ret = virStorageBackendUpdateVolTargetInfoFD(target, - fd, - &sb, - allocation, - capacity); + if ((ret = virStorageBackendUpdateVolTargetInfoFD(target, + fd, + &sb, + allocation, + capacity)) < 0) + goto cleanup; + + if (withBlockVolFormat) { + if ((ret = virStorageBackendDetectBlockVolFormatFD(target, fd)) < 0) + goto cleanup; + } + + cleanup: VIR_FORCE_CLOSE(fd); return ret; @@ -1241,6 +1323,7 @@ virStorageBackendUpdateVolTargetInfo(virStorageVolTargetPtr target, int virStorageBackendUpdateVolInfo(virStorageVolDefPtr vol, bool withCapacity, + bool withBlockVolFormat, unsigned int openflags) { int ret; @@ -1248,12 +1331,14 @@ virStorageBackendUpdateVolInfo(virStorageVolDefPtr vol, if ((ret = virStorageBackendUpdateVolTargetInfo(&vol->target, &vol->allocation, withCapacity ? &vol->capacity : NULL, + withBlockVolFormat, openflags)) < 0) return ret; if (vol->backingStore.path && (ret = virStorageBackendUpdateVolTargetInfo(&vol->backingStore, NULL, NULL, + withBlockVolFormat, VIR_STORAGE_VOL_OPEN_DEFAULT)) < 0) return ret; @@ -1358,80 +1443,6 @@ virStorageBackendUpdateVolTargetInfoFD(virStorageVolTargetPtr target, } -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 -virStorageBackendDetectBlockVolFormatFD(virStorageVolTargetPtr target, - int fd) -{ - size_t i; - off_t start; - 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(errno, - _("cannot seek to beginning of file '%s'"), - target->path); - return -1; - } - bytes = saferead(fd, buffer, sizeof(buffer)); - if (bytes < 0) { - virReportSystemError(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; -} - - /* * Given a volume path directly in /dev/XXX, iterate over the * entries in the directory pool->def->target.path and find the diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h index 085951d76a..9283d2b4fa 100644 --- a/src/storage/storage_backend.h +++ b/src/storage/storage_backend.h @@ -116,19 +116,18 @@ int virStorageBackendVolOpenCheckMode(const char *path, struct stat *sb, int virStorageBackendUpdateVolInfo(virStorageVolDefPtr vol, bool withCapacity, + bool withBlockVolFormat, unsigned int openflags); int virStorageBackendUpdateVolTargetInfo(virStorageVolTargetPtr target, unsigned long long *allocation, unsigned long long *capacity, + bool withBlockVolFormat, unsigned int openflags); int virStorageBackendUpdateVolTargetInfoFD(virStorageVolTargetPtr target, int fd, struct stat *sb, unsigned long long *allocation, unsigned long long *capacity); -int -virStorageBackendDetectBlockVolFormatFD(virStorageVolTargetPtr target, - int fd); char *virStorageBackendStablePath(virStoragePoolObjPtr pool, const char *devpath, diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c index feaaf466d8..b9609dd29e 100644 --- a/src/storage/storage_backend_disk.c +++ b/src/storage/storage_backend_disk.c @@ -115,7 +115,7 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr pool, } /* Refresh allocation/capacity/perms */ - if (virStorageBackendUpdateVolInfo(vol, true, + if (virStorageBackendUpdateVolInfo(vol, true, false, VIR_STORAGE_VOL_OPEN_DEFAULT) < 0) return -1; diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index 6c54478397..377cd67721 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -875,7 +875,7 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED, vol->backingStore.format = backingStoreFormat; if (virStorageBackendUpdateVolTargetInfo(&vol->backingStore, - NULL, NULL, + NULL, NULL, false, VIR_STORAGE_VOL_OPEN_DEFAULT) < 0) { /* The backing file is currently unavailable, the capacity, * allocation, owner, group and mode are unknown. Just log the @@ -1164,7 +1164,7 @@ virStorageBackendFileSystemVolRefresh(virConnectPtr conn, int ret; /* Refresh allocation / permissions info in case its changed */ - ret = virStorageBackendUpdateVolInfo(vol, false, + ret = virStorageBackendUpdateVolInfo(vol, false, false, VIR_STORAGE_VOL_FS_OPEN_FLAGS); if (ret < 0) return ret; diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c index 7604ff3ccb..2417f68a24 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -136,7 +136,7 @@ virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool, if (!vol->key && VIR_STRDUP(vol->key, groups[2]) < 0) goto cleanup; - if (virStorageBackendUpdateVolInfo(vol, true, + if (virStorageBackendUpdateVolInfo(vol, true, false, VIR_STORAGE_VOL_OPEN_DEFAULT) < 0) goto cleanup; diff --git a/src/storage/storage_backend_mpath.c b/src/storage/storage_backend_mpath.c index 1e65a8d3cb..7ae1547f64 100644 --- a/src/storage/storage_backend_mpath.c +++ b/src/storage/storage_backend_mpath.c @@ -39,37 +39,6 @@ #define VIR_FROM_THIS VIR_FROM_STORAGE -static int -virStorageBackendMpathUpdateVolTargetInfo(virStorageVolTargetPtr target, - unsigned long long *allocation, - unsigned long long *capacity) -{ - int ret = -1; - int fdret, fd = -1; - struct stat sb; - - if ((fdret = virStorageBackendVolOpenCheckMode(target->path, &sb, - VIR_STORAGE_VOL_OPEN_DEFAULT)) < 0) - goto out; - fd = fdret; - - if (virStorageBackendUpdateVolTargetInfoFD(target, - fd, - &sb, - allocation, - capacity) < 0) - goto out; - - if (virStorageBackendDetectBlockVolFormatFD(target, fd) < 0) - goto out; - - ret = 0; -out: - VIR_FORCE_CLOSE(fd); - return ret; -} - - static int virStorageBackendMpathNewVol(virStoragePoolObjPtr pool, const int devnum, @@ -89,9 +58,8 @@ virStorageBackendMpathNewVol(virStoragePoolObjPtr pool, if (virAsprintf(&vol->target.path, "/dev/%s", dev) < 0) goto cleanup; - if (virStorageBackendMpathUpdateVolTargetInfo(&vol->target, - &vol->allocation, - &vol->capacity) < 0) { + if (virStorageBackendUpdateVolInfo(vol, true, true, + VIR_STORAGE_VOL_OPEN_DEFAULT) < 0) { goto cleanup; } diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 14261217af..9c38ca24c6 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -100,70 +100,6 @@ 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(virStorageVolTargetPtr target, - unsigned long long *allocation, - unsigned long long *capacity) -{ - int fdret, fd = -1; - int ret = -1; - struct stat sb; - - if ((fdret = virStorageBackendVolOpenCheckMode(target->path, &sb, - VIR_STORAGE_VOL_OPEN_DEFAULT)) < 0) - goto cleanup; - fd = fdret; - - if (virStorageBackendUpdateVolTargetInfoFD(target, - fd, - &sb, - allocation, - capacity) < 0) - goto cleanup; - - if (virStorageBackendDetectBlockVolFormatFD(target, fd) < 0) - goto cleanup; - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - - return ret; -} - - static char * virStorageBackendSCSISerial(const char *dev) { @@ -261,10 +197,8 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr pool, goto free_vol; } - if (virStorageBackendSCSIUpdateVolTargetInfo(&vol->target, - &vol->allocation, - &vol->capacity) < 0) { - + if (virStorageBackendUpdateVolInfo(vol, true, true, + VIR_STORAGE_VOL_OPEN_DEFAULT) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to update volume for '%s'"), devpath);