#include "kvm/disk-image.h" #include #include /* * raw image and blk dev are similar, so reuse raw image ops. */ static struct disk_image_operations blk_dev_ops = { .read = raw_image__read, .write = raw_image__write, .wait = raw_image__wait, .async = true, }; static bool is_mounted(struct stat *st) { struct stat st_buf; struct mntent *mnt; FILE *f; f = setmntent("/proc/mounts", "r"); if (!f) return false; while ((mnt = getmntent(f)) != NULL) { if (stat(mnt->mnt_fsname, &st_buf) == 0 && S_ISBLK(st_buf.st_mode) && st->st_rdev == st_buf.st_rdev) { fclose(f); return true; } } fclose(f); return false; } struct disk_image *blkdev__probe(const char *filename, int flags, struct stat *st) { int fd, r; u64 size; if (!S_ISBLK(st->st_mode)) return ERR_PTR(-EINVAL); if (is_mounted(st)) { pr_err("Block device %s is already mounted! Unmount before use.", filename); return ERR_PTR(-EINVAL); } /* * Be careful! We are opening host block device! * Open it readonly since we do not want to break user's data on disk. */ fd = open(filename, flags); if (fd < 0) return ERR_PTR(fd); if (ioctl(fd, BLKGETSIZE64, &size) < 0) { r = -errno; close(fd); return ERR_PTR(r); } /* * FIXME: This will not work on 32-bit host because we can not * mmap large disk. There is not enough virtual address space * in 32-bit host. However, this works on 64-bit host. */ return disk_image__new(fd, size, &blk_dev_ops, DISK_IMAGE_REGULAR); }