]> git.ipfire.org Git - thirdparty/util-linux.git/blob - misc-utils/lsblk-mnt.c
Merge branch 'uuidv7' of https://github.com/t-8ch/util-linux
[thirdparty/util-linux.git] / misc-utils / lsblk-mnt.c
1 #include "c.h"
2 #include "pathnames.h"
3 #include "xalloc.h"
4 #include "nls.h"
5
6 #include <libmount.h>
7
8 #include "lsblk.h"
9
10 static struct libmnt_table *mtab, *swaps;
11 static struct libmnt_cache *mntcache;
12
13 static int table_parser_errcb(struct libmnt_table *tb __attribute__((__unused__)),
14 const char *filename, int line)
15 {
16 if (filename)
17 warnx(_("%s: parse error at line %d -- ignored"), filename, line);
18 return 1;
19 }
20
21 static int is_active_swap(const char *filename)
22 {
23 if (!swaps) {
24 swaps = mnt_new_table();
25 if (!swaps)
26 return 0;
27 if (!mntcache)
28 mntcache = mnt_new_cache();
29
30 mnt_table_set_parser_errcb(swaps, table_parser_errcb);
31 mnt_table_set_cache(swaps, mntcache);
32
33 if (!lsblk->sysroot)
34 mnt_table_parse_swaps(swaps, NULL);
35 else {
36 char buf[PATH_MAX];
37 snprintf(buf, sizeof(buf), "%s" _PATH_PROC_SWAPS, lsblk->sysroot);
38 mnt_table_parse_swaps(swaps, buf);
39 }
40 }
41
42 return mnt_table_find_srcpath(swaps, filename, MNT_ITER_BACKWARD) != NULL;
43 }
44
45 char *lsblk_device_get_mountpoint(struct lsblk_device *dev)
46 {
47 struct libmnt_fs *fs;
48 const char *fsroot;
49
50 assert(dev);
51 assert(dev->filename);
52
53 if (dev->is_mounted || dev->is_swap)
54 return dev->mountpoint;
55
56 if (!mtab) {
57 mtab = mnt_new_table();
58 if (!mtab)
59 return NULL;
60 if (!mntcache)
61 mntcache = mnt_new_cache();
62
63 mnt_table_set_parser_errcb(mtab, table_parser_errcb);
64 mnt_table_set_cache(mtab, mntcache);
65
66 if (!lsblk->sysroot)
67 mnt_table_parse_mtab(mtab, NULL);
68 else {
69 char buf[PATH_MAX];
70 snprintf(buf, sizeof(buf), "%s" _PATH_PROC_MOUNTINFO, lsblk->sysroot);
71 mnt_table_parse_mtab(mtab, buf);
72 }
73 }
74
75 /* Note that maj:min in /proc/self/mountinfo does not have to match with
76 * devno as returned by stat(), so we have to try devname too
77 */
78 fs = mnt_table_find_devno(mtab, makedev(dev->maj, dev->min), MNT_ITER_BACKWARD);
79 if (!fs)
80 fs = mnt_table_find_srcpath(mtab, dev->filename, MNT_ITER_BACKWARD);
81 if (!fs) {
82 if (is_active_swap(dev->filename)) {
83 dev->mountpoint = xstrdup("[SWAP]");
84 dev->is_swap = 1;
85 } else
86 dev->mountpoint = NULL;
87
88 return dev->mountpoint;
89 }
90
91 /* found */
92 fsroot = mnt_fs_get_root(fs);
93 if (fsroot && strcmp(fsroot, "/") != 0) {
94 /* hmm.. we found bind mount or btrfs subvolume, let's try to
95 * get real FS root mountpoint */
96 struct libmnt_fs *rfs;
97 struct libmnt_iter *itr = mnt_new_iter(MNT_ITER_BACKWARD);
98
99 mnt_table_set_iter(mtab, itr, fs);
100 while (mnt_table_next_fs(mtab, itr, &rfs) == 0) {
101 fsroot = mnt_fs_get_root(rfs);
102 if ((!fsroot || strcmp(fsroot, "/") == 0)
103 && mnt_fs_match_source(rfs, dev->filename, mntcache)) {
104 fs = rfs;
105 break;
106 }
107 }
108 mnt_free_iter(itr);
109 }
110
111 DBG(DEV, ul_debugobj(dev, "mountpoint: %s", mnt_fs_get_target(fs)));
112 dev->mountpoint = xstrdup(mnt_fs_get_target(fs));
113 dev->is_mounted = 1;
114 return dev->mountpoint;
115 }
116
117 void lsblk_mnt_init(void)
118 {
119 mnt_init_debug(0);
120 }
121
122 void lsblk_mnt_deinit(void)
123 {
124 mnt_unref_table(mtab);
125 mnt_unref_table(swaps);
126 mnt_unref_cache(mntcache);
127 }