static void update_mounts (GUnixVolumeMonitor *monitor) { GList *new_mounts; GList *removed, *added; GList *l; GUnixMount *mount; GUnixVolume *volume; const char *mount_path; new_mounts = g_unix_mounts_get (NULL); new_mounts = g_list_sort (new_mounts, (GCompareFunc) g_unix_mount_compare); diff_sorted_lists (monitor->last_mounts, new_mounts, (GCompareFunc) g_unix_mount_compare, &added, &removed); for (l = removed; l != NULL; l = l->next) { GUnixMountEntry *mount_entry = l->data; mount = find_mount_by_mountpath (monitor, g_unix_mount_get_mount_path (mount_entry)); if (mount) { _g_unix_mount_unmounted (mount); monitor->mounts = g_list_remove (monitor->mounts, mount); g_signal_emit_by_name (monitor, "mount-removed", mount); g_signal_emit_by_name (mount, "unmounted"); g_object_unref (mount); } } for (l = added; l != NULL; l = l->next) { GUnixMountEntry *mount_entry = l->data; mount_path = g_unix_mount_get_mount_path (mount_entry); volume = _g_unix_volume_monitor_lookup_volume_for_mount_path (monitor, mount_path); mount = _g_unix_mount_new (G_VOLUME_MONITOR (monitor), mount_entry, volume); if (mount) { monitor->mounts = g_list_prepend (monitor->mounts, mount); g_signal_emit_by_name (monitor, "mount-added", mount); } } g_list_free (added); g_list_free (removed); g_list_foreach (monitor->last_mounts, (GFunc)g_unix_mount_free, NULL); g_list_free (monitor->last_mounts); monitor->last_mounts = new_mounts; }
static VALUE unixmounts_get(G_GNUC_UNUSED VALUE self) { guint64 time_read; GList *mounts; mounts = g_unix_mounts_get(&time_read); return rb_assoc_new(GLIST2ARY_STR_FREE(mounts), GUINT642RVAL(time_read)); }
static void ldsm_mounts_changed (GObject *monitor, gpointer data) { GList *mounts; /* remove the saved data for mounts that got removed */ mounts = g_unix_mounts_get (time_read); g_hash_table_foreach_remove (ldsm_notified_hash, ldsm_is_hash_item_not_in_mounts, mounts); g_list_free_full (mounts, (GDestroyNotify) g_unix_mount_free); /* check the status now, for the new mounts */ ldsm_check_all_mounts (NULL); /* and reset the timeout */ if (ldsm_timeout_id) g_source_remove (ldsm_timeout_id); ldsm_timeout_id = g_timeout_add_seconds (CHECK_EVERY_X_SECONDS, ldsm_check_all_mounts, NULL); }
static RmMountEntries *rm_mount_list_open(RmMountTable *table) { RmMountEntries *self = g_slice_new(RmMountEntries); self->mnt_entries = g_unix_mounts_get(NULL); self->entries = NULL; self->current = NULL; for(GList *iter = self->mnt_entries; iter; iter = iter->next) { RmMountEntry *wrap_entry = g_slice_new(RmMountEntry); GUnixMountEntry *entry = iter->data; wrap_entry->fsname = g_strdup(g_unix_mount_get_device_path(entry)); wrap_entry->dir = g_strdup(g_unix_mount_get_mount_path(entry)); wrap_entry->type = g_strdup(g_unix_mount_get_fs_type(entry)); self->entries = g_list_prepend(self->entries, wrap_entry); } RmMountEntry *wrap_entry = NULL; while((wrap_entry = rm_mount_list_next(self))) { /* bindfs mounts mirror directory trees. * This cannot be detected properly by rmlint since * files in it have the same inode as their unmirrored file, but * a different dev_t. * * Also ignore kernel filesystems. * * So better go and ignore it. */ static struct RmEvilFs { /* fsname as show by `mount` */ const char *name; /* Wether to warn about the exclusion on this */ bool unusual; } evilfs_types[] = {{"bindfs", 1}, {"nullfs", 1}, /* Ignore the usual linux file system spam */ {"proc", 0}, {"cgroup", 0}, {"configfs", 0}, {"sys", 0}, {"devtmpfs", 0}, {"debugfs", 0}, {NULL, 0}}; /* btrfs and ocfs2 filesystems support reflinks for deduplication */ static const char *reflinkfs_types[] = {"btrfs", "ocfs2", NULL}; const struct RmEvilFs *evilfs_found = NULL; for(int i = 0; evilfs_types[i].name && !evilfs_found; ++i) { if(strcmp(evilfs_types[i].name, wrap_entry->type) == 0) { evilfs_found = &evilfs_types[i]; } } const char *reflinkfs_found = NULL; for(int i = 0; reflinkfs_types[i] && !reflinkfs_found; ++i) { if(strcmp(reflinkfs_types[i], wrap_entry->type) == 0) { reflinkfs_found = reflinkfs_types[i]; break; } } if(evilfs_found != NULL) { RmStat dir_stat; rm_sys_stat(wrap_entry->dir, &dir_stat); g_hash_table_insert(table->evilfs_table, GUINT_TO_POINTER(dir_stat.st_dev), GUINT_TO_POINTER(1)); GLogLevelFlags log_level = G_LOG_LEVEL_DEBUG; if(evilfs_found->unusual) { log_level = G_LOG_LEVEL_WARNING; rm_log_warning_prefix(); } else { rm_log_debug_prefix(); } g_log("rmlint", log_level, _("`%s` mount detected at %s (#%u); Ignoring all files in it.\n"), evilfs_found->name, wrap_entry->dir, (unsigned)dir_stat.st_dev); } rm_log_debug_line("Filesystem %s: %s", wrap_entry->dir, (reflinkfs_found) ? "reflink" : "normal"); if(reflinkfs_found != NULL) { RmStat dir_stat; rm_sys_stat(wrap_entry->dir, &dir_stat); g_hash_table_insert(table->reflinkfs_table, GUINT_TO_POINTER(dir_stat.st_dev), (gpointer)reflinkfs_found); } } return self; }