From: David Zeuthen Date: Tue, 3 Mar 2009 21:20:08 +0000 (-0500) Subject: use dev_t to identify mounts, not device files X-Git-Tag: upstream/2.1.2~913 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7cca7ee84bd3f15f86a8648e4c39a2d3f8756803;p=platform%2Fupstream%2Fudisks2.git use dev_t to identify mounts, not device files This should fix all issues with things like device-mapper using non-canonical device file names (e.g. /dev/mapper/VolGroup00-LogVol00). Also, this allows us to delete a bunch of special case code that already tried to deal with this See https://bugzilla.redhat.com/show_bug.cgi?id=488258 for details. --- diff --git a/src/devkit-disks-daemon.c b/src/devkit-disks-daemon.c index 944a231..4a2582f 100644 --- a/src/devkit-disks-daemon.c +++ b/src/devkit-disks-daemon.c @@ -96,6 +96,7 @@ struct DevkitDisksDaemonPrivate GIOChannel *mdstat_channel; + GHashTable *map_dev_t_to_device; GHashTable *map_device_file_to_device; GHashTable *map_native_path_to_device; GHashTable *map_object_path_to_device; @@ -504,6 +505,10 @@ static void devkit_disks_daemon_init (DevkitDisksDaemon *daemon) { daemon->priv = DEVKIT_DISKS_DAEMON_GET_PRIVATE (daemon); + daemon->priv->map_dev_t_to_device = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + NULL); daemon->priv->map_device_file_to_device = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, @@ -546,6 +551,9 @@ devkit_disks_daemon_finalize (GObject *object) if (daemon->priv->mdstat_channel != NULL) g_io_channel_unref (daemon->priv->mdstat_channel); + if (daemon->priv->map_dev_t_to_device != NULL) { + g_hash_table_unref (daemon->priv->map_dev_t_to_device); + } if (daemon->priv->map_device_file_to_device != NULL) { g_hash_table_unref (daemon->priv->map_device_file_to_device); } @@ -678,6 +686,9 @@ device_went_away (gpointer user_data, GObject *where_the_object_was) g_hash_table_foreach_remove (daemon->priv->map_device_file_to_device, device_went_away_remove_cb, where_the_object_was); + g_hash_table_foreach_remove (daemon->priv->map_dev_t_to_device, + device_went_away_remove_quiet_cb, + where_the_object_was); g_hash_table_foreach_remove (daemon->priv->map_native_path_to_device, device_went_away_remove_quiet_cb, where_the_object_was); @@ -755,6 +766,9 @@ device_add (DevkitDisksDaemon *daemon, DevkitDevice *d, gboolean emit_event) * dbus-glib, no cookie for you. */ g_object_weak_ref (G_OBJECT (device), device_went_away, daemon); + g_hash_table_insert (daemon->priv->map_dev_t_to_device, + GINT_TO_POINTER (devkit_disks_device_local_get_dev (device)), + device); g_hash_table_insert (daemon->priv->map_device_file_to_device, g_strdup (devkit_disks_device_local_get_device_file (device)), device); @@ -817,6 +831,12 @@ device_event_signal_handler (DevkitClient *client, } DevkitDisksDevice * +devkit_disks_daemon_local_find_by_dev (DevkitDisksDaemon *daemon, dev_t dev) +{ + return g_hash_table_lookup (daemon->priv->map_dev_t_to_device, GINT_TO_POINTER (dev)); +} + +DevkitDisksDevice * devkit_disks_daemon_local_find_by_device_file (DevkitDisksDaemon *daemon, const char *device_file) { return g_hash_table_lookup (daemon->priv->map_device_file_to_device, device_file); @@ -849,8 +869,8 @@ mount_removed (DevkitDisksMountMonitor *monitor, DevkitDisksDaemon *daemon = DEVKIT_DISKS_DAEMON (user_data); DevkitDisksDevice *device; - device = g_hash_table_lookup (daemon->priv->map_device_file_to_device, - devkit_disks_mount_get_device_file (mount)); + device = g_hash_table_lookup (daemon->priv->map_dev_t_to_device, + GINT_TO_POINTER (devkit_disks_mount_get_dev (mount))); if (device != NULL) { g_print ("**** UNMOUNTED %s\n", device->priv->native_path); devkit_disks_daemon_local_synthesize_changed (daemon, device); @@ -865,8 +885,8 @@ mount_added (DevkitDisksMountMonitor *monitor, DevkitDisksDaemon *daemon = DEVKIT_DISKS_DAEMON (user_data); DevkitDisksDevice *device; - device = g_hash_table_lookup (daemon->priv->map_device_file_to_device, - devkit_disks_mount_get_device_file (mount)); + device = g_hash_table_lookup (daemon->priv->map_dev_t_to_device, + GINT_TO_POINTER (devkit_disks_mount_get_dev (mount))); if (device != NULL) { g_print ("**** MOUNTED %s\n", device->priv->native_path); devkit_disks_daemon_local_synthesize_changed (daemon, device); diff --git a/src/devkit-disks-daemon.h b/src/devkit-disks-daemon.h index a31cc28..c29c6c4 100644 --- a/src/devkit-disks-daemon.h +++ b/src/devkit-disks-daemon.h @@ -98,6 +98,9 @@ DevkitDisksDevice *devkit_disks_daemon_local_find_by_object_path (DevkitDisksDae DevkitDisksDevice *devkit_disks_daemon_local_find_by_device_file (DevkitDisksDaemon *daemon, const char *device_file); +DevkitDisksDevice *devkit_disks_daemon_local_find_by_dev (DevkitDisksDaemon *daemon, + dev_t dev); + PolKitCaller *devkit_disks_damon_local_get_caller_for_context (DevkitDisksDaemon *daemon, DBusGMethodInvocation *context); diff --git a/src/devkit-disks-device-private.h b/src/devkit-disks-device-private.h index 78f83f7..e84b80c 100644 --- a/src/devkit-disks-device-private.h +++ b/src/devkit-disks-device-private.h @@ -88,6 +88,8 @@ struct DevkitDisksDevicePrivate /* if non-zero, the id of the idle for emitting a 'change' signal */ guint emit_changed_idle_id; + dev_t dev; /* not exported */ + /**************/ /* properties */ /*************/ diff --git a/src/devkit-disks-device.c b/src/devkit-disks-device.c index 7c45806..bd2ec7f 100644 --- a/src/devkit-disks-device.c +++ b/src/devkit-disks-device.c @@ -2643,7 +2643,7 @@ update_info_mount_state (DevkitDisksDevice *device) goto out; monitor = devkit_disks_daemon_local_get_mount_monitor (device->priv->daemon); - mount = devkit_disks_mount_monitor_get_mount_for_device_file (monitor, device->priv->device_file); + mount = devkit_disks_mount_monitor_get_mount_for_dev (monitor, device->priv->dev); was_mounted = device->priv->device_is_mounted; old_mount_path = g_strdup (device->priv->device_mount_path); @@ -2762,6 +2762,8 @@ update_info (DevkitDisksDevice *device) GPtrArray *symlinks_by_path; GPtrArray *slaves; GPtrArray *holders; + gint major; + gint minor; ret = FALSE; @@ -2780,6 +2782,16 @@ update_info (DevkitDisksDevice *device) devkit_disks_device_set_device_is_drive (device, FALSE); } + if (!devkit_device_has_property (device->priv->d, "MAJOR") || + !devkit_device_has_property (device->priv->d, "MINOR")) { + g_warning ("No major/minor for %s", device->priv->native_path); + goto out; + } + + major = devkit_device_get_property_as_int (device->priv->d, "MAJOR"); + minor = devkit_device_get_property_as_int (device->priv->d, "MINOR"); + device->priv->dev = makedev (major, minor); + devkit_disks_device_set_device_file (device, devkit_device_get_device_file (device->priv->d)); if (device->priv->device_file == NULL) { g_warning ("No device file for %s", device->priv->native_path); @@ -3347,6 +3359,12 @@ devkit_disks_device_local_get_native_path (DevkitDisksDevice *device) return device->priv->native_path; } +dev_t +devkit_disks_device_local_get_dev (DevkitDisksDevice *device) +{ + return device->priv->dev; +} + const char * devkit_disks_device_local_get_device_file (DevkitDisksDevice *device) { diff --git a/src/devkit-disks-device.h b/src/devkit-disks-device.h index 6470580..739ed1f 100644 --- a/src/devkit-disks-device.h +++ b/src/devkit-disks-device.h @@ -66,6 +66,7 @@ void devkit_disks_device_removed (DevkitDisksDevice const char *devkit_disks_device_local_get_object_path (DevkitDisksDevice *device); const char *devkit_disks_device_local_get_native_path (DevkitDisksDevice *device); +dev_t devkit_disks_device_local_get_dev (DevkitDisksDevice *device); const char *devkit_disks_device_local_get_device_file (DevkitDisksDevice *device); const char *devkit_disks_device_local_get_mount_path (DevkitDisksDevice *device); diff --git a/src/devkit-disks-mount-monitor.c b/src/devkit-disks-mount-monitor.c index 4dd0190..ff4722a 100644 --- a/src/devkit-disks-mount-monitor.c +++ b/src/devkit-disks-mount-monitor.c @@ -82,9 +82,9 @@ devkit_disks_mount_monitor_init (DevkitDisksMountMonitor *monitor) DEVKIT_DISKS_TYPE_MOUNT_MONITOR, DevkitDisksMountMonitorPrivate); - monitor->priv->mounts = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, + monitor->priv->mounts = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, g_object_unref); } @@ -262,79 +262,6 @@ out: return mount_monitor; } -static const char * -_resolve_dev_root (void) -{ - static gboolean have_real_dev_root = FALSE; - static char real_dev_root[256]; - struct stat statbuf; - - /* see if it's cached already */ - if (have_real_dev_root) - goto found; - - /* otherwise we're going to find it right away.. */ - have_real_dev_root = TRUE; - - if (stat ("/dev/root", &statbuf) == 0) { - if (! S_ISLNK (statbuf.st_mode)) { - dev_t root_dev = statbuf.st_dev; - FILE *f; - char buf[1024]; - - /* see if device with similar major:minor as /dev/root is mentioned - * in /etc/mtab (it usually is) - */ - f = fopen ("/etc/mtab", "r"); - if (f != NULL) { - struct mntent *entp; - struct mntent ent; - while ((entp = getmntent_r (f, &ent, buf, sizeof (buf))) != NULL) { - if (stat (entp->mnt_fsname, &statbuf) == 0 && - statbuf.st_dev == root_dev) { - strncpy (real_dev_root, entp->mnt_fsname, sizeof (real_dev_root) - 1); - real_dev_root[sizeof (real_dev_root) - 1] = '\0'; - fclose (f); - goto found; - } - } - endmntent (f); - } - /* no, that didn't work.. next we could scan /dev ... but I digress.. */ - } else { - char resolved[PATH_MAX]; - if (realpath ("/dev/root", resolved) != NULL) { - strncpy (real_dev_root, resolved, sizeof (real_dev_root) - 1); - real_dev_root[sizeof (real_dev_root) - 1] = '\0'; - goto found; - } - } - } - - /* bah sucks.. */ - strcpy (real_dev_root, "/dev/root"); -found: - return real_dev_root; -} - -/* device-mapper likes to create it's own device nodes a'la /dev/mapper/VolGroup00-LogVol00; - * this is pretty useless... So check the major/minor and map back to /dev/dm- - * if major==253. - */ -static char * -_check_lvm (const char *device_path) -{ - struct stat statbuf; - if (stat (device_path, &statbuf) == 0) { - if (major (statbuf.st_rdev) == 253) { - /* TODO: should check that /dev/dm-%d exists and has same major/minor */ - return g_strdup_printf ("/dev/dm-%d", minor (statbuf.st_rdev)); - } - } - - return NULL; -} - void devkit_disks_mount_monitor_invalidate (DevkitDisksMountMonitor *monitor) { @@ -358,37 +285,22 @@ devkit_disks_mount_monitor_ensure (DevkitDisksMountMonitor *monitor) } while ((m = getmntent (f)) != NULL) { DevkitDisksMount *mount; - const gchar *device_file; - gchar *s; - gchar real_path[PATH_MAX]; + struct stat statbuf; /* ignore if not an absolute patch */ if (m->mnt_fsname[0] != '/') continue; - /* canonicalize */ - realpath (m->mnt_fsname, real_path); - if (strcmp (real_path, "/dev/root") == 0) { - device_file = _resolve_dev_root (); - } else { - device_file = real_path; - } - - s = NULL; - if (g_str_has_prefix (device_file, "/dev/mapper/")) { - s = _check_lvm (m->mnt_fsname); - if (s != NULL) { - device_file = s; - } - } - - mount = _devkit_disks_mount_new (device_file, m->mnt_dir); + if (stat (m->mnt_fsname, &statbuf) != 0) { + g_warning ("Cannot stat %s: %m", m->mnt_fsname); + } else if (statbuf.st_rdev != 0) { - g_free (s); + mount = _devkit_disks_mount_new (statbuf.st_rdev, m->mnt_dir); - g_hash_table_insert (monitor->priv->mounts, - g_strdup (device_file), - mount); + g_hash_table_insert (monitor->priv->mounts, + GINT_TO_POINTER (statbuf.st_rdev), + mount); + } } fclose (f); @@ -399,10 +311,14 @@ out: } DevkitDisksMount * -devkit_disks_mount_monitor_get_mount_for_device_file (DevkitDisksMountMonitor *monitor, - const gchar *device_file) +devkit_disks_mount_monitor_get_mount_for_dev (DevkitDisksMountMonitor *monitor, + dev_t dev) { + DevkitDisksMount *ret; + devkit_disks_mount_monitor_ensure (monitor); - return g_hash_table_lookup (monitor->priv->mounts, device_file); + ret = g_hash_table_lookup (monitor->priv->mounts, GINT_TO_POINTER (dev)); + + return ret; } diff --git a/src/devkit-disks-mount-monitor.h b/src/devkit-disks-mount-monitor.h index c931431..ac9a9ee 100644 --- a/src/devkit-disks-mount-monitor.h +++ b/src/devkit-disks-mount-monitor.h @@ -48,8 +48,8 @@ struct DevkitDisksMountMonitorClass GType devkit_disks_mount_monitor_get_type (void) G_GNUC_CONST; DevkitDisksMountMonitor *devkit_disks_mount_monitor_new (void); -DevkitDisksMount *devkit_disks_mount_monitor_get_mount_for_device_file (DevkitDisksMountMonitor *monitor, - const gchar *device_file); +DevkitDisksMount *devkit_disks_mount_monitor_get_mount_for_dev (DevkitDisksMountMonitor *monitor, + dev_t dev); void devkit_disks_mount_monitor_invalidate (DevkitDisksMountMonitor *monitor); G_END_DECLS diff --git a/src/devkit-disks-mount.c b/src/devkit-disks-mount.c index c283c5e..3f71375 100644 --- a/src/devkit-disks-mount.c +++ b/src/devkit-disks-mount.c @@ -43,7 +43,7 @@ struct DevkitDisksMountPrivate { gchar *mount_path; - gchar *device_file; + dev_t dev; }; G_DEFINE_TYPE (DevkitDisksMount, devkit_disks_mount, G_TYPE_OBJECT) @@ -56,7 +56,6 @@ devkit_disks_mount_finalize (GObject *object) DevkitDisksMount *mount = DEVKIT_DISKS_MOUNT (object); g_free (mount->priv->mount_path); - g_free (mount->priv->device_file); if (G_OBJECT_CLASS (devkit_disks_mount_parent_class)->finalize) (* G_OBJECT_CLASS (devkit_disks_mount_parent_class)->finalize) (object); @@ -80,12 +79,12 @@ devkit_disks_mount_class_init (DevkitDisksMountClass *klass) DevkitDisksMount * -_devkit_disks_mount_new (const gchar *device_file, const gchar *mount_path) +_devkit_disks_mount_new (dev_t dev, const gchar *mount_path) { DevkitDisksMount *mount; mount = DEVKIT_DISKS_MOUNT (g_object_new (DEVKIT_DISKS_TYPE_MOUNT, NULL)); - mount->priv->device_file = g_strdup (device_file); + mount->priv->dev = dev; mount->priv->mount_path = g_strdup (mount_path); return mount; @@ -98,11 +97,11 @@ devkit_disks_mount_get_mount_path (DevkitDisksMount *mount) return mount->priv->mount_path; } -const gchar * -devkit_disks_mount_get_device_file (DevkitDisksMount *mount) +dev_t +devkit_disks_mount_get_dev (DevkitDisksMount *mount) { - g_return_val_if_fail (DEVKIT_DISKS_IS_MOUNT (mount), NULL); - return mount->priv->device_file; + g_return_val_if_fail (DEVKIT_DISKS_IS_MOUNT (mount), 0); + return mount->priv->dev; } gint @@ -115,7 +114,7 @@ devkit_disks_mount_compare (DevkitDisksMount *a, if (ret != 0) goto out; - ret = g_strcmp0 (a->priv->device_file, b->priv->device_file); + ret = (a->priv->dev - b->priv->dev); out: return ret; diff --git a/src/devkit-disks-mount.h b/src/devkit-disks-mount.h index f8fc2c9..e6bc1d0 100644 --- a/src/devkit-disks-mount.h +++ b/src/devkit-disks-mount.h @@ -21,6 +21,8 @@ #ifndef __DEVKIT_DISKS_MOUNT_H__ #define __DEVKIT_DISKS_MOUNT_H__ +#include + #include "devkit-disks-types.h" G_BEGIN_DECLS @@ -48,7 +50,7 @@ struct DevkitDisksMountClass GType devkit_disks_mount_get_type (void) G_GNUC_CONST; const gchar *devkit_disks_mount_get_mount_path (DevkitDisksMount *mount); -const gchar *devkit_disks_mount_get_device_file (DevkitDisksMount *mount); +dev_t devkit_disks_mount_get_dev (DevkitDisksMount *mount); gint devkit_disks_mount_compare (DevkitDisksMount *a, DevkitDisksMount *b); diff --git a/src/devkit-disks-private.h b/src/devkit-disks-private.h index c746ae0..c528eda 100644 --- a/src/devkit-disks-private.h +++ b/src/devkit-disks-private.h @@ -25,7 +25,8 @@ G_BEGIN_DECLS -DevkitDisksMount *_devkit_disks_mount_new (const gchar *device_file, const gchar *mount_path); +DevkitDisksMount *_devkit_disks_mount_new (dev_t dev, + const gchar *mount_path); G_END_DECLS