All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <levinsasha928@gmail.com>
To: penberg@kernel.org
Cc: mingo@elte.hu, gorcunov@gmail.com, asias.hejun@gmail.com,
	kvm@vger.kernel.org, Sasha Levin <levinsasha928@gmail.com>
Subject: [RFC 10/12] kvm tools: Fixes for disk image module
Date: Mon, 19 Dec 2011 15:58:32 +0200	[thread overview]
Message-ID: <1324303114-5948-11-git-send-email-levinsasha928@gmail.com> (raw)
In-Reply-To: <1324303114-5948-1-git-send-email-levinsasha928@gmail.com>

Fixes include:
 - Error handling
 - Cleanup
 - Standard init/uninit

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/builtin-run.c            |   27 +++++++++---
 tools/kvm/disk/blk.c               |   13 ++++--
 tools/kvm/disk/core.c              |   76 ++++++++++++++++++++++--------------
 tools/kvm/disk/qcow.c              |    2 +-
 tools/kvm/disk/raw.c               |    9 ++--
 tools/kvm/include/kvm/disk-image.h |    2 +-
 tools/kvm/include/kvm/virtio-blk.h |    5 +-
 tools/kvm/virtio/blk.c             |   37 +++++++++++++-----
 8 files changed, 111 insertions(+), 60 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 2950ea8..0b94ef0 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -1052,11 +1052,13 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 
 	if (image_count) {
 		kvm->nr_disks = image_count;
-		kvm->disks    = disk_image__open_all(image_filename, readonly_image, image_count);
-		if (!kvm->disks)
-			die("Unable to load all disk images.");
-
-		virtio_blk__init_all(kvm);
+		kvm->disks = disk_image__open_all(image_filename, readonly_image, image_count);
+		if (IS_ERR(kvm->disks)) {
+			r = PTR_ERR(kvm->disks);
+			pr_error("disk_image__open_all() failed with error %ld\n",
+					PTR_ERR(kvm->disks));
+			goto fail;
+		}
 	}
 
 	printf("  # kvm run -k %s -m %Lu -c %d --name %s\n", kernel_filename, ram_size / 1024 / 1024, nrcpus, guest_name);
@@ -1082,6 +1084,12 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 		goto fail;
 	}
 
+	r = virtio_blk__init(kvm);
+	if (r < 0) {
+		pr_error("virtio_blk__init() failed with error %d\n", r);
+		goto fail;
+	}
+
 	if (active_console == CONSOLE_VIRTIO)
 		virtio_console__init(kvm);
 
@@ -1222,10 +1230,15 @@ static void kvm_cmd_run_uninit(int guest_ret)
 
 	fb__stop();
 
-	virtio_blk__delete_all(kvm);
+	r = virtio_blk__uninit(kvm);
+	if (r < 0)
+		pr_warning("virtio_blk__uninit() failed with error %d\n", r);
+
 	virtio_rng__delete_all(kvm);
 
-	disk_image__close_all(kvm->disks, image_count);
+	r = disk_image__close_all(kvm->disks, image_count);
+	if (r < 0)
+		pr_warning("disk_image__close_all() failed with error %d\n", r);
 
 	r = serial8250__uninit(kvm);
 	if (r < 0)
diff --git a/tools/kvm/disk/blk.c b/tools/kvm/disk/blk.c
index 59294e8..72c1722 100644
--- a/tools/kvm/disk/blk.c
+++ b/tools/kvm/disk/blk.c
@@ -1,5 +1,7 @@
 #include "kvm/disk-image.h"
 
+#include <linux/err.h>
+
 /*
  * raw image and blk dev are similar, so reuse raw image ops.
  */
