1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
3
* Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
#include <glib/gi18n-lib.h>
28
#include "udiskslogging.h"
29
#include "udisksdaemon.h"
30
#include "udisksdaemonutil.h"
31
#include "udiskslinuxprovider.h"
32
#include "udiskslinuxdriveobject.h"
33
#include "udiskslinuxdrive.h"
34
#include "udiskslinuxdriveata.h"
35
#include "udiskslinuxblockobject.h"
36
#include "udiskslinuxdevice.h"
39
* SECTION:udiskslinuxdriveobject
40
* @title: UDisksLinuxDriveObject
41
* @short_description: Object representing a drive on Linux
43
* Object corresponding to a drive on Linux.
46
typedef struct _UDisksLinuxDriveObjectClass UDisksLinuxDriveObjectClass;
49
* UDisksLinuxDriveObject:
51
* The #UDisksLinuxDriveObject structure contains only private data and
52
* should only be accessed using the provided API.
54
struct _UDisksLinuxDriveObject
56
UDisksObjectSkeleton parent_instance;
60
/* list of UDisksLinuxDevice objects for block objects */
64
UDisksDrive *iface_drive;
65
UDisksDriveAta *iface_drive_ata;
68
struct _UDisksLinuxDriveObjectClass
70
UDisksObjectSkeletonClass parent_class;
80
G_DEFINE_TYPE (UDisksLinuxDriveObject, udisks_linux_drive_object, UDISKS_TYPE_OBJECT_SKELETON);
83
udisks_linux_drive_object_finalize (GObject *_object)
85
UDisksLinuxDriveObject *object = UDISKS_LINUX_DRIVE_OBJECT (_object);
87
/* note: we don't hold a ref to drive_object->daemon or drive_object->mount_monitor */
88
g_list_foreach (object->devices, (GFunc) g_object_unref, NULL);
89
g_list_free (object->devices);
91
if (object->iface_drive != NULL)
92
g_object_unref (object->iface_drive);
93
if (object->iface_drive_ata != NULL)
94
g_object_unref (object->iface_drive_ata);
96
if (G_OBJECT_CLASS (udisks_linux_drive_object_parent_class)->finalize != NULL)
97
G_OBJECT_CLASS (udisks_linux_drive_object_parent_class)->finalize (_object);
101
udisks_linux_drive_object_get_property (GObject *__object,
106
UDisksLinuxDriveObject *object = UDISKS_LINUX_DRIVE_OBJECT (__object);
111
g_value_set_object (value, udisks_linux_drive_object_get_daemon (object));
115
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
121
udisks_linux_drive_object_set_property (GObject *__object,
126
UDisksLinuxDriveObject *object = UDISKS_LINUX_DRIVE_OBJECT (__object);
131
g_assert (object->daemon == NULL);
132
/* we don't take a reference to the daemon */
133
object->daemon = g_value_get_object (value);
137
g_assert (object->devices == NULL);
138
object->devices = g_list_prepend (NULL, g_value_dup_object (value));
142
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
149
udisks_linux_drive_object_init (UDisksLinuxDriveObject *object)
153
static GObjectConstructParam *
154
find_construct_property (guint n_construct_properties,
155
GObjectConstructParam *construct_properties,
159
for (n = 0; n < n_construct_properties; n++)
160
if (g_strcmp0 (g_param_spec_get_name (construct_properties[n].pspec), name) == 0)
161
return &construct_properties[n];
165
/* unless given, compute object path from sysfs path */
167
udisks_linux_drive_object_constructor (GType type,
168
guint n_construct_properties,
169
GObjectConstructParam *construct_properties)
171
GObjectConstructParam *cp;
172
UDisksDaemon *daemon;
174
UDisksLinuxDevice *device;
176
cp = find_construct_property (n_construct_properties, construct_properties, "daemon");
177
g_assert (cp != NULL);
178
daemon = UDISKS_DAEMON (g_value_get_object (cp->value));
179
g_assert (daemon != NULL);
181
client = udisks_linux_provider_get_udev_client (udisks_daemon_get_linux_provider (daemon));
183
cp = find_construct_property (n_construct_properties, construct_properties, "device");
184
g_assert (cp != NULL);
185
device = g_value_get_object (cp->value);
186
g_assert (device != NULL);
188
if (!udisks_linux_drive_object_should_include_device (client, device, NULL))
194
return G_OBJECT_CLASS (udisks_linux_drive_object_parent_class)->constructor (type,
195
n_construct_properties,
196
construct_properties);
201
strip_and_replace_with_uscore (gchar *s)
210
for (n = 0; s != NULL && s[n] != '\0'; n++)
212
if (s[n] == ' ' || s[n] == '-')
221
udisks_linux_drive_object_constructed (GObject *_object)
223
UDisksLinuxDriveObject *object = UDISKS_LINUX_DRIVE_OBJECT (_object);
229
/* initial coldplug */
230
udisks_linux_drive_object_uevent (object, "add", object->devices->data);
232
/* compute the object path */
233
vendor = g_strdup (udisks_drive_get_vendor (object->iface_drive));
234
model = g_strdup (udisks_drive_get_model (object->iface_drive));
235
serial = g_strdup (udisks_drive_get_serial (object->iface_drive));
236
strip_and_replace_with_uscore (vendor);
237
strip_and_replace_with_uscore (model);
238
strip_and_replace_with_uscore (serial);
239
str = g_string_new ("/org/freedesktop/UDisks2/drives/");
240
if (vendor == NULL && model == NULL && serial == NULL)
242
g_string_append (str, "drive");
246
/* <VENDOR>_<MODEL>_<SERIAL> */
247
if (vendor != NULL && strlen (vendor) > 0)
249
udisks_safe_append_to_object_path (str, vendor);
251
if (model != NULL && strlen (model) > 0)
253
if (str->str[str->len - 1] != '/')
254
g_string_append_c (str, '_');
255
udisks_safe_append_to_object_path (str, model);
257
if (serial != NULL && strlen (serial) > 0)
259
if (str->str[str->len - 1] != '/')
260
g_string_append_c (str, '_');
261
udisks_safe_append_to_object_path (str, serial);
267
g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), str->str);
268
g_string_free (str, TRUE);
270
if (G_OBJECT_CLASS (udisks_linux_drive_object_parent_class)->constructed != NULL)
271
G_OBJECT_CLASS (udisks_linux_drive_object_parent_class)->constructed (_object);
275
udisks_linux_drive_object_class_init (UDisksLinuxDriveObjectClass *klass)
277
GObjectClass *gobject_class;
279
gobject_class = G_OBJECT_CLASS (klass);
280
gobject_class->constructor = udisks_linux_drive_object_constructor;
281
gobject_class->finalize = udisks_linux_drive_object_finalize;
282
gobject_class->constructed = udisks_linux_drive_object_constructed;
283
gobject_class->set_property = udisks_linux_drive_object_set_property;
284
gobject_class->get_property = udisks_linux_drive_object_get_property;
287
* UDisksLinuxDriveObject:daemon:
289
* The #UDisksDaemon the object is for.
291
g_object_class_install_property (gobject_class,
293
g_param_spec_object ("daemon",
295
"The daemon the object is for",
299
G_PARAM_CONSTRUCT_ONLY |
300
G_PARAM_STATIC_STRINGS));
303
* UDisksLinuxDriveObject:device:
305
* The #UDisksLinuxDevice for the object. Connect to the #GObject::notify
306
* signal to get notified whenever this is updated.
308
g_object_class_install_property (gobject_class,
310
g_param_spec_object ("device",
312
"The device for the object",
313
UDISKS_TYPE_LINUX_DEVICE,
315
G_PARAM_CONSTRUCT_ONLY |
316
G_PARAM_STATIC_STRINGS));
321
* udisks_linux_drive_object_new:
322
* @daemon: A #UDisksDaemon.
323
* @device: The #UDisksLinuxDevice for the sysfs block device.
325
* Create a new drive object.
327
* Returns: A #UDisksLinuxDriveObject object or %NULL if @device does not represent a drive. Free with g_object_unref().
329
UDisksLinuxDriveObject *
330
udisks_linux_drive_object_new (UDisksDaemon *daemon,
331
UDisksLinuxDevice *device)
335
g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), NULL);
336
g_return_val_if_fail (UDISKS_IS_LINUX_DEVICE (device), NULL);
338
object = g_object_new (UDISKS_TYPE_LINUX_DRIVE_OBJECT,
344
return UDISKS_LINUX_DRIVE_OBJECT (object);
350
* udisks_linux_drive_object_get_daemon:
351
* @object: A #UDisksLinuxDriveObject.
353
* Gets the daemon used by @object.
355
* Returns: A #UDisksDaemon. Do not free, the object is owned by @object.
358
udisks_linux_drive_object_get_daemon (UDisksLinuxDriveObject *object)
360
g_return_val_if_fail (UDISKS_IS_LINUX_DRIVE_OBJECT (object), NULL);
361
return object->daemon;
365
* udisks_linux_drive_object_get_devices:
366
* @object: A #UDisksLinuxDriveObject.
368
* Gets the current #UDisksLinuxDevice objects associated with @object.
370
* Returns: A list of #UDisksLinuxDevice objects. Free each element with
371
* g_object_unref(), then free the list with g_list_free().
374
udisks_linux_drive_object_get_devices (UDisksLinuxDriveObject *object)
377
g_return_val_if_fail (UDISKS_IS_LINUX_DRIVE_OBJECT (object), NULL);
378
ret = g_list_copy (object->devices);
379
g_list_foreach (ret, (GFunc) g_object_ref, NULL);
384
* udisks_linux_drive_object_get_device:
385
* @object: A #UDisksLinuxDriveObject.
386
* @get_hw: If the drive is multipath, set to %TRUE to get a path device instead of the multipath device.
388
* Gets one of the #UDisksLinuxDevice object associated with @object.
390
* If @get_hw is %TRUE and @object represents a multipath device then
391
* one of the paths is returned rather than the multipath device. This
392
* is useful if you e.g. need to configure the physical hardware.
394
* Returns: A #UDisksLinuxDevice or %NULL. The returned object must be freed
395
* with g_object_unref().
398
udisks_linux_drive_object_get_device (UDisksLinuxDriveObject *object,
401
UDisksLinuxDevice *ret = NULL;
402
/* TODO: actually look at @get_hw */
403
if (object->devices != NULL)
405
ret = object->devices->data;
413
* udisks_linux_drive_object_get_block:
414
* @object: A #UDisksLinuxDriveObject.
415
* @get_hw: If the drive is multipath, set to %TRUE to get a path device instead of the multipath device.
417
* Gets a #UDisksLinuxBlockObject representing a block device associated with @object.
419
* Returns: A #UDisksLinuxBlockObject or %NULL. The returned object
420
* must be freed with g_object_unref().
422
UDisksLinuxBlockObject *
423
udisks_linux_drive_object_get_block (UDisksLinuxDriveObject *object,
426
GDBusObjectManagerServer *object_manager;
427
UDisksLinuxBlockObject *ret;
431
/* TODO: actually look at @get_hw */
435
object_manager = udisks_daemon_get_object_manager (object->daemon);
436
objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager));
437
for (l = objects; l != NULL; l = l->next)
439
GDBusObjectSkeleton *iter_object = G_DBUS_OBJECT_SKELETON (l->data);
441
UDisksLinuxDevice *device;
444
if (!UDISKS_IS_LINUX_BLOCK_OBJECT (iter_object))
447
device = udisks_linux_block_object_get_device (UDISKS_LINUX_BLOCK_OBJECT (iter_object));
448
is_disk = (g_strcmp0 (g_udev_device_get_devtype (device->udev_device), "disk") == 0);
449
g_object_unref (device);
454
block = udisks_object_peek_block (UDISKS_OBJECT (iter_object));
455
if (g_strcmp0 (udisks_block_get_drive (block),
456
g_dbus_object_get_object_path (G_DBUS_OBJECT (object))) == 0)
458
ret = g_object_ref (iter_object);
464
g_list_foreach (objects, (GFunc) g_object_unref, NULL);
465
g_list_free (objects);
469
/* ---------------------------------------------------------------------------------------------------- */
471
typedef gboolean (*HasInterfaceFunc) (UDisksLinuxDriveObject *object);
472
typedef void (*ConnectInterfaceFunc) (UDisksLinuxDriveObject *object);
473
typedef gboolean (*UpdateInterfaceFunc) (UDisksLinuxDriveObject *object,
474
const gchar *uevent_action,
475
GDBusInterface *interface);
478
update_iface (UDisksLinuxDriveObject *object,
479
const gchar *uevent_action,
480
HasInterfaceFunc has_func,
481
ConnectInterfaceFunc connect_func,
482
UpdateInterfaceFunc update_func,
484
gpointer _interface_pointer)
486
gboolean ret = FALSE;
489
GDBusInterface **interface_pointer = _interface_pointer;
491
g_return_val_if_fail (object != NULL, FALSE);
492
g_return_val_if_fail (has_func != NULL, FALSE);
493
g_return_val_if_fail (update_func != NULL, FALSE);
494
g_return_val_if_fail (g_type_is_a (skeleton_type, G_TYPE_OBJECT), FALSE);
495
g_return_val_if_fail (g_type_is_a (skeleton_type, G_TYPE_DBUS_INTERFACE), FALSE);
496
g_return_val_if_fail (interface_pointer != NULL, FALSE);
497
g_return_val_if_fail (*interface_pointer == NULL || G_IS_DBUS_INTERFACE (*interface_pointer), FALSE);
500
has = has_func (object);
501
if (*interface_pointer == NULL)
505
*interface_pointer = g_object_new (skeleton_type, NULL);
506
if (connect_func != NULL)
507
connect_func (object);
515
g_dbus_object_skeleton_remove_interface (G_DBUS_OBJECT_SKELETON (object),
516
G_DBUS_INTERFACE_SKELETON (*interface_pointer));
517
g_object_unref (*interface_pointer);
518
*interface_pointer = NULL;
522
if (*interface_pointer != NULL)
524
if (update_func (object, uevent_action, G_DBUS_INTERFACE (*interface_pointer)))
527
g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (object),
528
G_DBUS_INTERFACE_SKELETON (*interface_pointer));
534
/* ---------------------------------------------------------------------------------------------------- */
537
drive_check (UDisksLinuxDriveObject *object)
543
drive_connect (UDisksLinuxDriveObject *object)
548
drive_update (UDisksLinuxDriveObject *object,
549
const gchar *uevent_action,
550
GDBusInterface *_iface)
552
return udisks_linux_drive_update (UDISKS_LINUX_DRIVE (object->iface_drive), object);
555
/* ---------------------------------------------------------------------------------------------------- */
558
drive_ata_check (UDisksLinuxDriveObject *object)
561
UDisksLinuxDevice *device;
564
if (object->devices == NULL)
567
device = object->devices->data;
568
if (device->ata_identify_device_data != NULL || device->ata_identify_packet_device_data != NULL)
576
drive_ata_connect (UDisksLinuxDriveObject *object)
582
drive_ata_update (UDisksLinuxDriveObject *object,
583
const gchar *uevent_action,
584
GDBusInterface *_iface)
586
return udisks_linux_drive_ata_update (UDISKS_LINUX_DRIVE_ATA (object->iface_drive_ata), object);
589
/* ---------------------------------------------------------------------------------------------------- */
591
static void apply_configuration (UDisksLinuxDriveObject *object);
594
find_link_for_sysfs_path (UDisksLinuxDriveObject *object,
595
const gchar *sysfs_path)
600
for (l = object->devices; l != NULL; l = l->next)
602
UDisksLinuxDevice *device = l->data;
603
if (g_strcmp0 (g_udev_device_get_sysfs_path (device->udev_device), sysfs_path) == 0)
614
* udisks_linux_drive_object_uevent:
615
* @object: A #UDisksLinuxDriveObject.
616
* @action: Uevent action or %NULL
617
* @device: A #UDisksLinuxDevice device object or %NULL if the device hasn't changed.
619
* Updates all information on interfaces on @drive.
622
udisks_linux_drive_object_uevent (UDisksLinuxDriveObject *object,
624
UDisksLinuxDevice *device)
627
gboolean conf_changed;
629
g_return_if_fail (UDISKS_IS_LINUX_DRIVE_OBJECT (object));
630
g_return_if_fail (device == NULL || UDISKS_IS_LINUX_DEVICE (device));
634
link = find_link_for_sysfs_path (object, g_udev_device_get_sysfs_path (device->udev_device));
635
if (g_strcmp0 (action, "remove") == 0)
639
g_object_unref (UDISKS_LINUX_DEVICE (link->data));
640
object->devices = g_list_delete_link (object->devices, link);
644
udisks_warning ("Drive doesn't have device with sysfs path %s on remove event",
645
g_udev_device_get_sysfs_path (device->udev_device));
652
g_object_unref (UDISKS_LINUX_DEVICE (link->data));
653
link->data = g_object_ref (device);
658
object->devices = g_list_append (object->devices, g_object_ref (device));
662
conf_changed = FALSE;
663
conf_changed |= update_iface (object, action, drive_check, drive_connect, drive_update,
664
UDISKS_TYPE_LINUX_DRIVE, &object->iface_drive);
665
conf_changed |= update_iface (object, action, drive_ata_check, drive_ata_connect, drive_ata_update,
666
UDISKS_TYPE_LINUX_DRIVE_ATA, &object->iface_drive_ata);
669
apply_configuration (object);
672
/* ---------------------------------------------------------------------------------------------------- */
675
apply_configuration (UDisksLinuxDriveObject *object)
677
GVariant *configuration = NULL;
678
UDisksLinuxDevice *device = NULL;
680
if (object->iface_drive == NULL)
683
configuration = udisks_drive_dup_configuration (object->iface_drive);
684
if (configuration == NULL)
687
device = udisks_linux_drive_object_get_device (object, TRUE /* get_hw */);
691
if (object->iface_drive_ata != NULL)
693
udisks_linux_drive_ata_apply_configuration (UDISKS_LINUX_DRIVE_ATA (object->iface_drive_ata),
699
g_clear_object (&device);
700
if (configuration != NULL)
701
g_variant_unref (configuration);
704
/* ---------------------------------------------------------------------------------------------------- */
706
/* utility routine to blacklist WWNs that are not suitable to use
707
* for identification purposes
710
is_wwn_black_listed (const gchar *wwn)
712
g_return_val_if_fail (wwn != NULL, FALSE);
714
if (g_str_has_prefix (wwn, "0x") || g_str_has_prefix (wwn, "0X"))
717
if (g_ascii_strcasecmp (wwn, "50f0000000000000") == 0)
719
/* SAMSUNG SP1604N (PATA), see https://bugzilla.redhat.com/show_bug.cgi?id=838691#c4 */
729
check_for_vpd (GUdevDevice *device)
736
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
738
/* order of preference: WWN_serial, WWN, serial, path */
739
serial = g_udev_device_get_property (device, "ID_SERIAL");
740
wwn = g_udev_device_get_property (device, "ID_WWN_WITH_EXTENSION");
741
path = g_udev_device_get_property (device, "ID_PATH");
742
if (wwn != NULL && strlen (wwn) > 0 && !is_wwn_black_listed (wwn))
744
if (serial != NULL && strlen (serial) > 0)
745
ret = g_strdup_printf ("%s_%s", wwn, serial);
747
ret = g_strdup (wwn);
749
else if (serial != NULL && strlen (serial) > 0)
751
ret = g_strdup (serial);
753
else if (path != NULL && strlen (path) > 0)
755
ret = g_strdup (path);
761
* udisks_linux_drive_object_should_include_device:
762
* @client: A #GUdevClient.
763
* @device: A #UDisksLinuxDevice.
764
* @out_vpd: Return location for unique ID or %NULL.
766
* Checks if we should even construct a #UDisksLinuxDriveObject for @device.
768
* Returns: %TRUE if we should construct an object, %FALSE otherwise.
771
udisks_linux_drive_object_should_include_device (GUdevClient *client,
772
UDisksLinuxDevice *device,
781
/* The 'block' subsystem encompasses several objects with varying
787
* and we are only interested in the first.
789
if (g_strcmp0 (g_udev_device_get_devtype (device->udev_device), "disk") != 0)
792
vpd = check_for_vpd (device->udev_device);
799
const gchar *dm_name;
802
name = g_udev_device_get_name (device->udev_device);
804
/* workaround for floppy devices */
805
if (g_str_has_prefix (name, "fd"))
807
vpd = g_strdup_printf ("pcfloppy_%s", name);
811
/* workaround for missing serial/wwn on virtio-blk */
812
if (g_str_has_prefix (name, "vd"))
814
vpd = g_strdup (name);
818
/* workaround for missing serial/wwn on VMware */
819
vendor = g_udev_device_get_property (device->udev_device, "ID_VENDOR");
820
model = g_udev_device_get_property (device->udev_device, "ID_MODEL");
821
if (g_str_has_prefix (name, "sd") &&
822
vendor != NULL && g_strcmp0 (vendor, "VMware") == 0 &&
823
model != NULL && g_str_has_prefix (model, "Virtual"))
825
vpd = g_strdup (name);
829
/* workaround for missing serial/wwn on firewire devices */
830
parent = g_udev_device_get_parent_with_subsystem (device->udev_device, "firewire", NULL);
833
vpd = g_strdup (name);
834
g_object_unref (parent);
839
dm_name = g_udev_device_get_sysfs_attr (device->udev_device, "dm/name");
840
if (dm_name != NULL && g_str_has_prefix (dm_name, "mpath"))
844
slaves = udisks_daemon_util_resolve_links (g_udev_device_get_sysfs_path (device->udev_device), "slaves");
845
for (n = 0; slaves[n] != NULL; n++)
848
slave = g_udev_client_query_by_sysfs_path (client, slaves[n]);
851
vpd = check_for_vpd (slave);
854
g_object_unref (slave);
858
g_object_unref (slave);
881
/* ---------------------------------------------------------------------------------------------------- */
884
* udisks_linux_drive_object_housekeeping:
885
* @object: A #UDisksLinuxDriveObject.
886
* @secs_since_last: Number of seconds sincex the last housekeeping or 0 if the first housekeeping ever.
887
* @cancellable: A %GCancellable or %NULL.
888
* @error: Return location for error or %NULL.
890
* Called periodically (every ten minutes or so) to perform
891
* housekeeping tasks such as refreshing ATA SMART data.
893
* The function runs in a dedicated thread and is allowed to perform
896
* Long-running tasks should periodically check @cancellable to see if
897
* they have been cancelled.
899
* Returns: %TRUE if the operation succeeded, %FALSE if @error is set.
902
udisks_linux_drive_object_housekeeping (UDisksLinuxDriveObject *object,
903
guint secs_since_last,
904
GCancellable *cancellable,
911
if (object->iface_drive_ata != NULL &&
912
udisks_drive_ata_get_smart_supported (object->iface_drive_ata) &&
913
udisks_drive_ata_get_smart_enabled (object->iface_drive_ata))
918
/* Wake-up only on start-up */
920
if (secs_since_last == 0)
923
udisks_info ("Refreshing SMART data on %s (nowakeup=%d)",
924
g_dbus_object_get_object_path (G_DBUS_OBJECT (object)),
928
if (!udisks_linux_drive_ata_refresh_smart_sync (UDISKS_LINUX_DRIVE_ATA (object->iface_drive_ata),
930
NULL, /* simulate_path */
934
if (nowakeup && (local_error->domain == UDISKS_ERROR &&
935
local_error->code == UDISKS_ERROR_WOULD_WAKEUP))
937
udisks_info ("Drive %s is in a sleep state",
938
g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
939
g_error_free (local_error);
941
else if (nowakeup && (local_error->domain == UDISKS_ERROR &&
942
local_error->code == UDISKS_ERROR_DEVICE_BUSY))
944
/* typically because a "secure erase" operation is pending */
945
udisks_info ("Drive %s is busy",
946
g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
947
g_error_free (local_error);
951
g_propagate_prefixed_error (error, local_error, "Error updating SMART data: ");
964
is_block_unlocked (GList *objects, const gchar *crypto_object_path)
966
gboolean ret = FALSE;
968
for (l = objects; l != NULL; l = l->next)
970
UDisksObject *object = UDISKS_OBJECT (l->data);
972
block = udisks_object_peek_block (object);
975
if (g_strcmp0 (udisks_block_get_crypto_backing_device (block), crypto_object_path) == 0)
987
* udisks_linux_drive_object_is_not_in_use:
988
* @object: A #UDisksLinuxDriveObject.
989
* @cancellable: (allow-none): A #GCancellable or %NULL.
990
* @error: A #GError or %NULL.
992
* Checks if the drive represented by @object is in use and sets
995
* Returns: %TRUE if @object is not is use, %FALSE if @error is set.
998
udisks_linux_drive_object_is_not_in_use (UDisksLinuxDriveObject *object,
999
GCancellable *cancellable,
1002
GDBusObjectManagerServer *object_manager;
1003
const gchar *drive_object_path;
1004
gboolean ret = TRUE;
1005
GList *objects = NULL;
1008
g_return_val_if_fail (UDISKS_IS_LINUX_DRIVE_OBJECT (object), FALSE);
1009
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1010
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1012
drive_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
1014
object_manager = udisks_daemon_get_object_manager (object->daemon);
1015
objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager));
1017
/* Visit all block devices related to the drive... */
1018
for (l = objects; l != NULL; l = l->next)
1020
GDBusObjectSkeleton *iter_object = G_DBUS_OBJECT_SKELETON (l->data);
1022
UDisksFilesystem *filesystem;
1024
if (!UDISKS_IS_LINUX_BLOCK_OBJECT (iter_object))
1027
block = udisks_object_peek_block (UDISKS_OBJECT (iter_object));
1028
filesystem = udisks_object_peek_filesystem (UDISKS_OBJECT (iter_object));
1030
if (g_strcmp0 (udisks_block_get_drive (block), drive_object_path) != 0)
1033
/* bail if block device is mounted */
1034
if (filesystem != NULL)
1036
if (g_strv_length ((gchar **) udisks_filesystem_get_mount_points (filesystem)) > 0)
1040
UDISKS_ERROR_DEVICE_BUSY,
1041
"Device %s is mounted",
1042
udisks_block_get_preferred_device (block));
1048
/* bail if block device is unlocked (LUKS) */
1049
if (is_block_unlocked (objects, g_dbus_object_get_object_path (G_DBUS_OBJECT (iter_object))))
1053
UDISKS_ERROR_DEVICE_BUSY,
1054
"Encrypted device %s is unlocked",
1055
udisks_block_get_preferred_device (block));
1062
g_list_free_full (objects, g_object_unref);
1066
/* ---------------------------------------------------------------------------------------------------- */
1069
* udisks_linux_drive_object_get_siblings:
1070
* @object: A #UDisksLinuxDriveObject.
1072
* Gets the siblings for @object, if any.
1074
* Returns: (transfer full) (element-type UDisksLinuxDriveObject): A list of #UDisksLinuxDriveObject
1075
* instances. The returned list should be freed with g_list_free() after each element has been
1076
* freed with g_object_unref().
1079
udisks_linux_drive_object_get_siblings (UDisksLinuxDriveObject *object)
1081
GDBusObjectManagerServer *object_manager;
1083
GList *objects = NULL;
1085
gchar *sibling_id = NULL;
1087
if (object->iface_drive == NULL)
1090
sibling_id = udisks_drive_dup_sibling_id (object->iface_drive);
1091
if (sibling_id == NULL || strlen (sibling_id) == 0)
1094
object_manager = udisks_daemon_get_object_manager (object->daemon);
1095
objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager));
1096
for (l = objects; l != NULL; l = l->next)
1098
GDBusObjectSkeleton *iter_object = G_DBUS_OBJECT_SKELETON (l->data);
1099
UDisksLinuxDriveObject *iter_linux_drive_object;
1101
if (!UDISKS_IS_LINUX_DRIVE_OBJECT (iter_object))
1104
iter_linux_drive_object = UDISKS_LINUX_DRIVE_OBJECT (iter_object);
1105
if (iter_linux_drive_object->iface_drive != NULL &&
1106
g_strcmp0 (udisks_drive_get_sibling_id (iter_linux_drive_object->iface_drive), sibling_id) == 0)
1108
ret = g_list_prepend (ret, g_object_ref (iter_object));
1113
ret = g_list_reverse (ret);
1114
g_list_foreach (objects, (GFunc) g_object_unref, NULL);
1115
g_list_free (objects);
1116
g_free (sibling_id);