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
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list