1 #include "kvm/disk-image.h" 2 #include "kvm/qcow.h" 3 #include "kvm/virtio-blk.h" 4 5 #include <linux/err.h> 6 #include <sys/eventfd.h> 7 #include <sys/poll.h> 8 9 #define AIO_MAX 32 10 11 int debug_iodelay; 12 13 #ifdef CONFIG_HAS_AIO 14 static void *disk_image__thread(void *param) 15 { 16 struct disk_image *disk = param; 17 struct io_event event[AIO_MAX]; 18 struct timespec notime = {0}; 19 int nr, i; 20 u64 dummy; 21 22 while (read(disk->evt, &dummy, sizeof(dummy)) > 0) { 23 nr = io_getevents(disk->ctx, 1, ARRAY_SIZE(event), event, ¬ime); 24 for (i = 0; i < nr; i++) 25 disk->disk_req_cb(event[i].data, event[i].res); 26 } 27 28 return NULL; 29 } 30 #endif 31 32 struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operations *ops, int use_mmap) 33 { 34 struct disk_image *disk; 35 int r; 36 37 disk = malloc(sizeof *disk); 38 if (!disk) 39 return ERR_PTR(-ENOMEM); 40 41 *disk = (struct disk_image) { 42 .fd = fd, 43 .size = size, 44 .ops = ops, 45 }; 46 47 if (use_mmap == DISK_IMAGE_MMAP) { 48 /* 49 * The write to disk image will be discarded 50 */ 51 disk->priv = mmap(NULL, size, PROT_RW, MAP_PRIVATE | MAP_NORESERVE, fd, 0); 52 if (disk->priv == MAP_FAILED) { 53 r = -errno; 54 free(disk); 55 return ERR_PTR(r); 56 } 57 } 58 59 #ifdef CONFIG_HAS_AIO 60 if (disk) { 61 pthread_t thread; 62 63 disk->evt = eventfd(0, 0); 64 io_setup(AIO_MAX, &disk->ctx); 65 r = pthread_create(&thread, NULL, disk_image__thread, disk); 66 if (r) { 67 r = -errno; 68 free(disk); 69 return ERR_PTR(r); 70 } 71 } 72 #endif 73 return disk; 74 } 75 76 struct disk_image *disk_image__open(const char *filename, bool readonly) 77 { 78 struct disk_image *disk; 79 struct stat st; 80 int fd; 81 82 if (stat(filename, &st) < 0) 83 return ERR_PTR(-errno); 84 85 /* blk device ?*/ 86 disk = blkdev__probe(filename, &st); 87 if (!IS_ERR_OR_NULL(disk)) 88 return disk; 89 90 fd = open(filename, readonly ? O_RDONLY : O_RDWR); 91 if (fd < 0) 92 return ERR_PTR(fd); 93 94 /* qcow image ?*/ 95 disk = qcow_probe(fd, true); 96 if (!IS_ERR_OR_NULL(disk)) { 97 pr_warning("Forcing read-only support for QCOW"); 98 return disk; 99 } 100 101 /* raw image ?*/ 102 disk = raw_image__probe(fd, &st, readonly); 103 if (!IS_ERR_OR_NULL(disk)) 104 return disk; 105 106 if (close(fd) < 0) 107 pr_warning("close() failed"); 108 109 return ERR_PTR(-ENOSYS); 110 } 111 112 struct disk_image **disk_image__open_all(const char **filenames, bool *readonly, int count) 113 { 114 struct disk_image **disks; 115 int i; 116 void *err; 117 118 if (!count) 119 return ERR_PTR(-EINVAL); 120 if (count > MAX_DISK_IMAGES) 121 return ERR_PTR(-ENOSPC); 122 123 disks = calloc(count, sizeof(*disks)); 124 if (!disks) 125 return ERR_PTR(-ENOMEM); 126 127 for (i = 0; i < count; i++) { 128 if (!filenames[i]) 129 continue; 130 131 disks[i] = disk_image__open(filenames[i], readonly[i]); 132 if (IS_ERR_OR_NULL(disks[i])) { 133 pr_err("Loading disk image '%s' failed", filenames[i]); 134 err = disks[i]; 135 goto error; 136 } 137 } 138 139 return disks; 140 error: 141 for (i = 0; i < count; i++) 142 if (!IS_ERR_OR_NULL(disks[i])) 143 disk_image__close(disks[i]); 144 145 free(disks); 146 return err; 147 } 148 149 int disk_image__flush(struct disk_image *disk) 150 { 151 if (disk->ops->flush) 152 return disk->ops->flush(disk); 153 154 return fsync(disk->fd); 155 } 156 157 int disk_image__close(struct disk_image *disk) 158 { 159 /* If there was no disk image then there's nothing to do: */ 160 if (!disk) 161 return 0; 162 163 if (disk->ops->close) 164 return disk->ops->close(disk); 165 166 if (close(disk->fd) < 0) 167 pr_warning("close() failed"); 168 169 free(disk); 170 171 return 0; 172 } 173 174 int disk_image__close_all(struct disk_image **disks, int count) 175 { 176 while (count) 177 disk_image__close(disks[--count]); 178 179 free(disks); 180 181 return 0; 182 } 183 184 /* 185 * Fill iov with disk data, starting from sector 'sector'. 186 * Return amount of bytes read. 187 */ 188 ssize_t disk_image__read(struct disk_image *disk, u64 sector, const struct iovec *iov, 189 int iovcount, void *param) 190 { 191 ssize_t total = 0; 192 193 if (debug_iodelay) 194 msleep(debug_iodelay); 195 196 if (disk->ops->read) { 197 total = disk->ops->read(disk, sector, iov, iovcount, param); 198 if (total < 0) { 199 pr_info("disk_image__read error: total=%ld\n", (long)total); 200 return total; 201 } 202 } else { 203 /* Do nothing */ 204 } 205 206 if (!disk->async && disk->disk_req_cb) 207 disk->disk_req_cb(param, total); 208 209 return total; 210 } 211 212 /* 213 * Write iov to disk, starting from sector 'sector'. 214 * Return amount of bytes written. 215 */ 216 ssize_t disk_image__write(struct disk_image *disk, u64 sector, const struct iovec *iov, 217 int iovcount, void *param) 218 { 219 ssize_t total = 0; 220 221 if (debug_iodelay) 222 msleep(debug_iodelay); 223 224 if (disk->ops->write) { 225 /* 226 * Try writev based operation first 227 */ 228 229 total = disk->ops->write(disk, sector, iov, iovcount, param); 230 if (total < 0) { 231 pr_info("disk_image__write error: total=%ld\n", (long)total); 232 return total; 233 } 234 } else { 235 /* Do nothing */ 236 } 237 238 if (!disk->async && disk->disk_req_cb) 239 disk->disk_req_cb(param, total); 240 241 return total; 242 } 243 244 ssize_t disk_image__get_serial(struct disk_image *disk, void *buffer, ssize_t *len) 245 { 246 struct stat st; 247 int r; 248 249 r = fstat(disk->fd, &st); 250 if (r) 251 return r; 252 253 *len = snprintf(buffer, *len, "%llu%llu%llu", (u64)st.st_dev, (u64)st.st_rdev, (u64)st.st_ino); 254 return *len; 255 } 256 257 void disk_image__set_callback(struct disk_image *disk, void (*disk_req_cb)(void *param, long len)) 258 { 259 disk->disk_req_cb = disk_req_cb; 260 } 261