From ca7c891bfee4076bdc4d973120af7e6b5ea5a000 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Thu, 6 Jan 2011 01:37:29 +0300 Subject: [PATCH] kvm: Setup disk geometry if needed Signed-off-by: Cyrill Gorcunov --- blk-virtio.c | 10 +++++++++- disk-image.c | 31 +++++++++++++++++++++++++++++++ include/kvm/blk-virtio.h | 4 +++- include/kvm/disk-image.h | 4 ++++ main.c | 2 +- 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/blk-virtio.c b/blk-virtio.c index a284e30..da295bc 100644 --- a/blk-virtio.c +++ b/blk-virtio.c @@ -230,8 +230,16 @@ static struct pci_device_header blk_virtio_pci_device = { .irq_line = VIRTIO_BLK_IRQ, }; -void blk_virtio__init(void) +void blk_virtio__init(struct kvm *self) { + /* update disk geometry */ + if (self->disk_image) { + device.blk_config.capacity = self->disk_image->size; + device.blk_config.geometry.cylinders = self->disk_image->cylinders; + device.blk_config.geometry.heads = self->disk_image->heads; + device.blk_config.geometry.sectors = self->disk_image->sectors; + } + pci__register(&blk_virtio_pci_device, 1); ioport__register(IOPORT_VIRTIO, &blk_virtio_io_ops, 256); diff --git a/disk-image.c b/disk-image.c index fad6f6f..7ac16e4 100644 --- a/disk-image.c +++ b/disk-image.c @@ -17,6 +17,7 @@ struct disk_image *disk_image__open(const char *filename) { struct disk_image *self; struct stat st; + int cylinders, heads, sectors; self = malloc(sizeof *self); if (!self) @@ -35,6 +36,36 @@ struct disk_image *disk_image__open(const char *filename) if (self->mmap == MAP_FAILED) goto failed_close_fd; + /* + * set the standart disk geometry of the image + * + * real disk example + * Disk /dev/sda: 500.1 GB, 500107862016 bytes + * 255 heads, 63 sectors/track, 60801 cylinders, total 976773168 sectors + */ + cylinders = (self->size >> SECTOR_SHIFT) / 16383; + if (cylinders > 16383) + cylinders = 16383; + else if (cylinders < 2) + cylinders = 2; + heads = (self->size >> SECTOR_SHIFT) / cylinders; + if (heads > 255) + heads = 255; + else if (heads < 1) + heads = 1; + sectors = (self->size >> SECTOR_SHIFT) / cylinders / heads; + if (sectors > 255) + sectors = 255; + else if (sectors < 1) + sectors = 1; + + self->sectors = sectors; + self->heads = heads; + self->cylinders = cylinders; + + info("block image geometry: sectors: %d heads: %d cylinders: %d", + sectors, heads, cylinders); + return self; failed_close_fd: diff --git a/include/kvm/blk-virtio.h b/include/kvm/blk-virtio.h index f108291..02f39df 100644 --- a/include/kvm/blk-virtio.h +++ b/include/kvm/blk-virtio.h @@ -1,6 +1,8 @@ #ifndef KVM__BLK_VIRTIO_H #define KVM__BLK_VIRTIO_H -void blk_virtio__init(void); +struct kvm; + +void blk_virtio__init(struct kvm *self); #endif /* KVM__BLK_VIRTIO_H */ diff --git a/include/kvm/disk-image.h b/include/kvm/disk-image.h index 6cba338..ed6c580 100644 --- a/include/kvm/disk-image.h +++ b/include/kvm/disk-image.h @@ -7,6 +7,10 @@ struct disk_image { void *mmap; int fd; uint64_t size; + + uint16_t cylinders; + uint8_t heads; + uint8_t sectors; }; struct disk_image *disk_image__open(const char *filename); diff --git a/main.c b/main.c index e87eb8f..09c17c6 100644 --- a/main.c +++ b/main.c @@ -134,7 +134,7 @@ int main(int argc, char *argv[]) pci__init(); if (enable_virtio) - blk_virtio__init(); + blk_virtio__init(kvm); for (;;) { kvm__run(kvm);