Since this effects multiple packages, I wasn't sure how to open a bug report. The patches fix a random process to be deterministic. There are already bug reports, my fav:
https://gitlab.gnome.org/GNOME/gvfs/-/issues/519 Been in discussions and have ruffled feathers and had gotten nowhere. Some ppl seem to want to complicate the issue by introducing unnecessary complications, my fav is to take every `char *` device name or `uint64_t` device id and unionize it with a UUID. This complicates every piece of code that operates on all these variables and is an utter trash idea, IMHO. The approach taken in these patches is to use a canonical device. As long as every function that chooses/finds/enumerates/scans devices resolves the same canonical device, everything works. It may take some time to find and augment every program, but currently those programs have a bug without any proposed solution. With these patches, I no-longer have extra icons on my XFCE desktop. One reason to adopt these patches instead of working out some other solution is that these make small changes. Hadn't considered partial application of these patches, so there is more work that needs to be done. Am finished with this, aside from answering questions and taking part in discussions. Won't be opening more bug reports, making changes to these patches, or gathering the justice league. May assist in testing and will attempt to make comments/offer corrections, for other patches. Further to-do items discovered while researching this: 1. btrfs on disk representation should expose the following 3 unsigned integers to blkid and others X of N where Y are unhealthy/unavailable. Add them to the superblock works, but because these are dynamic, a journal and timestamps may be appropriate. Discussion with filesystem and block device exports would help. Things that come to mind are like if a shared resource is having problems and the removal of one drive shouldn't cause every superblock on another effected drive to be updated, that could lead to disaster. This aids in knowing whether all devices are good, and also `X == 1` could be how a canonical device is chosen. 2. kernel can easily be changed to list a UUID instead of device name in mountinfo and others, I wrote a patch but it needs love. Applying the patch doesn't break things so badly you can't boot, but I did note that grub-probe had trouble with it. ``` diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c index 392ef5162..2e62bb906 100644 --- a/fs/proc_namespace.c +++ b/fs/proc_namespace.c @@ -98,6 +98,30 @@ static void show_type(struct seq_file *m, struct super_block *sb) } } +__always_inline int show_devname(struct seq_file *m, struct vfsmount *mnt, + struct super_block *sb, struct mount *r) +{ + int err = 0; + if (memcmp(sb->s_type->name, "btrfs", 6) != 0 || + uuid_is_null(&sb->s_uuid)) { + if (sb->s_op->show_devname) { + struct path mnt_path = { .dentry = mnt->mnt_root, + .mnt = mnt }; + err = sb->s_op->show_devname(m, mnt_path.dentry); + if (err) + goto out; + } else { + mangle(m, r->mnt_devname ? r->mnt_devname : "none"); + } + seq_putc(m, ' '); + } else { + seq_printf(m, "UUID=%pUb ", &sb->s_uuid); + } + +out: + return err; +} + static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt) { struct proc_mounts *p = m->private; @@ -106,14 +130,9 @@ static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt) struct super_block *sb = mnt_path.dentry->d_sb; int err; - if (sb->s_op->show_devname) { - err = sb->s_op->show_devname(m, mnt_path.dentry); - if (err) - goto out; - } else { - mangle(m, r->mnt_devname ? r->mnt_devname : "none"); - } - seq_putc(m, ' '); + err = show_devname(m, mnt, sb, r); + if (err) + goto out; /* mountpoints outside of chroot jail will give SEQ_SKIP on this */ err = seq_path_root(m, &mnt_path, &p->root, " \t\n\\"); if (err) @@ -176,14 +195,10 @@ static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt) seq_puts(m, " - "); show_type(m, sb); seq_putc(m, ' '); - if (sb->s_op->show_devname) { - err = sb->s_op->show_devname(m, mnt->mnt_root); - if (err) - goto out; - } else { - mangle(m, r->mnt_devname ? r->mnt_devname : "none"); - } - seq_puts(m, sb_rdonly(sb) ? " ro" : " rw"); + err = show_devname(m, mnt, sb, r); + if (err) + goto out; + seq_puts(m, sb_rdonly(sb) ? "ro" : "rw"); err = show_sb_opts(m, sb); if (err) goto out; ``` Someone pointed out that `show_devname` would be perfect for this, I just didn't think about it.
From 3cea32343aaf29a678d43665425ea344043c8d35 Mon Sep 17 00:00:00 2001 From: Michael Mestnik <[email protected]> Date: Wed, 7 Jul 2021 23:00:59 -0500 Subject: [PATCH] udisksmountmonitor: redirect mountinfo btrfs device lookups --- src/udisksmountmonitor.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/udisksmountmonitor.c b/src/udisksmountmonitor.c index bdc7a5df..63d7e744 100644 --- a/src/udisksmountmonitor.c +++ b/src/udisksmountmonitor.c @@ -31,6 +31,8 @@ #include <sys/sysmacros.h> #include <mntent.h> +#include <blkid/blkid.h> + #include <glib.h> #include <glib-object.h> @@ -86,6 +88,8 @@ struct _UDisksMountMonitor gchar *swaps_checksum; GMainContext *monitor_context; + + blkid_cache blkid_cache; }; typedef struct _UDisksMountMonitorClass UDisksMountMonitorClass; @@ -146,6 +150,8 @@ udisks_mount_monitor_finalize (GObject *object) g_free (monitor->mountinfo_checksum); g_free (monitor->swaps_checksum); + blkid_put_cache (monitor->blkid_cache); + g_mutex_clear (&monitor->mounts_mutex); if (G_OBJECT_CLASS (udisks_mount_monitor_parent_class)->finalize != NULL) @@ -157,6 +163,8 @@ udisks_mount_monitor_init (UDisksMountMonitor *monitor) { monitor->mounts = NULL; monitor->old_mounts = NULL; + blkid_init_debug (0); + g_assert_cmpint (blkid_get_cache (&monitor->blkid_cache, NULL), ==, 0); g_mutex_init (&monitor->mounts_mutex); } @@ -595,6 +603,8 @@ udisks_mount_monitor_parse_mountinfo (UDisksMountMonitor *monitor, { gchar fstype[PATH_MAX + 1]; gchar mount_source[PATH_MAX + 1]; + char *devname; + char *uuid; struct stat statbuf; if (sscanf (sep + 3, PATH_MAX_FMT " " PATH_MAX_FMT, fstype, mount_source) != 2) @@ -608,6 +618,14 @@ udisks_mount_monitor_parse_mountinfo (UDisksMountMonitor *monitor, if (g_strcmp0 (fstype, "btrfs") != 0) continue; + devname = blkid_get_devname(monitor->blkid_cache, mount_source, NULL); + uuid = blkid_get_tag_value(monitor->blkid_cache, "UUID", devname); + + if (!uuid && (('0' <= uuid[0] && uuid[0] <= '9') || ('a' <= uuid[0] && uuid[0] <= 'f') || ('A' <= uuid[0] && uuid[0] <= 'F'))) { + if(g_snprintf(mount_source, PATH_MAX, "/dev/disk/by-uuid/%s", uuid) != 54) + continue; + } + if (!g_str_has_prefix (mount_source, "/dev/")) continue; -- 2.20.1
From 8d09dd37875c98a50bbeaf0a464523ac92cf26f5 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek <[email protected]> Date: Tue, 11 May 2021 18:21:31 +0200 Subject: [PATCH 1/2] daemon: Link with libblkid Unversioned requirement for the moment, brings useful util functions in as a complement to libmount. --- configure.ac | 4 ++++ src/Makefile.am | 2 ++ 2 files changed, 6 insertions(+) diff --git a/configure.ac b/configure.ac index f349dd2b..d9c48034 100644 --- a/configure.ac +++ b/configure.ac @@ -175,6 +175,10 @@ if test "x$enable_daemon" = "xyes"; then AC_SUBST(LIBATASMART_CFLAGS) AC_SUBST(LIBATASMART_LIBS) + PKG_CHECK_MODULES(LIBBLKID, [blkid]) + AC_SUBST(LIBBLKID_CFLAGS) + AC_SUBST(LIBBLKID_LIBS) + PKG_CHECK_MODULES(LIBMOUNT, [mount >= 2.18]) AC_SUBST(LIBMOUNT_CFLAGS) AC_SUBST(LIBMOUNT_LIBS) diff --git a/src/Makefile.am b/src/Makefile.am index 4048854c..675f6df3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -121,6 +121,7 @@ libudisks_daemon_la_CFLAGS = \ $(GMODULE_CFLAGS) \ $(GUDEV_CFLAGS) \ $(LIBATASMART_CFLAGS) \ + $(LIBBLKID_CFLAGS) \ $(LIBMOUNT_CFLAGS) \ $(LIBUUID_CFLAGS) \ $(POLKIT_GOBJECT_1_CFLAGS) \ @@ -139,6 +140,7 @@ libudisks_daemon_la_LIBADD = \ $(BLOCKDEV_LIBS) \ -lbd_utils \ $(LIBATASMART_LIBS) \ + $(LIBBLKID_LIBS) \ $(LIBMOUNT_LIBS) \ $(LIBUUID_LIBS) \ $(POLKIT_GOBJECT_1_LIBS) \ -- 2.20.1
From 79c320d92fde7114228950827bc03a6350c91899 Mon Sep 17 00:00:00 2001 From: Michael Mestnik <[email protected]> Date: Wed, 7 Jul 2021 12:40:45 -0500 Subject: [PATCH] libblkid: Treat btrfs multidevice with care --- libblkid/src/blkidP.h | 1 + libblkid/src/superblocks/btrfs.c | 36 ++++++++++++++++++++++++-- libblkid/src/superblocks/superblocks.c | 10 +++++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h index e3a160aa9..82b3985e8 100644 --- a/libblkid/src/blkidP.h +++ b/libblkid/src/blkidP.h @@ -163,6 +163,7 @@ struct blkid_idinfo { const char *name; /* fs, raid or partition table name */ int usage; /* BLKID_USAGE_* flag */ + int (*usagefunc)(blkid_probe pr); int flags; /* BLKID_IDINFO_* flags */ int minsz; /* minimal device size */ diff --git a/libblkid/src/superblocks/btrfs.c b/libblkid/src/superblocks/btrfs.c index 03aa7e979..83900d218 100644 --- a/libblkid/src/superblocks/btrfs.c +++ b/libblkid/src/superblocks/btrfs.c @@ -17,6 +17,7 @@ #endif #include "superblocks.h" +#define BLKID_USAGE_FILESYSTEM_PART (1 << 5) struct btrfs_super_block { uint8_t csum[32]; @@ -197,6 +198,8 @@ out: static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag) { struct btrfs_super_block *bfs; + char tmpdev[55]; + struct stat statbuf; if (pr->zone_size) { #ifdef HAVE_LINUX_BLKZONED_H @@ -228,13 +231,42 @@ static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag) blkid_probe_set_uuid_as(pr, bfs->dev_item.uuid, "UUID_SUB"); blkid_probe_set_block_size(pr, le32_to_cpu(bfs->sectorsize)); - return 0; + strncpy(tmpdev, "/dev/disk/by-uuid/", sizeof(tmpdev)); + snprintf(tmpdev + 18, sizeof(tmpdev) - 18, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + bfs->fsid[0], bfs->fsid[1], bfs->fsid[2], bfs->fsid[3], + bfs->fsid[4], bfs->fsid[5], + bfs->fsid[6], bfs->fsid[7], + bfs->fsid[8], bfs->fsid[9], + bfs->fsid[10], bfs->fsid[11], bfs->fsid[12], bfs->fsid[13], bfs->fsid[14], bfs->fsid[15]); + + if (stat(tmpdev, &statbuf) == 0 && + S_ISBLK(statbuf.st_mode) && + blkid_probe_get_devno(pr) != statbuf.st_rdev) + return blkid_probe_set_value(pr, "CHILD_DEVICE", (const unsigned char *)"true", 4); + + return blkid_probe_set_value(pr, "CHILD_DEVICE", (const unsigned char *)"f", 1); + +} + +static int usage_func(blkid_probe pr) +{ + const char *v; + int ret = BLKID_USAGE_FILESYSTEM; + + if (blkid_probe_lookup_value(pr, "CHILD_DEVICE", &v, NULL) != 0) + return ret; + + if (v[0] == 't') + ret = BLKID_USAGE_FILESYSTEM_PART; + + return ret; } const struct blkid_idinfo btrfs_idinfo = { .name = "btrfs", - .usage = BLKID_USAGE_FILESYSTEM, + .usagefunc = usage_func, .probefunc = probe_btrfs, .minsz = 1024 * 1024, .magics = diff --git a/libblkid/src/superblocks/superblocks.c b/libblkid/src/superblocks/superblocks.c index f21365538..bc5f63949 100644 --- a/libblkid/src/superblocks/superblocks.c +++ b/libblkid/src/superblocks/superblocks.c @@ -425,8 +425,12 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn) (const unsigned char *) id->name, strlen(id->name) + 1); - if (!rc) - rc = blkid_probe_set_usage(pr, id->usage); + if (!rc) { + if(!id->usagefunc) { + rc = blkid_probe_set_usage(pr, id->usage); + } else + rc = blkid_probe_set_usage(pr, id->usagefunc(pr)); + } if (!rc && mag) rc = blkid_probe_set_magic(pr, off, mag->len, @@ -578,6 +582,8 @@ static int blkid_probe_set_usage(blkid_probe pr, int usage) u = "crypto"; else if (usage & BLKID_USAGE_OTHER) u = "other"; + else if (usage & (1 << 5)) + u = "f1lesystem-part"; /* s/i/1/ */ else u = "unknown"; -- 2.20.1
_______________________________________________ Pkg-utopia-maintainers mailing list [email protected] https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/pkg-utopia-maintainers
