diff -ruN hal-0.5.11~rc2/hald/linux/blockdev.c hal-0.5.11~rc2.new/hald/linux/blockdev.c --- hal-0.5.11~rc2/hald/linux/blockdev.c 2008-03-17 22:25:13.000000000 +0100 +++ hal-0.5.11~rc2.new/hald/linux/blockdev.c 2008-11-28 12:09:50.000000000 +0100 @@ -850,6 +850,44 @@ return ret; } +HalDevice * +generate_lvm2_group (const char *group_name, GSList *physical_volume_udi) +{ + HalDevice *d; + gchar udi[256]; + + HAL_INFO(("Generate new LVM2 goup with name '%s'", group_name)); + + d = hal_device_new (); + hal_device_property_set_int (d, "lvm.version", 2); + hal_device_property_set_string (d, "lvm.group.name", group_name); + hal_device_property_set_strlist (d, "lvm.group.physical_volume", physical_volume_udi); + hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer"); + hal_device_property_set_string (d, "info.product", "LVM2 Group"); + hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi), "/org/freedesktop/Hal/devices/lvm2_group_%s", group_name); + hal_device_set_udi (d, udi); + hal_device_property_set_string (d, "info.udi", udi); + hal_device_add_capability (d, "lvm"); + hal_device_add_capability (d, "lvm.group"); + hal_device_property_set_string (d, "info.category", "lvm.group"); + + /* TODO : find a way to get more info about the group (extend size, extend used, extand free...) */ + + hal_device_store_add (hald_get_tdl (), d); + + /* Process fdi files */ + di_search_and_merge (d, DEVICE_INFO_TYPE_PREPROBE); + di_search_and_merge (d, DEVICE_INFO_TYPE_INFORMATION); + di_search_and_merge (d, DEVICE_INFO_TYPE_POLICY); + + /* TODO : callouts ? */ + + hal_device_store_remove (hald_get_tdl (), d); + hal_device_store_add (hald_get_gdl (), d); + + return d; +} + void hotplug_event_begin_add_blockdev (const gchar *sysfs_path, const gchar *device_file, gboolean is_partition, @@ -863,12 +901,12 @@ char *sysfs_path_real = NULL; int floppy_num; gboolean is_device_mapper; - gboolean is_md_device; - int md_number; + gboolean is_md_device; + int md_number; is_device_mapper = FALSE; - is_fakevolume = FALSE; - is_md_device = FALSE; + is_fakevolume = FALSE; + is_md_device = FALSE; HAL_INFO (("block_add: sysfs_path=%s dev=%s is_part=%d, parent=0x%08x", sysfs_path, device_file, is_partition, parent)); @@ -882,14 +920,14 @@ HAL_INFO (("Handling %s as fakevolume - sysfs_path_real=%s", device_file, sysfs_path_real)); is_fakevolume = TRUE; sysfs_path_real = hal_util_get_parent_path (sysfs_path); - } else if (sscanf (hal_util_get_last_element (sysfs_path), "md%d", &md_number) == 1) { + } else if (sscanf (hal_util_get_last_element (sysfs_path), "md%d", &md_number) == 1) { HAL_INFO (("Handling %s as MD device", device_file)); - is_md_device = TRUE; + is_md_device = TRUE; sysfs_path_real = g_strdup (sysfs_path); - /* set parent to root computer device object */ - parent = hal_device_store_find (hald_get_gdl (), "/org/freedesktop/Hal/devices/computer"); - if (parent == NULL) - d = hal_device_store_find (hald_get_tdl (), "/org/freedesktop/Hal/devices/computer"); + /* set parent to root computer device object */ + parent = hal_device_store_find (hald_get_gdl (), "/org/freedesktop/Hal/devices/computer"); + if (parent == NULL) + d = hal_device_store_find (hald_get_tdl (), "/org/freedesktop/Hal/devices/computer"); } else { sysfs_path_real = g_strdup (sysfs_path); } @@ -917,7 +955,13 @@ if ((dir = opendir (path)) == NULL) { HAL_WARNING (("Unable to open %s: %s", path, strerror(errno))); } else { + GSList *slaves_volume = NULL; + GSList *slaves_volume_udi = NULL; + char *slaves_volume_fstype = NULL; + while (((dp = readdir (dir)) != NULL) && (parent == NULL)) { + HalDevice *slave_volume; + char *slave_volume_fstype; char *link; char *target; @@ -925,43 +969,81 @@ target = resolve_symlink (link); HAL_INFO ((" %s -> %s", link, target)); - if (target != NULL) { - HalDevice *slave_volume; + slave_volume = hal_device_store_match_key_value_string (hald_get_gdl (), + "linux.sysfs_path", target); + if (slave_volume == NULL) { + slaves_volume_fstype = NULL; + continue; + } + HAL_INFO((" -> Slave volume : '%s'", hal_device_get_udi (slave_volume))); + + slave_volume_fstype = (char *) hal_device_property_get_string (slave_volume, "volume.fstype"); + if (slave_volume_fstype == NULL ) { + slaves_volume_fstype = NULL; + continue; + } + HAL_INFO((" -> Slave volume type : '%s'", slave_volume_fstype)); + + if (slaves_volume == NULL) + slaves_volume_fstype = slave_volume_fstype; + else if (strcmp(slave_volume_fstype, slaves_volume_fstype) != 0) { + slaves_volume_fstype = NULL; + HAL_WARNING(("Not all slaves volume of %s have the same type.", device_file)); + break; + } + + slaves_volume = g_slist_append (slaves_volume, slave_volume); + slaves_volume_udi = g_slist_append (slaves_volume_udi, (char *) hal_device_get_udi (slave_volume)); + } + closedir(dir); + + if (slaves_volume_fstype != NULL) { + + if (g_slist_length(slaves_volume) == 1 && strcmp (slaves_volume_fstype, "crypto_LUKS") == 0 ) { + const char *slave_volume_stordev_udi; + + slave_volume_stordev_udi = hal_device_property_get_string (g_slist_nth (slaves_volume, 0)->data, "block.storage_device"); + parent = hal_device_store_find (hald_get_gdl (), slave_volume_stordev_udi); + if (parent != NULL) { + HAL_INFO ((" parent='%s'!", hal_device_get_udi (parent))); + hal_device_property_set_string (d, "volume.crypto_luks.clear.backing_volume", + g_slist_nth (slaves_volume_udi, 0)->data); + is_device_mapper = TRUE; + } + } + + if (g_slist_length (slaves_volume) >= 1 && strcmp (slaves_volume_fstype, "LVM2_member") == 0 ) { + gchar **lvm_name; + + HAL_INFO(("Processing %s as an LVM2 volume", device_file)); + + /* LVM2 volume appears as mapper/GroupName-VolName in the dev tree */ - slave_volume = hal_device_store_match_key_value_string (hald_get_gdl (), - "linux.sysfs_path", - target); - if (slave_volume != NULL) { - const char *slave_volume_stordev_udi; - const char *slave_volume_fstype; - - slave_volume_stordev_udi = hal_device_property_get_string (slave_volume, "block.storage_device"); - slave_volume_fstype = hal_device_property_get_string (slave_volume, "volume.fstype"); - - /* Yup, we only support crypto_LUKS right now. - * - * In the future we can support other device-mapper mappings - * such as LVM etc. - */ - if (slave_volume_stordev_udi != NULL && - slave_volume_fstype != NULL && - (strcmp (slave_volume_fstype, "crypto_LUKS") == 0)) { - HAL_INFO ((" slave_volume_stordev_udi='%s'!", slave_volume_stordev_udi)); - parent = hal_device_store_find (hald_get_gdl (), slave_volume_stordev_udi); - if (parent != NULL) { - HAL_INFO ((" parent='%s'!", hal_device_get_udi (parent))); - hal_device_property_set_string (d, "volume.crypto_luks.clear.backing_volume", hal_device_get_udi (slave_volume)); - is_device_mapper = TRUE; - } + lvm_name = g_strsplit(hal_util_get_last_element(device_file), "-", 2); + HAL_INFO (("LVM Group : %s | LVM Volume name : %s", lvm_name[0], lvm_name[1])); + + if (lvm_name[0] != NULL && lvm_name[1] != NULL) { + parent = hal_device_store_match_key_value_string (hald_get_gdl (), "lvm.group.name", lvm_name[0]); + if (parent == NULL) + parent = generate_lvm2_group (lvm_name[0], slaves_volume_udi); + + if (parent != NULL) { + HAL_INFO ((" parent='%s'!", hal_device_get_udi (parent))); + hal_device_add_capability (d, "lvm"); + hal_device_add_capability (d, "lvm.volume"); + hal_device_property_set_string (d, "lvm.volume.name", lvm_name[1]); + hal_device_property_set_string (d, "lvm.volume.group", parent); + hal_device_property_set_int (d, "lvm.version", 2); + is_device_mapper = TRUE; } } else { HAL_INFO(("Couldn't find slave volume in devices")); } + g_strfreev(lvm_name); } - g_free (target); } - closedir(dir); - HAL_INFO (("Done looking in %s", path)); + g_slist_free (slaves_volume); + g_slist_free (slaves_volume_udi); } } @@ -1373,6 +1455,7 @@ } else { guint sysfs_path_len; gboolean is_physical_partition; + const char *parent_drive_type; /************************* * @@ -1392,9 +1475,9 @@ hal_device_property_set_bool (d, "volume.is_mounted", FALSE); hal_device_property_set_bool (d, "volume.is_mounted_read_only", FALSE); hal_device_property_set_bool (d, "volume.linux.is_device_mapper", is_device_mapper); - hal_device_property_set_bool ( - d, "volume.is_disc", - strcmp (hal_device_property_get_string (parent, "storage.drive_type"), "cdrom") == 0); + parent_drive_type = hal_device_property_get_string (parent, "storage.drive_type"); + if (parent_drive_type != NULL) + hal_device_property_set_bool (d, "volume.is_disc", strcmp (parent_drive_type, "cdrom") == 0); is_physical_partition = TRUE; @@ -1404,7 +1487,7 @@ hal_device_property_set_bool (d, "volume.is_partition", is_physical_partition); hal_device_property_set_string (d, "info.category", "volume"); - if (strcmp(hal_device_property_get_string (parent, "storage.drive_type"), "cdrom") == 0) { + if (parent_drive_type != NULL && strcmp(parent_drive_type, "cdrom") == 0) { hal_device_add_capability (d, "volume.disc"); } hal_device_add_capability (d, "volume"); diff -ruN hal-0.5.11~rc2/hald/linux/probing/probe-volume.c hal-0.5.11~rc2.new/hald/linux/probing/probe-volume.c --- hal-0.5.11~rc2/hald/linux/probing/probe-volume.c 2008-03-17 22:25:13.000000000 +0100 +++ hal-0.5.11~rc2.new/hald/linux/probing/probe-volume.c 2008-11-28 12:00:03.000000000 +0100 @@ -603,10 +603,10 @@ if (should_probe_for_fs) { - if ((stordev_dev_file = libhal_device_get_property_string ( - ctx, parent_udi, "block.device", &error)) == NULL) { - goto out; - } + if (libhal_device_property_exists(ctx, parent_udi, "block.device", &error)) + stordev_dev_file = libhal_device_get_property_string (ctx, parent_udi, "block.device", &error); + else + stordev_dev_file = NULL; /* Optical discs have problems reporting the exact * size so we should never look for data there since @@ -649,7 +649,7 @@ * this is good enough for now... the only discs I know of that does this * is in fact Apple's install disc.) */ - if (vid_ret != 0 && is_disc) { + if (vid_ret != 0 && is_disc && stordev_dev_file != NULL) { PartitionTable *p; p = part_table_load_from_disk (stordev_dev_file); if (p != NULL) { @@ -691,7 +691,7 @@ /* get partition type number, if we find a msdos partition table */ if (partition_number_str != NULL && partition_number <= 256 && partition_number > 0 && - partition_start > 0) { + partition_start > 0 && stordev_dev_file != NULL) { PartitionTable *p; HAL_INFO (("Loading part table"));