backup: Wire up qemu full pull backup commands over QMP
[libvirt/ericb.git] / tests / virfilemock.c
blob6d1153dd9f4229e11665c95b19ba9e374cfb53f4
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 #if HAVE_LINUX_MAGIC_H
25 # include <linux/magic.h>
26 #endif
28 #include "virmock.h"
29 #include "virstring.h"
30 #include "viralloc.h"
32 #define VIR_FROM_THIS VIR_FROM_NONE
34 static FILE *(*real_setmntent)(const char *filename, const char *type);
35 static int (*real_statfs)(const char *path, struct statfs *buf);
36 static char *(*real_canonicalize_file_name)(const char *path);
39 static void
40 init_syms(void)
42 if (real_setmntent)
43 return;
45 VIR_MOCK_REAL_INIT(setmntent);
46 VIR_MOCK_REAL_INIT(statfs);
47 VIR_MOCK_REAL_INIT(canonicalize_file_name);
51 FILE *
52 setmntent(const char *filename, const char *type)
54 const char *mtab;
56 init_syms();
58 if ((mtab = getenv("LIBVIRT_MTAB")))
59 filename = mtab;
61 return real_setmntent(filename, type);
65 #ifndef NFS_SUPER_MAGIC
66 # define NFS_SUPER_MAGIC 0x6969
67 #endif
68 #ifndef OCFS2_SUPER_MAGIC
69 # define OCFS2_SUPER_MAGIC 0x7461636f
70 #endif
71 #ifndef GFS2_MAGIC
72 # define GFS2_MAGIC 0x01161970
73 #endif
74 #ifndef AFS_FS_MAGIC
75 # define AFS_FS_MAGIC 0x6B414653
76 #endif
77 #ifndef SMB_SUPER_MAGIC
78 # define SMB_SUPER_MAGIC 0x517B
79 #endif
80 #ifndef CIFS_SUPER_MAGIC
81 # define CIFS_SUPER_MAGIC 0xFF534D42
82 #endif
83 #ifndef HUGETLBFS_MAGIC
84 # define HUGETLBFS_MAGIC 0x958458f6
85 #endif
86 #ifndef FUSE_SUPER_MAGIC
87 # define FUSE_SUPER_MAGIC 0x65735546
88 #endif
89 #ifndef CEPH_SUPER_MAGIC
90 # define CEPH_SUPER_MAGIC 0x00c36400
91 #endif
92 #ifndef GPFS_SUPER_MAGIC
93 # define GPFS_SUPER_MAGIC 0x47504653
94 #endif
95 #ifndef QB_MAGIC
96 # define QB_MAGIC 0x51626d6e
97 #endif
100 static int
101 statfs_mock(const char *mtab,
102 const char *path,
103 struct statfs *buf)
105 FILE *f;
106 struct mntent mb;
107 char mntbuf[1024];
108 char *canonPath = NULL;
109 int ret = -1;
111 if (!(f = real_setmntent(mtab, "r"))) {
112 fprintf(stderr, "Unable to open %s", mtab);
113 return -1;
116 /* We don't need to do this in callers because real statfs(2)
117 * does that for us. However, in mocked implementation we
118 * need to do this. */
119 if (!(canonPath = canonicalize_file_name(path)))
120 return -1;
122 while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
123 int ftype;
125 if (STRNEQ(mb.mnt_dir, canonPath))
126 continue;
128 if (STREQ(mb.mnt_type, "nfs") ||
129 STREQ(mb.mnt_type, "nfs4")) {
130 ftype = NFS_SUPER_MAGIC;
131 } else if (STREQ(mb.mnt_type, "gfs2")||
132 STREQ(mb.mnt_type, "gfs2meta")) {
133 ftype = GFS2_MAGIC;
134 } else if (STREQ(mb.mnt_type, "ocfs2")) {
135 ftype = OCFS2_SUPER_MAGIC;
136 } else if (STREQ(mb.mnt_type, "afs")) {
137 ftype = AFS_FS_MAGIC;
138 } else if (STREQ(mb.mnt_type, "smb3")) {
139 ftype = SMB_SUPER_MAGIC;
140 } else if (STREQ(mb.mnt_type, "cifs")) {
141 ftype = CIFS_SUPER_MAGIC;
142 } else if (STRPREFIX(mb.mnt_type, "fuse")) {
143 ftype = FUSE_SUPER_MAGIC;
144 } else if (STRPREFIX(mb.mnt_type, "ceph")) {
145 ftype = CEPH_SUPER_MAGIC;
146 } else if (STRPREFIX(mb.mnt_type, "gpfs")) {
147 ftype = GPFS_SUPER_MAGIC;
148 } else {
149 /* Everything else is EXT4. We don't care really for other paths. */
150 ftype = EXT4_SUPER_MAGIC;
153 memset(buf, 0, sizeof(*buf));
154 /* We only care about f_type so far. */
155 buf->f_type = ftype;
156 ret = 0;
157 break;
160 endmntent(f);
161 VIR_FREE(canonPath);
162 return ret;
167 statfs(const char *path, struct statfs *buf)
169 const char *mtab;
171 init_syms();
173 if ((mtab = getenv("LIBVIRT_MTAB")))
174 return statfs_mock(mtab, path, buf);
176 return real_statfs(path, buf);
180 char *
181 canonicalize_file_name(const char *path)
184 init_syms();
186 if (getenv("LIBVIRT_MTAB")) {
187 const char *p;
188 char *ret;
190 if ((p = STRSKIP(path, "/some/symlink")))
191 ignore_value(virAsprintfQuiet(&ret, "/gluster%s", p));
192 else
193 ignore_value(VIR_STRDUP_QUIET(ret, path));
195 return ret;
198 return real_canonicalize_file_name(path);