]> git.ipfire.org Git - thirdparty/util-linux.git/blob - misc-utils/lsblk-mnt.c
Fix misspellings
[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 "lsblk.h"
7
8 static struct libmnt_table *mtab, *swaps;
9 static struct libmnt_cache *mntcache;
10
11 static int table_parser_errcb(struct libmnt_table *tb __attribute__((__unused__)),
12 const char *filename, int line)
13 {
14 if (filename)
15 warnx(_("%s: parse error at line %d -- ignored"), filename, line);
16 return 1;
17 }
18
19 static struct libmnt_fs *get_active_swap(const char *filename)
20 {
21 assert(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);
43 }
44
45 void lsblk_device_free_filesystems(struct lsblk_device *dev)
46 {
47 if (!dev)
48 return;
49
50 free(dev->fss);
51
52 dev->fss = NULL;
53 dev->nfss = 0;
54 dev->is_mounted = 0;
55 dev->is_swap = 0;
56 }
57
58 static void add_filesystem(struct lsblk_device *dev, struct libmnt_fs *fs)
59 {
60 assert(dev);
61 assert(fs);
62
63 dev->fss = xrealloc(dev->fss, (dev->nfss + 1)
64 * sizeof(struct libmnt_fs *));
65 dev->fss[dev->nfss] = fs;
66 dev->nfss++;
67 dev->is_mounted = 1;
68 }
69
70 struct libmnt_fs **lsblk_device_get_filesystems(struct lsblk_device *dev, size_t *n)
71 {
72 struct libmnt_fs *fs;
73 struct libmnt_iter *itr = NULL;
74 dev_t devno;
75
76 assert(dev);
77 assert(dev->filename);
78
79 if (dev->is_mounted)
80 goto done;
81
82 lsblk_device_free_filesystems(dev); /* reset */
83
84 if (!mtab) {
85 mtab = mnt_new_table();
86 if (!mtab)
87 return NULL;
88 if (!mntcache)
89 mntcache = mnt_new_cache();
90
91 mnt_table_set_parser_errcb(mtab, table_parser_errcb);
92 mnt_table_set_cache(mtab, mntcache);
93
94 if (!lsblk->sysroot)
95 mnt_table_parse_mtab(mtab, NULL);
96 else {
97 char buf[PATH_MAX];
98 snprintf(buf, sizeof(buf), "%s" _PATH_PROC_MOUNTINFO, lsblk->sysroot);
99 mnt_table_parse_mtab(mtab, buf);
100 }
101 }
102
103 devno = makedev(dev->maj, dev->min);
104
105 /* All mounpoint where is used devno or device name
106 */
107 itr = mnt_new_iter(MNT_ITER_BACKWARD);
108 while (mnt_table_next_fs(mtab, itr, &fs) == 0) {
109 if (mnt_fs_get_devno(fs) != devno &&
110 !mnt_fs_streq_srcpath(fs, dev->filename))
111 continue;
112 add_filesystem(dev, fs);
113 }
114
115 /* Try mnt_table_find_srcpath() which also canonicalizes patches, etc.
116 */
117 if (!dev->nfss) {
118 fs = get_active_swap(dev->filename);
119 if (!fs) {
120 fs = mnt_table_find_srcpath(mtab, dev->filename, MNT_ITER_BACKWARD);
121 if (fs)
122 dev->is_swap = 1;
123 }
124 if (fs)
125 add_filesystem(dev, fs);
126 }
127
128 done:
129 mnt_free_iter(itr);
130 if (n)
131 *n = dev->nfss;
132 return dev->fss;
133 }
134
135 /* Returns mounpoint where the device is mounted. If the device is used for
136 * more filesystems (subvolumes, ...) than returns the "best" one.
137 */
138 const char *lsblk_device_get_mountpoint(struct lsblk_device *dev)
139 {
140 struct libmnt_fs *fs = NULL;
141 const char *root;
142
143 lsblk_device_get_filesystems(dev, NULL);
144 if (!dev->nfss)
145 return NULL;
146
147 /* lsblk_device_get_filesystems() scans mountinfo/swaps in backward
148 * order. It means the first in fss[] is the last mounted FS. Let's
149 * keep it as default */
150 fs = dev->fss[0];
151 root = mnt_fs_get_root(fs);
152
153 if (root && strcmp(root, "/") != 0) {
154 /* FS is subvolume (or subdirectory bind-mount). Try to get
155 * FS with "/" root */
156 size_t i;
157
158 for (i = 1; i < dev->nfss; i++) {
159 root = mnt_fs_get_root(dev->fss[i]);
160 if (!root || strcmp(root, "/") == 0) {
161 fs = dev->fss[i];
162 break;
163 }
164 }
165 }
166 if (mnt_fs_is_swaparea(fs))
167 return "[SWAP]";
168 return mnt_fs_get_target(fs);
169 }
170
171 void lsblk_mnt_init(void)
172 {
173 mnt_init_debug(0);
174 }
175
176 void lsblk_mnt_deinit(void)
177 {
178 mnt_unref_table(mtab);
179 mnt_unref_table(swaps);
180 mnt_unref_cache(mntcache);
181 }