xref: /kvmtool/disk/blk.c (revision 9f9207c5ad925aebcdad11d5145d2da0cd4a17aa)
1708dc6cbSAsias He #include "kvm/disk-image.h"
2708dc6cbSAsias He 
3*9f9207c5SSasha Levin #include <linux/err.h>
4*9f9207c5SSasha Levin 
5708dc6cbSAsias He /*
6708dc6cbSAsias He  * raw image and blk dev are similar, so reuse raw image ops.
7708dc6cbSAsias He  */
8063e87a0SAsias He static struct disk_image_operations blk_dev_ops = {
987ee33c8SAsias He 	.read_sector		= raw_image__read_sector,
1087ee33c8SAsias He 	.write_sector		= raw_image__write_sector,
1187ee33c8SAsias He 	.close			= raw_image__close,
12708dc6cbSAsias He };
13708dc6cbSAsias He 
14708dc6cbSAsias He struct disk_image *blkdev__probe(const char *filename, struct stat *st)
15708dc6cbSAsias He {
16708dc6cbSAsias He 	u64 size;
17*9f9207c5SSasha Levin 	int fd, r;
18708dc6cbSAsias He 
19708dc6cbSAsias He 	if (!S_ISBLK(st->st_mode))
20*9f9207c5SSasha Levin 		return ERR_PTR(-EINVAL);
21708dc6cbSAsias He 
22063e87a0SAsias He 	/*
23063e87a0SAsias He 	 * Be careful! We are opening host block device!
24063e87a0SAsias He 	 * Open it readonly since we do not want to break user's data on disk.
25063e87a0SAsias He 	 */
26708dc6cbSAsias He 	fd = open(filename, O_RDONLY);
27708dc6cbSAsias He 	if (fd < 0)
28*9f9207c5SSasha Levin 		return ERR_PTR(fd);
29708dc6cbSAsias He 
30708dc6cbSAsias He 	if (ioctl(fd, BLKGETSIZE64, &size) < 0) {
31*9f9207c5SSasha Levin 		r = -errno;
32708dc6cbSAsias He 		close(fd);
33*9f9207c5SSasha Levin 		return ERR_PTR(r);
34708dc6cbSAsias He 	}
35708dc6cbSAsias He 
36063e87a0SAsias He 	/*
37063e87a0SAsias He 	 * FIXME: This will not work on 32-bit host because we can not
38063e87a0SAsias He 	 * mmap large disk. There is not enough virtual address space
39063e87a0SAsias He 	 * in 32-bit host. However, this works on 64-bit host.
40063e87a0SAsias He 	 */
41063e87a0SAsias He 	return disk_image__new(fd, size, &blk_dev_ops, DISK_IMAGE_MMAP);
42708dc6cbSAsias He }
43