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

Reply via email to