1 #include "kvm/disk-image.h" 2 #include "kvm/qcow.h" 3 #include "kvm/virtio-blk.h" 4 #include "kvm/kvm.h" 5 #include "kvm/iovec.h" 6 7 #include <linux/err.h> 8 #include <poll.h> 9 10 int debug_iodelay; 11 12 static int disk_image__close(struct disk_image *disk); 13 14 int disk_img_name_parser(const struct option *opt, const char *arg, int unset) 15 { 16 const char *cur; 17 char *sep; 18 struct kvm *kvm = opt->ptr; 19 20 if (kvm->nr_disks >= MAX_DISK_IMAGES) 21 die("Currently only 4 images are supported"); 22 23 kvm->cfg.disk_image[kvm->nr_disks].filename = arg; 24 cur = arg; 25 26 if (strncmp(arg, "scsi:", 5) == 0) { 27 sep = strstr(arg, ":"); 28 kvm->cfg.disk_image[kvm->nr_disks].wwpn = sep + 1; 29 30 /* Old invocation had two parameters. Ignore the second one. */ 31 sep = strstr(sep + 1, ":"); 32 if (sep) { 33 *sep = 0; 34 cur = sep + 1; 35 } 36 } 37 38 do { 39 sep = strstr(cur, ","); 40 if (sep) { 41 if (strncmp(sep + 1, "ro", 2) == 0) 42 kvm->cfg.disk_image[kvm->nr_disks].readonly = true; 43 else if (strncmp(sep + 1, "direct", 6) == 0) 44 kvm->cfg.disk_image[kvm->nr_disks].direct = true; 45 *sep = 0; 46 cur = sep + 1; 47 } 48 } while (sep); 49 50 kvm->nr_disks++; 51 52 return 0; 53 } 54 55 struct disk_image *disk_image__new(int fd, u64 size, 56 struct disk_image_operations *ops, 57 int use_mmap) 58 { 59 struct disk_image *disk; 60 int r; 61 62 disk = malloc(sizeof *disk); 63 if (!disk) 64 return ERR_PTR(-ENOMEM); 65 66 *disk = (struct disk_image) { 67 .fd = fd, 68 .size = size, 69 .ops = ops, 70 }; 71 72 if (use_mmap == DISK_IMAGE_MMAP) { 73 /* 74 * The write to disk image will be discarded 75 */ 76 disk->priv = mmap(NULL, size, PROT_RW, MAP_PRIVATE | MAP_NORESERVE, fd, 0); 77 if (disk->priv == MAP_FAILED) { 78 r = -errno; 79 goto err_free_disk; 80 } 81 } 82 83 r = disk_aio_setup(disk); 84 if (r) 85 goto err_unmap_disk; 86 87 return disk; 88 89 err_unmap_disk: 90 if (disk->priv) 91 munmap(disk->priv, size); 92 err_free_disk: 93 free(disk); 94 return ERR_PTR(r); 95 } 96 97 static struct disk_image *disk_image__open(const char *filename, bool readonly, bool direct) 98 { 99 struct disk_image *disk; 100 struct stat st; 101 int fd, flags; 102 103 if (readonly) 104 flags = O_RDONLY; 105 else 106 flags = O_RDWR; 107 if (direct) 108 flags |= O_DIRECT; 109 110 if (stat(filename, &st) < 0) 111 return ERR_PTR(-errno); 112 113 /* blk device ?*/ 114 disk = blkdev__probe(filename, flags, &st); 115 if (!IS_ERR_OR_NULL(disk)) { 116 disk->readonly = readonly; 117 return disk; 118 } 119 120 fd = open(filename, flags); 121 if (fd < 0) 122 return ERR_PTR(fd); 123 124 /* qcow image ?*/ 125 disk = qcow_probe(fd, true); 126 if (!IS_ERR_OR_NULL(disk)) { 127 pr_warning("Forcing read-only support for QCOW"); 128 disk->readonly = true; 129 return disk; 130 } 131 132 /* raw image ?*/ 133 disk = raw_image__probe(fd, &st, readonly); 134 if (!IS_ERR_OR_NULL(disk)) { 135 disk->readonly = readonly; 136 return disk; 137 } 138 139 if (close(fd) < 0) 140 pr_warning("close() failed"); 141 142 return ERR_PTR(-ENOSYS); 143 } 144 145 static struct disk_image **disk_image__open_all(struct kvm *kvm) 146 { 147 struct disk_image **disks; 148 const char *filename; 149 const char *wwpn; 150 bool readonly; 151 bool direct; 152 void *err; 153 int i; 154 struct disk_image_params *params = (struct disk_image_params *)&kvm->cfg.disk_image; 155 int count = kvm->nr_disks; 156 157 if (!count) 158 return ERR_PTR(-EINVAL); 159 if (count > MAX_DISK_IMAGES) 160 return ERR_PTR(-ENOSPC); 161 162 disks = calloc(count, sizeof(*disks)); 163 if (!disks) 164 return ERR_PTR(-ENOMEM); 165 166 for (i = 0; i < count; i++) { 167 filename = params[i].filename; 168 readonly = params[i].readonly; 169 direct = params[i].direct; 170 wwpn = params[i].wwpn; 171 172 if (wwpn) { 173 disks[i] = malloc(sizeof(struct disk_image)); 174 if (!disks[i]) 175 return ERR_PTR(-ENOMEM); 176 disks[i]->wwpn = wwpn; 177 continue; 178 } 179 180 if (!filename) 181 continue; 182 183 disks[i] = disk_image__open(filename, readonly, direct); 184 if (IS_ERR_OR_NULL(disks[i])) { 185 pr_err("Loading disk image '%s' failed", filename); 186 err = disks[i]; 187 goto error; 188 } 189 disks[i]->debug_iodelay = kvm->cfg.debug_iodelay; 190 } 191 192 return disks; 193 error: 194 for (i = 0; i < count; i++) 195 if (!IS_ERR_OR_NULL(disks[i])) 196 disk_image__close(disks[i]); 197 198 free(disks); 199 return err; 200 } 201 202 int disk_image__wait(struct disk_image *disk) 203 { 204 if (disk->ops->wait) 205 return disk->ops->wait(disk); 206 207 return 0; 208 } 209 210 int disk_image__flush(struct disk_image *disk) 211 { 212 if (disk->ops->flush) 213 return disk->ops->flush(disk); 214 215 return fsync(disk->fd); 216 } 217 218 static int disk_image__close(struct disk_image *disk) 219 { 220 /* If there was no disk image then there's nothing to do: */ 221 if (!disk) 222 return 0; 223 224 disk_aio_destroy(disk); 225 226 if (disk->ops->close) 227 return disk->ops->close(disk); 228 229 if (close(disk->fd) < 0) 230 pr_warning("close() failed"); 231 232 free(disk); 233 234 return 0; 235 } 236 237 static int disk_image__close_all(struct disk_image **disks, int count) 238 { 239 while (count) 240 disk_image__close(disks[--count]); 241 242 free(disks); 243 244 return 0; 245 } 246 247 /* 248 * Fill iov with disk data, starting from sector 'sector'. 249 * Return amount of bytes read. 250 */ 251 ssize_t disk_image__read(struct disk_image *disk, u64 sector, 252 const struct iovec *iov, int iovcount, void *param) 253 { 254 ssize_t total = 0; 255 256 if (debug_iodelay) 257 msleep(debug_iodelay); 258 259 if (disk->ops->read) { 260 total = disk->ops->read(disk, sector, iov, iovcount, param); 261 if (total < 0) { 262 pr_info("disk_image__read error: total=%ld\n", (long)total); 263 return total; 264 } 265 } 266 267 if (!disk->async && disk->disk_req_cb) 268 disk->disk_req_cb(param, total); 269 270 return total; 271 } 272 273 /* 274 * Write iov to disk, starting from sector 'sector'. 275 * Return amount of bytes written. 276 */ 277 ssize_t disk_image__write(struct disk_image *disk, u64 sector, 278 const struct iovec *iov, int iovcount, void *param) 279 { 280 ssize_t total = 0; 281 282 if (debug_iodelay) 283 msleep(debug_iodelay); 284 285 if (disk->ops->write) { 286 /* 287 * Try writev based operation first 288 */ 289 290 total = disk->ops->write(disk, sector, iov, iovcount, param); 291 if (total < 0) { 292 pr_info("disk_image__write error: total=%ld\n", (long)total); 293 return total; 294 } 295 } else { 296 /* Do nothing */ 297 } 298 299 if (!disk->async && disk->disk_req_cb) 300 disk->disk_req_cb(param, total); 301 302 return total; 303 } 304 305 ssize_t disk_image__get_serial(struct disk_image *disk, struct iovec *iov, 306 int iovcount, ssize_t len) 307 { 308 struct stat st; 309 void *buf; 310 int r; 311 312 r = fstat(disk->fd, &st); 313 if (r) 314 return r; 315 316 buf = malloc(len); 317 if (!buf) 318 return -ENOMEM; 319 320 len = snprintf(buf, len, "%llu%llu%llu", 321 (unsigned long long)st.st_dev, 322 (unsigned long long)st.st_rdev, 323 (unsigned long long)st.st_ino); 324 if (len < 0 || (size_t)len > iov_size(iov, iovcount)) { 325 free(buf); 326 return -ENOMEM; 327 } 328 329 memcpy_toiovec(iov, buf, len); 330 free(buf); 331 return len; 332 } 333 334 void disk_image__set_callback(struct disk_image *disk, 335 void (*disk_req_cb)(void *param, long len)) 336 { 337 disk->disk_req_cb = disk_req_cb; 338 } 339 340 int disk_image__init(struct kvm *kvm) 341 { 342 if (kvm->nr_disks) { 343 kvm->disks = disk_image__open_all(kvm); 344 if (IS_ERR(kvm->disks)) 345 return PTR_ERR(kvm->disks); 346 } 347 348 return 0; 349 } 350 dev_base_init(disk_image__init); 351 352 int disk_image__exit(struct kvm *kvm) 353 { 354 return disk_image__close_all(kvm->disks, kvm->nr_disks); 355 } 356 dev_base_exit(disk_image__exit); 357