summaryrefslogtreecommitdiff
path: root/src/udiskslinuxmdraidobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/udiskslinuxmdraidobject.c')
-rw-r--r--src/udiskslinuxmdraidobject.c725
1 files changed, 0 insertions, 725 deletions
diff --git a/src/udiskslinuxmdraidobject.c b/src/udiskslinuxmdraidobject.c
deleted file mode 100644
index dbfdec0..0000000
--- a/src/udiskslinuxmdraidobject.c
+++ /dev/null
@@ -1,725 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include "config.h"
-#include <glib/gi18n-lib.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "udiskslogging.h"
-#include "udisksdaemon.h"
-#include "udisksdaemonutil.h"
-#include "udiskslinuxprovider.h"
-#include "udiskslinuxmdraidobject.h"
-#include "udiskslinuxmdraid.h"
-#include "udiskslinuxblockobject.h"
-#include "udiskslinuxdevice.h"
-
-/**
- * SECTION:udiskslinuxmdraidobject
- * @title: UDisksLinuxMDRaidObject
- * @short_description: Object representing a Linux Software RAID array
- *
- * Object corresponding to a Linux Software RAID array.
- */
-
-typedef struct _UDisksLinuxMDRaidObjectClass UDisksLinuxMDRaidObjectClass;
-
-/**
- * UDisksLinuxMDRaidObject:
- *
- * The #UDisksLinuxMDRaidObject structure contains only private data and
- * should only be accessed using the provided API.
- */
-struct _UDisksLinuxMDRaidObject
-{
- UDisksObjectSkeleton parent_instance;
-
- UDisksDaemon *daemon;
-
- /* The UUID for the object */
- gchar *uuid;
-
- /* The UDisksLinuxDevice for the RAID device (e.g. /dev/md0), if any */
- UDisksLinuxDevice *raid_device;
-
- /* list of UDisksLinuxDevice objects for detected member devices */
- GList *member_devices;
-
- /* interfaces */
- UDisksMDRaid *iface_mdraid;
-
- /* watches for sysfs attr changes */
- GSource *sync_action_source;
- GSource *degraded_source;
-};
-
-struct _UDisksLinuxMDRaidObjectClass
-{
- UDisksObjectSkeletonClass parent_class;
-};
-
-enum
-{
- PROP_0,
- PROP_UUID,
- PROP_DAEMON,
-};
-
-static void
-remove_watches (UDisksLinuxMDRaidObject *object)
-{
- if (object->sync_action_source != NULL)
- {
- g_source_destroy (object->sync_action_source);
- object->sync_action_source = NULL;
- }
- if (object->degraded_source != NULL)
- {
- g_source_destroy (object->degraded_source);
- object->degraded_source = NULL;
- }
-}
-
-G_DEFINE_TYPE (UDisksLinuxMDRaidObject, udisks_linux_mdraid_object, UDISKS_TYPE_OBJECT_SKELETON);
-
-static void
-udisks_linux_mdraid_object_finalize (GObject *_object)
-{
- UDisksLinuxMDRaidObject *object = UDISKS_LINUX_MDRAID_OBJECT (_object);
-
- /* note: we don't hold a ref to object->daemon */
-
- remove_watches (object);
-
- if (object->iface_mdraid != NULL)
- g_object_unref (object->iface_mdraid);
-
- g_clear_object (&object->raid_device);
-
- g_list_foreach (object->member_devices, (GFunc) g_object_unref, NULL);
- g_list_free (object->member_devices);
-
- g_free (object->uuid);
-
- if (G_OBJECT_CLASS (udisks_linux_mdraid_object_parent_class)->finalize != NULL)
- G_OBJECT_CLASS (udisks_linux_mdraid_object_parent_class)->finalize (_object);
-}
-
-static void
-udisks_linux_mdraid_object_get_property (GObject *__object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- UDisksLinuxMDRaidObject *object = UDISKS_LINUX_MDRAID_OBJECT (__object);
-
- switch (prop_id)
- {
- case PROP_DAEMON:
- g_value_set_object (value, udisks_linux_mdraid_object_get_daemon (object));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-udisks_linux_mdraid_object_set_property (GObject *__object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- UDisksLinuxMDRaidObject *object = UDISKS_LINUX_MDRAID_OBJECT (__object);
-
- switch (prop_id)
- {
- case PROP_DAEMON:
- g_assert (object->daemon == NULL);
- /* we don't take a reference to the daemon */
- object->daemon = g_value_get_object (value);
- break;
-
- case PROP_UUID:
- object->uuid = g_value_dup_string (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-static void
-udisks_linux_mdraid_object_init (UDisksLinuxMDRaidObject *object)
-{
-}
-
-static void
-strip_and_replace_with_uscore (gchar *s)
-{
- guint n;
-
- if (s == NULL)
- goto out;
-
- g_strstrip (s);
-
- for (n = 0; s != NULL && s[n] != '\0'; n++)
- {
- if (s[n] == ' ' || s[n] == '-' || s[n] == ':')
- s[n] = '_';
- }
-
- out:
- ;
-}
-
-static void
-udisks_linux_mdraid_object_constructed (GObject *_object)
-{
- UDisksLinuxMDRaidObject *object = UDISKS_LINUX_MDRAID_OBJECT (_object);
- gchar *uuid;
- gchar *s;
-
- /* compute the object path */
- uuid = g_strdup (object->uuid);
- strip_and_replace_with_uscore (uuid);
- s = g_strdup_printf ("/org/freedesktop/UDisks2/mdraid/%s", uuid);
- g_free (uuid);
- g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), s);
- g_free (s);
-
- if (G_OBJECT_CLASS (udisks_linux_mdraid_object_parent_class)->constructed != NULL)
- G_OBJECT_CLASS (udisks_linux_mdraid_object_parent_class)->constructed (_object);
-}
-
-static void
-udisks_linux_mdraid_object_class_init (UDisksLinuxMDRaidObjectClass *klass)
-{
- GObjectClass *gobject_class;
-
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = udisks_linux_mdraid_object_finalize;
- gobject_class->constructed = udisks_linux_mdraid_object_constructed;
- gobject_class->set_property = udisks_linux_mdraid_object_set_property;
- gobject_class->get_property = udisks_linux_mdraid_object_get_property;
-
- /**
- * UDisksLinuxMDRaidObject:daemon:
- *
- * The #UDisksDaemon the object is for.
- */
- g_object_class_install_property (gobject_class,
- PROP_DAEMON,
- g_param_spec_object ("daemon",
- "Daemon",
- "The daemon the object is for",
- UDISKS_TYPE_DAEMON,
- G_PARAM_READABLE |
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
- /**
- * UDisksLinuxMDRaidObject:uuid:
- *
- * The UUID for the array.
- */
- g_object_class_install_property (gobject_class,
- PROP_UUID,
- g_param_spec_string ("uuid",
- "UUID",
- "The UUID for the array",
- NULL,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-}
-
-/**
- * udisks_linux_mdraid_object_new:
- * @daemon: A #UDisksDaemon.
- * @uuid: The UUID for the array.
- *
- * Create a new MDRaid object.
- *
- * Returns: A #UDisksLinuxMDRaidObject object. Free with g_object_unref().
- */
-UDisksLinuxMDRaidObject *
-udisks_linux_mdraid_object_new (UDisksDaemon *daemon,
- const gchar *uuid)
-{
- g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), NULL);
- g_return_val_if_fail (uuid != NULL, NULL);
- return UDISKS_LINUX_MDRAID_OBJECT (g_object_new (UDISKS_TYPE_LINUX_MDRAID_OBJECT,
- "daemon", daemon,
- "uuid", uuid,
- NULL));
-}
-
-/**
- * udisks_linux_mdraid_object_get_daemon:
- * @object: A #UDisksLinuxMDRaidObject.
- *
- * Gets the daemon used by @object.
- *
- * Returns: A #UDisksDaemon. Do not free, the object is owned by @object.
- */
-UDisksDaemon *
-udisks_linux_mdraid_object_get_daemon (UDisksLinuxMDRaidObject *object)
-{
- g_return_val_if_fail (UDISKS_IS_LINUX_MDRAID_OBJECT (object), NULL);
- return object->daemon;
-}
-
-/**
- * udisks_linux_mdraid_object_get_members:
- * @object: A #UDisksLinuxMDRaidObject.
- *
- * Gets the current #UDisksLinuxDevice objects for the RAID members associated with @object.
- *
- * Returns: A list of #UDisksLinuxDevice objects. Free each element with
- * g_object_unref(), then free the list with g_list_free().
- */
-GList *
-udisks_linux_mdraid_object_get_members (UDisksLinuxMDRaidObject *object)
-{
- GList *ret = NULL;
-
- g_return_val_if_fail (UDISKS_IS_LINUX_MDRAID_OBJECT (object), NULL);
-
- ret = g_list_copy (object->member_devices);
- g_list_foreach (ret, (GFunc) g_object_ref, NULL);
-
- return ret;
-}
-
-/**
- * udisks_linux_mdraid_object_get_device:
- * @object: A #UDisksLinuxMDRaidObject.
- *
- * Gets the current #UDisksLinuxDevice object for the RAID device
- * (e.g. /dev/md0) associated with @object, if any.
- *
- * Returns: (transfer full): A #UDisksLinuxDevice or %NULL. Free with g_object_unref().
- */
-UDisksLinuxDevice *
-udisks_linux_mdraid_object_get_device (UDisksLinuxMDRaidObject *object)
-{
- UDisksLinuxDevice *ret = NULL;
-
- g_return_val_if_fail (UDISKS_IS_LINUX_MDRAID_OBJECT (object), NULL);
-
- ret = object->raid_device != NULL ? g_object_ref (object->raid_device) : NULL;
-
- return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-typedef gboolean (*HasInterfaceFunc) (UDisksLinuxMDRaidObject *object);
-typedef void (*ConnectInterfaceFunc) (UDisksLinuxMDRaidObject *object);
-typedef gboolean (*UpdateInterfaceFunc) (UDisksLinuxMDRaidObject *object,
- const gchar *uevent_action,
- GDBusInterface *interface);
-
-static gboolean
-update_iface (UDisksLinuxMDRaidObject *object,
- const gchar *uevent_action,
- HasInterfaceFunc has_func,
- ConnectInterfaceFunc connect_func,
- UpdateInterfaceFunc update_func,
- GType skeleton_type,
- gpointer _interface_pointer)
-{
- gboolean ret = FALSE;
- gboolean has;
- gboolean add;
- GDBusInterface **interface_pointer = _interface_pointer;
-
- g_return_val_if_fail (object != NULL, FALSE);
- g_return_val_if_fail (has_func != NULL, FALSE);
- g_return_val_if_fail (update_func != NULL, FALSE);
- g_return_val_if_fail (g_type_is_a (skeleton_type, G_TYPE_OBJECT), FALSE);
- g_return_val_if_fail (g_type_is_a (skeleton_type, G_TYPE_DBUS_INTERFACE), FALSE);
- g_return_val_if_fail (interface_pointer != NULL, FALSE);
- g_return_val_if_fail (*interface_pointer == NULL || G_IS_DBUS_INTERFACE (*interface_pointer), FALSE);
-
- add = FALSE;
- has = has_func (object);
- if (*interface_pointer == NULL)
- {
- if (has)
- {
- *interface_pointer = g_object_new (skeleton_type, NULL);
- if (connect_func != NULL)
- connect_func (object);
- add = TRUE;
- }
- }
- else
- {
- if (!has)
- {
- g_dbus_object_skeleton_remove_interface (G_DBUS_OBJECT_SKELETON (object),
- G_DBUS_INTERFACE_SKELETON (*interface_pointer));
- g_object_unref (*interface_pointer);
- *interface_pointer = NULL;
- }
- }
-
- if (*interface_pointer != NULL)
- {
- if (update_func (object, uevent_action, G_DBUS_INTERFACE (*interface_pointer)))
- ret = TRUE;
- if (add)
- g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (object),
- G_DBUS_INTERFACE_SKELETON (*interface_pointer));
- }
-
- return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static gboolean
-mdraid_check (UDisksLinuxMDRaidObject *object)
-{
- return TRUE;
-}
-
-static void
-mdraid_connect (UDisksLinuxMDRaidObject *object)
-{
-}
-
-static gboolean
-mdraid_update (UDisksLinuxMDRaidObject *object,
- const gchar *uevent_action,
- GDBusInterface *_iface)
-{
- return udisks_linux_mdraid_update (UDISKS_LINUX_MDRAID (object->iface_mdraid), object);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static GList *
-find_link_for_sysfs_path_for_member (UDisksLinuxMDRaidObject *object,
- const gchar *sysfs_path)
-{
- GList *l;
- GList *ret;
- ret = NULL;
-
- for (l = object->member_devices; l != NULL; l = l->next)
- {
- UDisksLinuxDevice *device = UDISKS_LINUX_DEVICE (l->data);
- if (g_strcmp0 (g_udev_device_get_sysfs_path (device->udev_device), sysfs_path) == 0)
- {
- ret = l;
- goto out;
- }
- }
- out:
- return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static GSource *
-watch_attr (UDisksLinuxDevice *device,
- const gchar *attr,
- GSourceFunc callback,
- gpointer user_data)
-{
- GError *error = NULL;
- gchar *path = NULL;
- GIOChannel *channel = NULL;
- GSource *ret = NULL;;
-
- g_return_val_if_fail (UDISKS_IS_LINUX_DEVICE (device), NULL);
-
- path = g_strdup_printf ("%s/%s", g_udev_device_get_sysfs_path (device->udev_device), attr);
- channel = g_io_channel_new_file (path, "r", &error);
- if (channel != NULL)
- {
- ret = g_io_create_watch (channel, G_IO_ERR);
- g_source_set_callback (ret, callback, user_data, NULL);
- g_source_attach (ret, g_main_context_get_thread_default ());
- g_source_unref (ret);
- g_io_channel_unref (channel); /* the keeps a reference to this object */
- }
- else
- {
- udisks_warning ("Error creating watch for file %s: %s (%s, %d)",
- path, error->message, g_quark_to_string (error->domain), error->code);
- g_clear_error (&error);
- }
- g_free (path);
-
- return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static gboolean
-attr_changed (GIOChannel *channel,
- GIOCondition cond,
- gpointer user_data)
-{
- UDisksLinuxMDRaidObject *object = UDISKS_LINUX_MDRAID_OBJECT (user_data);
- gboolean bail = FALSE;
- GError *error = NULL;
- gchar *str = NULL;
- gsize len = 0;
-
- if (cond & ~G_IO_ERR)
- goto out;
-
- if (g_io_channel_seek_position (channel, 0, G_SEEK_SET, &error) != G_IO_STATUS_NORMAL)
- {
- udisks_debug ("Error seeking in channel (uuid %s): %s (%s, %d)",
- object->uuid, error->message, g_quark_to_string (error->domain), error->code);
- g_clear_error (&error);
- bail = TRUE;
- goto out;
- }
-
- if (g_io_channel_read_to_end (channel, &str, &len, &error) != G_IO_STATUS_NORMAL)
- {
- udisks_debug ("Error reading (uuid %s): %s (%s, %d)",
- object->uuid, error->message, g_quark_to_string (error->domain), error->code);
- g_clear_error (&error);
- bail = TRUE;
- goto out;
- }
-
- g_free (str);
-
- /* synthesize uevent */
- if (object->raid_device != NULL)
- udisks_linux_mdraid_object_uevent (object, "change", object->raid_device, FALSE);
-
- out:
- if (bail)
- remove_watches (object);
- return TRUE; /* keep event source around */
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-/* The md(4) driver does not use the usual uevent 'change' mechanism
- * for notification - instead it excepts user-space to select(2)-ish
- * on a fd for the sysfs attribute. Annoying. See
- *
- * http://www.kernel.org/doc/Documentation/md.txt
- *
- * for more details.
- */
-
-static void
-raid_device_added (UDisksLinuxMDRaidObject *object,
- UDisksLinuxDevice *device)
-{
- g_assert (object->sync_action_source == NULL);
- g_assert (object->degraded_source == NULL);
-
- /* udisks_debug ("start watching %s", g_udev_device_get_sysfs_path (device->udev_device)); */
- object->sync_action_source = watch_attr (device,
- "md/sync_action",
- (GSourceFunc) attr_changed,
- object);
- object->degraded_source = watch_attr (device,
- "md/degraded",
- (GSourceFunc) attr_changed,
- object);
-}
-
-static void
-raid_device_removed (UDisksLinuxMDRaidObject *object,
- UDisksLinuxDevice *device)
-{
- /* udisks_debug ("stop watching %s", g_udev_device_get_sysfs_path (device->udev_device)); */
- remove_watches (object);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-/**
- * udisks_linux_mdraid_object_uevent:
- * @object: A #UDisksLinuxMDRaidObject.
- * @action: Uevent action or %NULL
- * @device: A #UDisksLinuxDevice device object or %NULL if the device hasn't changed.
- * @is_member: %TRUE if @device is a member, %FALSE if it's the raid device.
- *
- * Updates all information on interfaces on @mdraid.
- */
-void
-udisks_linux_mdraid_object_uevent (UDisksLinuxMDRaidObject *object,
- const gchar *action,
- UDisksLinuxDevice *device,
- gboolean is_member)
-{
- gboolean conf_changed = FALSE;
-
- g_return_if_fail (UDISKS_IS_LINUX_MDRAID_OBJECT (object));
- g_return_if_fail (UDISKS_IS_LINUX_DEVICE (device));
-
- /* udisks_debug ("is_member=%d for uuid %s and device %s", is_member, object->uuid, g_udev_device_get_device_file (device->udev_device)); */
-
- if (is_member)
- {
- GList *link = NULL;
- link = NULL;
- if (device != NULL)
- link = find_link_for_sysfs_path_for_member (object, g_udev_device_get_sysfs_path (device->udev_device));
-
- if (g_strcmp0 (action, "remove") == 0)
- {
- if (link != NULL)
- {
- g_object_unref (UDISKS_LINUX_DEVICE (link->data));
- object->member_devices = g_list_delete_link (object->member_devices, link);
- }
- else
- {
- udisks_warning ("MDRaid with UUID %s doesn't have member device with sysfs path %s on remove event",
- object->uuid,
- g_udev_device_get_sysfs_path (device->udev_device));
- }
- }
- else
- {
- if (link != NULL)
- {
- if (device != link->data)
- {
- g_object_unref (UDISKS_LINUX_DEVICE (link->data));
- link->data = g_object_ref (device);
- }
- }
- else
- {
- if (device != NULL)
- {
- object->member_devices = g_list_append (object->member_devices, g_object_ref (device));
- }
- }
- }
- }
- else
- {
- /* Skip partitions of raid devices */
- if (g_strcmp0 (g_udev_device_get_devtype (device->udev_device), "disk") != 0)
- goto out;
-
- if (g_strcmp0 (action, "remove") == 0)
- {
- if (object->raid_device != NULL)
- if (g_strcmp0 (g_udev_device_get_sysfs_path (object->raid_device->udev_device),
- g_udev_device_get_sysfs_path (device->udev_device)) == 0)
- {
- g_clear_object (&object->raid_device);
- raid_device_removed (object, object->raid_device);
- }
- else
- {
- udisks_warning ("MDRaid with UUID %s doesn't have raid device with sysfs path %s on remove event (it has %s)",
- object->uuid,
- g_udev_device_get_sysfs_path (device->udev_device),
- g_udev_device_get_sysfs_path (object->raid_device->udev_device));
- }
- else
- {
- udisks_warning ("MDRaid with UUID %s doesn't have raid device with sysfs path %s on remove event",
- object->uuid,
- g_udev_device_get_sysfs_path (device->udev_device));
- }
- }
- else
- {
- if (object->raid_device == NULL)
- {
- object->raid_device = g_object_ref (device);
- raid_device_added (object, object->raid_device);
- }
- else
- {
- if (device != object->raid_device)
- {
- g_clear_object (&object->raid_device);
- object->raid_device = g_object_ref (device);
- }
- }
- }
- }
-
- /* if we don't have any devices, no point in updating (we should get nuked soon anyway) */
- if (udisks_linux_mdraid_object_have_devices (object))
- {
- conf_changed = FALSE;
- conf_changed |= update_iface (object, action, mdraid_check, mdraid_connect, mdraid_update,
- UDISKS_TYPE_LINUX_MDRAID, &object->iface_mdraid);
- }
- out:
- ;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-/**
- * udisks_linux_mdraid_object_have_devices:
- * @object: A #UDisksLinuxMDRaidObject.
- *
- * Checks if there are any devices associated with @object at
- * all. This includes both member devices and the raid device.
- *
- * Returns: %TRUE if at least one device is associated with @object, %FALSE otherwise.
- */
-gboolean
-udisks_linux_mdraid_object_have_devices (UDisksLinuxMDRaidObject *object)
-{
- g_return_val_if_fail (UDISKS_IS_LINUX_MDRAID_OBJECT (object), FALSE);
-
- return g_list_length (object->member_devices) > 0 || object->raid_device != NULL;
-}
-
-/**
- * udisks_linux_mdraid_object_get_uuid:
- * @object: A #UDisksLinuxMDRaidObject.
- *
- * Gets the UUID for @object.
- *
- * Returns: (transfer none): The UUID for object. Do not free, the string belongs to @object.
- */
-const gchar *
-udisks_linux_mdraid_object_get_uuid (UDisksLinuxMDRaidObject *object)
-{
- g_return_val_if_fail (UDISKS_IS_LINUX_MDRAID_OBJECT (object), NULL);
- return object->uuid;
-}
-
-