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(const char **filenames, 115 bool *readonly, int count) 116 { 117 struct disk_image **disks; 118 int i; 119 void *err; 120 121 if (!count) 122 return ERR_PTR(-EINVAL); 123 if (count > MAX_DISK_IMAGES) 124 return ERR_PTR(-ENOSPC); 125 126 disks = calloc(count, sizeof(*disks)); 127 if (!disks) 128 return ERR_PTR(-ENOMEM); 129 130 for (i = 0; i < count; i++) { 131 if (!filenames[i]) 132 continue; 133 134 disks[i] = disk_image__open(filenames[i], readonly[i]); 135 if (IS_ERR_OR_NULL(disks[i])) { 136 pr_err("Loading disk image '%s' failed", filenames[i]); 137 err = disks[i]; 138 goto error; 139 } 140 } 141 142 return disks; 143 error: 144 for (i = 0; i < count; i++) 145 if (!IS_ERR_OR_NULL(disks[i])) 146 disk_image__close(disks[i]); 147 148 free(disks); 149 return err; 150 } 151 152 int disk_image__flush(struct disk_image *disk) 153 { 154 if (disk->ops->flush) 155 return disk->ops->flush(disk); 156 157 return fsync(disk->fd); 158 } 159 160 int disk_image__close(struct disk_image *disk) 161 { 162 /* If there was no disk image then there's nothing to do: */ 163 if (!disk) 164 return 0; 165 166 if (disk->ops->close) 167 return disk->ops->close(disk); 168 169 if (close(disk->fd) < 0) 170 pr_warning("close() failed"); 171 172 free(disk); 173 174 return 0; 175 } 176 177 int disk_image__close_all(struct disk_image **disks, int count) 178 { 179 while (count) 180 disk_image__close(disks[--count]); 181 182 free(disks); 183 184 return 0; 185 } 186 187 /* 188 * Fill iov with disk data, starting from sector 'sector'. 189 * Return amount of bytes read. 190 */ 191 ssize_t disk_image__read(struct disk_image *disk, u64 sector, 192 const struct iovec *iov, int iovcount, void *param) 193 { 194 ssize_t total = 0; 195 196 if (debug_iodelay) 197 msleep(debug_iodelay); 198 199 if (disk->ops->read) { 200 total = disk->ops->read(disk, sector, iov, iovcount, param); 201 if (total < 0) { 202 pr_info("disk_image__read error: total=%ld\n", (long)total); 203 return total; 204 } 205 } 206 207 if (!disk->async && disk->disk_req_cb) 208 disk->disk_req_cb(param, total); 209 210 return total; 211 } 212 213 /* 214 * Write iov to disk, starting from sector 'sector'. 215 * Return amount of bytes written. 216 */ 217 ssize_t disk_image__write(struct disk_image *disk, u64 sector, 218 const struct iovec *iov, int iovcount, void *param) 219 { 220 ssize_t total = 0; 221 222 if (debug_iodelay) 223 msleep(debug_iodelay); 224 225 if (disk->ops->write) { 226 /* 227 * Try writev based operation first 228 */ 229 230 total = disk->ops->write(disk, sector, iov, iovcount, param); 231 if (total < 0) { 232 pr_info("disk_image__write error: total=%ld\n", (long)total); 233 return total; 234 } 235 } else { 236 /* Do nothing */ 237 } 238 239 if (!disk->async && disk->disk_req_cb) 240 disk->disk_req_cb(param, total); 241 242 return total; 243 } 244 245 ssize_t disk_image__get_serial(struct disk_image *disk, void *buffer, ssize_t *len) 246 { 247 struct stat st; 248 int r; 249 250 r = fstat(disk->fd, &st); 251 if (r) 252 return r; 253 254 *len = snprintf(buffer, *len, "%llu%llu%llu", 255 (u64)st.st_dev, (u64)st.st_rdev, (u64)st.st_ino); 256 return *len; 257 } 258 259 void disk_image__set_callback(struct disk_image *disk, 260 void (*disk_req_cb)(void *param, long len)) 261 { 262 disk->disk_req_cb = disk_req_cb; 263 } 264