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 if (sep) 29 kvm->cfg.disk_image[kvm->nr_disks].wwpn = sep + 1; 30 sep = strstr(sep + 1, ":"); 31 if (sep) { 32 *sep = 0; 33 kvm->cfg.disk_image[kvm->nr_disks].tpgt = sep + 1; 34 } 35 cur = sep + 1; 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 const char *tpgt; 151 bool readonly; 152 bool direct; 153 void *err; 154 int i; 155 struct disk_image_params *params = (struct disk_image_params *)&kvm->cfg.disk_image; 156 int count = kvm->nr_disks; 157 158 if (!count) 159 return ERR_PTR(-EINVAL); 160 if (count > MAX_DISK_IMAGES) 161 return ERR_PTR(-ENOSPC); 162 163 disks = calloc(count, sizeof(*disks)); 164 if (!disks) 165 return ERR_PTR(-ENOMEM); 166 167 for (i = 0; i < count; i++) { 168 filename = params[i].filename; 169 readonly = params[i].readonly; 170 direct = params[i].direct; 171 wwpn = params[i].wwpn; 172 tpgt = params[i].tpgt; 173 174 if (wwpn) { 175 disks[i] = malloc(sizeof(struct disk_image)); 176 if (!disks[i]) 177 return ERR_PTR(-ENOMEM); 178 disks[i]->wwpn = wwpn; 179 disks[i]->tpgt = tpgt; 180 continue; 181 } 182 183 if (!filename) 184 continue; 185 186 disks[i] = disk_image__open(filename, readonly, direct); 187 if (IS_ERR_OR_NULL(disks[i])) { 188 pr_err("Loading disk image '%s' failed", filename); 189 err = disks[i]; 190 goto error; 191 } 192 disks[i]->debug_iodelay = kvm->cfg.debug_iodelay; 193 } 194 195 return disks; 196 error: 197 for (i = 0; i < count; i++) 198 if (!IS_ERR_OR_NULL(disks[i])) 199 disk_image__close(disks[i]); 200 201 free(disks); 202 return err; 203 } 204 205 int disk_image__wait(struct disk_image *disk) 206 { 207 if (disk->ops->wait) 208 return disk->ops->wait(disk); 209 210 return 0; 211 } 212 213 int disk_image__flush(struct disk_image *disk) 214 { 215 if (disk->ops->flush) 216 return disk->ops->flush(disk); 217 218 return fsync(disk->fd); 219 } 220 221 static int disk_image__close(struct disk_image *disk) 222 { 223 /* If there was no disk image then there's nothing to do: */ 224 if (!disk) 225 return 0; 226 227 disk_aio_destroy(disk); 228 229 if (disk->ops->close) 230 return disk->ops->close(disk); 231 232 if (close(disk->fd) < 0) 233 pr_warning("close() failed"); 234 235 free(disk); 236 237 return 0; 238 } 239 240 static int disk_image__close_all(struct disk_image **disks, int count) 241 { 242 while (count) 243 disk_image__close(disks[--count]); 244 245 free(disks); 246 247 return 0; 248 } 249 250 /* 251 * Fill iov with disk data, starting from sector 'sector'. 252 * Return amount of bytes read. 253 */ 254 ssize_t disk_image__read(struct disk_image *disk, u64 sector, 255 const struct iovec *iov, int iovcount, void *param) 256 { 257 ssize_t total = 0; 258 259 if (debug_iodelay) 260 msleep(debug_iodelay); 261 262 if (disk->ops->read) { 263 total = disk->ops->read(disk, sector, iov, iovcount, param); 264 if (total < 0) { 265 pr_info("disk_image__read error: total=%ld\n", (long)total); 266 return total; 267 } 268 } 269 270 if (!disk->async && disk->disk_req_cb) 271 disk->disk_req_cb(param, total); 272 273 return total; 274 } 275 276 /* 277 * Write iov to disk, starting from sector 'sector'. 278 * Return amount of bytes written. 279 */ 280 ssize_t disk_image__write(struct disk_image *disk, u64 sector, 281 const struct iovec *iov, int iovcount, void *param) 282 { 283 ssize_t total = 0; 284 285 if (debug_iodelay) 286 msleep(debug_iodelay); 287 288 if (disk->ops->write) { 289 /* 290 * Try writev based operation first 291 */ 292 293 total = disk->ops->write(disk, sector, iov, iovcount, param); 294 if (total < 0) { 295 pr_info("disk_image__write error: total=%ld\n", (long)total); 296 return total; 297 } 298 } else { 299 /* Do nothing */ 300 } 301 302 if (!disk->async && disk->disk_req_cb) 303 disk->disk_req_cb(param, total); 304 305 return total; 306 } 307 308 ssize_t disk_image__get_serial(struct disk_image *disk, struct iovec *iov, 309 int iovcount, ssize_t len) 310 { 311 struct stat st; 312 void *buf; 313 int r; 314 315 r = fstat(disk->fd, &st); 316 if (r) 317 return r; 318 319 buf = malloc(len); 320 if (!buf) 321 return -ENOMEM; 322 323 len = snprintf(buf, len, "%llu%llu%llu", 324 (unsigned long long)st.st_dev, 325 (unsigned long long)st.st_rdev, 326 (unsigned long long)st.st_ino); 327 if (len < 0 || (size_t)len > iov_size(iov, iovcount)) { 328 free(buf); 329 return -ENOMEM; 330 } 331 332 memcpy_toiovec(iov, buf, len); 333 free(buf); 334 return len; 335 } 336 337 void disk_image__set_callback(struct disk_image *disk, 338 void (*disk_req_cb)(void *param, long len)) 339 { 340 disk->disk_req_cb = disk_req_cb; 341 } 342 343 int disk_image__init(struct kvm *kvm) 344 { 345 if (kvm->nr_disks) { 346 kvm->disks = disk_image__open_all(kvm); 347 if (IS_ERR(kvm->disks)) 348 return PTR_ERR(kvm->disks); 349 } 350 351 return 0; 352 } 353 dev_base_init(disk_image__init); 354 355 int disk_image__exit(struct kvm *kvm) 356 { 357 return disk_image__close_all(kvm->disks, kvm->nr_disks); 358 } 359 dev_base_exit(disk_image__exit); 360