remote: add sysusers file to create 'libvirt' group
[libvirt.git] / tests / virfilemock.c
blob4f1b8aecd7d4dd59b77d7a41a4b0d9996b0e97fb
1 /*
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/>.
19 #include <config.h>
21 #include <stdio.h>
22 #include <mntent.h>
23 #include <sys/vfs.h>
24 #ifdef __linux__
25 # include <linux/magic.h>
26 #endif
28 #include "virmock.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);
37 static void
38 init_syms(void)
40 if (real_setmntent)
41 return;
43 VIR_MOCK_REAL_INIT(setmntent);
44 VIR_MOCK_REAL_INIT(statfs);
45 VIR_MOCK_REAL_INIT(realpath);
49 FILE *
50 setmntent(const char *filename, const char *type)
52 const char *mtab;
54 init_syms();
56 if ((mtab = getenv("LIBVIRT_MTAB")))
57 filename = mtab;
59 return real_setmntent(filename, type);
63 #ifndef NFS_SUPER_MAGIC
64 # define NFS_SUPER_MAGIC 0x6969
65 #endif
66 #ifndef OCFS2_SUPER_MAGIC
67 # define OCFS2_SUPER_MAGIC 0x7461636f
68 #endif
69 #ifndef GFS2_MAGIC
70 # define GFS2_MAGIC 0x01161970
71 #endif
72 #ifndef AFS_FS_MAGIC
73 # define AFS_FS_MAGIC 0x6B414653
74 #endif
75 #ifndef SMB_SUPER_MAGIC
76 # define SMB_SUPER_MAGIC 0x517B
77 #endif
78 #ifndef CIFS_SUPER_MAGIC
79 # define CIFS_SUPER_MAGIC 0xFF534D42
80 #endif
81 #ifndef HUGETLBFS_MAGIC
82 # define HUGETLBFS_MAGIC 0x958458f6
83 #endif
84 #ifndef FUSE_SUPER_MAGIC
85 # define FUSE_SUPER_MAGIC 0x65735546
86 #endif
87 #ifndef CEPH_SUPER_MAGIC
88 # define CEPH_SUPER_MAGIC 0x00c36400
89 #endif
90 #ifndef GPFS_SUPER_MAGIC
91 # define GPFS_SUPER_MAGIC 0x47504653
92 #endif
93 #ifndef QB_MAGIC
94 # define QB_MAGIC 0x51626d6e
95 #endif
98 static int
99 statfs_mock(const char *mtab,
100 const char *path,
101 struct statfs *buf)
103 FILE *f;
104 struct mntent mb;
105 char mntbuf[1024];
106 g_autofree char *canonPath = NULL;
107 int ret = -1;
109 if (!(f = real_setmntent(mtab, "r"))) {
110 fprintf(stderr, "Unable to open %s", mtab);
111 return -1;
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)))
118 return -1;
120 while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
121 int ftype;
123 if (STRNEQ(mb.mnt_dir, canonPath))
124 continue;
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")) {
131 ftype = GFS2_MAGIC;
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;
146 } else {
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. */
153 buf->f_type = ftype;
154 ret = 0;
155 break;
158 endmntent(f);
159 return ret;
164 statfs(const char *path, struct statfs *buf)
166 const char *mtab;
168 init_syms();
170 if ((mtab = getenv("LIBVIRT_MTAB")))
171 return statfs_mock(mtab, path, buf);
173 return real_statfs(path, buf);
177 char *
178 realpath(const char *path, char *resolved)
181 init_syms();
183 if (getenv("LIBVIRT_MTAB")) {
184 const char *p;
186 if ((p = STRSKIP(path, "/some/symlink"))) {
187 if (resolved)
188 g_snprintf(resolved, PATH_MAX, "/gluster%s", p);
189 else
190 resolved = g_strdup_printf("/gluster%s", p);
191 } else {
192 if (resolved)
193 g_strlcpy(resolved, path, PATH_MAX);
194 else
195 resolved = g_strdup(path);
198 return resolved;
201 return real_realpath(path, resolved);