diff options
author | Hyunjee Kim <hj0426.kim@samsung.com> | 2019-12-03 09:46:57 +0900 |
---|---|---|
committer | Hyunjee Kim <hj0426.kim@samsung.com> | 2019-12-03 09:46:57 +0900 |
commit | 2edc4beaf99a0eb139005443a9ed9ebad1d4cf5f (patch) | |
tree | 2f1062b20f87d04526d39be4fe68d55500bd45ab /gio/gunixmounts.c | |
parent | 199bcd7237c3abbe4c62cdc742a3396301de64c0 (diff) | |
download | glib-2edc4beaf99a0eb139005443a9ed9ebad1d4cf5f.tar.gz glib-2edc4beaf99a0eb139005443a9ed9ebad1d4cf5f.tar.bz2 glib-2edc4beaf99a0eb139005443a9ed9ebad1d4cf5f.zip |
Imported Upstream version 2.55.0
Diffstat (limited to 'gio/gunixmounts.c')
-rw-r--r-- | gio/gunixmounts.c | 147 |
1 files changed, 128 insertions, 19 deletions
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c index 8e32b4f1e..fc3712987 100644 --- a/gio/gunixmounts.c +++ b/gio/gunixmounts.c @@ -148,6 +148,7 @@ G_DEFINE_BOXED_TYPE (GUnixMountPoint, g_unix_mount_point, static GList *_g_get_unix_mounts (void); static GList *_g_get_unix_mount_points (void); +static gboolean proc_mounts_watch_is_running (void); static guint64 mount_poller_time = 0; @@ -280,35 +281,99 @@ g_unix_is_mount_path_system_internal (const char *mount_path) return FALSE; } -static gboolean -guess_system_internal (const char *mountpoint, - const char *fs, - const char *device) +/** + * g_unix_is_system_fs_type: + * @fs_type: a file system type, e.g. `procfs` or `tmpfs` + * + * Determines if @fs_type is considered a type of file system which is only + * used in implementation of the OS. This is primarily used for hiding + * mounted volumes that are intended as APIs for programs to read, and system + * administrators at a shell; rather than something that should, for example, + * appear in a GUI. For example, the Linux `/proc` filesystem. + * + * The list of file system types considered ‘system’ ones may change over time. + * + * Returns: %TRUE if @fs_type is considered an implementation detail of the OS. + * Since: 2.56 + */ +gboolean +g_unix_is_system_fs_type (const char *fs_type) { const char *ignore_fs[] = { + "adfs", + "afs", "auto", "autofs", + "autofs4", + "cgroup", + "cifs", + "configfs", + "cxfs", + "debugfs", "devfs", "devpts", + "devtmpfs", "ecryptfs", "fdescfs", + "fusectl", + "gfs", + "gfs2", + "gpfs", + "hugetlbfs", "kernfs", "linprocfs", + "linsysfs", + "lustre", + "lustre_lite", "mfs", + "mqueue", + "ncpfs", + "nfs", + "nfs4", + "nfsd", "nullfs", + "ocfs2", + "overlay", "proc", "procfs", + "pstore", "ptyfs", "rootfs", + "rpc_pipefs", + "securityfs", "selinuxfs", + "smbfs", "sysfs", "tmpfs", "usbfs", - "nfsd", - "rpc_pipefs", "zfs", NULL }; + + g_return_val_if_fail (fs_type != NULL && *fs_type != '\0', FALSE); + + return is_in (fs_type, ignore_fs); +} + +/** + * g_unix_is_system_device_path: + * @device_path: a device path, e.g. `/dev/loop0` or `nfsd` + * + * Determines if @device_path is considered a block device path which is only + * used in implementation of the OS. This is primarily used for hiding + * mounted volumes that are intended as APIs for programs to read, and system + * administrators at a shell; rather than something that should, for example, + * appear in a GUI. For example, the Linux `/proc` filesystem. + * + * The list of device paths considered ‘system’ ones may change over time. + * + * Returns: %TRUE if @device_path is considered an implementation detail of + * the OS. + * Since: 2.56 + */ +gboolean +g_unix_is_system_device_path (const char *device_path) +{ const char *ignore_devices[] = { "none", "sunrpc", @@ -318,11 +383,21 @@ guess_system_internal (const char *mountpoint, "/dev/vn", NULL }; - - if (is_in (fs, ignore_fs)) + + g_return_val_if_fail (device_path != NULL && *device_path != '\0', FALSE); + + return is_in (device_path, ignore_devices); +} + +static gboolean +guess_system_internal (const char *mountpoint, + const char *fs, + const char *device) +{ + if (g_unix_is_system_fs_type (fs)) return TRUE; - if (is_in (device, ignore_devices)) + if (g_unix_is_system_device_path (device)) return TRUE; if (g_unix_is_mount_path_system_internal (mountpoint)) @@ -430,7 +505,7 @@ _g_get_unix_mounts (void) mnt_free_iter (iter); out: - mnt_unref_table (table); + mnt_free_table (table); return g_list_reverse (return_list); } @@ -954,7 +1029,7 @@ _g_get_unix_mount_points (void) mnt_free_iter (iter); out: - mnt_unref_table (table); + mnt_free_table (table); return g_list_reverse (return_list); } @@ -1279,7 +1354,6 @@ _g_get_unix_mount_points (void) GList *return_list; #ifdef HAVE_SYS_SYSCTL_H int usermnt = 0; - size_t len = sizeof(usermnt); struct stat sb; #endif @@ -1290,10 +1364,15 @@ _g_get_unix_mount_points (void) #ifdef HAVE_SYS_SYSCTL_H #if defined(HAVE_SYSCTLBYNAME) - sysctlbyname ("vfs.usermount", &usermnt, &len, NULL, 0); + { + size_t len = sizeof(usermnt); + + sysctlbyname ("vfs.usermount", &usermnt, &len, NULL, 0); + } #elif defined(CTL_VFS) && defined(VFS_USERMOUNT) { int mib[2]; + size_t len = sizeof(usermnt); mib[0] = CTL_VFS; mib[1] = VFS_USERMOUNT; @@ -1302,6 +1381,7 @@ _g_get_unix_mount_points (void) #elif defined(CTL_KERN) && defined(KERN_USERMOUNT) { int mib[2]; + size_t len = sizeof(usermnt); mib[0] = CTL_KERN; mib[1] = KERN_USERMOUNT; @@ -1368,15 +1448,26 @@ get_mounts_timestamp (void) struct stat buf; monitor_file = get_mtab_monitor_file (); - if (monitor_file) + /* Don't return mtime for /proc/ files */ + if (monitor_file && !g_str_has_prefix (monitor_file, "/proc/")) { if (stat (monitor_file, &buf) == 0) return (guint64)buf.st_mtime; } - else + else if (proc_mounts_watch_is_running ()) { + /* it's being monitored by poll, so return mount_poller_time */ return mount_poller_time; } + else + { + /* Case of /proc/ file not being monitored - Be on the safe side and + * send a new timestamp to force g_unix_mounts_changed_since() to + * return TRUE so any application caches depending on it (like eg. + * the one in GIO) get invalidated and don't hold possibly outdated + * data - see Bug 787731 */ + return (guint64) g_get_monotonic_time (); + } return 0; } @@ -1566,6 +1657,13 @@ static GFileMonitor *mtab_monitor; static GSource *proc_mounts_watch_source; static GList *mount_poller_mounts; +static gboolean +proc_mounts_watch_is_running (void) +{ + return proc_mounts_watch_source != NULL && + !g_source_is_destroyed (proc_mounts_watch_source); +} + static void fstab_file_changed (GFileMonitor *monitor, GFile *file, @@ -1602,7 +1700,10 @@ proc_mounts_changed (GIOChannel *channel, gpointer user_data) { if (cond & G_IO_ERR) - g_context_specific_group_emit (&mount_monitor_group, signals[MOUNTS_CHANGED]); + { + mount_poller_time = (guint64) g_get_monotonic_time (); + g_context_specific_group_emit (&mount_monitor_group, signals[MOUNTS_CHANGED]); + } return TRUE; } @@ -1652,7 +1753,10 @@ mount_monitor_stop (void) } if (proc_mounts_watch_source != NULL) - g_source_destroy (proc_mounts_watch_source); + { + g_source_destroy (proc_mounts_watch_source); + proc_mounts_watch_source = NULL; + } if (mtab_monitor) { @@ -2049,9 +2153,14 @@ g_unix_mount_is_readonly (GUnixMountEntry *mount_entry) /** * g_unix_mount_is_system_internal: * @mount_entry: a #GUnixMount. + * + * Checks if a Unix mount is a system mount. This is the Boolean OR of + * g_unix_is_system_fs_type(), g_unix_is_system_device_path() and + * g_unix_is_mount_path_system_internal() on @mount_entry’s properties. * - * Checks if a unix mount is a system path. - * + * The definition of what a ‘system’ mount entry is may change over time as new + * file system types and device paths are ignored. + * * Returns: %TRUE if the unix mount is for a system path. */ gboolean |