@@ -12,22 +14,23 @@ static struct disk_image_operations blk_dev_ops = {
 struct disk_image *blkdev__probe(const char *filename, struct stat *st)
 {
 	u64 size;
-	int fd;
+	int fd, r;
 
 	if (!S_ISBLK(st->st_mode))
-		return NULL;
+		return ERR_PTR(-EINVAL);
 
 	/*
 	 * Be careful! We are opening host block device!
 	 * Open it readonly since we do not want to break user's data on disk.
 	 */
-	fd			= open(filename, O_RDONLY);
+	fd = open(filename, O_RDONLY);
 	if (fd < 0)
-		return NULL;
+		return ERR_PTR(fd);
 
 	if (ioctl(fd, BLKGETSIZE64, &size) < 0) {
+		r = -errno;
 		close(fd);
-		return NULL;
+		return ERR_PTR(r);
 	}
 
 	/*
diff --git a/tools/kvm/disk/core.c b/tools/kvm/disk/core.c
index 4915efd..fb547ba 100644
--- a/tools/kvm/disk/core.c
+++ b/tools/kvm/disk/core.c
@@ -2,6 +2,7 @@
 #include "kvm/qcow.h"
 #include "kvm/virtio-blk.h"
 
+#include <linux/err.h>
 #include <sys/eventfd.h>
 #include <sys/poll.h>
 
@@ -31,14 +32,17 @@ static void *disk_image__thread(void *param)
 struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operations *ops, int use_mmap)
 {
 	struct disk_image *disk;
+	int r;
 
-	disk		= malloc(sizeof *disk);
+	disk = malloc(sizeof *disk);
 	if (!disk)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
-	disk->fd	= fd;
-	disk->size	= size;
-	disk->ops	= ops;
+	*disk = (struct disk_image) {
+		.fd	= fd,
+		.size	= size,
+		.ops	= ops,
+	};
 
 	if (use_mmap == DISK_IMAGE_MMAP) {
 		/*
@@ -46,8 +50,9 @@ struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operation
 		 */
 		disk->priv = mmap(NULL, size, PROT_RW, MAP_PRIVATE | MAP_NORESERVE, fd, 0);
 		if (disk->priv == MAP_FAILED) {
+			r = -errno;
 			free(disk);
-			disk = NULL;
+			return ERR_PTR(r);
 		}
 	}
 
@@ -57,8 +62,12 @@ struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operation
 
 		disk->evt = eventfd(0, 0);
 		io_setup(AIO_MAX, &disk->ctx);
-		if (pthread_create(&thread, NULL, disk_image__thread, disk) != 0)
-			die("Failed starting IO thread");
+		r = pthread_create(&thread, NULL, disk_image__thread, disk);
+		if (r) {
+			r = -errno;
+			free(disk);
+			return ERR_PTR(r);
+		}
 	}
 #endif
 	return disk;
@@ -71,54 +80,58 @@ struct disk_image *disk_image__open(const char *filename, bool readonly)
 	int fd;
 
 	if (stat(filename, &st) < 0)
-		return NULL;
+		return ERR_PTR(-errno);
 
 	/* blk device ?*/
-	disk		= blkdev__probe(filename, &st);
-	if (disk)
+	disk = blkdev__probe(filename, &st);
+	if (!IS_ERR_OR_NULL(disk))
 		return disk;
 
-	fd		= open(filename, readonly ? O_RDONLY : O_RDWR);
+	fd = open(filename, readonly ? O_RDONLY : O_RDWR);
 	if (fd < 0)
-		return NULL;
+		return ERR_PTR(fd);
 
 	/* qcow image ?*/
