2 * Copyright (C) 2018 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
25 # include <linux/magic.h>
30 #define VIR_FROM_THIS VIR_FROM_NONE
32 static FILE *(*real_setmntent
)(const char *filename
, const char *type
);
33 static int (*real_statfs
)(const char *path
, struct statfs
*buf
);
34 static char *(*real_realpath
)(const char *path
, char *resolved
);
43 VIR_MOCK_REAL_INIT(setmntent
);
44 VIR_MOCK_REAL_INIT(statfs
);
45 VIR_MOCK_REAL_INIT(realpath
);
50 setmntent(const char *filename
, const char *type
)
56 if ((mtab
= getenv("LIBVIRT_MTAB")))
59 return real_setmntent(filename
, type
);
63 #ifndef NFS_SUPER_MAGIC
64 # define NFS_SUPER_MAGIC 0x6969
66 #ifndef OCFS2_SUPER_MAGIC
67 # define OCFS2_SUPER_MAGIC 0x7461636f
70 # define GFS2_MAGIC 0x01161970
73 # define AFS_FS_MAGIC 0x6B414653
75 #ifndef SMB_SUPER_MAGIC
76 # define SMB_SUPER_MAGIC 0x517B
78 #ifndef CIFS_SUPER_MAGIC
79 # define CIFS_SUPER_MAGIC 0xFF534D42
81 #ifndef HUGETLBFS_MAGIC
82 # define HUGETLBFS_MAGIC 0x958458f6
84 #ifndef FUSE_SUPER_MAGIC
85 # define FUSE_SUPER_MAGIC 0x65735546
87 #ifndef CEPH_SUPER_MAGIC
88 # define CEPH_SUPER_MAGIC 0x00c36400
90 #ifndef GPFS_SUPER_MAGIC
91 # define GPFS_SUPER_MAGIC 0x47504653
94 # define QB_MAGIC 0x51626d6e
99 statfs_mock(const char *mtab
,
106 g_autofree
char *canonPath
= NULL
;
109 if (!(f
= real_setmntent(mtab
, "r"))) {
110 fprintf(stderr
, "Unable to open %s", mtab
);
114 /* We don't need to do this in callers because real statfs(2)
115 * does that for us. However, in mocked implementation we
116 * need to do this. */
117 if (!(canonPath
= realpath(path
, NULL
)))
120 while (getmntent_r(f
, &mb
, mntbuf
, sizeof(mntbuf
))) {
123 if (STRNEQ(mb
.mnt_dir
, canonPath
))
126 if (STREQ(mb
.mnt_type
, "nfs") ||
127 STREQ(mb
.mnt_type
, "nfs4")) {
128 ftype
= NFS_SUPER_MAGIC
;
129 } else if (STREQ(mb
.mnt_type
, "gfs2")||
130 STREQ(mb
.mnt_type
, "gfs2meta")) {
132 } else if (STREQ(mb
.mnt_type
, "ocfs2")) {
133 ftype
= OCFS2_SUPER_MAGIC
;
134 } else if (STREQ(mb
.mnt_type
, "afs")) {
135 ftype
= AFS_FS_MAGIC
;
136 } else if (STREQ(mb
.mnt_type
, "smb3")) {
137 ftype
= SMB_SUPER_MAGIC
;
138 } else if (STREQ(mb
.mnt_type
, "cifs")) {
139 ftype
= CIFS_SUPER_MAGIC
;
140 } else if (STRPREFIX(mb
.mnt_type
, "fuse")) {
141 ftype
= FUSE_SUPER_MAGIC
;
142 } else if (STRPREFIX(mb
.mnt_type
, "ceph")) {
143 ftype
= CEPH_SUPER_MAGIC
;
144 } else if (STRPREFIX(mb
.mnt_type
, "gpfs")) {
145 ftype
= GPFS_SUPER_MAGIC
;
147 /* Everything else is EXT4. We don't care really for other paths. */
148 ftype
= EXT4_SUPER_MAGIC
;
151 memset(buf
, 0, sizeof(*buf
));
152 /* We only care about f_type so far. */
164 statfs(const char *path
, struct statfs
*buf
)
170 if ((mtab
= getenv("LIBVIRT_MTAB")))
171 return statfs_mock(mtab
, path
, buf
);
173 return real_statfs(path
, buf
);
178 realpath(const char *path
, char *resolved
)
183 if (getenv("LIBVIRT_MTAB")) {
186 if ((p
= STRSKIP(path
, "/some/symlink"))) {
188 g_snprintf(resolved
, PATH_MAX
, "/gluster%s", p
);
190 resolved
= g_strdup_printf("/gluster%s", p
);
193 g_strlcpy(resolved
, path
, PATH_MAX
);
195 resolved
= g_strdup(path
);
201 return real_realpath(path
, resolved
);