[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/5] raw-posix: unmount CD-ROM filesystem via udisks
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH 5/5] raw-posix: unmount CD-ROM filesystem via udisks |
Date: |
Wed, 8 Feb 2012 18:37:36 +0100 |
We need to use O_EXCL in order to suppress event generation in the
kernel. However, O_EXCL by definition fails when the CD-ROM drive
is mounted. Automatically unmount it when it is passed through to
the guest.
Signed-off-by: Paolo Bonzini <address@hidden>
---
Makefile.objs | 3 +
block.c | 7 +++
block/raw-posix-udisks.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++
block/raw-posix-udisks.h | 39 +++++++++++++++++
block/raw-posix.c | 17 ++++++-
5 files changed, 168 insertions(+), 3 deletions(-)
create mode 100644 block/raw-posix-udisks.c
create mode 100644 block/raw-posix-udisks.h
diff --git a/Makefile.objs b/Makefile.objs
index ec35320..a30a80d 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -41,6 +41,9 @@ block-nested-$(CONFIG_POSIX) += raw-posix.o
block-nested-$(CONFIG_LIBISCSI) += iscsi.o
block-nested-$(CONFIG_CURL) += curl.o
block-nested-$(CONFIG_RBD) += rbd.o
+ifeq ($(CONFIG_DBUS),y)
+block-nested-$(CONFIG_LINUX) += raw-posix-udisks.o
+endif
block-obj-y += $(addprefix block/, $(block-nested-y))
diff --git a/block.c b/block.c
index 3621d11..6dad6b5 100644
--- a/block.c
+++ b/block.c
@@ -42,6 +42,10 @@
#endif
#endif
+#ifdef CONFIG_DBUS
+#include <glib-object.h>
+#endif
+
#ifdef _WIN32
#include <windows.h>
#endif
@@ -3278,6 +3282,9 @@ BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
void bdrv_init(void)
{
module_call_init(MODULE_INIT_BLOCK);
+#ifdef CONFIG_DBUS
+ g_type_init();
+#endif
}
void bdrv_init_with_whitelist(void)
diff --git a/block/raw-posix-udisks.c b/block/raw-posix-udisks.c
new file mode 100644
index 0000000..3ab3cbe
--- /dev/null
+++ b/block/raw-posix-udisks.c
@@ -0,0 +1,105 @@
+/*
+ * Udisks interaction for CD-ROM unmounting
+ *
+ * Copyright (c) 2012 Red Hat, Inc.
+ *
+ * Author: Paolo Bonzini <address@hidden>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include "block/raw-posix-udisks.h"
+
+static void udisks_find_device_by_device_file(DBusGConnection *bus,
+ const char *path,
+ char **object_path,
+ GError **error)
+{
+ DBusGProxy *proxy;
+ proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks",
+ "/org/freedesktop/UDisks",
+ "org.freedesktop.UDisks");
+ dbus_g_proxy_call (proxy, "FindDeviceByDeviceFile", error,
+ G_TYPE_STRING, path, G_TYPE_INVALID,
+ DBUS_TYPE_G_OBJECT_PATH, object_path, G_TYPE_INVALID);
+ g_object_unref (proxy);
+}
+
+static void udisks_device_filesystem_unmount(DBusGConnection *bus,
+ const char *object_path,
+ GError **error)
+{
+ DBusGProxy *proxy;
+ proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks",
+ object_path,
+ "org.freedesktop.UDisks.Device");
+ dbus_g_proxy_call (proxy, "FilesystemUnmount", error,
+ G_TYPE_STRV, NULL, G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ g_object_unref (proxy);
+}
+
+int
+udisks_unmount (const char *path)
+{
+ DBusGConnection *bus;
+ char *object_path;
+ GError *error;
+ int ret;
+
+ error = NULL;
+ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (bus == NULL) {
+ g_warning ("Couldn't connect to system bus: %s", error->message);
+ ret = -EACCES;
+ goto out;
+ }
+
+ udisks_find_device_by_device_file(bus, path, &object_path, &error);
+ if (error || !object_path) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ udisks_device_filesystem_unmount(bus, object_path, &error);
+ if (error) {
+ g_print ("Unmount failed: %s\n", error->message);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ret = 0; /* success */
+out:
+ g_free (object_path);
+ if (error != NULL) {
+ g_error_free (error);
+ }
+ if (bus != NULL) {
+ dbus_g_connection_unref (bus);
+ }
+ return ret;
+}
diff --git a/block/raw-posix-udisks.h b/block/raw-posix-udisks.h
new file mode 100644
index 0000000..47dd638
--- /dev/null
+++ b/block/raw-posix-udisks.h
@@ -0,0 +1,39 @@
+/*
+ * Udisks interaction for CD-ROM unmounting
+ *
+ * Copyright (c) 2012 Red Hat, Inc.
+ *
+ * Author: Paolo Bonzini <address@hidden>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef QEMU_UDISKS_H
+#define QEMU_UDISKS_H 1
+
+#include "config-host.h"
+#include <errno.h>
+
+#ifdef CONFIG_DBUS
+int udisks_unmount (const char *path);
+#else
+static int udisks_unmount (const char *path) { return -ENOSYS; }
+#endif
+
+#endif
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 1b51bd4..c61d07a 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -28,6 +28,7 @@
#include "block_int.h"
#include "module.h"
#include "block/raw-posix-aio.h"
+#include "block/raw-posix-udisks.h"
#ifdef CONFIG_COCOA
#include <paths.h>
@@ -1069,15 +1070,25 @@ static int cdrom_open(BlockDriverState *bs, const char
*filename, int flags)
{
BDRVRawState *s = bs->opaque;
int rc;
+ int i;
s->type = FTYPE_CD;
/* open will not fail even if no CD is inserted, so add O_NONBLOCK. First
* try with O_EXCL to see whether the CD is mounted.
*/
- rc = raw_open_common(bs, filename, flags, O_NONBLOCK | O_EXCL);
- if (rc < 0 && rc != -EBUSY) {
- return rc;
+ for (i = 0; i < 20; i++) {
+ rc = raw_open_common(bs, filename, flags, O_NONBLOCK | O_EXCL);
+ if (rc == 0) {
+ break;
+ }
+ if (rc != -EBUSY) {
+ return rc;
+ }
+ if (i == 0 && udisks_unmount(filename) < 0) {
+ break;
+ }
+ usleep(100 * 1000);
}
s->cd.manage_door = false;
--
1.7.7.6
[Qemu-devel] [PATCH 2/5] raw-posix: put Linux fd fields into a union, Paolo Bonzini, 2012/02/08
[Qemu-devel] [PATCH 4/5] configure: probe for dbus, Paolo Bonzini, 2012/02/08
[Qemu-devel] [PATCH 5/5] raw-posix: unmount CD-ROM filesystem via udisks,
Paolo Bonzini <=