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