summaryrefslogtreecommitdiff
path: root/src/udiskslinuxdrive.c
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2012-02-28 09:55:20 -0500
committerDavid Zeuthen <davidz@redhat.com>2012-02-28 09:55:20 -0500
commit7ecf57035d73c35619e06fa4cbb8334bdfe35630 (patch)
tree8a15f9830255c05f6be09a8405244fa058b49ab2 /src/udiskslinuxdrive.c
parent3b277903af128fb632897d8932fe300f216ead38 (diff)
Add iSCSI bits back
Signed-off-by: David Zeuthen <davidz@redhat.com>
Diffstat (limited to 'src/udiskslinuxdrive.c')
-rw-r--r--src/udiskslinuxdrive.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/src/udiskslinuxdrive.c b/src/udiskslinuxdrive.c
index 6192f4a..c7017b0 100644
--- a/src/udiskslinuxdrive.c
+++ b/src/udiskslinuxdrive.c
@@ -121,6 +121,207 @@ udisks_linux_drive_new (void)
/* ---------------------------------------------------------------------------------------------------- */
+static const gchar *
+find_iscsi_target (GDBusObjectManagerServer *object_manager,
+ const gchar *target_name)
+{
+ const gchar *ret;
+ GList *objects;
+ GList *l;
+
+ ret = NULL;
+
+ objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager));
+ for (l = objects; l != NULL; l = l->next)
+ {
+ UDisksObjectSkeleton *object = UDISKS_OBJECT_SKELETON (l->data);
+ UDisksiSCSITarget *target;
+
+ target = udisks_object_peek_iscsi_target (UDISKS_OBJECT (object));
+ if (target == NULL)
+ continue;
+
+ if (g_strcmp0 (udisks_iscsi_target_get_name (target), target_name) == 0)
+ {
+ ret = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
+ goto out;
+ }
+ }
+
+ out:
+ g_list_foreach (objects, (GFunc) g_object_unref, NULL);
+ g_list_free (objects);
+ return ret;
+}
+
+static gboolean
+find_iscsi_devices_for_block (GUdevClient *udev_client,
+ GUdevDevice *block_device,
+ GUdevDevice **out_session_device,
+ GUdevDevice **out_connection_device)
+{
+ gchar *s;
+ gchar *session_sysfs_path;
+ gchar *connection_sysfs_path;
+ GDir *session_dir;
+ GDir *connection_dir;
+ const gchar *name;
+ gboolean ret;
+ GUdevDevice *session_device;
+ GUdevDevice *connection_device;
+
+ ret = FALSE;
+ session_device = NULL;
+ connection_device = NULL;
+
+ session_dir = NULL;
+ connection_dir = NULL;
+ s = NULL;
+ session_sysfs_path = NULL;
+ connection_sysfs_path = NULL;
+
+ /* This is a bit sketchy and includes assumptions about what sysfs
+ * currently looks like...
+ */
+
+ if (out_session_device != NULL)
+ {
+ s = g_strdup_printf ("%s/device/../../iscsi_session", g_udev_device_get_sysfs_path (block_device));
+ if (!g_file_test (s, G_FILE_TEST_IS_DIR))
+ goto out;
+ session_dir = g_dir_open (s, 0, NULL);
+ if (session_dir == NULL)
+ goto out;
+ while ((name = g_dir_read_name (session_dir)) != NULL)
+ {
+ gint session_num;
+ if (sscanf (name, "session%d", &session_num) == 1)
+ {
+ session_sysfs_path = g_strdup_printf ("%s/%s", s, name);
+ break;
+ }
+ }
+ if (session_sysfs_path == NULL)
+ goto out;
+ session_device = g_udev_client_query_by_sysfs_path (udev_client, session_sysfs_path);
+ if (session_device == NULL)
+ goto out;
+ }
+
+ if (out_connection_device != NULL)
+ {
+ /* here we assume there is only one connection per session... this could end up not being true */
+ g_free (s);
+ s = g_strdup_printf ("%s/device/../..", g_udev_device_get_sysfs_path (block_device));
+ if (!g_file_test (s, G_FILE_TEST_IS_DIR))
+ goto out;
+ connection_dir = g_dir_open (s, 0, NULL);
+ if (connection_dir == NULL)
+ goto out;
+ while ((name = g_dir_read_name (connection_dir)) != NULL)
+ {
+ gint connection_num;
+ if (sscanf (name, "connection%d", &connection_num) == 1)
+ {
+ connection_sysfs_path = g_strdup_printf ("%s/%s/iscsi_connection/%s", s, name, name);
+ break;
+ }
+ }
+ if (connection_sysfs_path == NULL)
+ goto out;
+ connection_device = g_udev_client_query_by_sysfs_path (udev_client, connection_sysfs_path);
+ if (connection_device == NULL)
+ goto out;
+ }
+
+ ret = TRUE;
+
+ out:
+ g_free (s);
+ g_free (session_sysfs_path);
+ if (session_dir != NULL)
+ g_dir_close (session_dir);
+ g_free (connection_sysfs_path);
+ if (connection_dir != NULL)
+ g_dir_close (connection_dir);
+
+ if (ret)
+ {
+ if (out_session_device != NULL)
+ *out_session_device = session_device;
+ else
+ g_object_unref (session_device);
+
+ if (out_connection_device != NULL)
+ *out_connection_device = connection_device;
+ else
+ g_object_unref (connection_device);
+ }
+ else
+ {
+ if (session_device != NULL)
+ g_object_unref (session_device);
+ if (connection_device != NULL)
+ g_object_unref (connection_device);
+ }
+
+ return ret;
+}
+
+static void
+set_iscsi_target (UDisksLinuxDrive *drive,
+ UDisksDrive *iface,
+ GUdevDevice *device,
+ UDisksDaemon *daemon)
+{
+ GUdevClient *udev_client;
+ GUdevDevice *session_device;
+ GUdevDevice *connection_device;
+
+ /* note: @device may vary - it can be any path for drive */
+ session_device = NULL;
+ connection_device = NULL;
+
+ udisks_drive_set_iscsi_target (iface, "/");
+
+ udev_client = udisks_linux_provider_get_udev_client (udisks_daemon_get_linux_provider (daemon));
+ if (find_iscsi_devices_for_block (udev_client,
+ device,
+ &session_device,
+ &connection_device))
+ {
+ GDBusObjectManagerServer *object_manager;
+ const gchar *target_name;
+ const gchar *target_object_path;
+
+ target_name = g_udev_device_get_sysfs_attr (session_device, "targetname");
+ if (target_name == NULL)
+ {
+ udisks_warning ("Cannot find iSCSI target name for sysfs path %s",
+ g_udev_device_get_sysfs_path (session_device));
+ goto out;
+ }
+
+ object_manager = udisks_daemon_get_object_manager (daemon);
+ target_object_path = find_iscsi_target (object_manager, target_name);
+ if (target_object_path == NULL)
+ {
+ udisks_warning ("Cannot find iSCSI target object for name `%s'",
+ target_name);
+ goto out;
+ }
+ udisks_drive_set_iscsi_target (iface, target_object_path);
+
+ }
+ out:
+ if (connection_device != NULL)
+ g_object_unref (connection_device);
+ if (session_device != NULL)
+ g_object_unref (session_device);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static const struct
{
const gchar *udev_property;
@@ -519,6 +720,8 @@ udisks_linux_drive_update (UDisksLinuxDrive *drive,
udisks_drive_set_revision (iface, g_udev_device_get_property (device, "ID_REVISION"));
udisks_drive_set_serial (iface, g_udev_device_get_property (device, "ID_SCSI_SERIAL"));
udisks_drive_set_wwn (iface, g_udev_device_get_property (device, "ID_WWN_WITH_EXTENSION"));
+
+ set_iscsi_target (drive, iface, device, daemon);
}
else if (g_str_has_prefix (g_udev_device_get_name (device), "mmcblk"))
{