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