19f532d00SPekka Enberg #include "kvm/disk-image.h" 29f532d00SPekka Enberg 3*c4d7847bSPekka Enberg #include "kvm/read-write.h" 49f532d00SPekka Enberg #include "kvm/util.h" 59f532d00SPekka Enberg 69f532d00SPekka Enberg #include <sys/types.h> 733d33901SPekka Enberg #include <inttypes.h> 89f532d00SPekka Enberg #include <sys/mman.h> 99f532d00SPekka Enberg #include <sys/stat.h> 105646450dSPekka Enberg #include <stdbool.h> 119f532d00SPekka Enberg #include <stddef.h> 129f532d00SPekka Enberg #include <stdlib.h> 139f532d00SPekka Enberg #include <unistd.h> 149f532d00SPekka Enberg #include <fcntl.h> 159f532d00SPekka Enberg 169f532d00SPekka Enberg struct disk_image *disk_image__open(const char *filename) 179f532d00SPekka Enberg { 189f532d00SPekka Enberg struct disk_image *self; 199f532d00SPekka Enberg struct stat st; 209f532d00SPekka Enberg 219f532d00SPekka Enberg self = malloc(sizeof *self); 229f532d00SPekka Enberg if (!self) 239f532d00SPekka Enberg return NULL; 249f532d00SPekka Enberg 25*c4d7847bSPekka Enberg self->fd = open(filename, O_RDWR); 269f532d00SPekka Enberg if (self->fd < 0) 279f532d00SPekka Enberg goto failed_free; 289f532d00SPekka Enberg 299f532d00SPekka Enberg if (fstat(self->fd, &st) < 0) 309f532d00SPekka Enberg goto failed_close_fd; 319f532d00SPekka Enberg 329f532d00SPekka Enberg self->size = st.st_size; 339f532d00SPekka Enberg 349f532d00SPekka Enberg return self; 359f532d00SPekka Enberg 369f532d00SPekka Enberg failed_close_fd: 379f532d00SPekka Enberg close(self->fd); 389f532d00SPekka Enberg failed_free: 399f532d00SPekka Enberg free(self); 409f532d00SPekka Enberg 419f532d00SPekka Enberg return NULL; 429f532d00SPekka Enberg } 439f532d00SPekka Enberg 449f532d00SPekka Enberg void disk_image__close(struct disk_image *self) 459f532d00SPekka Enberg { 469f532d00SPekka Enberg if (close(self->fd) < 0) 479f532d00SPekka Enberg warning("close() failed"); 489f532d00SPekka Enberg 499f532d00SPekka Enberg free(self); 509f532d00SPekka Enberg } 519f532d00SPekka Enberg 525a24a9f2SPekka Enberg int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len) 539f532d00SPekka Enberg { 549f532d00SPekka Enberg uint64_t offset = sector << SECTOR_SHIFT; 559f532d00SPekka Enberg 565a24a9f2SPekka Enberg if (offset + dst_len > self->size) 579f532d00SPekka Enberg return -1; 589f532d00SPekka Enberg 59*c4d7847bSPekka Enberg if (lseek(self->fd, offset, SEEK_SET) < 0) 60*c4d7847bSPekka Enberg return -1; 61*c4d7847bSPekka Enberg 62*c4d7847bSPekka Enberg if (read_in_full(self->fd, dst, dst_len) < 0) 63*c4d7847bSPekka Enberg return -1; 649f532d00SPekka Enberg 659f532d00SPekka Enberg return 0; 669f532d00SPekka Enberg } 67258dd093SPekka Enberg 68258dd093SPekka Enberg int disk_image__write_sector(struct disk_image *self, uint64_t sector, void *src, uint32_t src_len) 69258dd093SPekka Enberg { 70258dd093SPekka Enberg uint64_t offset = sector << SECTOR_SHIFT; 71258dd093SPekka Enberg 72258dd093SPekka Enberg if (offset + src_len > self->size) 73258dd093SPekka Enberg return -1; 74258dd093SPekka Enberg 75*c4d7847bSPekka Enberg if (lseek(self->fd, offset, SEEK_SET) < 0) 76*c4d7847bSPekka Enberg return -1; 77*c4d7847bSPekka Enberg 78*c4d7847bSPekka Enberg if (write_in_full(self->fd, src, src_len) < 0) 79*c4d7847bSPekka Enberg return -1; 80258dd093SPekka Enberg 81258dd093SPekka Enberg return 0; 82258dd093SPekka Enberg } 83