1 /*
2 * virfile.h: safer file handling
3 *
4 * Copyright (C) 2010-2014 Red Hat, Inc.
5 * Copyright (C) 2010 IBM Corporation
6 * Copyright (C) 2010 Stefan Berger
7 * Copyright (C) 2010 Eric Blake
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library. If not, see
21 * <http://www.gnu.org/licenses/>.
22 *
23 */
24
25 #pragma once
26
27 #include <dirent.h>
28
29 #include "internal.h"
30 #include "virbitmap.h"
31 #include "virenum.h"
32
33 typedef enum {
34 VIR_FILE_CLOSE_PRESERVE_ERRNO = 1 << 0,
35 VIR_FILE_CLOSE_IGNORE_EBADF = 1 << 1,
36 VIR_FILE_CLOSE_DONT_LOG = 1 << 2,
37 } virFileCloseFlags;
38
39 #ifdef __APPLE__
40 # define VIR_FILE_MODULE_EXT ".dylib"
41 #else
42 # define VIR_FILE_MODULE_EXT ".so"
43 #endif
44
45 ssize_t saferead(int fd, void *buf, size_t count) G_GNUC_WARN_UNUSED_RESULT;
46 ssize_t safewrite(int fd, const void *buf, size_t count)
47 G_GNUC_WARN_UNUSED_RESULT;
48 int safezero(int fd, off_t offset, off_t len)
49 G_GNUC_WARN_UNUSED_RESULT;
50 int virFileAllocate(int fd, off_t offset, off_t len)
51 G_GNUC_WARN_UNUSED_RESULT;
52
53 /* Don't call these directly - use the macros below */
54 int virFileClose(int *fdptr, virFileCloseFlags flags)
55 G_GNUC_WARN_UNUSED_RESULT;
56 int virFileFclose(FILE **file, bool preserve_errno) G_GNUC_WARN_UNUSED_RESULT;
57 FILE *virFileFdopen(int *fdptr, const char *mode) G_GNUC_WARN_UNUSED_RESULT;
58
virForceCloseHelper(int * fd)59 static inline void virForceCloseHelper(int *fd)
60 {
61 ignore_value(virFileClose(fd, VIR_FILE_CLOSE_PRESERVE_ERRNO));
62 }
63
64 /* For use on normal paths; caller must check return value,
65 and failure sets errno per close. */
66 #define VIR_CLOSE(FD) virFileClose(&(FD), 0)
67 #define VIR_FCLOSE(FILE) virFileFclose(&(FILE), false)
68
69 /* Wrapper around fdopen that consumes fd on success. */
70 #define VIR_FDOPEN(FD, MODE) virFileFdopen(&(FD), MODE)
71
72 /* For use on cleanup paths; errno is unaffected by close,
73 and no return value to worry about. */
74 #define VIR_FORCE_CLOSE(FD) virForceCloseHelper(&(FD))
75 #define VIR_FORCE_FCLOSE(FILE) ignore_value(virFileFclose(&(FILE), true))
76
77 /* Similar VIR_FORCE_CLOSE() but ignores EBADF errors since they are expected
78 * during mass close after fork(). */
79 #define VIR_MASS_CLOSE(FD) \
80 ignore_value(virFileClose(&(FD), \
81 VIR_FILE_CLOSE_PRESERVE_ERRNO | \
82 VIR_FILE_CLOSE_IGNORE_EBADF))
83
84 #define VIR_LOG_CLOSE(FD) \
85 ignore_value(virFileClose(&(FD), \
86 VIR_FILE_CLOSE_PRESERVE_ERRNO | \
87 VIR_FILE_CLOSE_DONT_LOG))
88
89 /**
90 * VIR_AUTOCLOSE:
91 *
92 * Macro to automatically force close the fd by calling virForceCloseHelper
93 * when the fd goes out of scope. It's used to eliminate VIR_FORCE_CLOSE
94 * in cleanup sections.
95 */
96 #define VIR_AUTOCLOSE __attribute__((cleanup(virForceCloseHelper))) int
97
98 G_DEFINE_AUTOPTR_CLEANUP_FUNC(FILE, fclose);
99
100 /* Opaque type for managing a wrapper around a fd. */
101 struct _virFileWrapperFd;
102
103 typedef struct _virFileWrapperFd virFileWrapperFd;
104
105 int virFileDirectFdFlag(void);
106
107 typedef enum {
108 VIR_FILE_WRAPPER_BYPASS_CACHE = (1 << 0),
109 VIR_FILE_WRAPPER_NON_BLOCKING = (1 << 1),
110 } virFileWrapperFdFlags;
111
112 virFileWrapperFd *virFileWrapperFdNew(int *fd,
113 const char *name,
114 unsigned int flags)
115 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT;
116
117 int virFileWrapperFdClose(virFileWrapperFd *dfd);
118
119 void virFileWrapperFdFree(virFileWrapperFd *dfd);
120
121 int virFileLock(int fd, bool shared, off_t start, off_t len, bool waitForLock)
122 G_GNUC_NO_INLINE;
123 int virFileUnlock(int fd, off_t start, off_t len)
124 G_GNUC_NO_INLINE;
125
126 typedef int (*virFileRewriteFunc)(int fd, const void *opaque);
127 int virFileRewrite(const char *path,
128 mode_t mode,
129 virFileRewriteFunc rewrite,
130 const void *opaque);
131 int virFileRewriteStr(const char *path,
132 mode_t mode,
133 const char *str);
134
135 int virFileResize(const char *path,
136 unsigned long long capacity,
137 bool pre_allocate);
138
139 int virFileTouch(const char *path, mode_t mode);
140
141 int virFileUpdatePerm(const char *path,
142 mode_t mode_remove,
143 mode_t mode_add);
144
145 int virFileLoopDeviceAssociate(const char *file,
146 char **dev);
147
148 int virFileNBDDeviceAssociate(const char *file,
149 const char *fmtstr,
150 bool readonly,
151 char **dev);
152
153 int virFileDeleteTree(const char *dir);
154
155 int virFileReadHeaderFD(int fd, int maxlen, char **buf)
156 G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NONNULL(3);
157 int virFileReadHeaderQuiet(const char *path, int maxlen, char **buf)
158 G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
159 int virFileReadLimFD(int fd, int maxlen, char **buf)
160 G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NONNULL(3);
161 int virFileReadAll(const char *path, int maxlen, char **buf)
162 G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
163 int virFileReadAllQuiet(const char *path, int maxlen, char **buf)
164 G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
165 int virFileReadBufQuiet(const char *file, char *buf, int len)
166 G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
167
168 int virFileWriteStr(const char *path, const char *str, mode_t mode)
169 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT;
170
171 int virFileLinkPointsTo(const char *checkLink,
172 const char *checkDest)
173 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
174 int virFileRelLinkPointsTo(const char *directory,
175 const char *checkLink,
176 const char *checkDest)
177 ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
178
179 int virFileResolveLink(const char *linkpath,
180 char **resultpath) G_GNUC_WARN_UNUSED_RESULT;
181 int virFileResolveAllLinks(const char *linkpath,
182 char **resultpath) G_GNUC_WARN_UNUSED_RESULT;
183
184 int virFileIsLink(const char *linkpath)
185 ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT;
186
187 char *virFindFileInPath(const char *file)
188 G_GNUC_NO_INLINE;
189
190 char *virFileFindResource(const char *filename,
191 const char *builddir,
192 const char *installdir)
193 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
194 char *virFileFindResourceFull(const char *filename,
195 const char *prefix,
196 const char *suffix,
197 const char *builddir,
198 const char *installdir,
199 const char *envname)
200 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
201 void virFileActivateDirOverrideForProg(const char *argv0)
202 ATTRIBUTE_NONNULL(1);
203 void virFileActivateDirOverrideForLib(void);
204
205 off_t virFileLength(const char *path, int fd) ATTRIBUTE_NONNULL(1);
206 bool virFileIsDir (const char *file) ATTRIBUTE_NONNULL(1);
207 bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1) G_GNUC_NO_INLINE;
208 bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1);
209 bool virFileIsRegular(const char *file) ATTRIBUTE_NONNULL(1);
210
211 enum {
212 VIR_FILE_SHFS_NFS = (1 << 0),
213 VIR_FILE_SHFS_GFS2 = (1 << 1),
214 VIR_FILE_SHFS_OCFS = (1 << 2),
215 VIR_FILE_SHFS_AFS = (1 << 3),
216 VIR_FILE_SHFS_SMB = (1 << 4),
217 VIR_FILE_SHFS_CIFS = (1 << 5),
218 VIR_FILE_SHFS_CEPH = (1 << 6),
219 VIR_FILE_SHFS_GPFS = (1 << 7),
220 VIR_FILE_SHFS_QB = (1 << 8),
221 VIR_FILE_SHFS_ACFS = (1 << 9),
222 };
223
224 int virFileIsSharedFSType(const char *path, int fstypes) ATTRIBUTE_NONNULL(1);
225 int virFileIsSharedFS(const char *path) ATTRIBUTE_NONNULL(1);
226 int virFileIsClusterFS(const char *path) ATTRIBUTE_NONNULL(1);
227 int virFileIsMountPoint(const char *file) ATTRIBUTE_NONNULL(1);
228 int virFileIsCDROM(const char *path)
229 ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT;
230
231 int virFileGetMountSubtree(const char *mtabpath,
232 const char *prefix,
233 char ***mountsret,
234 size_t *nmountsret) G_GNUC_WARN_UNUSED_RESULT;
235 int virFileGetMountReverseSubtree(const char *mtabpath,
236 const char *prefix,
237 char ***mountsret,
238 size_t *nmountsret) G_GNUC_WARN_UNUSED_RESULT;
239
240 char *virFileSanitizePath(const char *path);
241 char *virFileCanonicalizePath(const char *path) G_GNUC_NO_INLINE;
242
243 enum {
244 VIR_FILE_OPEN_NONE = 0,
245 VIR_FILE_OPEN_NOFORK = (1 << 0),
246 VIR_FILE_OPEN_FORK = (1 << 1),
247 VIR_FILE_OPEN_FORCE_MODE = (1 << 2),
248 VIR_FILE_OPEN_FORCE_OWNER = (1 << 3),
249 };
250 int virFileAccessibleAs(const char *path, int mode,
251 uid_t uid, gid_t gid)
252 ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT;
253 int virFileOpenAs(const char *path, int openflags, mode_t mode,
254 uid_t uid, gid_t gid,
255 unsigned int flags)
256 ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT;
257 int virFileRemove(const char *path, uid_t uid, gid_t gid);
258
259 int virFileChownFiles(const char *name, uid_t uid, gid_t gid)
260 ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT;
261
262 enum {
263 VIR_DIR_CREATE_NONE = 0,
264 VIR_DIR_CREATE_AS_UID = (1 << 0),
265 VIR_DIR_CREATE_ALLOW_EXIST = (1 << 1),
266 };
267 int virDirCreate(const char *path, mode_t mode, uid_t uid, gid_t gid,
268 unsigned int flags) G_GNUC_WARN_UNUSED_RESULT;
269 int virDirOpen(DIR **dirp, const char *dirname)
270 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT;
271 int virDirOpenIfExists(DIR **dirp, const char *dirname)
272 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT;
273 int virDirOpenQuiet(DIR **dirp, const char *dirname)
274 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT;
275 int virDirRead(DIR *dirp, struct dirent **ent, const char *dirname)
276 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT;
277 void virDirClose(DIR *dirp);
278 G_DEFINE_AUTOPTR_CLEANUP_FUNC(DIR, virDirClose);
279
280 int virFileMakeParentPath(const char *path) G_GNUC_WARN_UNUSED_RESULT;
281
282 char *virFileBuildPath(const char *dir,
283 const char *name,
284 const char *ext) G_GNUC_WARN_UNUSED_RESULT;
285
286 void virFileRemoveLastComponent(char *path);
287
288 int virFileOpenTty(int *ttymaster,
289 char **ttyName,
290 int rawmode);
291
292 char *virFileFindMountPoint(const char *type);
293
294 /* NB: this should be combined with virFileBuildPath */
295 #define virBuildPath(path, ...) \
296 virBuildPathInternal(path, __VA_ARGS__, NULL)
297 void virBuildPathInternal(char **path, ...) G_GNUC_NULL_TERMINATED;
298
299 typedef struct _virHugeTLBFS virHugeTLBFS;
300 struct _virHugeTLBFS {
301 char *mnt_dir; /* Where the FS is mount to */
302 unsigned long long size; /* page size in kibibytes */
303 bool deflt; /* is this the default huge page size */
304 };
305
306 int virFileGetHugepageSize(const char *path,
307 unsigned long long *size);
308 int virFileFindHugeTLBFS(virHugeTLBFS **ret_fs,
309 size_t *ret_nfs);
310
311 virHugeTLBFS *virFileGetDefaultHugepage(virHugeTLBFS *fs,
312 size_t nfs);
313
314 int virFileSetupDev(const char *path,
315 const char *mount_options);
316
317 int virFileBindMountDevice(const char *src,
318 const char *dst);
319
320 int virFileMoveMount(const char *src,
321 const char *dst);
322
323 int virFileGetACLs(const char *file,
324 void **acl);
325
326 int virFileSetACLs(const char *file,
327 void *acl);
328
329 void virFileFreeACLs(void **acl);
330
331 int virFileCopyACLs(const char *src,
332 const char *dst);
333
334 int virFileComparePaths(const char *p1, const char *p2);
335
336 int virFileReadValueInt(int *value, const char *format, ...)
337 G_GNUC_PRINTF(2, 3);
338 int virFileReadValueUint(unsigned int *value, const char *format, ...)
339 G_GNUC_PRINTF(2, 3);
340 int virFileReadValueUllong(unsigned long long *value, const char *format, ...)
341 G_GNUC_PRINTF(2, 3);
342 int virFileReadValueUllongQuiet(unsigned long long *value, const char *format, ...)
343 G_GNUC_PRINTF(2, 3);
344 int virFileReadValueBitmap(virBitmap **value, const char *format, ...)
345 G_GNUC_PRINTF(2, 3);
346 int virFileReadValueScaledInt(unsigned long long *value, const char *format, ...)
347 G_GNUC_PRINTF(2, 3);
348 int virFileReadValueString(char **value, const char *format, ...)
349 G_GNUC_PRINTF(2, 3);
350
351 int virFileWaitForExists(const char *path, size_t ms, size_t tries);
352
353
354 int virFileInData(int fd,
355 int *inData,
356 long long *length);
357
358 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virFileWrapperFd, virFileWrapperFdFree);
359
360 int virFileGetXAttr(const char *path,
361 const char *name,
362 char **value)
363 G_GNUC_NO_INLINE;
364
365 int virFileGetXAttrQuiet(const char *path,
366 const char *name,
367 char **value)
368 G_GNUC_NO_INLINE;
369
370 int virFileSetXAttr(const char *path,
371 const char *name,
372 const char *value)
373 G_GNUC_NO_INLINE;
374
375 int virFileRemoveXAttr(const char *path,
376 const char *name)
377 G_GNUC_NO_INLINE;
378
379 int virFileDataSync(int fd);
380
381 int virFileSetCOW(const char *path,
382 virTristateBool state);
383