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