Chris Lalancette wrote: > To support LVM partitioning in oVirt, one of the things we need is the ability > to tell what kind of label is currently on a block device. Here, a 'label' is > used in the same sense that it is used in parted; namely, it defines which kind > of partition table is on the disk, whether it be DOS, LVM2, SUN, BSD, etc. Note > that this is different than the partition type; those are things like Linux, > FAT16, FAT32, etc. Updated patch based on jim's feedback. I did not remove the pc98 type; if everyone else thinks it's a good idea, I'll remove it, but it is part of the ABI in some sense. Otherwise, I followed all of jim's suggestions. -- Chris Lalancette
Index: src/storage_backend.c =================================================================== RCS file: /data/cvs/libvirt/src/storage_backend.c,v retrieving revision 1.21 diff -u -r1.21 storage_backend.c --- src/storage_backend.c 5 Sep 2008 12:03:45 -0000 1.21 +++ src/storage_backend.c 16 Oct 2008 09:49:01 -0000 @@ -192,6 +192,30 @@ return ret; } +struct diskType disk_types[] = { + { "lvm2", VIR_STORAGE_POOL_DISK_LVM2, 0x218, 8, 0x31303020324D564CUL }, + { "gpt", VIR_STORAGE_POOL_DISK_GPT, 0x200, 8, 0x5452415020494645UL }, + { "dvh", VIR_STORAGE_POOL_DISK_DVH, 0x0, 4, 0x41A9E50BUL }, + { "mac", VIR_STORAGE_POOL_DISK_MAC, 0x0, 2, 0x5245UL }, + { "bsd", VIR_STORAGE_POOL_DISK_BSD, 0x40, 4, 0x82564557UL }, + { "sun", VIR_STORAGE_POOL_DISK_SUN, 0x1fc, 2, 0xBEDAUL }, + /* + * 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. + */ + /*{ "pc98", 0x1fe, 2, 0xAA55UL },*/ + { "pc98", VIR_STORAGE_POOL_DISK_PC98, 0x0, 8, 0x314C5049000000CBUL }, + /* + * 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. + */ + { "dos", VIR_STORAGE_POOL_DISK_DOS, 0x1fe, 2, 0xAA55UL }, + { NULL, -1, 0x0, 0, 0x0UL }, +}; + int virStorageBackendUpdateVolInfoFD(virConnectPtr conn, virStorageVolDefPtr vol, @@ -245,6 +269,41 @@ if (withCapacity) vol->capacity = end; } + /* make sure to set the target format "unknown" to begin with */ + vol->target.format = VIR_STORAGE_POOL_DISK_UNKNOWN; + + if (S_ISBLK(sb.st_mode)) { + off_t start; + int i; + unsigned char buffer[1024]; + ssize_t bytes; + + start = lseek(fd, 0, SEEK_SET); + if (start < 0) { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("cannot seek to beginning of file '%s':%s"), + vol->target.path, strerror(errno)); + return -1; + } + bytes = saferead(fd, buffer, sizeof(buffer)); + if (bytes < 0) { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("cannot read beginning of file '%s':%s"), + vol->target.path, strerror(errno)); + return -1; + } + + for (i = 0; disk_types[i].name != NULL; 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) { + vol->target.format = disk_types[i].part_table_type; + break; + } + } + } + vol->target.perms.mode = sb.st_mode; vol->target.perms.uid = sb.st_uid; vol->target.perms.gid = sb.st_gid; @@ -348,6 +407,34 @@ return devpath; } +int +virStorageBackendDiskLabelFormatFromString(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *format) { + int i; + + if (format == NULL) + return VIR_STORAGE_POOL_DISK_UNKNOWN; + + for (i = 0; disk_types[i].name != NULL; i++) { + if (STREQ(format, disk_types[i].name)) + return disk_types[i].part_table_type; + } + + return VIR_STORAGE_POOL_DISK_UNKNOWN; +} + +const char * +virStorageBackendDiskLabelFormatToString(virConnectPtr conn ATTRIBUTE_UNUSED, + int format) { + int i; + + for (i = 0; disk_types[i].name != NULL; i++) { + if (format == disk_types[i].part_table_type) + return disk_types[i].name; + } + + return "unknown"; +} #ifndef __MINGW32__ /* Index: src/storage_backend.h =================================================================== RCS file: /data/cvs/libvirt/src/storage_backend.h,v retrieving revision 1.7 diff -u -r1.7 storage_backend.h --- src/storage_backend.h 2 Sep 2008 14:15:42 -0000 1.7 +++ src/storage_backend.h 16 Oct 2008 09:49:01 -0000 @@ -56,6 +56,29 @@ VIR_STORAGE_BACKEND_POOL_SOURCE_NAME = (1<<4), }; +enum partTableType { + VIR_STORAGE_POOL_DISK_DOS = 1, + VIR_STORAGE_POOL_DISK_DVH, + VIR_STORAGE_POOL_DISK_GPT, + VIR_STORAGE_POOL_DISK_MAC, + VIR_STORAGE_POOL_DISK_BSD, + VIR_STORAGE_POOL_DISK_PC98, + VIR_STORAGE_POOL_DISK_SUN, + VIR_STORAGE_POOL_DISK_LVM2, + /* the "unknown" disk is 1 billion (and not, for instance, -1), to make + sure it doesn't run afoul of error checking */ + VIR_STORAGE_POOL_DISK_UNKNOWN = 1 * 1024 * 1024 * 1024, +}; + +struct diskType { + const char *name; + enum partTableType part_table_type; + unsigned short offset; + unsigned short length; + unsigned long long magic; +}; +extern struct diskType disk_types[]; + typedef struct _virStorageBackendPoolOptions virStorageBackendPoolOptions; typedef virStorageBackendPoolOptions *virStorageBackendPoolOptionsPtr; struct _virStorageBackendPoolOptions { @@ -132,6 +155,11 @@ char **const groups, void *data); +int virStorageBackendDiskLabelFormatFromString(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *format); +const char *virStorageBackendDiskLabelFormatToString(virConnectPtr conn ATTRIBUTE_UNUSED, + int format); + int virStorageBackendRunProgRegex(virConnectPtr conn, virStoragePoolObjPtr pool, const char *const*prog, Index: src/storage_backend_disk.c =================================================================== RCS file: /data/cvs/libvirt/src/storage_backend_disk.c,v retrieving revision 1.14 diff -u -r1.14 storage_backend_disk.c --- src/storage_backend_disk.c 13 Oct 2008 16:46:29 -0000 1.14 +++ src/storage_backend_disk.c 16 Oct 2008 09:49:01 -0000 @@ -30,16 +30,6 @@ #include "util.h" #include "memory.h" -enum { - VIR_STORAGE_POOL_DISK_DOS = 0, - VIR_STORAGE_POOL_DISK_DVH, - VIR_STORAGE_POOL_DISK_GPT, - VIR_STORAGE_POOL_DISK_MAC, - VIR_STORAGE_POOL_DISK_BSD, - VIR_STORAGE_POOL_DISK_PC98, - VIR_STORAGE_POOL_DISK_SUN, -}; - /* * XXX these are basically partition types. * @@ -63,57 +53,6 @@ #define PARTHELPER BINDIR "/libvirt_parthelper" static int -virStorageBackendDiskPoolFormatFromString(virConnectPtr conn, - const char *format) { - if (format == NULL) - return VIR_STORAGE_POOL_DISK_DOS; - - if (STREQ(format, "dos")) - return VIR_STORAGE_POOL_DISK_DOS; - if (STREQ(format, "dvh")) - return VIR_STORAGE_POOL_DISK_DVH; - if (STREQ(format, "gpt")) - return VIR_STORAGE_POOL_DISK_GPT; - if (STREQ(format, "mac")) - return VIR_STORAGE_POOL_DISK_MAC; - if (STREQ(format, "bsd")) - return VIR_STORAGE_POOL_DISK_BSD; - if (STREQ(format, "pc98")) - return VIR_STORAGE_POOL_DISK_PC98; - if (STREQ(format, "sun")) - return VIR_STORAGE_POOL_DISK_SUN; - - virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("unsupported pool format %s"), format); - return -1; -} - -static const char * -virStorageBackendDiskPoolFormatToString(virConnectPtr conn, - int format) { - switch (format) { - case VIR_STORAGE_POOL_DISK_DOS: - return "dos"; - case VIR_STORAGE_POOL_DISK_DVH: - return "dvh"; - case VIR_STORAGE_POOL_DISK_GPT: - return "gpt"; - case VIR_STORAGE_POOL_DISK_MAC: - return "mac"; - case VIR_STORAGE_POOL_DISK_BSD: - return "bsd"; - case VIR_STORAGE_POOL_DISK_PC98: - return "pc98"; - case VIR_STORAGE_POOL_DISK_SUN: - return "sun"; - } - - virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("unsupported pool format %d"), format); - return NULL; -} - -static int virStorageBackendDiskVolFormatFromString(virConnectPtr conn, const char *format) { if (format == NULL) @@ -414,8 +353,8 @@ "mklabel", "--script", ((pool->def->source.format == VIR_STORAGE_POOL_DISK_DOS) ? "msdos" : - virStorageBackendDiskPoolFormatToString(conn, - pool->def->source.format)), + virStorageBackendDiskLabelFormatToString(conn, + pool->def->source.format)), NULL, }; @@ -557,8 +496,8 @@ .poolOptions = { .flags = (VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE), - .formatFromString = virStorageBackendDiskPoolFormatFromString, - .formatToString = virStorageBackendDiskPoolFormatToString, + .formatFromString = virStorageBackendDiskLabelFormatFromString, + .formatToString = virStorageBackendDiskLabelFormatToString, }, .volOptions = { .formatFromString = virStorageBackendDiskVolFormatFromString, Index: src/storage_backend_iscsi.c =================================================================== RCS file: /data/cvs/libvirt/src/storage_backend_iscsi.c,v retrieving revision 1.14 diff -u -r1.14 storage_backend_iscsi.c --- src/storage_backend_iscsi.c 10 Oct 2008 15:13:28 -0000 1.14 +++ src/storage_backend_iscsi.c 16 Oct 2008 09:49:02 -0000 @@ -636,18 +636,20 @@ return 0; } - virStorageBackend virStorageBackendISCSI = { - .type = VIR_STORAGE_POOL_ISCSI, + .type = VIR_STORAGE_POOL_ISCSI, - .startPool = virStorageBackendISCSIStartPool, - .refreshPool = virStorageBackendISCSIRefreshPool, - .stopPool = virStorageBackendISCSIStopPool, + .startPool = virStorageBackendISCSIStartPool, + .refreshPool = virStorageBackendISCSIRefreshPool, + .stopPool = virStorageBackendISCSIStopPool, - .poolOptions = { + .poolOptions = { .flags = (VIR_STORAGE_BACKEND_POOL_SOURCE_HOST | VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE) }, - .volType = VIR_STORAGE_VOL_BLOCK, + .volType = VIR_STORAGE_VOL_BLOCK, + .volOptions = { + .formatToString = virStorageBackendDiskLabelFormatToString, + } };
-- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list