xref: /kvmtool/disk/core.c (revision c4d7847b220c2cccfc0cf6c4d78da631b3edcd6b)
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