From 049be7d4abf77ef63b573f1694d43fe3ec1279a8 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 19 2020 00:14:16 +0000 Subject: import udisks2-2.9.0-5.el8 --- diff --git a/SOURCES/udisks-2.9.1-daemon-Always-flush-interface-property-changes.patch b/SOURCES/udisks-2.9.1-daemon-Always-flush-interface-property-changes.patch new file mode 100644 index 0000000..5698c5b --- /dev/null +++ b/SOURCES/udisks-2.9.1-daemon-Always-flush-interface-property-changes.patch @@ -0,0 +1,190 @@ +From e039516b103eb9749a3e261c5ee1a9bc110676cf Mon Sep 17 00:00:00 2001 +From: Tomas Bzatek +Date: Fri, 26 Jun 2020 17:42:32 +0200 +Subject: [PATCH 1/8] daemon: Always flush interface property changes + +Setting properties on a GDBusInterfaceSkeleton from the main thread +as a result of uevent is somewhat racy to clients that are waiting +for a method call to return that is processed in a separate thread +by the daemon. Perhaps there's a race in the GDBus worker thread +that processes changes from both threads and send them out on the bus. + +Explicit flush on GDBusInterfaceSkeleton interfaces seems to fix +the issue. Such approach was used before on some places, this change +adds explicit flushes at all places where properties may change. +--- + src/udiskslinuxblock.c | 2 ++ + src/udiskslinuxdrive.c | 1 + + src/udiskslinuxdriveata.c | 5 +++++ + src/udiskslinuxencrypted.c | 5 +++++ + src/udiskslinuxfilesystem.c | 3 +++ + src/udiskslinuxloop.c | 1 + + src/udiskslinuxmdraid.c | 1 + + src/udiskslinuxpartition.c | 2 ++ + src/udiskslinuxpartitiontable.c | 1 + + src/udiskslinuxswapspace.c | 1 + + 10 files changed, 22 insertions(+) + +diff --git a/src/udiskslinuxblock.c b/src/udiskslinuxblock.c +index ddc7fe1f..34d73f0e 100644 +--- a/src/udiskslinuxblock.c ++++ b/src/udiskslinuxblock.c +@@ -893,6 +893,7 @@ update_configuration (UDisksLinuxBlock *block, + configuration = g_variant_new ("a(sa{sv})", NULL); + } + udisks_block_set_configuration (UDISKS_BLOCK (block), configuration); ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (block)); + } + + #ifdef HAVE_LIBMOUNT_UTAB +@@ -1280,6 +1281,7 @@ udisks_linux_block_update (UDisksLinuxBlock *block, + update_mdraid (block, device, drive, object_manager); + + out: ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (block)); + if (device != NULL) + g_object_unref (device); + if (drive != NULL) +diff --git a/src/udiskslinuxdrive.c b/src/udiskslinuxdrive.c +index e9dd7117..28a90ce9 100644 +--- a/src/udiskslinuxdrive.c ++++ b/src/udiskslinuxdrive.c +@@ -950,6 +950,7 @@ udisks_linux_drive_update (UDisksLinuxDrive *drive, + ret = update_configuration (drive, object); + + out: ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (drive)); + if (device != NULL) + g_clear_object (&device); + +diff --git a/src/udiskslinuxdriveata.c b/src/udiskslinuxdriveata.c +index d65f3254..4ba66d09 100644 +--- a/src/udiskslinuxdriveata.c ++++ b/src/udiskslinuxdriveata.c +@@ -339,6 +339,8 @@ udisks_linux_drive_ata_update (UDisksLinuxDriveAta *drive, + update_security (drive, device); + + out: ++ /* ensure property changes are sent before the method return */ ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (drive)); + if (device != NULL) + g_object_unref (device); + +@@ -681,6 +683,9 @@ udisks_linux_drive_ata_refresh_smart_sync (UDisksLinuxDriveAta *drive, + /* update stats again to account for the IO we just did to read the SMART info */ + update_io_stats (drive, device); + ++ /* ensure property changes are sent before the method return */ ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (drive)); ++ + out: + g_clear_object (&device); + if (d != NULL) +diff --git a/src/udiskslinuxencrypted.c b/src/udiskslinuxencrypted.c +index 73c78873..8a230fda 100644 +--- a/src/udiskslinuxencrypted.c ++++ b/src/udiskslinuxencrypted.c +@@ -237,6 +237,8 @@ udisks_linux_encrypted_update (UDisksLinuxEncrypted *encrypted, + update_metadata_size (encrypted, object); + + udisks_linux_block_encrypted_unlock (block); ++ ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (encrypted)); + } + + /* ---------------------------------------------------------------------------------------------------- */ +@@ -630,6 +632,9 @@ handle_unlock (UDisksEncrypted *encrypted, + g_udev_device_get_sysfs_attr (cleartext_device->udev_device, "dm/uuid"), + caller_uid); + ++ /* ensure property changes are sent before the method return */ ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (encrypted)); ++ + udisks_encrypted_complete_unlock (encrypted, + invocation, + g_dbus_object_get_object_path (G_DBUS_OBJECT (cleartext_object))); +diff --git a/src/udiskslinuxfilesystem.c b/src/udiskslinuxfilesystem.c +index 669fc40b..3ae11c32 100644 +--- a/src/udiskslinuxfilesystem.c ++++ b/src/udiskslinuxfilesystem.c +@@ -277,6 +277,8 @@ udisks_linux_filesystem_update (UDisksLinuxFilesystem *filesystem, + if (! skip_fs_size) + udisks_filesystem_set_size (UDISKS_FILESYSTEM (filesystem), get_filesystem_size (object)); + ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (filesystem)); ++ + g_object_unref (device); + } + +@@ -1865,6 +1867,7 @@ handle_resize (UDisksFilesystem *filesystem, + UDISKS_DEFAULT_WAIT_TIMEOUT); + + udisks_filesystem_set_size (filesystem, get_filesystem_size (UDISKS_LINUX_BLOCK_OBJECT (object))); ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (filesystem)); + udisks_filesystem_complete_resize (filesystem, invocation); + udisks_simple_job_complete (UDISKS_SIMPLE_JOB (job), TRUE, NULL); + +diff --git a/src/udiskslinuxloop.c b/src/udiskslinuxloop.c +index 6c8a4561..5d7e3553 100644 +--- a/src/udiskslinuxloop.c ++++ b/src/udiskslinuxloop.c +@@ -187,6 +187,7 @@ udisks_linux_loop_update (UDisksLinuxLoop *loop, + } + udisks_loop_set_setup_by_uid (UDISKS_LOOP (loop), setup_by_uid); + ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (loop)); + g_object_unref (device); + } + +diff --git a/src/udiskslinuxmdraid.c b/src/udiskslinuxmdraid.c +index 85fc2a3b..7eca9764 100644 +--- a/src/udiskslinuxmdraid.c ++++ b/src/udiskslinuxmdraid.c +@@ -512,6 +512,7 @@ udisks_linux_mdraid_update (UDisksLinuxMDRaid *mdraid, + uuid)); + + out: ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (mdraid)); + if (raid_data) + bd_md_examine_data_free (raid_data); + g_free (sync_completed); +diff --git a/src/udiskslinuxpartition.c b/src/udiskslinuxpartition.c +index 97ba02fe..ff0fdfc0 100644 +--- a/src/udiskslinuxpartition.c ++++ b/src/udiskslinuxpartition.c +@@ -312,6 +312,8 @@ udisks_linux_partition_update (UDisksLinuxPartition *partition, + udisks_partition_set_is_container (UDISKS_PARTITION (partition), is_container); + udisks_partition_set_is_contained (UDISKS_PARTITION (partition), is_contained); + ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (partition)); ++ + g_free (name); + g_clear_object (&device); + g_clear_object (&disk_block_object); +diff --git a/src/udiskslinuxpartitiontable.c b/src/udiskslinuxpartitiontable.c +index b26849bc..e43a0708 100644 +--- a/src/udiskslinuxpartitiontable.c ++++ b/src/udiskslinuxpartitiontable.c +@@ -146,6 +146,7 @@ udisks_linux_partition_table_update (UDisksLinuxPartitionTable *table, + + udisks_partition_table_set_partitions (UDISKS_PARTITION_TABLE (table), + partition_object_paths); ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (table)); + + + g_free (partition_object_paths); +diff --git a/src/udiskslinuxswapspace.c b/src/udiskslinuxswapspace.c +index ee103528..bb47f3d4 100644 +--- a/src/udiskslinuxswapspace.c ++++ b/src/udiskslinuxswapspace.c +@@ -127,6 +127,7 @@ udisks_linux_swapspace_update (UDisksLinuxSwapspace *swapspace, + active = TRUE; + udisks_swapspace_set_active (UDISKS_SWAPSPACE (swapspace), active); + ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (swapspace)); + g_object_unref (device); + } + +-- +2.26.2 + diff --git a/SOURCES/udisks-2.9.1-drive_ata_tests.patch b/SOURCES/udisks-2.9.1-drive_ata_tests.patch new file mode 100644 index 0000000..1882642 --- /dev/null +++ b/SOURCES/udisks-2.9.1-drive_ata_tests.patch @@ -0,0 +1,39 @@ +commit 214d65ae4d2b779fc1674420a042082ae029eb6b +Author: Vojtech Trefny +Date: Mon Jul 13 16:16:47 2020 +0200 + + dbus_tests: Fix getting list of SATA drives for Drive.ATA test + + Resolves: rhbz#1855785 + +diff --git a/src/tests/dbus-tests/test_drive_ata.py b/src/tests/dbus-tests/test_drive_ata.py +index ff6d01cc..df298a9c 100644 +--- a/src/tests/dbus-tests/test_drive_ata.py ++++ b/src/tests/dbus-tests/test_drive_ata.py +@@ -14,8 +14,24 @@ SMART_ATA_CHECKSUM_FAIL = 1 << 2 + smart_unsupported = set() + smart_supported = set() + +-sata_disks = (dev for dev in os.listdir("/dev") if re.match(r'sd[a-z]+$', dev)) +-for disk in sata_disks: ++ ++DISK_PATH = "/dev/disk/by-path/" ++ ++ ++def _get_sata_disks(): ++ sata_disks = [] ++ by_path = os.listdir(DISK_PATH) ++ for dev in by_path: ++ if "ata" in dev and "part" not in dev: ++ path = os.path.realpath(os.path.join(DISK_PATH, dev)) ++ name = os.path.basename(path) ++ if name.startswith("sd"): ++ # ignore devices like CD drives etc. ++ sata_disks.append(name) ++ return sata_disks ++ ++ ++for disk in _get_sata_disks(): + ret, out = UdisksTestCase.run_command("smartctl -a /dev/%s" % disk) + + # Only the following bits in the exit status mean the device failed to diff --git a/SOURCES/udisks-2.9.1-iscsi-Always-flush-interface-property-changes.patch b/SOURCES/udisks-2.9.1-iscsi-Always-flush-interface-property-changes.patch new file mode 100644 index 0000000..7fade24 --- /dev/null +++ b/SOURCES/udisks-2.9.1-iscsi-Always-flush-interface-property-changes.patch @@ -0,0 +1,25 @@ +From 195f3b030de32f5993da736c75e6a9bd76e6a7c7 Mon Sep 17 00:00:00 2001 +From: Tomas Bzatek +Date: Fri, 26 Jun 2020 17:56:39 +0200 +Subject: [PATCH 5/8] iscsi: Always flush interface property changes + +--- + modules/iscsi/udiskslinuxiscsisessionobject.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/modules/iscsi/udiskslinuxiscsisessionobject.c b/modules/iscsi/udiskslinuxiscsisessionobject.c +index 9e525e3f..a43cecd1 100644 +--- a/modules/iscsi/udiskslinuxiscsisessionobject.c ++++ b/modules/iscsi/udiskslinuxiscsisessionobject.c +@@ -355,6 +355,8 @@ udisks_linux_iscsi_session_object_update_iface (UDisksLinuxISCSISessionObject *s + udisks_iscsi_session_set_lu_reset_timeout (iface, session_info.tmo.lu_reset_tmo); + udisks_iscsi_session_set_recovery_timeout (iface, session_info.tmo.recovery_tmo); + udisks_iscsi_session_set_tgt_reset_timeout (iface, session_info.tmo.tgt_reset_tmo); ++ ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (iface)); + } + + static gboolean +-- +2.26.2 + diff --git a/SOURCES/udisks-2.9.1-lsm-Always-flush-interface-property-changes.patch b/SOURCES/udisks-2.9.1-lsm-Always-flush-interface-property-changes.patch new file mode 100644 index 0000000..cfd77da --- /dev/null +++ b/SOURCES/udisks-2.9.1-lsm-Always-flush-interface-property-changes.patch @@ -0,0 +1,25 @@ +From 861a0d8721536e2d210b79c845bb4f5b266b037f Mon Sep 17 00:00:00 2001 +From: Tomas Bzatek +Date: Fri, 26 Jun 2020 17:57:01 +0200 +Subject: [PATCH 6/8] lsm: Always flush interface property changes + +--- + modules/lsm/lsm_linux_drive.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/modules/lsm/lsm_linux_drive.c b/modules/lsm/lsm_linux_drive.c +index 19e68c2f..6433c308 100644 +--- a/modules/lsm/lsm_linux_drive.c ++++ b/modules/lsm/lsm_linux_drive.c +@@ -220,6 +220,8 @@ _fill_drive_lsm (UDisksLinuxDriveLSM *drive_lsm, + udisks_drive_lsm_set_min_io_size (std_drv_lsm, lsm_vol_data->min_io_size); + udisks_drive_lsm_set_opt_io_size (std_drv_lsm, lsm_vol_data->opt_io_size); + udisks_drive_lsm_set_raid_disk_count (std_drv_lsm, lsm_vol_data->raid_disk_count); ++ ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (std_drv_lsm)); + } + + +-- +2.26.2 + diff --git a/SOURCES/udisks-2.9.1-lvm2-Always-flush-interface-property-changes.patch b/SOURCES/udisks-2.9.1-lvm2-Always-flush-interface-property-changes.patch new file mode 100644 index 0000000..8a920f2 --- /dev/null +++ b/SOURCES/udisks-2.9.1-lvm2-Always-flush-interface-property-changes.patch @@ -0,0 +1,110 @@ +From 39d13907f712269bb9debd0fd8a0852347c98136 Mon Sep 17 00:00:00 2001 +From: Tomas Bzatek +Date: Fri, 26 Jun 2020 17:55:53 +0200 +Subject: [PATCH 2/8] lvm2: Always flush interface property changes + +--- + modules/lvm2/udiskslinuxlogicalvolume.c | 3 +++ + modules/lvm2/udiskslinuxphysicalvolume.c | 2 ++ + modules/lvm2/udiskslinuxvdovolume.c | 2 ++ + modules/lvm2/udiskslinuxvolumegroup.c | 3 +++ + modules/lvm2/udiskslinuxvolumegroupobject.c | 3 +++ + 5 files changed, 13 insertions(+) + +diff --git a/modules/lvm2/udiskslinuxlogicalvolume.c b/modules/lvm2/udiskslinuxlogicalvolume.c +index 373cee2e..c0f074d8 100644 +--- a/modules/lvm2/udiskslinuxlogicalvolume.c ++++ b/modules/lvm2/udiskslinuxlogicalvolume.c +@@ -229,6 +229,8 @@ udisks_linux_logical_volume_update (UDisksLinuxLogicalVolume *logical_volume + logical_volume->needs_udev_hack = FALSE; + g_free (dev_file); + } ++ ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (iface)); + } + + void +@@ -248,6 +250,7 @@ udisks_linux_logical_volume_update_etctabs (UDisksLinuxLogicalVolume *logica + udisks_logical_volume_set_child_configuration (iface, + udisks_linux_find_child_configuration (daemon, + uuid)); ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (iface)); + } + + /* ---------------------------------------------------------------------------------------------------- */ +diff --git a/modules/lvm2/udiskslinuxphysicalvolume.c b/modules/lvm2/udiskslinuxphysicalvolume.c +index 27043030..36e7c322 100644 +--- a/modules/lvm2/udiskslinuxphysicalvolume.c ++++ b/modules/lvm2/udiskslinuxphysicalvolume.c +@@ -143,6 +143,8 @@ udisks_linux_physical_volume_update (UDisksLinuxPhysicalVolume *physical_vo + udisks_physical_volume_set_size (iface, pv_info->pv_size); + udisks_physical_volume_set_free_size (iface, pv_info->pv_free); + } ++ ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (iface)); + } + + /* ---------------------------------------------------------------------------------------------------- */ +diff --git a/modules/lvm2/udiskslinuxvdovolume.c b/modules/lvm2/udiskslinuxvdovolume.c +index 317eddc2..430e2814 100644 +--- a/modules/lvm2/udiskslinuxvdovolume.c ++++ b/modules/lvm2/udiskslinuxvdovolume.c +@@ -177,6 +177,8 @@ udisks_linux_vdo_volume_update (UDisksLinuxVDOVolume *vdo_volume, + + udisks_vdo_volume_set_compression (iface, vdo_info->compression); + udisks_vdo_volume_set_deduplication (iface, vdo_info->deduplication); ++ ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (iface)); + } + + /* ---------------------------------------------------------------------------------------------------- */ +diff --git a/modules/lvm2/udiskslinuxvolumegroup.c b/modules/lvm2/udiskslinuxvolumegroup.c +index aad2193e..3fbf6f02 100644 +--- a/modules/lvm2/udiskslinuxvolumegroup.c ++++ b/modules/lvm2/udiskslinuxvolumegroup.c +@@ -136,11 +136,14 @@ udisks_linux_volume_group_update (UDisksLinuxVolumeGroup *volume_group, + gboolean *needs_polling_ret) + { + UDisksVolumeGroup *iface = UDISKS_VOLUME_GROUP (volume_group); ++ + udisks_volume_group_set_name (iface, vg_info->name); + udisks_volume_group_set_uuid (iface, vg_info->uuid); + udisks_volume_group_set_size (iface, vg_info->size); + udisks_volume_group_set_free_size (iface, vg_info->free); + udisks_volume_group_set_extent_size (iface, vg_info->extent_size); ++ ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (iface)); + } + + /* ---------------------------------------------------------------------------------------------------- */ +diff --git a/modules/lvm2/udiskslinuxvolumegroupobject.c b/modules/lvm2/udiskslinuxvolumegroupobject.c +index 50e9c640..e3bc8dfc 100644 +--- a/modules/lvm2/udiskslinuxvolumegroupobject.c ++++ b/modules/lvm2/udiskslinuxvolumegroupobject.c +@@ -442,6 +442,7 @@ block_object_update_lvm_iface (UDisksLinuxBlockObject *object, + + udisks_linux_block_lvm2_update (UDISKS_LINUX_BLOCK_LVM2 (iface_block_lvm2), object); + udisks_block_lvm2_set_logical_volume (iface_block_lvm2, lv_obj_path); ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (iface_block_lvm2)); + } + + static void +@@ -456,6 +457,7 @@ lv_object_update_block_path (UDisksLinuxBlockObject *block_object, + { + block_objpath = g_dbus_object_get_object_path (G_DBUS_OBJECT (block_object)); + udisks_logical_volume_set_block_device (UDISKS_LOGICAL_VOLUME (lv), block_objpath); ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (lv)); + } + } + +@@ -695,6 +697,7 @@ update_vg (GObject *source_obj, + bd_lvm_vgdata_free (vg_info); + lv_list_free (lvs); + ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (object->iface_volume_group)); + g_object_unref (object); + } + +-- +2.26.2 + diff --git a/SOURCES/udisks-2.9.1-zram-Always-flush-interface-property-changes.patch b/SOURCES/udisks-2.9.1-zram-Always-flush-interface-property-changes.patch new file mode 100644 index 0000000..4bc30aa --- /dev/null +++ b/SOURCES/udisks-2.9.1-zram-Always-flush-interface-property-changes.patch @@ -0,0 +1,24 @@ +From 724ff8679e0ae0fd4d84f4e6c1b36007e648e8ca Mon Sep 17 00:00:00 2001 +From: Tomas Bzatek +Date: Fri, 26 Jun 2020 17:57:12 +0200 +Subject: [PATCH 7/8] zram: Always flush interface property changes + +--- + modules/zram/udiskslinuxblockzram.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/modules/zram/udiskslinuxblockzram.c b/modules/zram/udiskslinuxblockzram.c +index 132d4174..1bae3686 100644 +--- a/modules/zram/udiskslinuxblockzram.c ++++ b/modules/zram/udiskslinuxblockzram.c +@@ -277,6 +277,7 @@ udisks_linux_block_zram_update (UDisksLinuxBlockZRAM *zramblock, + + udisks_block_zram_set_active (iface, bd_swap_swapstatus (dev_file, &error)); + out: ++ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (iface)); + if (zram_info) + bd_kbd_zram_stats_free (zram_info); + if (error) +-- +2.26.2 + diff --git a/SOURCES/udisks-2.9.2-udisksdaemonutil-Refactor-udisks_daemon_util_trigger.patch b/SOURCES/udisks-2.9.2-udisksdaemonutil-Refactor-udisks_daemon_util_trigger.patch new file mode 100644 index 0000000..3d2aa1b --- /dev/null +++ b/SOURCES/udisks-2.9.2-udisksdaemonutil-Refactor-udisks_daemon_util_trigger.patch @@ -0,0 +1,528 @@ +From 8d5c90a1f4bbe548a1ae361f8d69970669d6e72e Mon Sep 17 00:00:00 2001 +From: Tomas Bzatek +Date: Fri, 13 Nov 2020 16:52:11 +0100 +Subject: [PATCH 1/2] udisksdaemonutil: Refactor + udisks_daemon_util_trigger_uevent() out of UDisksLinuxBlockObject + +This decouples uevent triggering from UDisksLinuxBlockObject as sometimes +we don't have a block object yet or it's outdated. +--- + doc/udisks2-sections.txt.daemon.sections.in | 2 + + src/udisksdaemonutil.c | 230 ++++++++++++++++++++ + src/udisksdaemonutil.h | 7 + + src/udiskslinuxblockobject.c | 180 ++------------- + 4 files changed, 253 insertions(+), 166 deletions(-) + +diff --git a/doc/udisks2-sections.txt.daemon.sections.in b/doc/udisks2-sections.txt.daemon.sections.in +index 26c3c2cd..3030fa95 100644 +--- a/doc/udisks2-sections.txt.daemon.sections.in ++++ b/doc/udisks2-sections.txt.daemon.sections.in +@@ -307,6 +307,8 @@ udisks_daemon_util_file_set_contents + udisks_daemon_util_on_user_seat + udisks_daemon_util_get_free_mdraid_device + udisks_ata_identify_get_word ++udisks_daemon_util_trigger_uevent ++udisks_daemon_util_trigger_uevent_sync + + +
+diff --git a/src/udisksdaemonutil.c b/src/udisksdaemonutil.c +index 75b877a0..d16c0766 100644 +--- a/src/udisksdaemonutil.c ++++ b/src/udisksdaemonutil.c +@@ -34,10 +34,14 @@ + #include + #include + ++#include ++ + #include "udisksdaemon.h" + #include "udisksdaemonutil.h" + #include "udisksstate.h" + #include "udiskslogging.h" ++#include "udiskslinuxdevice.h" ++#include "udiskslinuxprovider.h" + #include "udiskslinuxblockobject.h" + #include "udiskslinuxdriveobject.h" + +@@ -1626,3 +1630,229 @@ udisks_ata_identify_get_word (const guchar *identify_data, guint word_number) + out: + return ret; + } ++ ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static volatile guint uevent_serial = 0; ++ ++static gboolean ++trigger_uevent (const gchar *path, const gchar *str) ++{ ++ gint fd; ++ ++ fd = open (path, O_WRONLY); ++ if (fd < 0) ++ { ++ udisks_warning ("Error opening %s while triggering uevent: %m", path); ++ return FALSE; ++ } ++ ++ if (write (fd, str, strlen (str)) != (ssize_t) strlen (str)) ++ { ++ udisks_warning ("Error writing '%s' to file %s: %m", str, path); ++ close (fd); ++ return FALSE; ++ } ++ ++ close (fd); ++ return TRUE; ++} ++ ++typedef struct ++{ ++ UDisksDaemon *daemon; ++ GMainLoop *main_loop; ++ guint serial; ++ gchar *uevent_path; ++ gboolean success; ++} SynthUeventData; ++ ++static gboolean ++trigger_uevent_idle_cb (gpointer user_data) ++{ ++ SynthUeventData *data = user_data; ++ gchar *str; ++ ++ str = g_strdup_printf ("change %s UDISKSSERIAL=%u", udisks_daemon_get_uuid (data->daemon), data->serial); ++ ++ if (! trigger_uevent (data->uevent_path, str)) ++ { ++ /* kernel refused our string, try simple "change" but don't wait for it */ ++ trigger_uevent (data->uevent_path, "change"); ++ data->success = FALSE; ++ g_main_loop_quit (data->main_loop); ++ } ++ g_free (str); ++ ++ /* remove the source */ ++ return FALSE; ++} ++ ++static gboolean ++uevent_wait_timeout_cb (gpointer user_data) ++{ ++ SynthUeventData *data = user_data; ++ ++ data->success = FALSE; ++ g_main_loop_quit (data->main_loop); ++ ++ /* remove the source */ ++ return FALSE; ++} ++ ++static void ++uevent_probed_cb (UDisksLinuxProvider *provider, ++ const gchar *action, ++ UDisksLinuxDevice *device, ++ gpointer user_data) ++{ ++ SynthUeventData *data = user_data; ++ const gchar *received_serial_str; ++ gint64 received_serial; ++ gchar *endptr; ++ ++ received_serial_str = g_udev_device_get_property (device->udev_device, "SYNTH_ARG_UDISKSSERIAL"); ++ if (received_serial_str != NULL) ++ { ++ endptr = (gchar *) received_serial_str; ++ received_serial = g_ascii_strtoll (received_serial_str, &endptr, 0); ++ if (endptr != received_serial_str && received_serial == data->serial) ++ { ++ data->success = TRUE; ++ g_main_loop_quit (data->main_loop); ++ } ++ } ++} ++ ++/** ++ * udisks_daemon_util_trigger_uevent: ++ * @daemon: A #UDisksDaemon. ++ * @device_path: Block device path. ++ * ++ * Triggers a 'change' uevent in the kernel. ++ * ++ * The triggered event will bubble up from the kernel through the udev ++ * stack and will eventually be received by the udisks daemon process ++ * itself. This method does not wait for the event to be received. ++ */ ++void ++udisks_daemon_util_trigger_uevent (UDisksDaemon *daemon, ++ const gchar *device_path) ++{ ++ GUdevClient *gudev_client; ++ GUdevDevice *gudev_device; ++ gchar *path; ++ ++ g_return_if_fail (UDISKS_IS_DAEMON (daemon)); ++ g_return_if_fail (device_path != NULL); ++ ++ gudev_client = udisks_linux_provider_get_udev_client (udisks_daemon_get_linux_provider (daemon)); ++ gudev_device = g_udev_client_query_by_device_file (gudev_client, device_path); ++ if (gudev_device == NULL) ++ { ++ udisks_critical ("Device %s not found in udev database, skipping uevent trigger", device_path); ++ return; ++ } ++ ++ path = g_build_filename (g_udev_device_get_sysfs_path (gudev_device), "uevent", NULL); ++ trigger_uevent (path, "change"); ++ g_free (path); ++ ++ g_object_unref (gudev_device); ++} ++ ++/** ++ * udisks_daemon_util_trigger_uevent_sync: ++ * @daemon: A #UDisksDaemon. ++ * @device_path: Block device path. ++ * @timeout_seconds: Maximum time to wait for the uevent (in seconds). ++ * ++ * Triggers a 'change' uevent in the kernel and waits until it's received and ++ * processed by udisks. ++ * ++ * Unlike udisks_daemon_util_trigger_uevent() that just triggers ++ * a synthetic uevent to the kernel, this call will actually block and wait until ++ * the #UDisksLinuxProvider receives the uevent, performs probing and processes ++ * the uevent further down the UDisks object stack. Upon returning from this ++ * function call the caller may assume the event has been fully processed, all ++ * D-Bus objects are updated and settled. Typically used in busy wait for ++ * a particular D-Bus interface. ++ * ++ * Note that this uses synthetic uevent tagging and only works on linux kernel ++ * 4.13 and higher. In case an older kernel is detected this acts like the classic ++ * udisks_daemon_util_trigger_uevent() call and %FALSE is returned. ++ * ++ * Returns: %TRUE if the uevent has been successfully received, %FALSE otherwise ++ * or when the kernel version is too old. ++ */ ++gboolean ++udisks_daemon_util_trigger_uevent_sync (UDisksDaemon *daemon, ++ const gchar *device_path, ++ guint timeout_seconds) ++{ ++ UDisksLinuxProvider *provider; ++ GUdevClient *gudev_client; ++ GUdevDevice *gudev_device; ++ SynthUeventData data; ++ GMainContext *main_context; ++ GSource *idle_source; ++ GSource *timeout_source; ++ ++ g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), FALSE); ++ g_return_val_if_fail (device_path != NULL, FALSE); ++ ++ if (bd_utils_check_linux_version (4, 13, 0) < 0) ++ { ++ udisks_daemon_util_trigger_uevent (daemon, device_path); ++ return FALSE; ++ } ++ ++ provider = udisks_daemon_get_linux_provider (daemon); ++ gudev_client = udisks_linux_provider_get_udev_client (provider); ++ gudev_device = g_udev_client_query_by_device_file (gudev_client, device_path); ++ if (gudev_device == NULL) ++ { ++ udisks_critical ("Device %s not found in udev database, skipping uevent trigger", device_path); ++ return FALSE; ++ } ++ ++ data.daemon = daemon; ++ data.uevent_path = g_build_filename (g_udev_device_get_sysfs_path (gudev_device), "uevent", NULL); ++ data.serial = g_atomic_int_add (&uevent_serial, 1); ++ ++ main_context = g_main_context_new (); ++ g_main_context_push_thread_default (main_context); ++ data.main_loop = g_main_loop_new (main_context, FALSE); ++ ++ /* queue the actual trigger in the loop */ ++ idle_source = g_idle_source_new (); ++ g_source_set_callback (idle_source, (GSourceFunc) trigger_uevent_idle_cb, &data, NULL); ++ g_source_attach (idle_source, main_context); ++ g_source_unref (idle_source); ++ ++ /* add timeout as a fallback */ ++ timeout_source = g_timeout_source_new_seconds (timeout_seconds); ++ g_source_set_callback (timeout_source, (GSourceFunc) uevent_wait_timeout_cb, &data, NULL); ++ g_source_attach (timeout_source, main_context); ++ g_source_unref (timeout_source); ++ ++ /* catch incoming uevents */ ++ g_signal_connect (provider, "uevent-probed", G_CALLBACK (uevent_probed_cb), &data); ++ ++ data.success = FALSE; ++ g_main_loop_run (data.main_loop); ++ ++ g_signal_handlers_disconnect_by_func (provider, uevent_probed_cb, &data); ++ g_main_context_pop_thread_default (main_context); ++ ++ g_main_loop_unref (data.main_loop); ++ g_main_context_unref (main_context); ++ ++ g_free (data.uevent_path); ++ g_object_unref (gudev_device); ++ ++ return data.success; ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ +diff --git a/src/udisksdaemonutil.h b/src/udisksdaemonutil.h +index 4fe36214..2edf2122 100644 +--- a/src/udisksdaemonutil.h ++++ b/src/udisksdaemonutil.h +@@ -51,6 +51,13 @@ guint64 udisks_daemon_util_block_get_size (GUdevDevice *device, + gboolean *out_media_available, + gboolean *out_media_change_detected); + ++void udisks_daemon_util_trigger_uevent (UDisksDaemon *daemon, ++ const gchar *device_path); ++ ++gboolean udisks_daemon_util_trigger_uevent_sync (UDisksDaemon *daemon, ++ const gchar *device_path, ++ guint timeout_seconds); ++ + gchar *udisks_daemon_util_resolve_link (const gchar *path, + const gchar *name); + +diff --git a/src/udiskslinuxblockobject.c b/src/udiskslinuxblockobject.c +index 42ab17d7..5a68c84b 100644 +--- a/src/udiskslinuxblockobject.c ++++ b/src/udiskslinuxblockobject.c +@@ -38,8 +38,6 @@ + #include + #include + +-#include +- + #include "udiskslogging.h" + #include "udisksdaemon.h" + #include "udisksdaemonutil.h" +@@ -959,122 +957,24 @@ on_mount_monitor_mount_removed (UDisksMountMonitor *monitor, + + /* ---------------------------------------------------------------------------------------------------- */ + +-static volatile guint uevent_serial = 0; +- +-static gboolean +-trigger_uevent (const gchar *path, const gchar *str) +-{ +- gint fd; +- +- fd = open (path, O_WRONLY); +- if (fd < 0) +- { +- udisks_warning ("Error opening %s while triggering uevent: %m", path); +- return FALSE; +- } +- +- if (write (fd, str, strlen (str)) != (ssize_t) strlen (str)) +- { +- udisks_warning ("Error writing '%s' to file %s: %m", str, path); +- close (fd); +- return FALSE; +- } +- +- close (fd); +- return TRUE; +-} +- +-typedef struct +-{ +- UDisksLinuxBlockObject *object; +- GMainLoop *main_loop; +- guint serial; +- gchar *uevent_path; +- gboolean success; +-} SynthUeventData; +- +-static gboolean +-trigger_uevent_idle_cb (gpointer user_data) +-{ +- SynthUeventData *data = user_data; +- gchar *str; +- +- str = g_strdup_printf ("change %s UDISKSSERIAL=%u", udisks_daemon_get_uuid (data->object->daemon), data->serial); +- +- if (! trigger_uevent (data->uevent_path, str)) +- { +- /* kernel refused our string, try simple "change" but don't wait for it */ +- trigger_uevent (data->uevent_path, "change"); +- data->success = FALSE; +- g_main_loop_quit (data->main_loop); +- } +- g_free (str); +- +- /* remove the source */ +- return FALSE; +-} +- +-static gboolean +-uevent_wait_timeout_cb (gpointer user_data) +-{ +- SynthUeventData *data = user_data; +- +- data->success = FALSE; +- g_main_loop_quit (data->main_loop); +- +- /* remove the source */ +- return FALSE; +-} +- +-static void +-uevent_probed_cb (UDisksLinuxProvider *provider, +- const gchar *action, +- UDisksLinuxDevice *device, +- gpointer user_data) +-{ +- SynthUeventData *data = user_data; +- const gchar *received_serial_str; +- gint64 received_serial; +- gchar *endptr; +- +- received_serial_str = g_udev_device_get_property (device->udev_device, "SYNTH_ARG_UDISKSSERIAL"); +- if (received_serial_str != NULL) +- { +- endptr = (gchar *) received_serial_str; +- received_serial = g_ascii_strtoll (received_serial_str, &endptr, 0); +- if (endptr != received_serial_str && received_serial == data->serial) +- { +- data->success = TRUE; +- g_main_loop_quit (data->main_loop); +- } +- } +-} +- + /** + * udisks_linux_block_object_trigger_uevent: + * @object: A #UDisksLinuxBlockObject. + * + * Triggers a 'change' uevent in the kernel. + * +- * The triggered event will bubble up from the kernel through the udev +- * stack and will eventually be received by the udisks daemon process +- * itself. This method does not wait for the event to be received. ++ * Refer to udisks_daemon_util_trigger_uevent() for detailed description. + */ + void + udisks_linux_block_object_trigger_uevent (UDisksLinuxBlockObject *object) + { +- UDisksLinuxDevice *device; +- gchar *path; ++ gchar *device_file; + + g_return_if_fail (UDISKS_IS_LINUX_BLOCK_OBJECT (object)); + +- device = udisks_linux_block_object_get_device (object); +- path = g_strconcat (g_udev_device_get_sysfs_path (device->udev_device), "/uevent", NULL); +- +- trigger_uevent (path, "change"); +- +- g_free (path); +- g_object_unref (device); ++ device_file = udisks_linux_block_object_get_device_file (object); ++ udisks_daemon_util_trigger_uevent (object->daemon, device_file); ++ g_free (device_file); + } + + /** +@@ -1083,19 +983,10 @@ udisks_linux_block_object_trigger_uevent (UDisksLinuxBlockObject *object) + * @timeout_seconds: Maximum time to wait for the uevent (in seconds). + * + * Triggers a 'change' uevent in the kernel and waits until it's received and +- * processed by udisks. +- * +- * Unlike udisks_linux_block_object_trigger_uevent() that just triggers +- * a synthetic uevent to the kernel, this call will actually block and wait until +- * the #UDisksLinuxProvider receives the uevent, performs probing and processes +- * the uevent further down the UDisks object stack. Upon returning from this +- * function call the caller may assume the event has been fully processed, all +- * D-Bus objects are updated and settled. Typically used in busy wait for +- * a particular D-Bus interface. ++ * processed through the uevent queue. + * +- * Note that this uses synthetic uevent tagging and only works on linux kernel +- * 4.13 and higher. In case an older kernel is detected this acts like the classic +- * udisks_linux_block_object_trigger_uevent() call and %FALSE is returned. ++ * This is a convenient wrapper around udisks_daemon_util_trigger_uevent_sync(). ++ * Refer to this function for detailed documentation. + * + * Returns: %TRUE if the uevent has been successfully received, %FALSE otherwise + * or when the kernel version is too old. +@@ -1104,59 +995,16 @@ gboolean + udisks_linux_block_object_trigger_uevent_sync (UDisksLinuxBlockObject *object, + guint timeout_seconds) + { +- UDisksLinuxDevice *device; +- UDisksLinuxProvider *provider; +- SynthUeventData data; +- GMainContext *main_context; +- GSource *idle_source; +- GSource *timeout_source; ++ gchar *device_file; ++ gboolean ret; + + g_return_val_if_fail (UDISKS_IS_LINUX_BLOCK_OBJECT (object), FALSE); + +- if (bd_utils_check_linux_version (4, 13, 0) < 0) +- { +- udisks_linux_block_object_trigger_uevent (object); +- return FALSE; +- } +- +- data.object = object; +- device = udisks_linux_block_object_get_device (object); +- data.uevent_path = g_strconcat (g_udev_device_get_sysfs_path (device->udev_device), "/uevent", NULL); +- data.serial = g_atomic_int_add (&uevent_serial, 1); +- +- main_context = g_main_context_new (); +- g_main_context_push_thread_default (main_context); +- data.main_loop = g_main_loop_new (main_context, FALSE); +- +- /* queue the actual trigger in the loop */ +- idle_source = g_idle_source_new (); +- g_source_set_callback (idle_source, (GSourceFunc) trigger_uevent_idle_cb, &data, NULL); +- g_source_attach (idle_source, main_context); +- g_source_unref (idle_source); ++ device_file = udisks_linux_block_object_get_device_file (object); ++ ret = udisks_daemon_util_trigger_uevent_sync (object->daemon, device_file, timeout_seconds); ++ g_free (device_file); + +- /* add timeout as a fallback */ +- timeout_source = g_timeout_source_new_seconds (timeout_seconds); +- g_source_set_callback (timeout_source, (GSourceFunc) uevent_wait_timeout_cb, &data, NULL); +- g_source_attach (timeout_source, main_context); +- g_source_unref (timeout_source); +- +- /* catch incoming uevents */ +- provider = udisks_daemon_get_linux_provider (object->daemon); +- g_signal_connect (provider, "uevent-probed", G_CALLBACK (uevent_probed_cb), &data); +- +- data.success = FALSE; +- g_main_loop_run (data.main_loop); +- +- g_signal_handlers_disconnect_by_func (provider, uevent_probed_cb, &data); +- g_main_context_pop_thread_default (main_context); +- +- g_main_loop_unref (data.main_loop); +- g_main_context_unref (main_context); +- +- g_free (data.uevent_path); +- g_object_unref (device); +- +- return data.success; ++ return ret; + } + + /* ---------------------------------------------------------------------------------------------------- */ +-- +2.26.2 + diff --git a/SOURCES/udisks-2.9.2-udiskslinuxmanager-Trigger-uevent-after-loop-device-setup.patch b/SOURCES/udisks-2.9.2-udiskslinuxmanager-Trigger-uevent-after-loop-device-setup.patch new file mode 100644 index 0000000..c37d942 --- /dev/null +++ b/SOURCES/udisks-2.9.2-udiskslinuxmanager-Trigger-uevent-after-loop-device-setup.patch @@ -0,0 +1,27 @@ +From 7fe04e70dc5a5ccf621a0beacc6d4b9e904037df Mon Sep 17 00:00:00 2001 +From: Tomas Bzatek +Date: Fri, 13 Nov 2020 16:57:24 +0100 +Subject: [PATCH 2/2] udiskslinuxmanager: Trigger uevent after loop device + setup + +--- + src/udiskslinuxmanager.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/udiskslinuxmanager.c b/src/udiskslinuxmanager.c +index 1bbf980a..e0a83a80 100644 +--- a/src/udiskslinuxmanager.c ++++ b/src/udiskslinuxmanager.c +@@ -430,6 +430,9 @@ handle_loop_setup (UDisksManager *object, + error = NULL; + wait_data.loop_device = loop_device; + wait_data.path = path; ++ udisks_daemon_util_trigger_uevent_sync (manager->daemon, ++ loop_device, ++ UDISKS_DEFAULT_WAIT_TIMEOUT); + loop_object = udisks_daemon_wait_for_object_sync (manager->daemon, + wait_for_loop_object, + &wait_data, +-- +2.26.2 + diff --git a/SPECS/udisks2.spec b/SPECS/udisks2.spec index f58d217..7f30680 100644 --- a/SPECS/udisks2.spec +++ b/SPECS/udisks2.spec @@ -56,13 +56,23 @@ Name: udisks2 Summary: Disk Manager Version: 2.9.0 -Release: 3%{?dist} +Release: 5%{?dist} License: GPLv2+ Group: System Environment/Libraries URL: https://github.com/storaged-project/udisks Source0: https://github.com/storaged-project/udisks/releases/download/udisks-%{version}/udisks-%{version}.tar.bz2 Patch0: udisks-2.9.1-teardown-needle-match.patch Patch1: udisks-2.9.1-lvm_vdo-test_resize_physical-size.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1855785 +Patch2: udisks-2.9.1-drive_ata_tests.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1845973 +Patch10: udisks-2.9.1-daemon-Always-flush-interface-property-changes.patch +Patch11: udisks-2.9.1-lvm2-Always-flush-interface-property-changes.patch +Patch12: udisks-2.9.1-lsm-Always-flush-interface-property-changes.patch +Patch13: udisks-2.9.1-iscsi-Always-flush-interface-property-changes.patch +Patch14: udisks-2.9.1-zram-Always-flush-interface-property-changes.patch +Patch15: udisks-2.9.2-udisksdaemonutil-Refactor-udisks_daemon_util_trigger.patch +Patch16: udisks-2.9.2-udiskslinuxmanager-Trigger-uevent-after-loop-device-setup.patch BuildRequires: glib2-devel >= %{glib2_version} BuildRequires: gobject-introspection-devel >= %{gobject_introspection_version} @@ -269,6 +279,14 @@ This package contains module for VDO management. %setup -q -n udisks-%{version} %patch0 -p1 %patch1 -p1 +%patch2 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 sed -i udisks/udisks2.conf.in -e "s/encryption=luks1/encryption=%{default_luks_encryption}/" %build @@ -461,6 +479,13 @@ fi %endif %changelog +* Mon Nov 16 2020 Tomas Bzatek - 2.9.0-5 +- Fix loop device setup + +* Tue Nov 10 2020 Tomas Bzatek - 2.9.0-4 +- Fix Drive.Ata tests with system SAS drives (#1855785) +- Force D-Bus interfaces flush (#1845973) + * Mon Jun 22 2020 Tomas Bzatek - 2.9.0-3 - Fix the UdisksLVMVDOTest.test_resize_physical test (#1845435)