/** * mnt_fs_match_source: * @fs: filesystem * @source: tag or path (device or so) * @cache: tags/paths cache or NULL * * Possible are four attempts: * 1) compare @source with @fs->source * 2) compare realpath(@source) with @fs->source * 3) compare realpath(@source) with realpath(@fs->source) * 4) compare realpath(@source) with evaluated tag from @fs->source * * The 2nd, 3rd and 4th attempts are not performed when @cache is NULL. The * 2nd and 3rd attempts are not performed if @fs->source is tag. * * Returns: 1 if @fs source is equal to @source else 0. */ int mnt_fs_match_source(mnt_fs *fs, const char *source, mnt_cache *cache) { char *cn; const char *src, *t, *v; if (!fs || !source || !fs->source) return 0; /* 1) native paths/tags */ if (!strcmp(source, fs->source)) return 1; if (!cache) return 0; if (fs->flags & (MNT_FS_NET | MNT_FS_PSEUDO)) return 0; cn = mnt_resolve_spec(source, cache); if (!cn) return 0; /* 2) canonicalized and native */ src = mnt_fs_get_srcpath(fs); if (src && !strcmp(cn, src)) return 1; /* 3) canonicalized and canonicalized */ if (src) { src = mnt_resolve_path(src, cache); if (src && !strcmp(cn, src)) return 1; } if (src || mnt_fs_get_tag(fs, &t, &v)) /* src path does not match and tag is not defined */ return 0; /* read @source's tags to the cache */ if (mnt_cache_read_tags(cache, cn) < 0) { if (errno == EACCES) { /* we don't have permissions to read TAGs from * @source, but can translate @fs tag to devname. * * (because libblkid uses udev symlinks and this is * accessible for non-root uses) */ char *x = mnt_resolve_tag(t, v, cache); if (x && !strcmp(x, cn)) return 1; } return 0; } /* 4) has the @source a tag that matches with tag from @fs ? */ if (mnt_cache_device_has_tag(cache, cn, t, v)) return 1; return 0; }
/** * mnt_resolve_spec: * @spec: path or tag * @cache: paths cache * * Returns: canonicalized path or NULL. The result has to be * deallocated by free() if @cache is NULL. */ char *mnt_resolve_spec(const char *spec, struct libmnt_cache *cache) { char *cn = NULL; char *t = NULL, *v = NULL; if (!spec) return NULL; if (blkid_parse_tag_string(spec, &t, &v) == 0 && mnt_valid_tagname(t)) cn = mnt_resolve_tag(t, v, cache); else cn = mnt_resolve_path(spec, cache); free(t); free(v); return cn; }
/* * This function works like mnt_resolve_tag(), but it's able to read UUiD/LABEL * from regular swap files too (according to entries in /proc/swaps). Note that * mnt_resolve_tag() and mnt_resolve_spec() works with system visible block * devices only. */ static char *swapoff_resolve_tag(const char *name, const char *value, struct libmnt_cache *cache) { char *path; struct libmnt_table *tb; struct libmnt_iter *itr; struct libmnt_fs *fs; /* this is usual case for block devices (and it's really fast as it uses * udev /dev/disk/by-* symlinks by default */ path = mnt_resolve_tag(name, value, cache); if (path) return path; /* try regular files from /proc/swaps */ tb = get_swaps(); if (!tb) return NULL; itr = mnt_new_iter(MNT_ITER_BACKWARD); if (!itr) err(EXIT_FAILURE, _("failed to initialize libmount iterator")); while (tb && mnt_table_next_fs(tb, itr, &fs) == 0) { blkid_probe pr = NULL; const char *src = mnt_fs_get_source(fs); const char *type = mnt_fs_get_swaptype(fs); const char *data = NULL; if (!src || !type || strcmp(type, "file") != 0) continue; pr = get_swap_prober(src); if (!pr) continue; blkid_probe_lookup_value(pr, name, &data, NULL); if (data && strcmp(data, value) == 0) path = xstrdup(src); blkid_free_probe(pr); if (path) break; } mnt_free_iter(itr); return path; }
/** * mnt_resolve_spec: * @spec: path or tag * @cache: paths cache * * Returns: canonicalized path or NULL. The result has to be * deallocated by free() if @cache is NULL. */ char *mnt_resolve_spec(const char *spec, struct libmnt_cache *cache) { char *cn = NULL; if (!spec) return NULL; if (strchr(spec, '=')) { char *tag, *val; if (!blkid_parse_tag_string(spec, &tag, &val)) { cn = mnt_resolve_tag(tag, val, cache); free(tag); free(val); } } else cn = mnt_resolve_path(spec, cache); return cn; }