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