-	disk		= qcow_probe(fd, true);
-	if (disk) {
+	disk = qcow_probe(fd, true);
+	if (!IS_ERR_OR_NULL(disk)) {
 		pr_warning("Forcing read-only support for QCOW");
 		return disk;
 	}
 
 	/* raw image ?*/
-	disk		= raw_image__probe(fd, &st, readonly);
-	if (disk)
+	disk = raw_image__probe(fd, &st, readonly);
+	if (!IS_ERR_OR_NULL(disk))
 		return disk;
 
 	if (close(fd) < 0)
 		pr_warning("close() failed");
 
-	return NULL;
+	return ERR_PTR(-ENOSYS);
 }
 
 struct disk_image **disk_image__open_all(const char **filenames, bool *readonly, int count)
 {
 	struct disk_image **disks;
 	int i;
+	void *err;
 
-	if (!count || count > MAX_DISK_IMAGES)
-		return NULL;
+	if (!count)
+		return ERR_PTR(-EINVAL);
+	if (count > MAX_DISK_IMAGES)
+		return ERR_PTR(-ENOSPC);
 
 	disks = calloc(count, sizeof(*disks));
 	if (!disks)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	for (i = 0; i < count; i++) {
 		if (!filenames[i])
 			continue;
 
 		disks[i] = disk_image__open(filenames[i], readonly[i]);
-		if (!disks[i]) {
+		if (IS_ERR_OR_NULL(disks[i])) {
 			pr_error("Loading disk image '%s' failed", filenames[i]);
+			err = disks[i];
 			goto error;
 		}
 	}
@@ -126,10 +139,11 @@ struct disk_image **disk_image__open_all(const char **filenames, bool *readonly,
 	return disks;
 error:
 	for (i = 0; i < count; i++)
-		disk_image__close(disks[i]);
+		if (!IS_ERR_OR_NULL(disks[i]))
+			disk_image__close(disks[i]);
 
 	free(disks);
-	return NULL;
+	return err;
 }
 
 int disk_image__flush(struct disk_image *disk)
@@ -157,12 +171,14 @@ int disk_image__close(struct disk_image *disk)
 	return 0;
 }
 
-void disk_image__close_all(struct disk_image **disks, int count)
+int disk_image__close_all(struct disk_image **disks, int count)
 {
 	while (count)
 		disk_image__close(disks[--count]);
 
 	free(disks);
+
+	return 0;
 }
 
 /*
@@ -181,7 +197,7 @@ ssize_t disk_image__read(struct disk_image *disk, u64 sector, const struct iovec
 		total = disk->ops->read_sector(disk, sector, iov, iovcount, param);
 		if (total < 0) {
 			pr_info("disk_image__read error: total=%ld\n", (long)total);
-			return -1;
+			return total;
 		}
 	} else {
 		/* Do nothing */
@@ -213,7 +229,7 @@ ssize_t disk_image__write(struct disk_image *disk, u64 sector, const struct iove
 		total = disk->ops->write_sector(disk, sector, iov, iovcount, param);
 		if (total < 0) {
 			pr_info("disk_image__write error: total=%ld\n", (long)total);
-			return -1;
+			return total;
 		}
 	} else {
 		/* Do nothing */
@@ -228,9 +244,11 @@ ssize_t disk_image__write(struct disk_image *disk, u64 sector, const struct iove
 ssize_t disk_image__get_serial(struct disk_image *disk, void *buffer, ssize_t *len)
 {
 	struct stat st;
+	int r;
 
-	if (fstat(disk->fd, &st) != 0)
-		return 0;
+	r = fstat(disk->fd, &st);
+	if (r)
+		return r;
 
 	*len = snprintf(buffer, *len, "%llu%llu%llu", (u64)st.st_dev, (u64)st.st_rdev, (u64)st.st_ino);
 	return *len;
diff --git a/tools/kvm/disk/qcow.c b/tools/kvm/disk/qcow.c
index 712f811..23f11f2 100644
--- a/tools/kvm/disk/qcow.c
+++ b/tools/kvm/disk/qcow.c
@@ -1334,7 +1334,7 @@ static struct disk_image *qcow2_probe(int fd, bool readonly)
 	else
 		disk_image = disk_image__new(fd, h->size, &qcow_disk_ops, DISK_IMAGE_REGULAR);
 
-	if (!disk_image)
+	if (IS_ERR_OR_NULL(disk_image))
 		goto free_refcount_table;
 
 	disk_image->async = 0;
diff --git a/tools/kvm/disk/raw.c b/tools/kvm/disk/raw.c
index caa023c..d2df814 100644
--- a/tools/kvm/disk/raw.c
+++ b/tools/kvm/disk/raw.c
@@ -1,5 +1,7 @@
 #include "kvm/disk-image.h"
 
+#include <linux/err.h>
+
 #ifdef CONFIG_HAS_AIO
 #include <libaio.h>
 #endif
@@ -116,11 +118,10 @@ struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly)
 		struct disk_image *disk;
 
 		disk = disk_image__new(fd, st->st_size, &ro_ops, DISK_IMAGE_MMAP);
-		if (disk == NULL) {
-
+		if (IS_ERR_OR_NULL(disk)) {
 			disk = disk_image__new(fd, st->st_size, &ro_ops_nowrite, DISK_IMAGE_REGULAR);
 #ifdef CONFIG_HAS_AIO
-			if (disk)
+			if (!IS_ERR_OR_NULL(disk))
 				disk->async = 1;
 #endif
 		}
@@ -132,7 +133,7 @@ struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly)
 		 */
 		disk = disk_image__new(fd, st->st_size, &raw_image_regular_ops, DISK_IMAGE_REGULAR);
 #ifdef CONFIG_HAS_AIO
-		if (disk)
+		if (!IS_ERR_OR_NULL(disk))
 			disk->async = 1;
 #endif
 		return disk;
diff --git a/tools/kvm/include/kvm/disk-image.h b/tools/kvm/include/kvm/disk-image.h
index 56c08da..a0b61bf 100644
--- a/tools/kvm/include/kvm/disk-image.h
+++ b/tools/kvm/include/kvm/disk-image.h
@@ -57,7 +57,7 @@ struct disk_image *disk_image__open(const char *filename, bool readonly);
 struct disk_image **disk_image__open_all(const char **filenames, bool *readonly, int count);
 struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operations *ops, int mmap);
 int disk_image__close(struct disk_image *disk);
-void disk_image__close_all(struct disk_image **disks, int count);
+int disk_image__close_all(struct disk_image **disks, int count);
 int disk_image__flush(struct disk_image *disk);
 ssize_t disk_image__read(struct disk_image *disk, u64 sector, const struct iovec *iov,
 				int iovcount, void *param);
diff --git a/tools/kvm/include/kvm/virtio-blk.h b/tools/kvm/include/kvm/virtio-blk.h
index 63731a9..e0c0919 100644
--- a/tools/kvm/include/kvm/virtio-blk.h
+++ b/tools/kvm/include/kvm/virtio-blk.h
@@ -5,9 +5,8 @@
 
 struct kvm;
 
-void virtio_blk__init(struct kvm *kvm, struct disk_image *disk);
-void virtio_blk__init_all(struct kvm *kvm);
-void virtio_blk__delete_all(struct kvm *kvm);
+int virtio_blk__init(struct kvm *kvm);
+int virtio_blk__uninit(struct kvm *kvm);
 void virtio_blk_complete(void *param, long len);
 
 #endif /* KVM__BLK_VIRTIO_H */
diff --git a/tools/kvm/virtio/blk.c b/tools/kvm/virtio/blk.c
index d1a0197..e9b836a 100644
--- a/tools/kvm/virtio/blk.c
+++ b/tools/kvm/virtio/blk.c
@@ -208,17 +208,17 @@ static struct virtio_ops blk_dev_virtio_ops = (struct virtio_ops) {
 	.get_size_vq		= get_size_vq,
 };
 
-void virtio_blk__init(struct kvm *kvm, struct disk_image *disk)
+static int virtio_blk__init_one(struct kvm *kvm, struct disk_image *disk)
 {
 	struct blk_dev *bdev;
 	unsigned int i;
 
 	if (!disk)
-		return;
+		return -EINVAL;
 
 	bdev = calloc(1, sizeof(struct blk_dev));
 	if (bdev == NULL)
-		die("Failed allocating bdev");
+		return -ENOMEM;
 
 	*bdev = (struct blk_dev) {
 		.mutex			= PTHREAD_MUTEX_INITIALIZER,
@@ -251,23 +251,40 @@ void virtio_blk__init(struct kvm *kvm, struct disk_image *disk)
 						"Please make sure that the guest kernel was "
 						"compiled with CONFIG_VIRTIO_BLK=y enabled "
 						"in its .config");
+	return 0;
 }
 
-void virtio_blk__init_all(struct kvm *kvm)
+static int virtio_blk__uninit_one(struct kvm *kvm, struct blk_dev *bdev)
 {
-	int i;
+	list_del(&bdev->list);
+	free(bdev);
 
-	for (i = 0; i < kvm->nr_disks; i++)
-		virtio_blk__init(kvm, kvm->disks[i]);
+	return 0;
 }
 
-void virtio_blk__delete_all(struct kvm *kvm)
+int virtio_blk__init(struct kvm *kvm)
+{
+	int i, r = 0;
+
+	for (i = 0; i < kvm->nr_disks; i++) {
+		r = virtio_blk__init_one(kvm, kvm->disks[i]);
+		if (r < 0)
+			goto cleanup;
+	}
+
+	return 0;
+cleanup:
+	return virtio_blk__uninit(kvm);
+}
+
+int virtio_blk__uninit(struct kvm *kvm)
 {
 	while (!list_empty(&bdevs)) {
 		struct blk_dev *bdev;
 
 		bdev = list_first_entry(&bdevs, struct blk_dev, list);
-		list_del(&bdev->list);
-		free(bdev);
+		virtio_blk__uninit_one(kvm, bdev);
 	}
+
+	return 0;
 }
-- 
1.7.8


  parent reply	other threads:[~2011-12-19 13:59 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-19 13:58 [RFC 00/12] Overhaul of error handling and module init/uninit Sasha Levin
2011-12-19 13:58 ` [RFC 01/12] kvm tools: Split kvm_cmd_run into init, work and uninit Sasha Levin
2011-12-19 21:26   ` Pekka Enberg
2011-12-20 10:09     ` Sasha Levin
2011-12-20  8:55       ` Asias He
2011-12-19 13:58 ` [RFC 02/12] kvm tools: Fixes for symbol resolving module Sasha Levin
2011-12-19 13:58 ` [RFC 03/12] kvm tools: Fixes for IRQ module Sasha Levin
2011-12-19 13:58 ` [RFC 04/12] kvm tools: Fixes for UI modules Sasha Levin
2011-12-19 13:58 ` [RFC 05/12] kvm tools: Fixes for ioport module Sasha Levin
2011-12-19 13:58 ` [RFC 06/12] kvm tools: Fixes for ioeventfd module Sasha Levin
2011-12-19 13:58 ` [RFC 07/12] kvm tools: Fixes for serial module Sasha Levin
2011-12-19 13:58 ` [RFC 08/12] kvm tools: Fixes for mptable module Sasha Levin
2011-12-19 13:58 ` [RFC 09/12] kvm tools: Fixes for ioeventfd module Sasha Levin
2011-12-19 13:58 ` Sasha Levin [this message]
2011-12-19 13:58 ` [RFC 11/12] kvm tools: Fixes for rtc module Sasha Levin
2011-12-19 13:58 ` [RFC 12/12] kvm tools: Fixes for ioeventfd module Sasha Levin
2011-12-19 21:29 ` [RFC 00/12] Overhaul of error handling and module init/uninit Pekka Enberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1324303114-5948-11-git-send-email-levinsasha928@gmail.com \
    --to=levinsasha928@gmail.com \
    --cc=asias.hejun@gmail.com \
    --cc=gorcunov@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=penberg@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.