1 /*
2  * virfile.c: 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 #include <config.h>
26 #include "internal.h"
27 
28 #include <fcntl.h>
29 #ifndef WIN32
30 # include <termios.h>
31 #endif
32 #ifdef WITH_PTY_H
33 /* Linux openpty */
34 # include <pty.h>
35 #endif
36 #ifdef WITH_UTIL_H
37 /* macOS openpty */
38 # include <util.h>
39 #endif
40 #ifdef WITH_LIBUTIL_H
41 /* FreeBSD openpty */
42 # include <libutil.h>
43 #endif
44 #include <sys/stat.h>
45 #if defined(WITH_SYS_MOUNT_H)
46 # include <sys/mount.h>
47 #endif
48 #include <unistd.h>
49 #include <dirent.h>
50 #if defined WITH_MNTENT_H && defined WITH_GETMNTENT_R
51 # include <mntent.h>
52 #endif
53 #if WITH_MMAP
54 # include <sys/mman.h>
55 #endif
56 #if WITH_SYS_SYSCALL_H
57 # include <sys/syscall.h>
58 #endif
59 #if WITH_LIBACL
60 # include <sys/acl.h>
61 #endif
62 #include <sys/file.h>
63 
64 #ifdef __linux__
65 # if WITH_LINUX_MAGIC_H
66 #  include <linux/magic.h>
67 # endif
68 # include <sys/statfs.h>
69 # if WITH_DECL_LO_FLAGS_AUTOCLEAR
70 #  include <linux/loop.h>
71 # endif
72 # include <sys/ioctl.h>
73 # include <linux/cdrom.h>
74 # include <linux/fs.h>
75 #endif
76 
77 #if WITH_LIBATTR
78 # include <sys/xattr.h>
79 #endif
80 
81 #include "configmake.h"
82 #include "viralloc.h"
83 #include "vircommand.h"
84 #include "virerror.h"
85 #include "virfile.h"
86 #include "virkmod.h"
87 #include "virlog.h"
88 #include "virprocess.h"
89 #include "virstring.h"
90 #include "virutil.h"
91 #include "virsocket.h"
92 
93 #define VIR_FROM_THIS VIR_FROM_NONE
94 
95 VIR_LOG_INIT("util.file");
96 
97 #ifndef S_ISUID
98 # define S_ISUID 04000
99 #endif
100 #ifndef S_ISGID
101 # define S_ISGID 02000
102 #endif
103 #ifndef S_ISVTX
104 # define S_ISVTX 01000
105 #endif
106 
107 
108 #ifndef O_DIRECT
109 # define O_DIRECT 0
110 #endif
111 
virFileClose(int * fdptr,virFileCloseFlags flags)112 int virFileClose(int *fdptr, virFileCloseFlags flags)
113 {
114     int saved_errno = 0;
115     int rc = 0;
116 
117     if (*fdptr < 0)
118         return 0;
119 
120     if (flags & VIR_FILE_CLOSE_PRESERVE_ERRNO)
121         saved_errno = errno;
122 
123     rc = close(*fdptr);
124 
125     if (!(flags & VIR_FILE_CLOSE_DONT_LOG)) {
126         if (rc < 0) {
127             if (errno == EBADF) {
128                 if (!(flags & VIR_FILE_CLOSE_IGNORE_EBADF))
129                     VIR_WARN("Tried to close invalid fd %d", *fdptr);
130             } else {
131                 VIR_DEBUG("Failed to close fd %d: %s",
132                           *fdptr, g_strerror(errno));
133             }
134         }
135     }
136     *fdptr = -1;
137 
138     if (flags & VIR_FILE_CLOSE_PRESERVE_ERRNO)
139         errno = saved_errno;
140 
141     return rc;
142 }
143 
144 
virFileFclose(FILE ** file,bool preserve_errno)145 int virFileFclose(FILE **file, bool preserve_errno)
146 {
147     int saved_errno = 0;
148     int rc = 0;
149 
150     if (*file) {
151         if (preserve_errno)
152             saved_errno = errno;
153         rc = fclose(*file);
154         *file = NULL;
155         if (preserve_errno)
156             errno = saved_errno;
157     }
158 
159     return rc;
160 }
161 
162 
virFileFdopen(int * fdptr,const char * mode)163 FILE *virFileFdopen(int *fdptr, const char *mode)
164 {
165     FILE *file = NULL;
166 
167     if (*fdptr >= 0) {
168         file = fdopen(*fdptr, mode);
169         if (file)
170             *fdptr = -1;
171     } else {
172         errno = EBADF;
173     }
174 
175     return file;
176 }
177 
178 
179 /**
180  * virFileDirectFdFlag:
181  *
182  * Returns 0 if the kernel can avoid file system cache pollution
183  * without any additional flags, O_DIRECT if the original fd must be
184  * opened in direct mode, or -1 if there is no support for bypassing
185  * the file system cache.
186  */
187 int
virFileDirectFdFlag(void)188 virFileDirectFdFlag(void)
189 {
190     /* XXX For now, Linux posix_fadvise is not powerful enough to
191      * avoid O_DIRECT.  */
192     return O_DIRECT ? O_DIRECT : -1;
193 }
194 
195 /* Opaque type for managing a wrapper around a fd.  For now,
196  * read-write is not supported, just a single direction.  */
197 struct _virFileWrapperFd {
198     bool closed; /* Whether virFileWrapperFdClose() has been already called */
199     virCommand *cmd; /* Child iohelper process to do the I/O.  */
200     char *err_msg; /* stderr of @cmd */
201 };
202 
203 #ifndef WIN32
204 /**
205  * virFileWrapperFdNew:
206  * @fd: pointer to fd to wrap
207  * @name: name of fd, for diagnostics
208  * @flags: bitwise-OR of virFileWrapperFdFlags
209  *
210  * Update @fd so that it meets parameters requested by @flags.
211  *
212  * If VIR_FILE_WRAPPER_BYPASS_CACHE bit is set in @flags, @fd will be updated
213  * in a way that all I/O to that file will bypass the system cache.  The
214  * original fd must have been created with virFileDirectFdFlag() among the
215  * flags to open().
216  *
217  * If VIR_FILE_WRAPPER_NON_BLOCKING bit is set in @flags, @fd will be updated
218  * to ensure it properly supports non-blocking I/O, i.e., it will report
219  * EAGAIN.
220  *
221  * This must be called after open() and optional fchown() or fchmod(), but
222  * before any seek or I/O, and only on seekable fd.  The file must be O_RDONLY
223  * (to read the entire existing file) or O_WRONLY (to write to an empty file).
224  * In some cases, @fd is changed to a non-seekable pipe; in this case, the
225  * caller must not do anything further with the original fd.
226  *
227  * On success, the new wrapper object is returned, which must be later
228  * freed with virFileWrapperFdFree().  On failure, @fd is unchanged, an
229  * error message is output, and NULL is returned.
230  */
231 virFileWrapperFd *
virFileWrapperFdNew(int * fd,const char * name,unsigned int flags)232 virFileWrapperFdNew(int *fd, const char *name, unsigned int flags)
233 {
234     virFileWrapperFd *ret = NULL;
235     bool output = false;
236     int pipefd[2] = { -1, -1 };
237     int mode = -1;
238     g_autofree char *iohelper_path = NULL;
239 
240     if (!flags) {
241         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
242                        _("invalid use with no flags"));
243         return NULL;
244     }
245 
246     /* XXX support posix_fadvise rather than O_DIRECT, if the kernel support
247      * for that is decent enough. In that case, we will also need to
248      * explicitly support VIR_FILE_WRAPPER_NON_BLOCKING since
249      * VIR_FILE_WRAPPER_BYPASS_CACHE alone will no longer require spawning
250      * iohelper.
251      */
252 
253     if ((flags & VIR_FILE_WRAPPER_BYPASS_CACHE) && !O_DIRECT) {
254         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
255                        _("O_DIRECT unsupported on this platform"));
256         return NULL;
257     }
258 
259     ret = g_new0(virFileWrapperFd, 1);
260 
261     mode = fcntl(*fd, F_GETFL);
262 
263     if (mode < 0) {
264         virReportError(VIR_ERR_INTERNAL_ERROR, _("invalid fd %d for %s"),
265                        *fd, name);
266         goto error;
267     } else if ((mode & O_ACCMODE) == O_WRONLY) {
268         output = true;
269     } else if ((mode & O_ACCMODE) != O_RDONLY) {
270         virReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected mode 0x%x for %s"),
271                        mode & O_ACCMODE, name);
272         goto error;
273     }
274 
275     if (virPipe(pipefd) < 0)
276         goto error;
277 
278     if (!(iohelper_path = virFileFindResource("libvirt_iohelper",
279                                               abs_top_builddir "/src",
280                                               LIBEXECDIR)))
281         goto error;
282 
283     ret->cmd = virCommandNewArgList(iohelper_path, name, NULL);
284 
285     if (output) {
286         virCommandSetInputFD(ret->cmd, pipefd[0]);
287         virCommandSetOutputFD(ret->cmd, fd);
288         virCommandAddArg(ret->cmd, "1");
289     } else {
290         virCommandSetInputFD(ret->cmd, *fd);
291         virCommandSetOutputFD(ret->cmd, &pipefd[1]);
292         virCommandAddArg(ret->cmd, "0");
293     }
294 
295     /* In order to catch iohelper stderr, we must change
296      * iohelper's env so virLog functions print to stderr
297      */
298     virCommandAddEnvPair(ret->cmd, "LIBVIRT_LOG_OUTPUTS", "1:stderr");
299     virCommandSetErrorBuffer(ret->cmd, &ret->err_msg);
300     virCommandDoAsyncIO(ret->cmd);
301 
302     if (virCommandRunAsync(ret->cmd, NULL) < 0)
303         goto error;
304 
305     if (VIR_CLOSE(pipefd[!output]) < 0) {
306         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("unable to close pipe"));
307         goto error;
308     }
309 
310     VIR_FORCE_CLOSE(*fd);
311     *fd = pipefd[output];
312     return ret;
313 
314  error:
315     VIR_FORCE_CLOSE(pipefd[0]);
316     VIR_FORCE_CLOSE(pipefd[1]);
317     virFileWrapperFdFree(ret);
318     return NULL;
319 }
320 #else /* WIN32 */
321 virFileWrapperFd *
virFileWrapperFdNew(int * fd G_GNUC_UNUSED,const char * name G_GNUC_UNUSED,unsigned int fdflags G_GNUC_UNUSED)322 virFileWrapperFdNew(int *fd G_GNUC_UNUSED,
323                     const char *name G_GNUC_UNUSED,
324                     unsigned int fdflags G_GNUC_UNUSED)
325 {
326     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
327                    _("virFileWrapperFd unsupported on this platform"));
328     return NULL;
329 }
330 #endif /* WIN32 */
331 
332 /**
333  * virFileWrapperFdClose:
334  * @wfd: fd wrapper, or NULL
335  *
336  * If @wfd is valid, then ensure that I/O has completed, which may
337  * include reaping a child process.  Return 0 if all data for the
338  * wrapped fd is complete, or -1 on failure with an error emitted.
339  * This function intentionally returns 0 when @wfd is NULL, so that
340  * callers can conditionally create a virFileWrapperFd wrapper but
341  * unconditionally call the cleanup code.  To avoid deadlock, only
342  * call this after closing the fd resulting from virFileWrapperFdNew().
343  *
344  * This function can be safely called multiple times on the same @wfd.
345  */
346 int
virFileWrapperFdClose(virFileWrapperFd * wfd)347 virFileWrapperFdClose(virFileWrapperFd *wfd)
348 {
349     int ret;
350 
351     if (!wfd || wfd->closed)
352         return 0;
353 
354     ret = virCommandWait(wfd->cmd, NULL);
355 
356     /* If the command used to process I/O has failed and produced some
357      * messages on stderr, it's fair to assume those will be more
358      * relevant to the user than whatever eg. QEMU can figure out on its
359      * own having no knowledge of the fact a command is handling its I/O
360      * in the first place, so it's okay if we end up discarding an
361      * existing error here */
362     if (ret < 0 && wfd->err_msg && *wfd->err_msg)
363         virReportError(VIR_ERR_OPERATION_FAILED, "%s", wfd->err_msg);
364 
365     wfd->closed = true;
366 
367     return ret;
368 }
369 
370 /**
371  * virFileWrapperFdFree:
372  * @wfd: fd wrapper, or NULL
373  *
374  * Free all remaining resources associated with @wfd.  If
375  * virFileWrapperFdClose() was not previously called, then this may
376  * discard some previous I/O.  To avoid deadlock, only call this after
377  * closing the fd resulting from virFileWrapperFdNew().
378  */
379 void
virFileWrapperFdFree(virFileWrapperFd * wfd)380 virFileWrapperFdFree(virFileWrapperFd *wfd)
381 {
382     if (!wfd)
383         return;
384 
385     g_free(wfd->err_msg);
386     virCommandFree(wfd->cmd);
387     g_free(wfd);
388 }
389 
390 
391 #ifndef WIN32
392 
393 /**
394  * virFileLock:
395  * @fd: file descriptor to acquire the lock on
396  * @shared: type of lock to acquire
397  * @start: byte offset to start lock
398  * @len: length of lock (0 to acquire entire remaining file from @start)
399  * @waitForLock: wait for previously held lock or not
400  *
401  * Attempt to acquire a lock on the file @fd. If @shared
402  * is true, then a shared lock will be acquired,
403  * otherwise an exclusive lock will be acquired. If
404  * the lock cannot be acquired, an error will be
405  * returned. If @waitForLock is true, this will wait
406  * for the lock if another process has already acquired it.
407  *
408  * The lock will be released when @fd is closed. The lock
409  * will also be released if *any* other open file descriptor
410  * pointing to the same underlying file is closed. As such
411  * this function should not be relied on in multi-threaded
412  * apps where other threads can be opening/closing arbitrary
413  * files.
414  *
415  * Returns 0 on success, or -errno otherwise
416  */
virFileLock(int fd,bool shared,off_t start,off_t len,bool waitForLock)417 int virFileLock(int fd, bool shared, off_t start, off_t len, bool waitForLock)
418 {
419     struct flock fl = {
420         .l_type = shared ? F_RDLCK : F_WRLCK,
421         .l_whence = SEEK_SET,
422         .l_start = start,
423         .l_len = len,
424     };
425 
426     int cmd = waitForLock ? F_SETLKW : F_SETLK;
427 
428     if (fcntl(fd, cmd, &fl) < 0)
429         return -errno;
430 
431     return 0;
432 }
433 
434 
435 /**
436  * virFileUnlock:
437  * @fd: file descriptor to release the lock on
438  * @start: byte offset to start unlock
439  * @len: length of lock (0 to release entire remaining file from @start)
440  *
441  * Release a lock previously acquired with virFileUnlock().
442  * NB the lock will also be released if any open file descriptor
443  * pointing to the same file as @fd is closed
444  *
445  * Returns 0 on success, or -errno on error
446  */
virFileUnlock(int fd,off_t start,off_t len)447 int virFileUnlock(int fd, off_t start, off_t len)
448 {
449     struct flock fl = {
450         .l_type = F_UNLCK,
451         .l_whence = SEEK_SET,
452         .l_start = start,
453         .l_len = len,
454     };
455 
456     if (fcntl(fd, F_SETLK, &fl) < 0)
457         return -errno;
458 
459     return 0;
460 }
461 
462 
463 #else /* WIN32 */
464 
465 
virFileLock(int fd G_GNUC_UNUSED,bool shared G_GNUC_UNUSED,off_t start G_GNUC_UNUSED,off_t len G_GNUC_UNUSED,bool waitForLock G_GNUC_UNUSED)466 int virFileLock(int fd G_GNUC_UNUSED,
467                 bool shared G_GNUC_UNUSED,
468                 off_t start G_GNUC_UNUSED,
469                 off_t len G_GNUC_UNUSED,
470                 bool waitForLock G_GNUC_UNUSED)
471 {
472     return -ENOSYS;
473 }
474 
475 
virFileUnlock(int fd G_GNUC_UNUSED,off_t start G_GNUC_UNUSED,off_t len G_GNUC_UNUSED)476 int virFileUnlock(int fd G_GNUC_UNUSED,
477                   off_t start G_GNUC_UNUSED,
478                   off_t len G_GNUC_UNUSED)
479 {
480     return -ENOSYS;
481 }
482 
483 
484 #endif /* WIN32 */
485 
486 
487 int
virFileRewrite(const char * path,mode_t mode,virFileRewriteFunc rewrite,const void * opaque)488 virFileRewrite(const char *path,
489                mode_t mode,
490                virFileRewriteFunc rewrite,
491                const void *opaque)
492 {
493     g_autofree char *newfile = NULL;
494     int fd = -1;
495     int ret = -1;
496 
497     newfile = g_strdup_printf("%s.new", path);
498 
499     if ((fd = open(newfile, O_WRONLY | O_CREAT | O_TRUNC, mode)) < 0) {
500         virReportSystemError(errno, _("cannot create file '%s'"),
501                              newfile);
502         goto cleanup;
503     }
504 
505     if (rewrite(fd, opaque) < 0) {
506         virReportSystemError(errno, _("cannot write data to file '%s'"),
507                              newfile);
508         goto cleanup;
509     }
510 
511     if (g_fsync(fd) < 0) {
512         virReportSystemError(errno, _("cannot sync file '%s'"),
513                              newfile);
514         goto cleanup;
515     }
516 
517     if (VIR_CLOSE(fd) < 0) {
518         virReportSystemError(errno, _("cannot save file '%s'"),
519                              newfile);
520         goto cleanup;
521     }
522 
523     if (rename(newfile, path) < 0) {
524         virReportSystemError(errno, _("cannot rename file '%s' as '%s'"),
525                              newfile, path);
526         goto cleanup;
527     }
528 
529     ret = 0;
530 
531  cleanup:
532     VIR_FORCE_CLOSE(fd);
533     unlink(newfile);
534     return ret;
535 }
536 
537 
538 static int
virFileRewriteStrHelper(int fd,const void * opaque)539 virFileRewriteStrHelper(int fd, const void *opaque)
540 {
541     const char *data = opaque;
542 
543     if (safewrite(fd, data, strlen(data)) < 0)
544         return -1;
545 
546     return 0;
547 }
548 
549 
550 int
virFileRewriteStr(const char * path,mode_t mode,const char * str)551 virFileRewriteStr(const char *path,
552                   mode_t mode,
553                   const char *str)
554 {
555     return virFileRewrite(path, mode,
556                           virFileRewriteStrHelper, str);
557 }
558 
559 
560 /**
561  * virFileResize:
562  *
563  * Change the capacity of the raw storage file at 'path'.
564  */
565 int
virFileResize(const char * path,unsigned long long capacity,bool pre_allocate)566 virFileResize(const char *path,
567               unsigned long long capacity,
568               bool pre_allocate)
569 {
570     int rc;
571     VIR_AUTOCLOSE fd = -1;
572 
573     if ((fd = open(path, O_RDWR)) < 0) {
574         virReportSystemError(errno, _("Unable to open '%s'"), path);
575         return -1;
576     }
577 
578     if (pre_allocate) {
579         if ((rc = virFileAllocate(fd, 0, capacity)) != 0) {
580             if (rc == -2) {
581                 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
582                                _("preallocate is not supported on this platform"));
583             } else {
584                 virReportSystemError(errno,
585                                      _("Failed to pre-allocate space for "
586                                        "file '%s'"), path);
587             }
588             return -1;
589         }
590     }
591 
592     if (ftruncate(fd, capacity) < 0) {
593         virReportSystemError(errno,
594                              _("Failed to truncate file '%s'"), path);
595         return -1;
596     }
597 
598     if (VIR_CLOSE(fd) < 0) {
599         virReportSystemError(errno, _("Unable to save '%s'"), path);
600         return -1;
601     }
602 
603     return 0;
604 }
605 
606 
virFileTouch(const char * path,mode_t mode)607 int virFileTouch(const char *path, mode_t mode)
608 {
609     int fd = -1;
610 
611     if ((fd = open(path, O_WRONLY | O_CREAT, mode)) < 0) {
612         virReportSystemError(errno, _("cannot create file '%s'"),
613                              path);
614         return -1;
615     }
616 
617     if (VIR_CLOSE(fd) < 0) {
618         virReportSystemError(errno, _("cannot save file '%s'"),
619                              path);
620         VIR_FORCE_CLOSE(fd);
621         return -1;
622     }
623 
624     return 0;
625 }
626 
627 
628 #define MODE_BITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
629 
virFileUpdatePerm(const char * path,mode_t mode_remove,mode_t mode_add)630 int virFileUpdatePerm(const char *path,
631                       mode_t mode_remove,
632                       mode_t mode_add)
633 {
634     struct stat sb;
635     mode_t mode;
636 
637     if (mode_remove & ~MODE_BITS || mode_add & ~MODE_BITS) {
638         virReportError(VIR_ERR_INVALID_ARG, "%s", _("invalid mode"));
639         return -1;
640     }
641 
642     if (stat(path, &sb) < 0) {
643         virReportSystemError(errno, _("cannot stat '%s'"), path);
644         return -1;
645     }
646 
647     mode = sb.st_mode & MODE_BITS;
648 
649     if ((mode & mode_remove) == 0 && (mode & mode_add) == mode_add)
650         return 0;
651 
652     mode &= MODE_BITS ^ mode_remove;
653     mode |= mode_add;
654 
655     if (chmod(path, mode) < 0) {
656         virReportSystemError(errno, _("cannot change permission of '%s'"),
657                              path);
658         return -1;
659     }
660 
661     return 0;
662 }
663 
664 
665 #if defined(__linux__) && WITH_DECL_LO_FLAGS_AUTOCLEAR
666 
667 # if WITH_DECL_LOOP_CTL_GET_FREE
668 
669 /* virFileLoopDeviceOpenLoopCtl() returns -1 when a real failure has occurred
670  * while in the process of allocating or opening the loop device.  On success
671  * we return 0 and modify the fd to the appropriate file descriptor.
672  * If /dev/loop-control does not exist, we return 0 and do not set fd. */
673 
virFileLoopDeviceOpenLoopCtl(char ** dev_name,int * fd)674 static int virFileLoopDeviceOpenLoopCtl(char **dev_name, int *fd)
675 {
676     int devnr;
677     int ctl_fd;
678     char *looppath = NULL;
679 
680     VIR_DEBUG("Opening loop-control device");
681     if ((ctl_fd = open("/dev/loop-control", O_RDWR)) < 0) {
682         if (errno == ENOENT)
683             return 0;
684 
685         virReportSystemError(errno, "%s",
686                              _("Unable to open /dev/loop-control"));
687         return -1;
688     }
689 
690     if ((devnr = ioctl(ctl_fd, LOOP_CTL_GET_FREE)) < 0) {
691         virReportSystemError(errno, "%s",
692                              _("Unable to get free loop device via ioctl"));
693         close(ctl_fd);
694         return -1;
695     }
696     close(ctl_fd);
697 
698     VIR_DEBUG("Found free loop device number %i", devnr);
699 
700     looppath = g_strdup_printf("/dev/loop%i", devnr);
701 
702     if ((*fd = open(looppath, O_RDWR)) < 0) {
703         virReportSystemError(errno,
704                              _("Unable to open %s"), looppath);
705         VIR_FREE(looppath);
706         return -1;
707     }
708 
709     *dev_name = looppath;
710     return 0;
711 }
712 # endif /* WITH_DECL_LOOP_CTL_GET_FREE */
713 
virFileLoopDeviceOpenSearch(char ** dev_name)714 static int virFileLoopDeviceOpenSearch(char **dev_name)
715 {
716     int fd = -1;
717     g_autoptr(DIR) dh = NULL;
718     struct dirent *de;
719     char *looppath = NULL;
720     struct loop_info64 lo;
721     int direrr;
722 
723     VIR_DEBUG("Looking for loop devices in /dev");
724 
725     if (virDirOpen(&dh, "/dev") < 0)
726         goto cleanup;
727 
728     while ((direrr = virDirRead(dh, &de, "/dev")) > 0) {
729         /* Checking 'loop' prefix is insufficient, since
730          * new kernels have a dev named 'loop-control'
731          */
732         if (!STRPREFIX(de->d_name, "loop") ||
733             !g_ascii_isdigit(de->d_name[4]))
734             continue;
735 
736         looppath = g_build_filename("/dev", de->d_name, NULL);
737 
738         VIR_DEBUG("Checking up on device %s", looppath);
739         if ((fd = open(looppath, O_RDWR)) < 0) {
740             virReportSystemError(errno,
741                                  _("Unable to open %s"), looppath);
742             goto cleanup;
743         }
744 
745         if (ioctl(fd, LOOP_GET_STATUS64, &lo) < 0) {
746             /* Got a free device, return the fd */
747             if (errno == ENXIO)
748                 goto cleanup;
749 
750             VIR_FORCE_CLOSE(fd);
751             virReportSystemError(errno,
752                                  _("Unable to get loop status on %s"),
753                                  looppath);
754             goto cleanup;
755         }
756 
757         /* Oh well, try the next device */
758         VIR_FORCE_CLOSE(fd);
759         VIR_FREE(looppath);
760     }
761     if (direrr < 0)
762         goto cleanup;
763     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
764                    _("Unable to find a free loop device in /dev"));
765 
766  cleanup:
767     if (fd != -1) {
768         VIR_DEBUG("Got free loop device %s %d", looppath, fd);
769         *dev_name = looppath;
770     } else {
771         VIR_DEBUG("No free loop devices available");
772         VIR_FREE(looppath);
773     }
774     return fd;
775 }
776 
virFileLoopDeviceOpen(char ** dev_name)777 static int virFileLoopDeviceOpen(char **dev_name)
778 {
779     int loop_fd = -1;
780 
781 # if WITH_DECL_LOOP_CTL_GET_FREE
782     if (virFileLoopDeviceOpenLoopCtl(dev_name, &loop_fd) < 0)
783         return -1;
784 
785     VIR_DEBUG("Return from loop-control got fd %d", loop_fd);
786 
787     if (loop_fd >= 0)
788         return loop_fd;
789 # endif /* WITH_DECL_LOOP_CTL_GET_FREE */
790 
791     /* Without the loop control device we just use the old technique. */
792     loop_fd = virFileLoopDeviceOpenSearch(dev_name);
793 
794     return loop_fd;
795 }
796 
virFileLoopDeviceAssociate(const char * file,char ** dev)797 int virFileLoopDeviceAssociate(const char *file,
798                                char **dev)
799 {
800     int lofd = -1;
801     int fsfd = -1;
802     struct loop_info64 lo;
803     g_autofree char *loname = NULL;
804     int ret = -1;
805 
806     if ((lofd = virFileLoopDeviceOpen(&loname)) < 0)
807         return -1;
808 
809     memset(&lo, 0, sizeof(lo));
810     lo.lo_flags = LO_FLAGS_AUTOCLEAR;
811 
812     /* Set backing file name for LOOP_GET_STATUS64 queries */
813     if (virStrcpy((char *) lo.lo_file_name, file, LO_NAME_SIZE) < 0) {
814         virReportSystemError(errno,
815                              _("Unable to set backing file %s"), file);
816         goto cleanup;
817     }
818 
819     if ((fsfd = open(file, O_RDWR)) < 0) {
820         virReportSystemError(errno,
821                              _("Unable to open %s"), file);
822         goto cleanup;
823     }
824 
825     if (ioctl(lofd, LOOP_SET_FD, fsfd) < 0) {
826         virReportSystemError(errno,
827                              _("Unable to attach %s to loop device"),
828                              file);
829         goto cleanup;
830     }
831 
832     if (ioctl(lofd, LOOP_SET_STATUS64, &lo) < 0) {
833         virReportSystemError(errno, "%s",
834                              _("Unable to mark loop device as autoclear"));
835 
836         if (ioctl(lofd, LOOP_CLR_FD, 0) < 0)
837             VIR_WARN("Unable to detach %s from loop device", file);
838         goto cleanup;
839     }
840 
841     VIR_DEBUG("Attached loop device  %s %d to %s", file, lofd, loname);
842     *dev = g_steal_pointer(&loname);
843 
844     ret = 0;
845 
846  cleanup:
847     VIR_FORCE_CLOSE(fsfd);
848     if (ret == -1)
849         VIR_FORCE_CLOSE(lofd);
850     return lofd;
851 }
852 
853 
854 # define SYSFS_BLOCK_DIR "/sys/block"
855 # define NBD_DRIVER "nbd"
856 
857 
858 static int
virFileNBDDeviceIsBusy(const char * dev_name)859 virFileNBDDeviceIsBusy(const char *dev_name)
860 {
861     g_autofree char *path = NULL;
862 
863     path = g_build_filename(SYSFS_BLOCK_DIR, dev_name, "pid", NULL);
864 
865     if (!virFileExists(path)) {
866         if (errno == ENOENT)
867             return 0;
868         else
869             virReportSystemError(errno,
870                                  _("Cannot check NBD device %s pid"),
871                                  dev_name);
872         return -1;
873     }
874     return 1;
875 }
876 
877 
878 static char *
virFileNBDDeviceFindUnused(void)879 virFileNBDDeviceFindUnused(void)
880 {
881     g_autoptr(DIR) dh = NULL;
882     struct dirent *de;
883     int direrr;
884 
885     if (virDirOpen(&dh, SYSFS_BLOCK_DIR) < 0)
886         return NULL;
887 
888     while ((direrr = virDirRead(dh, &de, SYSFS_BLOCK_DIR)) > 0) {
889         if (STRPREFIX(de->d_name, "nbd")) {
890             int rv = virFileNBDDeviceIsBusy(de->d_name);
891 
892             if (rv < 0)
893                 return NULL;
894 
895             if (rv == 0)
896                 return g_build_filename("/dev", de->d_name, NULL);
897         }
898     }
899     if (direrr < 0)
900         return NULL;
901 
902     virReportSystemError(EBUSY, "%s", _("No free NBD devices"));
903     return NULL;
904 }
905 
906 static bool
virFileNBDLoadDriver(void)907 virFileNBDLoadDriver(void)
908 {
909     if (virKModIsProhibited(NBD_DRIVER)) {
910         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
911                        _("Failed to load nbd module: "
912                          "administratively prohibited"));
913         return false;
914     } else {
915         g_autofree char *errbuf = NULL;
916 
917         if ((errbuf = virKModLoad(NBD_DRIVER))) {
918             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
919                            _("Failed to load nbd module"));
920             return false;
921         }
922     }
923     return true;
924 }
925 
virFileNBDDeviceAssociate(const char * file,const char * fmtstr,bool readonly,char ** dev)926 int virFileNBDDeviceAssociate(const char *file,
927                               const char *fmtstr,
928                               bool readonly,
929                               char **dev)
930 {
931     g_autofree char *nbddev = NULL;
932     g_autofree char *qemunbd = NULL;
933     g_autoptr(virCommand) cmd = NULL;
934 
935     if (!virFileNBDLoadDriver())
936         return -1;
937 
938     if (!(nbddev = virFileNBDDeviceFindUnused()))
939         return -1;
940 
941     if (!(qemunbd = virFindFileInPath("qemu-nbd"))) {
942         virReportSystemError(ENOENT, "%s",
943                              _("Unable to find 'qemu-nbd' binary in $PATH"));
944         return -1;
945     }
946 
947     cmd = virCommandNew(qemunbd);
948 
949     /* Explicitly not trying to cope with old qemu-nbd which
950      * lacked --format. We want to see a fatal error in that
951      * case since it would be security flaw to continue */
952     if (fmtstr)
953         virCommandAddArgList(cmd, "--format", fmtstr, NULL);
954 
955     if (readonly)
956         virCommandAddArg(cmd, "-r");
957 
958     virCommandAddArgList(cmd,
959                          "-n", /* Don't cache in qemu-nbd layer */
960                          "-c", nbddev,
961                          file, NULL);
962 
963     /* qemu-nbd will daemonize itself */
964 
965     if (virCommandRun(cmd, NULL) < 0)
966         return -1;
967 
968     VIR_DEBUG("Associated NBD device %s with file %s and format %s",
969               nbddev, file, fmtstr);
970     *dev = nbddev;
971     nbddev = NULL;
972 
973     return 0;
974 }
975 
976 #else /* __linux__ */
977 
virFileLoopDeviceAssociate(const char * file,char ** dev G_GNUC_UNUSED)978 int virFileLoopDeviceAssociate(const char *file,
979                                char **dev G_GNUC_UNUSED)
980 {
981     virReportSystemError(ENOSYS,
982                          _("Unable to associate file %s with loop device"),
983                          file);
984     *dev = NULL;
985     return -1;
986 }
987 
virFileNBDDeviceAssociate(const char * file,const char * fmtstr G_GNUC_UNUSED,bool readonly G_GNUC_UNUSED,char ** dev G_GNUC_UNUSED)988 int virFileNBDDeviceAssociate(const char *file,
989                               const char *fmtstr G_GNUC_UNUSED,
990                               bool readonly G_GNUC_UNUSED,
991                               char **dev G_GNUC_UNUSED)
992 {
993     virReportSystemError(ENOSYS,
994                          _("Unable to associate file %s with NBD device"),
995                          file);
996     return -1;
997 }
998 
999 #endif /* __linux__ */
1000 
1001 
1002 /**
1003  * virFileDeleteTree:
1004  *
1005  * Recursively deletes all files / directories
1006  * starting from the directory @dir. Does not
1007  * follow symlinks
1008  *
1009  * NB the algorithm is not efficient, and is subject to
1010  * race conditions which can be exploited by malicious
1011  * code. It should not be used in any scenarios where
1012  * performance is important, or security is critical.
1013  */
virFileDeleteTree(const char * dir)1014 int virFileDeleteTree(const char *dir)
1015 {
1016     g_autoptr(DIR) dh = NULL;
1017     struct dirent *de;
1018     int direrr;
1019 
1020     /* Silently return 0 if passed NULL or directory doesn't exist */
1021     if (!dir || !virFileExists(dir))
1022         return 0;
1023 
1024     if (virDirOpen(&dh, dir) < 0)
1025         return -1;
1026 
1027     while ((direrr = virDirRead(dh, &de, dir)) > 0) {
1028         g_autofree char *filepath = NULL;
1029         GStatBuf sb;
1030 
1031         filepath = g_build_filename(dir, de->d_name, NULL);
1032 
1033         if (g_lstat(filepath, &sb) < 0) {
1034             virReportSystemError(errno, _("Cannot access '%s'"),
1035                                  filepath);
1036             return -1;
1037         }
1038 
1039         if (S_ISDIR(sb.st_mode)) {
1040             if (virFileDeleteTree(filepath) < 0)
1041                 return -1;
1042         } else {
1043             if (unlink(filepath) < 0 && errno != ENOENT) {
1044                 virReportSystemError(errno,
1045                                      _("Cannot delete file '%s'"),
1046                                      filepath);
1047                 return -1;
1048             }
1049         }
1050     }
1051     if (direrr < 0)
1052         return -1;
1053 
1054     if (rmdir(dir) < 0 && errno != ENOENT) {
1055         virReportSystemError(errno,
1056                              _("Cannot delete directory '%s'"),
1057                              dir);
1058         return -1;
1059     }
1060 
1061     return 0;
1062 }
1063 
1064 /* Like read(), but restarts after EINTR.  Doesn't play
1065  * nicely with nonblocking FD and EAGAIN, in which case
1066  * you want to use bare read(). Or even use virSocket()
1067  * if the FD is related to a socket rather than a plain
1068  * file or pipe. */
1069 ssize_t
saferead(int fd,void * buf,size_t count)1070 saferead(int fd, void *buf, size_t count)
1071 {
1072     size_t nread = 0;
1073     while (count > 0) {
1074         ssize_t r = read(fd, buf, count);
1075         if (r < 0 && errno == EINTR)
1076             continue;
1077         if (r < 0)
1078             return r;
1079         if (r == 0)
1080             return nread;
1081         buf = (char *)buf + r;
1082         count -= r;
1083         nread += r;
1084     }
1085     return nread;
1086 }
1087 
1088 /* Like write(), but restarts after EINTR. Doesn't play
1089  * nicely with nonblocking FD and EAGAIN, in which case
1090  * you want to use bare write(). Or even use virSocket()
1091  * if the FD is related to a socket rather than a plain
1092  * file or pipe. */
1093 ssize_t
safewrite(int fd,const void * buf,size_t count)1094 safewrite(int fd, const void *buf, size_t count)
1095 {
1096     size_t nwritten = 0;
1097     while (count > 0) {
1098         ssize_t r = write(fd, buf, count);
1099 
1100         if (r < 0 && errno == EINTR)
1101             continue;
1102         if (r < 0)
1103             return r;
1104         if (r == 0)
1105             return nwritten;
1106         buf = (const char *)buf + r;
1107         count -= r;
1108         nwritten += r;
1109     }
1110     return nwritten;
1111 }
1112 
1113 #ifdef WITH_POSIX_FALLOCATE
1114 static int
safezero_posix_fallocate(int fd,off_t offset,off_t len)1115 safezero_posix_fallocate(int fd, off_t offset, off_t len)
1116 {
1117     int ret = posix_fallocate(fd, offset, len);
1118     if (ret == 0) {
1119         return 0;
1120     } else if (ret == EINVAL) {
1121         /* EINVAL is returned when either:
1122            - Operation is not supported by the underlying filesystem,
1123            - offset or len argument values are invalid.
1124            Assuming that offset and len are valid, this error means
1125            the operation is not supported, and we need to fall back
1126            to other methods.
1127         */
1128         return -2;
1129     }
1130 
1131     errno = ret;
1132     return -1;
1133 }
1134 #else /* !WITH_POSIX_FALLOCATE */
1135 static int
safezero_posix_fallocate(int fd G_GNUC_UNUSED,off_t offset G_GNUC_UNUSED,off_t len G_GNUC_UNUSED)1136 safezero_posix_fallocate(int fd G_GNUC_UNUSED,
1137                          off_t offset G_GNUC_UNUSED,
1138                          off_t len G_GNUC_UNUSED)
1139 {
1140     return -2;
1141 }
1142 #endif /* !WITH_POSIX_FALLOCATE */
1143 
1144 #if WITH_SYS_SYSCALL_H && defined(SYS_fallocate)
1145 static int
safezero_sys_fallocate(int fd,off_t offset,off_t len)1146 safezero_sys_fallocate(int fd,
1147                        off_t offset,
1148                        off_t len)
1149 {
1150     return syscall(SYS_fallocate, fd, 0, offset, len);
1151 }
1152 #else /* !WITH_SYS_SYSCALL_H || !defined(SYS_fallocate) */
1153 static int
safezero_sys_fallocate(int fd G_GNUC_UNUSED,off_t offset G_GNUC_UNUSED,off_t len G_GNUC_UNUSED)1154 safezero_sys_fallocate(int fd G_GNUC_UNUSED,
1155                        off_t offset G_GNUC_UNUSED,
1156                        off_t len G_GNUC_UNUSED)
1157 {
1158     return -2;
1159 }
1160 #endif /* !WITH_SYS_SYSCALL_H || !defined(SYS_fallocate) */
1161 
1162 #ifdef WITH_MMAP
1163 static int
safezero_mmap(int fd,off_t offset,off_t len)1164 safezero_mmap(int fd, off_t offset, off_t len)
1165 {
1166     int r;
1167     char *buf;
1168     static long pagemask;
1169     off_t map_skip;
1170 
1171     /* align offset and length, rounding offset down and length up */
1172     if (pagemask == 0)
1173         pagemask = ~(virGetSystemPageSize() - 1);
1174     map_skip = offset - (offset & pagemask);
1175 
1176     /* memset wants the mmap'ed file to be present on disk so create a
1177      * sparse file
1178      */
1179     r = ftruncate(fd, offset + len);
1180     if (r < 0)
1181         return -1;
1182 
1183     buf = mmap(NULL, len + map_skip, PROT_READ | PROT_WRITE, MAP_SHARED,
1184                fd, offset - map_skip);
1185     if (buf != MAP_FAILED) {
1186         memset(buf + map_skip, 0, len);
1187         munmap(buf, len + map_skip);
1188 
1189         return 0;
1190     }
1191 
1192     /* fall back to writing zeroes using safewrite if mmap fails (for
1193      * example because of virtual memory limits) */
1194     return -2;
1195 }
1196 #else /* !WITH_MMAP */
1197 static int
safezero_mmap(int fd G_GNUC_UNUSED,off_t offset G_GNUC_UNUSED,off_t len G_GNUC_UNUSED)1198 safezero_mmap(int fd G_GNUC_UNUSED,
1199               off_t offset G_GNUC_UNUSED,
1200               off_t len G_GNUC_UNUSED)
1201 {
1202     return -2;
1203 }
1204 #endif /* !WITH_MMAP */
1205 
1206 static int
safezero_slow(int fd,off_t offset,off_t len)1207 safezero_slow(int fd, off_t offset, off_t len)
1208 {
1209     int r;
1210     g_autofree char *buf = NULL;
1211     unsigned long long remain, bytes;
1212 
1213     if (lseek(fd, offset, SEEK_SET) < 0)
1214         return -1;
1215 
1216     /* Split up the write in small chunks so as not to allocate lots of RAM */
1217     remain = len;
1218     bytes = MIN(1024 * 1024, len);
1219 
1220     buf = g_new0(char, bytes);
1221 
1222     while (remain) {
1223         if (bytes > remain)
1224             bytes = remain;
1225 
1226         r = safewrite(fd, buf, bytes);
1227         if (r < 0)
1228             return -1;
1229 
1230         /* safewrite() guarantees all data will be written */
1231         remain -= bytes;
1232     }
1233     return 0;
1234 }
1235 
safezero(int fd,off_t offset,off_t len)1236 int safezero(int fd, off_t offset, off_t len)
1237 {
1238     int ret;
1239 
1240     ret = safezero_posix_fallocate(fd, offset, len);
1241     if (ret != -2)
1242         return ret;
1243 
1244     if (safezero_sys_fallocate(fd, offset, len) == 0)
1245         return 0;
1246 
1247     ret = safezero_mmap(fd, offset, len);
1248     if (ret != -2)
1249         return ret;
1250     return safezero_slow(fd, offset, len);
1251 }
1252 
virFileAllocate(int fd,off_t offset,off_t len)1253 int virFileAllocate(int fd, off_t offset, off_t len)
1254 {
1255     int ret;
1256 
1257     ret = safezero_posix_fallocate(fd, offset, len);
1258     if (ret != -2)
1259         return ret;
1260 
1261     return safezero_sys_fallocate(fd, offset, len);
1262 }
1263 
1264 #if defined WITH_MNTENT_H && defined WITH_GETMNTENT_R
1265 /* search /proc/mounts for mount point of *type; return pointer to
1266  * malloc'ed string of the path if found, otherwise return NULL
1267  * with errno set to an appropriate value.
1268  */
1269 char *
virFileFindMountPoint(const char * type)1270 virFileFindMountPoint(const char *type)
1271 {
1272     FILE *f;
1273     struct mntent mb;
1274     char mntbuf[1024];
1275     char *ret = NULL;
1276 
1277     f = setmntent("/proc/mounts", "r");
1278     if (!f)
1279         return NULL;
1280 
1281     while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
1282         if (STREQ(mb.mnt_type, type)) {
1283             ret = g_strdup(mb.mnt_dir);
1284             goto cleanup;
1285         }
1286     }
1287 
1288     if (!ret)
1289         errno = ENOENT;
1290 
1291  cleanup:
1292     endmntent(f);
1293 
1294     return ret;
1295 }
1296 
1297 #else /* defined WITH_MNTENT_H && defined WITH_GETMNTENT_R */
1298 
1299 char *
virFileFindMountPoint(const char * type G_GNUC_UNUSED)1300 virFileFindMountPoint(const char *type G_GNUC_UNUSED)
1301 {
1302     errno = ENOSYS;
1303 
1304     return NULL;
1305 }
1306 
1307 #endif /* defined WITH_MNTENT_H && defined WITH_GETMNTENT_R */
1308 
1309 void
virBuildPathInternal(char ** path,...)1310 virBuildPathInternal(char **path, ...)
1311 {
1312     char *path_component = NULL;
1313     g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
1314     va_list ap;
1315 
1316     va_start(ap, path);
1317 
1318     path_component = va_arg(ap, char *);
1319     virBufferAdd(&buf, path_component, -1);
1320 
1321     while ((path_component = va_arg(ap, char *)) != NULL) {
1322         virBufferAddChar(&buf, '/');
1323         virBufferAdd(&buf, path_component, -1);
1324     }
1325 
1326     va_end(ap);
1327 
1328     *path = virBufferContentAndReset(&buf);
1329 }
1330 
1331 /* Read no more than the specified maximum number of bytes. */
1332 static char *
saferead_lim(int fd,size_t max_len,size_t * length)1333 saferead_lim(int fd, size_t max_len, size_t *length)
1334 {
1335     char *buf = NULL;
1336     size_t alloc = 0;
1337     size_t size = 0;
1338     int save_errno;
1339 
1340     for (;;) {
1341         int count;
1342         int requested;
1343 
1344         if (size + BUFSIZ + 1 > alloc) {
1345             alloc += alloc / 2;
1346             if (alloc < size + BUFSIZ + 1)
1347                 alloc = size + BUFSIZ + 1;
1348 
1349             VIR_REALLOC_N(buf, alloc);
1350         }
1351 
1352         /* Ensure that (size + requested <= max_len); */
1353         requested = MIN(size < max_len ? max_len - size : 0,
1354                         alloc - size - 1);
1355         count = saferead(fd, buf + size, requested);
1356         size += count;
1357 
1358         if (count != requested || requested == 0) {
1359             save_errno = errno;
1360             if (count < 0)
1361                 break;
1362             buf[size] = '\0';
1363             *length = size;
1364             return buf;
1365         }
1366     }
1367 
1368     VIR_FREE(buf);
1369     errno = save_errno;
1370     return NULL;
1371 }
1372 
1373 
1374 /* A wrapper around saferead_lim that merely stops reading at the
1375  * specified maximum size.  */
1376 int
virFileReadHeaderFD(int fd,int maxlen,char ** buf)1377 virFileReadHeaderFD(int fd, int maxlen, char **buf)
1378 {
1379     size_t len;
1380     char *s;
1381 
1382     if (maxlen <= 0) {
1383         errno = EINVAL;
1384         return -1;
1385     }
1386     s = saferead_lim(fd, maxlen, &len);
1387     if (s == NULL)
1388         return -1;
1389     *buf = s;
1390     return len;
1391 }
1392 
1393 
1394 int
virFileReadHeaderQuiet(const char * path,int maxlen,char ** buf)1395 virFileReadHeaderQuiet(const char *path,
1396                        int maxlen,
1397                        char **buf)
1398 {
1399     int fd;
1400     int len;
1401 
1402     fd = open(path, O_RDONLY);
1403     if (fd < 0)
1404         return -1;
1405 
1406     len = virFileReadHeaderFD(fd, maxlen, buf);
1407     VIR_FORCE_CLOSE(fd);
1408 
1409     return len;
1410 }
1411 
1412 
1413 /* A wrapper around saferead_lim that maps a failure due to
1414    exceeding the maximum size limitation to EOVERFLOW.  */
1415 int
virFileReadLimFD(int fd,int maxlen,char ** buf)1416 virFileReadLimFD(int fd, int maxlen, char **buf)
1417 {
1418     size_t len;
1419     char *s;
1420 
1421     if (maxlen <= 0) {
1422         errno = EINVAL;
1423         return -1;
1424     }
1425     s = saferead_lim(fd, (size_t) maxlen + 1, &len);
1426     if (s == NULL)
1427         return -1;
1428     if (len > maxlen || (int)len != len) {
1429         VIR_FREE(s);
1430         /* There was at least one byte more than MAXLEN.
1431            Set errno accordingly. */
1432         errno = EOVERFLOW;
1433         return -1;
1434     }
1435     *buf = s;
1436     return len;
1437 }
1438 
1439 int
virFileReadAll(const char * path,int maxlen,char ** buf)1440 virFileReadAll(const char *path, int maxlen, char **buf)
1441 {
1442     int fd;
1443     int len;
1444 
1445     fd = open(path, O_RDONLY);
1446     if (fd < 0) {
1447         virReportSystemError(errno, _("Failed to open file '%s'"), path);
1448         return -1;
1449     }
1450 
1451     len = virFileReadLimFD(fd, maxlen, buf);
1452     VIR_FORCE_CLOSE(fd);
1453     if (len < 0) {
1454         virReportSystemError(errno, _("Failed to read file '%s'"), path);
1455         return -1;
1456     }
1457 
1458     return len;
1459 }
1460 
1461 int
virFileReadAllQuiet(const char * path,int maxlen,char ** buf)1462 virFileReadAllQuiet(const char *path, int maxlen, char **buf)
1463 {
1464     int fd;
1465     int len;
1466 
1467     fd = open(path, O_RDONLY);
1468     if (fd < 0)
1469         return -errno;
1470 
1471     len = virFileReadLimFD(fd, maxlen, buf);
1472     VIR_FORCE_CLOSE(fd);
1473     if (len < 0)
1474         return -errno;
1475 
1476     return len;
1477 }
1478 
1479 /* Read @file into preallocated buffer @buf of size @len.
1480  * Return value is -errno in case of errors and size
1481  * of data read (no trailing zero) in case of success.
1482  * If there is more data then @len - 1 then data will be
1483  * truncated. */
1484 int
virFileReadBufQuiet(const char * file,char * buf,int len)1485 virFileReadBufQuiet(const char *file, char *buf, int len)
1486 {
1487     int fd;
1488     ssize_t sz;
1489 
1490     fd = open(file, O_RDONLY);
1491     if (fd < 0)
1492         return -errno;
1493 
1494     sz = saferead(fd, buf, len - 1);
1495     VIR_FORCE_CLOSE(fd);
1496     if (sz < 0)
1497         return -errno;
1498 
1499     buf[sz] = '\0';
1500     return sz;
1501 }
1502 
1503 /* Truncate @path and write @str to it.  If @mode is 0, ensure that
1504    @path exists; otherwise, use @mode if @path must be created.
1505    Return 0 for success, nonzero for failure.
1506    Be careful to preserve any errno value upon failure. */
1507 int
virFileWriteStr(const char * path,const char * str,mode_t mode)1508 virFileWriteStr(const char *path, const char *str, mode_t mode)
1509 {
1510     int fd;
1511 
1512     if (mode)
1513         fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, mode);
1514     else
1515         fd = open(path, O_WRONLY|O_TRUNC);
1516     if (fd == -1)
1517         return -1;
1518 
1519     if (safewrite(fd, str, strlen(str)) < 0) {
1520         VIR_FORCE_CLOSE(fd);
1521         return -1;
1522     }
1523 
1524     /* Use errno from failed close only if there was no write error.  */
1525     if (VIR_CLOSE(fd) != 0)
1526         return -1;
1527 
1528     return 0;
1529 }
1530 
1531 #define SAME_INODE(Stat_buf_1, Stat_buf_2) \
1532   ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \
1533    && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
1534 
1535 /* Return nonzero if checkLink and checkDest
1536  * refer to the same file.  Otherwise, return 0.
1537  */
1538 int
virFileLinkPointsTo(const char * checkLink,const char * checkDest)1539 virFileLinkPointsTo(const char *checkLink,
1540                     const char *checkDest)
1541 {
1542     struct stat src_sb;
1543     struct stat dest_sb;
1544 
1545     return (stat(checkLink, &src_sb) == 0
1546             && stat(checkDest, &dest_sb) == 0
1547             && SAME_INODE(src_sb, dest_sb));
1548 }
1549 
1550 
1551 /* Return positive if checkLink (residing within directory if not
1552  * absolute) and checkDest refer to the same file.  Otherwise, return
1553  * -1 on allocation failure (error reported), or 0 if not the same
1554  * (silent).
1555  */
1556 int
virFileRelLinkPointsTo(const char * directory,const char * checkLink,const char * checkDest)1557 virFileRelLinkPointsTo(const char *directory,
1558                        const char *checkLink,
1559                        const char *checkDest)
1560 {
1561     g_autofree char *candidate = NULL;
1562 
1563     if (*checkLink == '/')
1564         return virFileLinkPointsTo(checkLink, checkDest);
1565     if (!directory) {
1566         virReportError(VIR_ERR_INTERNAL_ERROR,
1567                        _("cannot resolve '%s' without starting directory"),
1568                        checkLink);
1569         return -1;
1570     }
1571     candidate = g_build_filename(directory, checkLink, NULL);
1572     return virFileLinkPointsTo(candidate, checkDest);
1573 }
1574 
1575 
1576 static int
virFileResolveLinkHelper(const char * linkpath,bool intermediatePaths,char ** resultpath)1577 virFileResolveLinkHelper(const char *linkpath,
1578                          bool intermediatePaths,
1579                          char **resultpath)
1580 {
1581     GStatBuf st;
1582 
1583     *resultpath = NULL;
1584 
1585     /* We don't need the full canonicalization of intermediate
1586      * directories, if linkpath is absolute and the basename is
1587      * already a non-symlink.  */
1588     if (g_path_is_absolute(linkpath) && !intermediatePaths) {
1589         if (g_lstat(linkpath, &st) < 0)
1590             return -1;
1591 
1592 #ifndef WIN32
1593         if (!S_ISLNK(st.st_mode)) {
1594             *resultpath = g_strdup(linkpath);
1595             return 0;
1596         }
1597 #endif /* WIN32 */
1598     }
1599 
1600     *resultpath = virFileCanonicalizePath(linkpath);
1601 
1602     return *resultpath == NULL ? -1 : 0;
1603 }
1604 
1605 /*
1606  * Attempt to resolve a symbolic link, returning an
1607  * absolute path where only the last component is guaranteed
1608  * not to be a symlink.
1609  *
1610  * Return 0 if path was not a symbolic, or the link was
1611  * resolved. Return -1 with errno set upon error
1612  */
1613 int
virFileResolveLink(const char * linkpath,char ** resultpath)1614 virFileResolveLink(const char *linkpath, char **resultpath)
1615 {
1616     return virFileResolveLinkHelper(linkpath, false, resultpath);
1617 }
1618 
1619 /*
1620  * Attempt to resolve a symbolic link, returning an
1621  * absolute path where every component is guaranteed
1622  * not to be a symlink.
1623  *
1624  * Return 0 if path was not a symbolic, or the link was
1625  * resolved. Return -1 with errno set upon error
1626  */
1627 int
virFileResolveAllLinks(const char * linkpath,char ** resultpath)1628 virFileResolveAllLinks(const char *linkpath, char **resultpath)
1629 {
1630     return virFileResolveLinkHelper(linkpath, true, resultpath);
1631 }
1632 
1633 /*
1634  * Check whether the given file is a link.
1635  * Returns 1 in case of the file being a link, 0 in case it is not
1636  * a link and the negative errno in all other cases.
1637  */
1638 int
virFileIsLink(const char * linkpath)1639 virFileIsLink(const char *linkpath)
1640 {
1641     GStatBuf st;
1642 
1643     /* Still do this on Windows so we report
1644      * errors like ENOENT, etc
1645      */
1646     if (g_lstat(linkpath, &st) < 0)
1647         return -errno;
1648 
1649 #ifndef WIN32
1650     return S_ISLNK(st.st_mode) != 0;
1651 #else /* WIN32 */
1652     return 0;
1653 #endif /* WIN32 */
1654 }
1655 
1656 /*
1657  * Finds a requested executable file in the PATH env. e.g.:
1658  * "qemu-img" will return "/usr/bin/qemu-img"
1659  *
1660  * You must free the result
1661  */
1662 char *
virFindFileInPath(const char * file)1663 virFindFileInPath(const char *file)
1664 {
1665     g_autofree char *path = NULL;
1666     if (file == NULL)
1667         return NULL;
1668 
1669     path = g_find_program_in_path(file);
1670     if (!path)
1671         return NULL;
1672 
1673     /* Workaround for a bug in g_find_program_in_path() not returning absolute
1674      * path as documented.  This has been fixed in
1675      * https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2127
1676      */
1677     return g_canonicalize_filename(path, NULL);
1678 }
1679 
1680 
1681 static bool useDirOverride;
1682 
1683 /**
1684  * virFileFindResourceFull:
1685  * @filename: libvirt distributed filename without any path
1686  * @prefix: optional string to prepend to filename
1687  * @suffix: optional string to append to filename
1688  * @builddir: location of the filename in the build tree including
1689  *            abs_top_srcdir or abs_top_builddir prefix
1690  * @installdir: location of the installed binary
1691  * @envname: environment variable used to override all dirs
1692  *
1693  * A helper which will return a path to @filename within
1694  * the current build tree, if the calling binary is being
1695  * run from the source tree. Otherwise it will return the
1696  * path in the installed location.
1697  *
1698  * Note that this function does not actually check whether
1699  * the file exists on disk, it merely builds the fully
1700  * qualified path where it is supposed to exist.
1701  *
1702  * If @envname is non-NULL it will override all other
1703  * directory lookup.
1704  *
1705  * Only use this with @filename files that are part of
1706  * the libvirt tree, not 3rd party binaries/files.
1707  *
1708  * Returns the resolved path (caller frees) or NULL on error
1709  */
1710 char *
virFileFindResourceFull(const char * filename,const char * prefix,const char * suffix,const char * builddir,const char * installdir,const char * envname)1711 virFileFindResourceFull(const char *filename,
1712                         const char *prefix,
1713                         const char *suffix,
1714                         const char *builddir,
1715                         const char *installdir,
1716                         const char *envname)
1717 {
1718     char *ret = NULL;
1719     const char *envval = envname ? getenv(envname) : NULL;
1720     const char *path;
1721     g_autofree char *fullFilename = NULL;
1722 
1723     if (!prefix)
1724         prefix = "";
1725     if (!suffix)
1726         suffix = "";
1727 
1728     if (envval)
1729         path = envval;
1730     else if (useDirOverride)
1731         path = builddir;
1732     else
1733         path = installdir;
1734 
1735     fullFilename = g_strdup_printf("%s%s%s", prefix, filename, suffix);
1736     ret = g_build_filename(path, fullFilename, NULL);
1737 
1738     VIR_DEBUG("Resolved '%s' to '%s'", filename, ret);
1739     return ret;
1740 }
1741 
1742 char *
virFileFindResource(const char * filename,const char * builddir,const char * installdir)1743 virFileFindResource(const char *filename,
1744                     const char *builddir,
1745                     const char *installdir)
1746 {
1747     return virFileFindResourceFull(filename, NULL, NULL, builddir, installdir, NULL);
1748 }
1749 
1750 
1751 /**
1752  * virFileActivateDirOverrideForProg:
1753  * @argv0: argv[0] of the calling program
1754  *
1755  * Canonicalize current process path from argv0 and check if abs_top_builddir
1756  * matches as prefix in the path.
1757  */
1758 void
virFileActivateDirOverrideForProg(const char * argv0)1759 virFileActivateDirOverrideForProg(const char *argv0)
1760 {
1761     g_autofree char *path = virFileCanonicalizePath(argv0);
1762 
1763     if (!path) {
1764         VIR_DEBUG("Failed to get canonicalized path errno=%d", errno);
1765         return;
1766     }
1767 
1768     if (STRPREFIX(path, abs_top_builddir)) {
1769         useDirOverride = true;
1770         VIR_DEBUG("Activating build dir override for %s", path);
1771     }
1772 }
1773 
1774 
1775 /**
1776  * virFileActivateDirOverrideForLib:
1777  *
1778  * Look for LIBVIRT_DIR_OVERRIDE env var to see if we should find files from
1779  * the build/src tree instead of install tree.
1780  */
1781 void
virFileActivateDirOverrideForLib(void)1782 virFileActivateDirOverrideForLib(void)
1783 {
1784     if (getenv("LIBVIRT_DIR_OVERRIDE") != NULL)
1785         useDirOverride = true;
1786 }
1787 
1788 
1789 /**
1790  * virFileLength:
1791  * @path: full path of the file
1792  * @fd: open file descriptor for file (or -1 to use @path)
1793  *
1794  * If fd >= 0, return the length of the open file indicated by @fd.
1795  * If fd < 0 (i.e. -1) return the length of the file indicated by
1796  * @path.
1797  *
1798  * Returns the length, or -1 if the file doesn't
1799  * exist or its info was inaccessible. No error is logged.
1800  */
1801 off_t
virFileLength(const char * path,int fd)1802 virFileLength(const char *path, int fd)
1803 {
1804     struct stat s;
1805 
1806     if (fd >= 0) {
1807         if (fstat(fd, &s) < 0)
1808             return -1;
1809     } else {
1810         if (stat(path, &s) < 0)
1811             return -1;
1812     }
1813 
1814     if (!S_ISREG(s.st_mode))
1815        return -1;
1816 
1817     return s.st_size;
1818 
1819 }
1820 
1821 
1822 bool
virFileIsDir(const char * path)1823 virFileIsDir(const char *path)
1824 {
1825     struct stat s;
1826     return (stat(path, &s) == 0) && S_ISDIR(s.st_mode);
1827 }
1828 
1829 
1830 bool
virFileIsRegular(const char * path)1831 virFileIsRegular(const char *path)
1832 {
1833     struct stat s;
1834     return (stat(path, &s) == 0) && S_ISREG(s.st_mode);
1835 }
1836 
1837 
1838 /**
1839  * virFileExists: Check for presence of file
1840  * @path: Path of file to check
1841  *
1842  * Returns true if the file exists, false if it doesn't, setting errno
1843  * appropriately.
1844  */
1845 bool
virFileExists(const char * path)1846 virFileExists(const char *path)
1847 {
1848     return access(path, F_OK) == 0;
1849 }
1850 
1851 /* Check that a file is regular and has executable bits.  If false is
1852  * returned, errno is valid.
1853  *
1854  * Note: In the presence of ACLs, this may return true for a file that
1855  * would actually fail with EACCES for a given user, or false for a
1856  * file that the user could actually execute, but setups with ACLs
1857  * that weird are unusual. */
1858 bool
virFileIsExecutable(const char * file)1859 virFileIsExecutable(const char *file)
1860 {
1861     struct stat sb;
1862 
1863     /* We would also want to check faccessat if we cared about ACLs,
1864      * but we don't.  */
1865     if (stat(file, &sb) < 0)
1866         return false;
1867     if (S_ISREG(sb.st_mode) && (sb.st_mode & 0111) != 0)
1868         return true;
1869     errno = S_ISDIR(sb.st_mode) ? EISDIR : EACCES;
1870     return false;
1871 }
1872 
1873 
1874 /*
1875  * Check that a file refers to a mount point. Trick is that for
1876  * a mount point, the st_dev field will differ from the parent
1877  * directory.
1878  *
1879  * Note that this will not detect bind mounts of dirs/files,
1880  * only true filesystem mounts.
1881  */
virFileIsMountPoint(const char * file)1882 int virFileIsMountPoint(const char *file)
1883 {
1884     g_autofree char *parent = NULL;
1885     int ret;
1886     struct stat sb1, sb2;
1887 
1888     parent = g_path_get_dirname(file);
1889 
1890     VIR_DEBUG("Comparing '%s' to '%s'", file, parent);
1891 
1892     if (stat(file, &sb1) < 0) {
1893         if (errno == ENOENT)
1894             return 0;
1895         else
1896             virReportSystemError(errno,
1897                                  _("Cannot stat '%s'"),
1898                                  file);
1899         return -1;
1900     }
1901 
1902     if (stat(parent, &sb2) < 0) {
1903         virReportSystemError(errno,
1904                              _("Cannot stat '%s'"),
1905                              parent);
1906         return -1;
1907     }
1908 
1909     if (!S_ISDIR(sb1.st_mode))
1910         return 0;
1911 
1912     ret = sb1.st_dev != sb2.st_dev;
1913     VIR_DEBUG("Is mount %d", ret);
1914 
1915     return ret;
1916 }
1917 
1918 
1919 #if defined(__linux__)
1920 /**
1921  * virFileIsCDROM:
1922  * @path: File to check
1923  *
1924  * Returns 1 if @path is a cdrom device 0 if it is not a cdrom and -1 on
1925  * error. 'errno' of the failure is preserved and no libvirt errors are
1926  * reported.
1927  */
1928 int
virFileIsCDROM(const char * path)1929 virFileIsCDROM(const char *path)
1930 {
1931     struct stat st;
1932     VIR_AUTOCLOSE fd = -1;
1933 
1934     if ((fd = open(path, O_RDONLY | O_NONBLOCK)) < 0)
1935         return -1;
1936 
1937     if (fstat(fd, &st) < 0)
1938         return -1;
1939 
1940     if (!S_ISBLK(st.st_mode))
1941         return 0;
1942 
1943     /* Attempt to detect via a CDROM specific ioctl */
1944     if (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) >= 0)
1945         return 1;
1946 
1947     return 0;
1948 }
1949 
1950 #else
1951 
1952 int
virFileIsCDROM(const char * path)1953 virFileIsCDROM(const char *path)
1954 {
1955     if (STRPREFIX(path, "/dev/cd") ||
1956         STRPREFIX(path, "/dev/acd"))
1957         return 1;
1958 
1959     return 0;
1960 }
1961 
1962 #endif /* defined(__linux__) */
1963 
1964 
1965 #if defined WITH_MNTENT_H && defined WITH_GETMNTENT_R
1966 static int
virFileGetMountSubtreeImpl(const char * mtabpath,const char * prefix,char *** mountsret,size_t * nmountsret,bool reverse)1967 virFileGetMountSubtreeImpl(const char *mtabpath,
1968                            const char *prefix,
1969                            char ***mountsret,
1970                            size_t *nmountsret,
1971                            bool reverse)
1972 {
1973     FILE *procmnt;
1974     struct mntent mntent;
1975     char mntbuf[1024];
1976     char **mounts = NULL;
1977     size_t nmounts = 0;
1978 
1979     VIR_DEBUG("prefix=%s", prefix);
1980 
1981     *mountsret = NULL;
1982     *nmountsret = 0;
1983 
1984     if (!(procmnt = setmntent(mtabpath, "r"))) {
1985         virReportSystemError(errno,
1986                              _("Failed to read %s"), mtabpath);
1987         return -1;
1988     }
1989 
1990     while (getmntent_r(procmnt, &mntent, mntbuf, sizeof(mntbuf)) != NULL) {
1991         if (!(STREQ(mntent.mnt_dir, prefix) ||
1992               (STRPREFIX(mntent.mnt_dir, prefix) &&
1993                mntent.mnt_dir[strlen(prefix)] == '/')))
1994             continue;
1995 
1996         VIR_EXPAND_N(mounts, nmounts, nmounts ? 1 : 2);
1997         mounts[nmounts - 2] = g_strdup(mntent.mnt_dir);
1998     }
1999 
2000     if (mounts)
2001         qsort(mounts, nmounts - 1, sizeof(mounts[0]),
2002               reverse ? virStringSortRevCompare : virStringSortCompare);
2003 
2004     *mountsret = mounts;
2005     *nmountsret = nmounts ? nmounts - 1 : 0;
2006     endmntent(procmnt);
2007     return 0;
2008 }
2009 #else /* ! defined WITH_MNTENT_H && defined WITH_GETMNTENT_R */
2010 static int
virFileGetMountSubtreeImpl(const char * mtabpath G_GNUC_UNUSED,const char * prefix G_GNUC_UNUSED,char *** mountsret G_GNUC_UNUSED,size_t * nmountsret G_GNUC_UNUSED,bool reverse G_GNUC_UNUSED)2011 virFileGetMountSubtreeImpl(const char *mtabpath G_GNUC_UNUSED,
2012                            const char *prefix G_GNUC_UNUSED,
2013                            char ***mountsret G_GNUC_UNUSED,
2014                            size_t *nmountsret G_GNUC_UNUSED,
2015                            bool reverse G_GNUC_UNUSED)
2016 {
2017     virReportSystemError(ENOSYS, "%s",
2018                          _("Unable to determine mount table on this platform"));
2019     return -1;
2020 }
2021 #endif /* ! defined WITH_MNTENT_H && defined WITH_GETMNTENT_R */
2022 
2023 /**
2024  * virFileGetMountSubtree:
2025  * @mtabpath: mount file to parser (eg /proc/mounts)
2026  * @prefix: mount path prefix to match
2027  * @mountsret: allocated and filled with matching mounts
2028  * @nmountsret: filled with number of matching mounts, not counting NULL terminator
2029  *
2030  * Return the list of mounts from @mtabpath which contain
2031  * the path @prefix, sorted alphabetically.
2032  *
2033  * The @mountsret array will be NULL terminated and should
2034  * be freed with g_strfreev
2035  *
2036  * Returns 0 on success, -1 on error
2037  */
virFileGetMountSubtree(const char * mtabpath,const char * prefix,char *** mountsret,size_t * nmountsret)2038 int virFileGetMountSubtree(const char *mtabpath,
2039                            const char *prefix,
2040                            char ***mountsret,
2041                            size_t *nmountsret)
2042 {
2043     return virFileGetMountSubtreeImpl(mtabpath, prefix, mountsret, nmountsret, false);
2044 }
2045 
2046 /**
2047  * virFileGetMountReverseSubtree:
2048  * @mtabpath: mount file to parser (eg /proc/mounts)
2049  * @prefix: mount path prefix to match
2050  * @mountsret: allocated and filled with matching mounts
2051  * @nmountsret: filled with number of matching mounts, not counting NULL terminator
2052  *
2053  * Return the list of mounts from @mtabpath which contain
2054  * the path @prefix, reverse-sorted alphabetically.
2055  *
2056  * The @mountsret array will be NULL terminated and should
2057  * be freed with g_strfreev
2058  *
2059  * Returns 0 on success, -1 on error
2060  */
virFileGetMountReverseSubtree(const char * mtabpath,const char * prefix,char *** mountsret,size_t * nmountsret)2061 int virFileGetMountReverseSubtree(const char *mtabpath,
2062                                   const char *prefix,
2063                                   char ***mountsret,
2064                                   size_t *nmountsret)
2065 {
2066     return virFileGetMountSubtreeImpl(mtabpath, prefix, mountsret, nmountsret, true);
2067 }
2068 
2069 #ifndef WIN32
2070 /* Check that a file is accessible under certain
2071  * user & gid.
2072  * @mode can be F_OK, or a bitwise combination of R_OK, W_OK, and X_OK.
2073  * see 'man access' for more details.
2074  * Returns 0 on success, -1 on fail with errno set.
2075  */
2076 int
virFileAccessibleAs(const char * path,int mode,uid_t uid,gid_t gid)2077 virFileAccessibleAs(const char *path, int mode,
2078                     uid_t uid, gid_t gid)
2079 {
2080     pid_t pid = 0;
2081     int status, ret = 0;
2082     g_autofree gid_t *groups = NULL;
2083     int ngroups;
2084 
2085     if (uid == geteuid() &&
2086         gid == getegid())
2087         return access(path, mode);
2088 
2089     ngroups = virGetGroupList(uid, gid, &groups);
2090     if (ngroups < 0)
2091         return -1;
2092 
2093     pid = virFork();
2094 
2095     if (pid < 0)
2096         return -1;
2097 
2098     if (pid) { /* parent */
2099         if (virProcessWait(pid, &status, false) < 0) {
2100             /* virProcessWait() already reported error */
2101             errno = EINTR;
2102             return -1;
2103         }
2104 
2105         if (status) {
2106             errno = status;
2107             return -1;
2108         }
2109 
2110         return 0;
2111     }
2112 
2113     if (virSetUIDGID(uid, gid, groups, ngroups) < 0) {
2114         ret = errno;
2115         goto childerror;
2116     }
2117 
2118     if (access(path, mode) < 0)
2119         ret = errno;
2120 
2121  childerror:
2122     if ((ret & 0xFF) != ret) {
2123         VIR_WARN("unable to pass desired return value %d", ret);
2124         ret = 0xFF;
2125     }
2126 
2127     _exit(ret);
2128 }
2129 
2130 /* virFileOpenForceOwnerMode() - an internal utility function called
2131  * only by virFileOpenAs().  Sets the owner and mode of the file
2132  * opened as "fd" if it's not correct AND the flags say it should be
2133  * forced. */
2134 static int
virFileOpenForceOwnerMode(const char * path,int fd,mode_t mode,uid_t uid,gid_t gid,unsigned int flags)2135 virFileOpenForceOwnerMode(const char *path, int fd, mode_t mode,
2136                           uid_t uid, gid_t gid, unsigned int flags)
2137 {
2138     int ret = 0;
2139     struct stat st;
2140 
2141     if (!(flags & (VIR_FILE_OPEN_FORCE_OWNER | VIR_FILE_OPEN_FORCE_MODE)))
2142         return 0;
2143 
2144     if (fstat(fd, &st) == -1) {
2145         ret = -errno;
2146         virReportSystemError(errno, _("stat of '%s' failed"), path);
2147         return ret;
2148     }
2149     /* NB: uid:gid are never "-1" (default) at this point - the caller
2150      * has always changed -1 to the value of get[gu]id().
2151     */
2152     if ((flags & VIR_FILE_OPEN_FORCE_OWNER) &&
2153         ((st.st_uid != uid) || (st.st_gid != gid)) &&
2154         (fchown(fd, uid, gid) < 0)) {
2155         ret = -errno;
2156         virReportSystemError(errno,
2157                              _("cannot chown '%s' to (%u, %u)"),
2158                              path, (unsigned int) uid,
2159                              (unsigned int) gid);
2160         return ret;
2161     }
2162     if ((flags & VIR_FILE_OPEN_FORCE_MODE) &&
2163         ((mode & (S_IRWXU|S_IRWXG|S_IRWXO)) !=
2164          (st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO))) &&
2165         (fchmod(fd, mode) < 0)) {
2166         ret = -errno;
2167         virReportSystemError(errno,
2168                              _("cannot set mode of '%s' to %04o"),
2169                              path, mode);
2170         return ret;
2171     }
2172     return ret;
2173 }
2174 
2175 /* virFileOpenForked() - an internal utility function called only by
2176  * virFileOpenAs(). It forks, then the child does setuid+setgid to
2177  * given uid:gid and attempts to open the file, while the parent just
2178  * calls recvfd to get the open fd back from the child. returns the
2179  * fd, or -errno if there is an error. Additionally, to avoid another
2180  * round-trip to unlink the file in a forked process; on error if this
2181  * function created the file, but failed to perform some action after
2182  * creation, then perform the unlink of the file. The storage driver
2183  * buildVol backend function expects the file to be deleted on error.
2184  */
2185 static int
virFileOpenForked(const char * path,int openflags,mode_t mode,uid_t uid,gid_t gid,unsigned int flags)2186 virFileOpenForked(const char *path, int openflags, mode_t mode,
2187                   uid_t uid, gid_t gid, unsigned int flags)
2188 {
2189     pid_t pid;
2190     int status = 0, ret = 0;
2191     int recvfd_errno = 0;
2192     int fd = -1;
2193     int pair[2] = { -1, -1 };
2194     g_autofree gid_t *groups = NULL;
2195     int ngroups;
2196     bool created = false;
2197 
2198     /* parent is running as root, but caller requested that the
2199      * file be opened as some other user and/or group). The
2200      * following dance avoids problems caused by root-squashing
2201      * NFS servers. */
2202 
2203     ngroups = virGetGroupList(uid, gid, &groups);
2204     if (ngroups < 0)
2205         return -errno;
2206 
2207     if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) < 0) {
2208         ret = -errno;
2209         virReportSystemError(errno,
2210                              _("failed to create socket needed for '%s'"),
2211                              path);
2212         return ret;
2213     }
2214 
2215     pid = virFork();
2216     if (pid < 0)
2217         return -errno;
2218 
2219     if (pid == 0) {
2220 
2221         /* child */
2222 
2223         /* set desired uid/gid, then attempt to create the file */
2224         VIR_FORCE_CLOSE(pair[0]);
2225         if (virSetUIDGID(uid, gid, groups, ngroups) < 0) {
2226             ret = -errno;
2227             goto childerror;
2228         }
2229 
2230         if ((fd = open(path, openflags, mode)) < 0) {
2231             ret = -errno;
2232             virReportSystemError(errno,
2233                                  _("child process failed to create file '%s'"),
2234                                  path);
2235             goto childerror;
2236         }
2237         if (openflags & O_CREAT)
2238             created = true;
2239 
2240         /* File is successfully open. Set permissions if requested. */
2241         ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags);
2242         if (ret < 0) {
2243             ret = -errno;
2244             virReportSystemError(errno,
2245                                  _("child process failed to force owner mode file '%s'"),
2246                                  path);
2247             goto childerror;
2248         }
2249 
2250         do {
2251             ret = virSocketSendFD(pair[1], fd);
2252         } while (ret < 0 && errno == EINTR);
2253 
2254         if (ret < 0) {
2255             ret = -errno;
2256             virReportSystemError(errno, "%s",
2257                                  _("child process failed to send fd to parent"));
2258             goto childerror;
2259         }
2260 
2261     childerror:
2262         /* ret tracks -errno on failure, but exit value must be positive.
2263          * If the child exits with EACCES, then the parent tries again.  */
2264         /* XXX This makes assumptions about errno being < 255, which is
2265          * not true on Hurd.  */
2266         VIR_FORCE_CLOSE(pair[1]);
2267         if (ret < 0) {
2268             VIR_FORCE_CLOSE(fd);
2269             if (created)
2270                 unlink(path);
2271         }
2272         ret = -ret;
2273         if ((ret & 0xff) != ret) {
2274             VIR_WARN("unable to pass desired return value %d", ret);
2275             ret = 0xff;
2276         }
2277         _exit(ret);
2278     }
2279 
2280     /* parent */
2281 
2282     VIR_FORCE_CLOSE(pair[1]);
2283 
2284     do {
2285         fd = virSocketRecvFD(pair[0], 0);
2286     } while (fd < 0 && errno == EINTR);
2287     VIR_FORCE_CLOSE(pair[0]); /* NB: this preserves errno */
2288     if (fd < 0)
2289         recvfd_errno = errno;
2290 
2291     if (virProcessWait(pid, &status, 0) < 0) {
2292         /* virProcessWait() reports errno on waitpid failure, so we'll just
2293          * set our return status to EINTR; otherwise, set status to EACCES
2294          * since the original failure for the fork+setuid path would have
2295          * been EACCES or EPERM by definition.
2296          */
2297         if (virLastErrorIsSystemErrno(0))
2298             status = EINTR;
2299         else if (!status)
2300             status = EACCES;
2301     }
2302 
2303     if (status) {
2304         VIR_FORCE_CLOSE(fd);
2305         return -status;
2306     }
2307 
2308     /* if waitpid succeeded, but recvfd failed, report recvfd_errno */
2309     if (recvfd_errno != 0) {
2310         virReportSystemError(recvfd_errno,
2311                              _("failed recvfd for child creating '%s'"),
2312                              path);
2313         return -recvfd_errno;
2314     }
2315 
2316     /* otherwise, waitpid and recvfd succeeded, return the fd */
2317     return fd;
2318 }
2319 
2320 /**
2321  * virFileOpenAs:
2322  * @path: file to open or create
2323  * @openflags: flags to pass to open
2324  * @mode: mode to use on creation or when forcing permissions
2325  * @uid: uid that should own file on creation
2326  * @gid: gid that should own file
2327  * @flags: bit-wise or of VIR_FILE_OPEN_* flags
2328  *
2329  * Open @path, and return an fd to the open file. @openflags contains
2330  * the flags normally passed to open(2), while those in @flags are
2331  * used internally. If @flags includes VIR_FILE_OPEN_NOFORK, then try
2332  * opening the file while executing with the current uid:gid
2333  * (i.e. don't fork+setuid+setgid before the call to open()).  If
2334  * @flags includes VIR_FILE_OPEN_FORK, then try opening the file while
2335  * the effective user id is @uid (by forking a child process); this
2336  * allows one to bypass root-squashing NFS issues; NOFORK is always
2337  * tried before FORK (the absence of both flags is treated identically
2338  * to (VIR_FILE_OPEN_NOFORK | VIR_FILE_OPEN_FORK)). If @flags includes
2339  * VIR_FILE_OPEN_FORCE_OWNER, then ensure that @path is owned by
2340  * uid:gid before returning (even if it already existed with a
2341  * different owner). If @flags includes VIR_FILE_OPEN_FORCE_MODE,
2342  * ensure it has those permissions before returning (again, even if
2343  * the file already existed with different permissions).
2344  *
2345  * The return value (if non-negative) is the file descriptor, left
2346  * open.  Returns -errno on failure. Additionally, to avoid another
2347  * round-trip to unlink the file; on error if this function created the
2348  * file, but failed to perform some action after creation, then perform
2349  * the unlink of the file. The storage driver buildVol backend function
2350  * expects the file to be deleted on error.
2351  */
2352 int
virFileOpenAs(const char * path,int openflags,mode_t mode,uid_t uid,gid_t gid,unsigned int flags)2353 virFileOpenAs(const char *path, int openflags, mode_t mode,
2354               uid_t uid, gid_t gid, unsigned int flags)
2355 {
2356     int ret = 0, fd = -1;
2357     bool created = false;
2358 
2359     /* allow using -1 to mean "current value" */
2360     if (uid == (uid_t) -1)
2361         uid = geteuid();
2362     if (gid == (gid_t) -1)
2363         gid = getegid();
2364 
2365     /* treat absence of both flags as presence of both for simpler
2366      * calling. */
2367     if (!(flags & (VIR_FILE_OPEN_NOFORK|VIR_FILE_OPEN_FORK)))
2368         flags |= VIR_FILE_OPEN_NOFORK|VIR_FILE_OPEN_FORK;
2369 
2370     if ((flags & VIR_FILE_OPEN_NOFORK)
2371         || (geteuid() != 0)
2372         || ((uid == 0) && (gid == 0))) {
2373 
2374         if ((fd = open(path, openflags, mode)) < 0) {
2375             ret = -errno;
2376             if (!(flags & VIR_FILE_OPEN_FORK))
2377                 goto error;
2378         } else {
2379             if (openflags & O_CREAT)
2380                 created = true;
2381             ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags);
2382             if (ret < 0)
2383                 goto error;
2384         }
2385     }
2386 
2387     /* If we either 1) didn't try opening as current user at all, or
2388      * 2) failed, and errno/virStorageFileIsSharedFS indicate we might
2389      * be successful if we try as a different uid, then try doing
2390      * fork+setuid+setgid before opening.
2391      */
2392     if ((fd < 0) && (flags & VIR_FILE_OPEN_FORK)) {
2393 
2394         if (ret < 0) {
2395             /* An open(2) that failed due to insufficient permissions
2396              * could return one or the other of these depending on OS
2397              * version and circumstances. Any other errno indicates a
2398              * problem that couldn't be remedied by fork+setuid
2399              * anyway. */
2400             if (ret != -EACCES && ret != -EPERM)
2401                 goto error;
2402 
2403             /* On Linux we can also verify the FS-type of the
2404              * directory.  (this is a NOP on other platforms). */
2405             if (virFileIsSharedFS(path) <= 0)
2406                 goto error;
2407         }
2408 
2409         /* passed all prerequisites - retry the open w/fork+setuid */
2410         if ((fd = virFileOpenForked(path, openflags, mode, uid, gid, flags)) < 0) {
2411             ret = fd;
2412             goto error;
2413         }
2414     }
2415 
2416     /* File is successfully opened */
2417     return fd;
2418 
2419  error:
2420     if (fd >= 0) {
2421         /* some other failure after the open succeeded */
2422         VIR_FORCE_CLOSE(fd);
2423         if (created)
2424             unlink(path);
2425     }
2426     /* whoever failed the open last has already set ret = -errno */
2427     return ret;
2428 }
2429 
2430 
2431 /* virFileRemoveNeedsSetuid:
2432  * @path: file we plan to remove
2433  * @uid: file uid to check
2434  * @gid: file gid to check
2435  *
2436  * Return true if we should use setuid/setgid before deleting a file
2437  * owned by the passed uid/gid pair. Needed for NFS with root-squash
2438  */
2439 static bool
virFileRemoveNeedsSetuid(const char * path,uid_t uid,gid_t gid)2440 virFileRemoveNeedsSetuid(const char *path, uid_t uid, gid_t gid)
2441 {
2442     /* If running unprivileged, setuid isn't going to work */
2443     if (geteuid() != 0)
2444         return false;
2445 
2446     /* uid/gid weren't specified */
2447     if ((uid == (uid_t) -1) && (gid == (gid_t) -1))
2448         return false;
2449 
2450     /* already running as proper uid/gid */
2451     if (uid == geteuid() && gid == getegid())
2452         return false;
2453 
2454     /* Only perform the setuid stuff for NFS, which is the only case
2455        that may actually need it. This can error, but just be safe and
2456        only check for a clear negative result. */
2457     if (virFileIsSharedFSType(path, VIR_FILE_SHFS_NFS) == 0)
2458         return false;
2459 
2460     return true;
2461 }
2462 
2463 
2464 /* virFileRemove:
2465  * @path: file to unlink or directory to remove
2466  * @uid: uid that was used to create the file (not required)
2467  * @gid: gid that was used to create the file (not required)
2468  *
2469  * If a file/volume was created in an NFS root-squash environment,
2470  * then we must 'unlink' the file in the same environment. Unlike
2471  * the virFileOpenAs[Forked] and virDirCreate[NoFork], this code
2472  * takes no extra flags and does not bother with EACCES failures
2473  * from the child.
2474  */
2475 int
virFileRemove(const char * path,uid_t uid,gid_t gid)2476 virFileRemove(const char *path,
2477               uid_t uid,
2478               gid_t gid)
2479 {
2480     pid_t pid;
2481     int status = 0, ret = 0;
2482     g_autofree gid_t *groups = NULL;
2483     int ngroups;
2484 
2485     if (!virFileRemoveNeedsSetuid(path, uid, gid)) {
2486         if (virFileIsDir(path))
2487             return rmdir(path);
2488         else
2489             return unlink(path);
2490     }
2491 
2492     /* Otherwise, we have to deal with the NFS root-squash craziness
2493      * to run under the uid/gid that created the volume in order to
2494      * perform the unlink of the volume.
2495      */
2496     if (uid == (uid_t) -1)
2497         uid = geteuid();
2498     if (gid == (gid_t) -1)
2499         gid = getegid();
2500 
2501     ngroups = virGetGroupList(uid, gid, &groups);
2502     if (ngroups < 0)
2503         return -errno;
2504 
2505     pid = virFork();
2506 
2507     if (pid < 0)
2508         return -errno;
2509 
2510     if (pid) { /* parent */
2511         /* wait for child to complete, and retrieve its exit code */
2512 
2513         if (virProcessWait(pid, &status, 0) < 0) {
2514             /* virProcessWait() reports errno on waitpid failure, so we'll just
2515              * set our return status to EINTR; otherwise, set status to EACCES
2516              * since the original failure for the fork+setuid path would have
2517              * been EACCES or EPERM by definition.
2518              */
2519             if (virLastErrorIsSystemErrno(0))
2520                 status = EINTR;
2521             else if (!status)
2522                 status = EACCES;
2523         }
2524 
2525         if (status) {
2526             errno = status;
2527             ret = -1;
2528         }
2529 
2530         return ret;
2531     }
2532 
2533     /* child */
2534 
2535     /* set desired uid/gid, then attempt to unlink the file */
2536     if (virSetUIDGID(uid, gid, groups, ngroups) < 0) {
2537         ret = errno;
2538         goto childerror;
2539     }
2540 
2541     if (virFileIsDir(path)) {
2542         if (rmdir(path) < 0) {
2543             ret = errno;
2544             goto childerror;
2545         }
2546     } else {
2547         if (unlink(path) < 0) {
2548             ret = errno;
2549             goto childerror;
2550         }
2551     }
2552 
2553  childerror:
2554     if ((ret & 0xff) != ret) {
2555         VIR_WARN("unable to pass desired return value %d", ret);
2556         ret = 0xff;
2557     }
2558     _exit(ret);
2559 }
2560 
2561 
2562 /* Attempt to create a directory and possibly adjust its owner/group and
2563  * permissions.
2564  *
2565  * return 0 on success or -errno on failure. Additionally to avoid another
2566  * round-trip to remove the directory on failure, perform the rmdir when
2567  * a mkdir was successful, but some other failure would cause a -1 return.
2568  * The storage driver buildVol backend function expects the directory to
2569  * be deleted on error.
2570  */
2571 static int
virDirCreateNoFork(const char * path,mode_t mode,uid_t uid,gid_t gid,unsigned int flags)2572 virDirCreateNoFork(const char *path,
2573                    mode_t mode, uid_t uid, gid_t gid,
2574                    unsigned int flags)
2575 {
2576     int ret = 0;
2577     struct stat st;
2578     bool created = false;
2579 
2580     if (!((flags & VIR_DIR_CREATE_ALLOW_EXIST) && virFileExists(path))) {
2581         if (mkdir(path, mode) < 0) {
2582             ret = -errno;
2583             virReportSystemError(errno, _("failed to create directory '%s'"),
2584                                  path);
2585             goto error;
2586         }
2587         created = true;
2588     }
2589 
2590     if (stat(path, &st) == -1) {
2591         ret = -errno;
2592         virReportSystemError(errno, _("stat of '%s' failed"), path);
2593         goto error;
2594     }
2595 
2596     if (((uid != (uid_t) -1 && st.st_uid != uid) ||
2597          (gid != (gid_t) -1 && st.st_gid != gid))
2598         && (chown(path, uid, gid) < 0)) {
2599         ret = -errno;
2600         virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"),
2601                              path, (unsigned int) uid, (unsigned int) gid);
2602         goto error;
2603     }
2604 
2605     if (mode != (mode_t) -1 && chmod(path, mode) < 0) {
2606         ret = -errno;
2607         virReportSystemError(errno,
2608                              _("cannot set mode of '%s' to %04o"),
2609                              path, mode);
2610         goto error;
2611     }
2612  error:
2613     if (ret < 0 && created)
2614         rmdir(path);
2615     return ret;
2616 }
2617 
2618 /*
2619  * virDirCreate:
2620  * @path: directory to create
2621  * @mode: mode to use on creation or when forcing permissions
2622  * @uid: uid that should own directory
2623  * @gid: gid that should own directory
2624  * @flags: bit-wise or of VIR_DIR_CREATE_* flags
2625  *
2626  * Attempt to create a directory and possibly adjust its owner/group and
2627  * permissions. If conditions allow, use the *NoFork code in order to create
2628  * the directory under current owner/group rather than via a forked process.
2629  *
2630  * return 0 on success or -errno on failure. Additionally to avoid another
2631  * round-trip to remove the directory on failure, perform the rmdir if a
2632  * mkdir was successful, but some other failure would cause a -1 return.
2633  * The storage driver buildVol backend function expects the directory to
2634  * be deleted on error.
2635  *
2636  */
2637 int
virDirCreate(const char * path,mode_t mode,uid_t uid,gid_t gid,unsigned int flags)2638 virDirCreate(const char *path,
2639              mode_t mode, uid_t uid, gid_t gid,
2640              unsigned int flags)
2641 {
2642     struct stat st;
2643     pid_t pid;
2644     int status = 0, ret = 0;
2645     g_autofree gid_t *groups = NULL;
2646     int ngroups;
2647     bool created = false;
2648 
2649     /* Everything after this check is crazyness to allow setting uid/gid
2650      * on directories that are on root-squash NFS shares. We only want
2651      * to go that route if the follow conditions are true:
2652      *
2653      * 1) VIR_DIR_CREATE_AS_UID was passed, currently only used when
2654      *    directory is being created for a NETFS pool
2655      * 2) We are running as root, since that's when the root-squash
2656      *    workaround is required.
2657      * 3) An explicit uid/gid was requested
2658      * 4) The directory doesn't already exist and the ALLOW_EXIST flag
2659      *    wasn't passed.
2660      *
2661      * If any of those conditions are _not_ met, ignore the fork crazyness
2662      */
2663     if ((!(flags & VIR_DIR_CREATE_AS_UID))
2664         || (geteuid() != 0)
2665         || ((uid == (uid_t) -1) && (gid == (gid_t) -1))
2666         || ((flags & VIR_DIR_CREATE_ALLOW_EXIST) && virFileExists(path))) {
2667         return virDirCreateNoFork(path, mode, uid, gid, flags);
2668     }
2669 
2670     if (uid == (uid_t) -1)
2671         uid = geteuid();
2672     if (gid == (gid_t) -1)
2673         gid = getegid();
2674 
2675     ngroups = virGetGroupList(uid, gid, &groups);
2676     if (ngroups < 0)
2677         return -errno;
2678 
2679     pid = virFork();
2680 
2681     if (pid < 0)
2682         return -errno;
2683 
2684     if (pid) { /* parent */
2685         /* wait for child to complete, and retrieve its exit code */
2686 
2687         if (virProcessWait(pid, &status, 0) < 0) {
2688             /* virProcessWait() reports errno on waitpid failure, so we'll just
2689              * set our return status to EINTR; otherwise, set status to EACCES
2690              * since the original failure for the fork+setuid path would have
2691              * been EACCES or EPERM by definition.
2692              */
2693             if (virLastErrorIsSystemErrno(0))
2694                 status = EINTR;
2695             else if (!status)
2696                 status = EACCES;
2697         }
2698 
2699         /*
2700          * If the child exited with EACCES, then fall back to non-fork method
2701          * as in the original logic introduced and explained by commit 98f6f381.
2702          */
2703         if (status == EACCES) {
2704             virResetLastError();
2705             return virDirCreateNoFork(path, mode, uid, gid, flags);
2706         }
2707 
2708         if (status)
2709             ret = -status;
2710 
2711         return ret;
2712     }
2713 
2714     /* child */
2715 
2716     /* set desired uid/gid, then attempt to create the directory */
2717     if (virSetUIDGID(uid, gid, groups, ngroups) < 0) {
2718         ret = errno;
2719         goto childerror;
2720     }
2721 
2722     if (mkdir(path, mode) < 0) {
2723         ret = errno;
2724         if (ret != EACCES) {
2725             /* in case of EACCES, the parent will retry */
2726             virReportSystemError(errno, _("child failed to create directory '%s'"),
2727                                  path);
2728         }
2729         goto childerror;
2730     }
2731     created = true;
2732 
2733     /* check if group was set properly by creating after
2734      * setgid. If not, try doing it with chown */
2735     if (stat(path, &st) == -1) {
2736         ret = errno;
2737         virReportSystemError(errno,
2738                              _("stat of '%s' failed"), path);
2739         goto childerror;
2740     }
2741 
2742     if ((st.st_gid != gid) && (chown(path, (uid_t) -1, gid) < 0)) {
2743         ret = errno;
2744         virReportSystemError(errno,
2745                              _("cannot chown '%s' to group %u"),
2746                              path, (unsigned int) gid);
2747         goto childerror;
2748     }
2749 
2750     if (mode != (mode_t) -1 && chmod(path, mode) < 0) {
2751         virReportSystemError(errno,
2752                              _("cannot set mode of '%s' to %04o"),
2753                              path, mode);
2754         goto childerror;
2755     }
2756 
2757  childerror:
2758     if (ret != 0 && created)
2759         rmdir(path);
2760 
2761     if ((ret & 0xff) != ret) {
2762         VIR_WARN("unable to pass desired return value %d", ret);
2763         ret = 0xff;
2764     }
2765     _exit(ret);
2766 }
2767 
2768 #else /* WIN32 */
2769 
2770 int
virFileAccessibleAs(const char * path,int mode,uid_t uid G_GNUC_UNUSED,gid_t gid G_GNUC_UNUSED)2771 virFileAccessibleAs(const char *path,
2772                     int mode,
2773                     uid_t uid G_GNUC_UNUSED,
2774                     gid_t gid G_GNUC_UNUSED)
2775 {
2776     VIR_WARN("Ignoring uid/gid due to WIN32");
2777 
2778     return access(path, mode);
2779 }
2780 
2781 /* return -errno on failure, or 0 on success */
2782 int
virFileOpenAs(const char * path G_GNUC_UNUSED,int openflags G_GNUC_UNUSED,mode_t mode G_GNUC_UNUSED,uid_t uid G_GNUC_UNUSED,gid_t gid G_GNUC_UNUSED,unsigned int flags_unused G_GNUC_UNUSED)2783 virFileOpenAs(const char *path G_GNUC_UNUSED,
2784               int openflags G_GNUC_UNUSED,
2785               mode_t mode G_GNUC_UNUSED,
2786               uid_t uid G_GNUC_UNUSED,
2787               gid_t gid G_GNUC_UNUSED,
2788               unsigned int flags_unused G_GNUC_UNUSED)
2789 {
2790     virReportError(VIR_ERR_INTERNAL_ERROR,
2791                    "%s", _("virFileOpenAs is not implemented for WIN32"));
2792 
2793     return -ENOSYS;
2794 }
2795 
2796 int
virDirCreate(const char * path G_GNUC_UNUSED,mode_t mode G_GNUC_UNUSED,uid_t uid G_GNUC_UNUSED,gid_t gid G_GNUC_UNUSED,unsigned int flags_unused G_GNUC_UNUSED)2797 virDirCreate(const char *path G_GNUC_UNUSED,
2798              mode_t mode G_GNUC_UNUSED,
2799              uid_t uid G_GNUC_UNUSED,
2800              gid_t gid G_GNUC_UNUSED,
2801              unsigned int flags_unused G_GNUC_UNUSED)
2802 {
2803     virReportError(VIR_ERR_INTERNAL_ERROR,
2804                    "%s", _("virDirCreate is not implemented for WIN32"));
2805 
2806     return -ENOSYS;
2807 }
2808 
2809 int
virFileRemove(const char * path,uid_t uid G_GNUC_UNUSED,gid_t gid G_GNUC_UNUSED)2810 virFileRemove(const char *path,
2811               uid_t uid G_GNUC_UNUSED,
2812               gid_t gid G_GNUC_UNUSED)
2813 {
2814     if (unlink(path) < 0) {
2815         virReportSystemError(errno, _("Unable to unlink path '%s'"),
2816                              path);
2817         return -1;
2818     }
2819 
2820     return 0;
2821 }
2822 #endif /* WIN32 */
2823 
2824 static int
virDirOpenInternal(DIR ** dirp,const char * name,bool ignoreENOENT,bool quiet)2825 virDirOpenInternal(DIR **dirp, const char *name, bool ignoreENOENT, bool quiet)
2826 {
2827     *dirp = opendir(name); /* exempt from syntax-check */
2828     if (!*dirp) {
2829         if (quiet)
2830             return -1;
2831 
2832         if (ignoreENOENT && errno == ENOENT)
2833             return 0;
2834         virReportSystemError(errno, _("cannot open directory '%s'"), name);
2835         return -1;
2836     }
2837     return 1;
2838 }
2839 
2840 /**
2841  * virDirOpen
2842  * @dirp: directory stream
2843  * @name: path of the directory
2844  *
2845  * Returns 1 on success.
2846  * On failure, -1 is returned and an error is reported.
2847  */
2848 int
virDirOpen(DIR ** dirp,const char * name)2849 virDirOpen(DIR **dirp, const char *name)
2850 {
2851     return virDirOpenInternal(dirp, name, false, false);
2852 }
2853 
2854 /**
2855  * virDirOpenIfExists
2856  * @dirp: directory stream
2857  * @name: path of the directory
2858  *
2859  * Returns 1 on success.
2860  * If opendir returns ENOENT, 0 is returned without reporting an error.
2861  * On other errors, -1 is returned and an error is reported.
2862  */
2863 int
virDirOpenIfExists(DIR ** dirp,const char * name)2864 virDirOpenIfExists(DIR **dirp, const char *name)
2865 {
2866     return virDirOpenInternal(dirp, name, true, false);
2867 }
2868 
2869 /**
2870  * virDirOpenQuiet
2871  * @dirp: directory stream
2872  * @name: path of the directory
2873  *
2874  * Returns 1 on success.
2875  *        -1 on failure.
2876  *
2877  * Does not report any errors and errno is preserved.
2878  */
2879 int
virDirOpenQuiet(DIR ** dirp,const char * name)2880 virDirOpenQuiet(DIR **dirp, const char *name)
2881 {
2882     return virDirOpenInternal(dirp, name, false, true);
2883 }
2884 
2885 /**
2886  * virDirRead:
2887  * @dirp: directory to read
2888  * @ent: output one entry
2889  * @name: if non-NULL, the name related to @dirp for use in error reporting
2890  *
2891  * Wrapper around readdir. Typical usage:
2892  *   g_autoptr(DIR) dir = NULL;
2893  *   struct dirent *ent;
2894  *   int rc;
2895  *   if (virDirOpen(&dir, name) < 0)
2896  *       goto error;
2897  *   while ((rc = virDirRead(dir, &ent, name)) > 0)
2898  *       process ent;
2899  *   if (rc < 0)
2900  *       goto error;
2901  *
2902  * Returns -1 on error, with error already reported if @name was
2903  * supplied.  On success, returns 1 for entry read, 0 for end-of-dir.
2904  */
virDirRead(DIR * dirp,struct dirent ** ent,const char * name)2905 int virDirRead(DIR *dirp, struct dirent **ent, const char *name)
2906 {
2907     do {
2908         errno = 0;
2909         *ent = readdir(dirp); /* exempt from syntax-check */
2910         if (!*ent && errno) {
2911             if (name)
2912                 virReportSystemError(errno, _("Unable to read directory '%s'"),
2913                                      name);
2914             return -1;
2915         }
2916     } while (*ent && (STREQ((*ent)->d_name, ".") ||
2917                       STREQ((*ent)->d_name, "..")));
2918     return !!*ent;
2919 }
2920 
virDirClose(DIR * dirp)2921 void virDirClose(DIR *dirp)
2922 {
2923     if (!dirp)
2924         return;
2925 
2926     closedir(dirp); /* exempt from syntax-check */
2927 }
2928 
2929 
2930 /*
2931  * virFileChownFiles:
2932  * @name: name of the directory
2933  * @uid: uid
2934  * @gid: gid
2935  *
2936  * Change ownership of all regular files in a directory.
2937  *
2938  * Returns -1 on error, with error already reported, 0 on success.
2939  */
2940 #ifndef WIN32
virFileChownFiles(const char * name,uid_t uid,gid_t gid)2941 int virFileChownFiles(const char *name,
2942                       uid_t uid,
2943                       gid_t gid)
2944 {
2945     struct dirent *ent;
2946     int direrr;
2947     g_autoptr(DIR) dir = NULL;
2948 
2949     if (virDirOpen(&dir, name) < 0)
2950         return -1;
2951 
2952     while ((direrr = virDirRead(dir, &ent, name)) > 0) {
2953         g_autofree char *path = NULL;
2954 
2955         path = g_build_filename(name, ent->d_name, NULL);
2956 
2957         if (!virFileIsRegular(path))
2958             continue;
2959 
2960         if (chown(path, uid, gid) < 0) {
2961             virReportSystemError(errno,
2962                                  _("cannot chown '%s' to (%u, %u)"),
2963                                  ent->d_name, (unsigned int) uid,
2964                                  (unsigned int) gid);
2965             return -1;
2966         }
2967     }
2968 
2969     if (direrr < 0)
2970         return -1;
2971 
2972     return 0;
2973 }
2974 
2975 #else /* WIN32 */
2976 
virFileChownFiles(const char * name,uid_t uid,gid_t gid)2977 int virFileChownFiles(const char *name,
2978                       uid_t uid,
2979                       gid_t gid)
2980 {
2981     virReportSystemError(ENOSYS,
2982                          _("cannot chown '%s' to (%u, %u)"),
2983                          name, (unsigned int) uid,
2984                          (unsigned int) gid);
2985     return -1;
2986 }
2987 #endif /* WIN32 */
2988 
2989 int
virFileMakeParentPath(const char * path)2990 virFileMakeParentPath(const char *path)
2991 {
2992     char *p;
2993     g_autofree char *tmp = NULL;
2994 
2995     VIR_DEBUG("path=%s", path);
2996 
2997     tmp = g_strdup(path);
2998 
2999     if ((p = strrchr(tmp, '/')) == NULL) {
3000         errno = EINVAL;
3001         return -1;
3002     }
3003     *p = '\0';
3004 
3005     return g_mkdir_with_parents(tmp, 0777);
3006 }
3007 
3008 
3009 /* Build up a fully qualified path for a config file to be
3010  * associated with a persistent guest or network */
3011 char *
virFileBuildPath(const char * dir,const char * name,const char * ext)3012 virFileBuildPath(const char *dir, const char *name, const char *ext)
3013 {
3014     char *path;
3015 
3016     if (ext == NULL) {
3017         path = g_build_filename(dir, name, NULL);
3018     } else {
3019         g_autofree char *extName = g_strdup_printf("%s%s", name, ext);
3020         path = g_build_filename(dir, extName, NULL);
3021     }
3022 
3023     return path;
3024 }
3025 
3026 /* Open a non-blocking primary side of a pty. If ttyName is not NULL,
3027  * then populate it with the name of the secondary peer. If rawmode is
3028  * set, also put the primary side into raw mode before returning.  */
3029 #ifndef WIN32
3030 int
virFileOpenTty(int * ttyprimary,char ** ttyName,int rawmode)3031 virFileOpenTty(int *ttyprimary, char **ttyName, int rawmode)
3032 {
3033     /* XXX A word of caution - on some platforms (Solaris and HP-UX),
3034      * additional ioctl() calls are needs after opening the secondary
3035      * before it will cause isatty() to return true.  Should we make
3036      * virFileOpenTty also return the opened secondary fd, so the caller
3037      * doesn't have to worry about that mess?  */
3038     int ret = -1;
3039     int secondary = -1;
3040     g_autofree char *name = NULL;
3041 
3042     /* Unfortunately, we can't use the name argument of openpty, since
3043      * there is no guarantee on how large the buffer has to be.
3044      * Likewise, we can't use the termios argument: we have to use
3045      * read-modify-write since there is no portable way to initialize
3046      * a struct termios without use of tcgetattr.  */
3047     if (openpty(ttyprimary, &secondary, NULL, NULL, NULL) < 0)
3048         return -1;
3049 
3050     /* What a shame that openpty cannot atomically set FD_CLOEXEC, but
3051      * that using posix_openpt/grantpt/unlockpt/ptsname is not
3052      * thread-safe, and that ptsname_r is not portable.  */
3053     if (virSetNonBlock(*ttyprimary) < 0 ||
3054         virSetCloseExec(*ttyprimary) < 0)
3055         goto cleanup;
3056 
3057     /* While Linux supports tcgetattr on either the primary or the
3058      * secondary, Solaris requires it to be on the secondary.  */
3059     if (rawmode) {
3060         struct termios ttyAttr;
3061         if (tcgetattr(secondary, &ttyAttr) < 0)
3062             goto cleanup;
3063 
3064         cfmakeraw(&ttyAttr);
3065 
3066         if (tcsetattr(secondary, TCSADRAIN, &ttyAttr) < 0)
3067             goto cleanup;
3068     }
3069 
3070     /* ttyname_r on the secondary is required by POSIX, while ptsname_r on
3071      * the primary is a glibc extension, and the POSIX ptsname is not
3072      * thread-safe.  Since openpty gave us both descriptors, guess
3073      * which way we will determine the name?  :)  */
3074     if (ttyName) {
3075         /* Initial guess of 64 is generally sufficient; rely on ERANGE
3076          * to tell us if we need to grow.  */
3077         size_t len = 64;
3078         int rc;
3079 
3080         name = g_new0(char, len);
3081 
3082         while ((rc = ttyname_r(secondary, name, len)) == ERANGE) {
3083             VIR_RESIZE_N(name, len, len, len);
3084         }
3085         if (rc != 0) {
3086             errno = rc;
3087             goto cleanup;
3088         }
3089         *ttyName = g_steal_pointer(&name);
3090     }
3091 
3092     ret = 0;
3093 
3094  cleanup:
3095     if (ret != 0)
3096         VIR_FORCE_CLOSE(*ttyprimary);
3097     VIR_FORCE_CLOSE(secondary);
3098 
3099     return ret;
3100 }
3101 #else /* WIN32 */
3102 int
virFileOpenTty(int * ttyprimary G_GNUC_UNUSED,char ** ttyName G_GNUC_UNUSED,int rawmode G_GNUC_UNUSED)3103 virFileOpenTty(int *ttyprimary G_GNUC_UNUSED,
3104                char **ttyName G_GNUC_UNUSED,
3105                int rawmode G_GNUC_UNUSED)
3106 {
3107     /* mingw completely lacks pseudo-terminals */
3108     errno = ENOSYS;
3109     return -1;
3110 }
3111 #endif /* WIN32 */
3112 
3113 /* Remove spurious / characters from a path. The result must be freed */
3114 char *
virFileSanitizePath(const char * path)3115 virFileSanitizePath(const char *path)
3116 {
3117     const char *cur = path;
3118     char *uri;
3119     char *cleanpath;
3120     int idx = 0;
3121 
3122     cleanpath = g_strdup(path);
3123 
3124     /* don't sanitize URIs - rfc3986 states that two slashes may lead to a
3125      * different resource, thus removing them would possibly change the path */
3126     if ((uri = strstr(path, "://")) && strchr(path, '/') > uri)
3127         return cleanpath;
3128 
3129     /* Need to sanitize:
3130      * //           -> //
3131      * ///          -> /
3132      * /../foo      -> /../foo
3133      * /foo///bar/  -> /foo/bar
3134      */
3135 
3136     /* Starting with // is valid posix, but ///foo == /foo */
3137     if (cur[0] == '/' && cur[1] == '/' && cur[2] != '/') {
3138         idx = 2;
3139         cur += 2;
3140     }
3141 
3142     /* Sanitize path in place */
3143     while (*cur != '\0') {
3144         if (*cur != '/') {
3145             cleanpath[idx++] = *cur++;
3146             continue;
3147         }
3148 
3149         /* Skip all extra / */
3150         while (*++cur == '/')
3151             continue;
3152 
3153         /* Don't add a trailing / */
3154         if (idx != 0 && *cur == '\0')
3155             break;
3156 
3157         cleanpath[idx++] = '/';
3158     }
3159     cleanpath[idx] = '\0';
3160 
3161     return cleanpath;
3162 }
3163 
3164 /**
3165  * virFileCanonicalizePath:
3166  *
3167  * Returns the canonical representation of @path.
3168  *
3169  * The returned string must be freed after use.
3170  */
3171 char *
virFileCanonicalizePath(const char * path)3172 virFileCanonicalizePath(const char *path)
3173 {
3174 #ifdef WIN32
3175     /* Does not resolve symlinks, only expands . & .. & repeated /.
3176      * It will never fail, so sanitize errno to indicate success */
3177     errno = 0;
3178     return g_canonicalize_filename(path, NULL);
3179 #else
3180     return realpath(path, NULL); /* exempt from syntax-check */
3181 #endif
3182 }
3183 
3184 /**
3185  * virFileRemoveLastComponent:
3186  *
3187  * For given path cut off the last component. If there's no dir
3188  * separator (whole path is one file name), @path is turned into
3189  * an empty string.
3190  */
3191 void
virFileRemoveLastComponent(char * path)3192 virFileRemoveLastComponent(char *path)
3193 {
3194     char *tmp;
3195 
3196     if ((tmp = strrchr(path, G_DIR_SEPARATOR)))
3197         tmp[1] = '\0';
3198     else
3199         path[0] = '\0';
3200 }
3201 
3202 #ifdef __linux__
3203 
3204 # ifndef NFS_SUPER_MAGIC
3205 #  define NFS_SUPER_MAGIC 0x6969
3206 # endif
3207 # ifndef OCFS2_SUPER_MAGIC
3208 #  define OCFS2_SUPER_MAGIC 0x7461636f
3209 # endif
3210 # ifndef GFS2_MAGIC
3211 #  define GFS2_MAGIC 0x01161970
3212 # endif
3213 # ifndef AFS_FS_MAGIC
3214 #  define AFS_FS_MAGIC 0x6B414653
3215 # endif
3216 # ifndef SMB_SUPER_MAGIC
3217 #  define SMB_SUPER_MAGIC 0x517B
3218 # endif
3219 # ifndef CIFS_SUPER_MAGIC
3220 #  define CIFS_SUPER_MAGIC 0xFF534D42
3221 # endif
3222 # ifndef HUGETLBFS_MAGIC
3223 #  define HUGETLBFS_MAGIC 0x958458f6
3224 # endif
3225 # ifndef FUSE_SUPER_MAGIC
3226 #  define FUSE_SUPER_MAGIC 0x65735546
3227 # endif
3228 # ifndef CEPH_SUPER_MAGIC
3229 #  define CEPH_SUPER_MAGIC 0x00C36400
3230 # endif
3231 # ifndef GPFS_SUPER_MAGIC
3232 #  define GPFS_SUPER_MAGIC 0x47504653
3233 # endif
3234 # ifndef QB_MAGIC
3235 #  define QB_MAGIC 0x51626d6e
3236 # endif
3237 
3238 # define VIR_ACFS_MAGIC 0x61636673
3239 
3240 # define PROC_MOUNTS "/proc/mounts"
3241 
3242 static int
virFileIsSharedFixFUSE(const char * path,long long * f_type)3243 virFileIsSharedFixFUSE(const char *path,
3244                        long long *f_type)
3245 {
3246     FILE *f = NULL;
3247     struct mntent mb;
3248     char mntbuf[1024];
3249     char *mntDir = NULL;
3250     char *mntType = NULL;
3251     char *canonPath = NULL;
3252     size_t maxMatching = 0;
3253     int ret = -1;
3254 
3255     if (!(canonPath = virFileCanonicalizePath(path))) {
3256         virReportSystemError(errno,
3257                              _("unable to canonicalize %s"),
3258                              path);
3259         return -1;
3260     }
3261 
3262     VIR_DEBUG("Path canonicalization: %s->%s", path, canonPath);
3263 
3264     if (!(f = setmntent(PROC_MOUNTS, "r"))) {
3265         virReportSystemError(errno,
3266                              _("Unable to open %s"),
3267                              PROC_MOUNTS);
3268         goto cleanup;
3269     }
3270 
3271     while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
3272         const char *p;
3273         size_t len = strlen(mb.mnt_dir);
3274 
3275         if (!(p = STRSKIP(canonPath, mb.mnt_dir)))
3276             continue;
3277 
3278         if (*(p - 1) != '/' && *p != '/' && *p != '\0')
3279             continue;
3280 
3281         if (len > maxMatching) {
3282             maxMatching = len;
3283             VIR_FREE(mntType);
3284             VIR_FREE(mntDir);
3285             mntDir = g_strdup(mb.mnt_dir);
3286             mntType = g_strdup(mb.mnt_type);
3287         }
3288     }
3289 
3290     if (STREQ_NULLABLE(mntType, "fuse.glusterfs")) {
3291         VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. "
3292                   "Fixing shared FS type", mntDir, canonPath);
3293         *f_type = GFS2_MAGIC;
3294     } else if (STREQ_NULLABLE(mntType, "fuse.quobyte")) {
3295         VIR_DEBUG("Found Quobyte FUSE mountpoint=%s for path=%s. "
3296                   "Fixing shared FS type", mntDir, canonPath);
3297         *f_type = QB_MAGIC;
3298     }
3299 
3300     ret = 0;
3301  cleanup:
3302     VIR_FREE(canonPath);
3303     VIR_FREE(mntType);
3304     VIR_FREE(mntDir);
3305     endmntent(f);
3306     return ret;
3307 }
3308 
3309 
3310 int
virFileIsSharedFSType(const char * path,int fstypes)3311 virFileIsSharedFSType(const char *path,
3312                       int fstypes)
3313 {
3314     g_autofree char *dirpath = NULL;
3315     char *p = NULL;
3316     struct statfs sb;
3317     int statfs_ret;
3318     long long f_type = 0;
3319 
3320     dirpath = g_strdup(path);
3321 
3322     statfs_ret = statfs(dirpath, &sb);
3323 
3324     while ((statfs_ret < 0) && (p != dirpath)) {
3325         /* Try less and less of the path until we get to a
3326          * directory we can stat. Even if we don't have 'x'
3327          * permission on any directory in the path on the NFS
3328          * server (assuming it's NFS), we will be able to stat the
3329          * mount point, and that will properly tell us if the
3330          * fstype is NFS.
3331          */
3332 
3333         if ((p = strrchr(dirpath, '/')) == NULL) {
3334             virReportSystemError(EINVAL,
3335                                  _("Invalid relative path '%s'"), path);
3336             return -1;
3337         }
3338 
3339         if (p == dirpath)
3340             *(p+1) = '\0';
3341         else
3342             *p = '\0';
3343 
3344         statfs_ret = statfs(dirpath, &sb);
3345     }
3346 
3347     if (statfs_ret < 0) {
3348         virReportSystemError(errno,
3349                              _("cannot determine filesystem for '%s'"),
3350                              path);
3351         return -1;
3352     }
3353 
3354     f_type = sb.f_type;
3355 
3356     if (f_type == FUSE_SUPER_MAGIC) {
3357         VIR_DEBUG("Found FUSE mount for path=%s. Trying to fix it", path);
3358         virFileIsSharedFixFUSE(path, &f_type);
3359     }
3360 
3361     VIR_DEBUG("Check if path %s with FS magic %lld is shared",
3362               path, f_type);
3363 
3364     if ((fstypes & VIR_FILE_SHFS_NFS) &&
3365         (f_type == NFS_SUPER_MAGIC))
3366         return 1;
3367 
3368     if ((fstypes & VIR_FILE_SHFS_GFS2) &&
3369         (f_type == GFS2_MAGIC))
3370         return 1;
3371     if ((fstypes & VIR_FILE_SHFS_OCFS) &&
3372         (f_type == OCFS2_SUPER_MAGIC))
3373         return 1;
3374     if ((fstypes & VIR_FILE_SHFS_AFS) &&
3375         (f_type == AFS_FS_MAGIC))
3376         return 1;
3377     if ((fstypes & VIR_FILE_SHFS_SMB) &&
3378         (f_type == SMB_SUPER_MAGIC))
3379         return 1;
3380     if ((fstypes & VIR_FILE_SHFS_CIFS) &&
3381         (f_type == CIFS_SUPER_MAGIC))
3382         return 1;
3383     if ((fstypes & VIR_FILE_SHFS_CEPH) &&
3384         (f_type == CEPH_SUPER_MAGIC))
3385         return 1;
3386     if ((fstypes & VIR_FILE_SHFS_GPFS) &&
3387         (f_type == GPFS_SUPER_MAGIC))
3388         return 1;
3389     if ((fstypes & VIR_FILE_SHFS_QB) &&
3390         (f_type == QB_MAGIC))
3391         return 1;
3392     if ((fstypes & VIR_FILE_SHFS_ACFS) &&
3393         (f_type == VIR_ACFS_MAGIC))
3394         return 1;
3395 
3396     return 0;
3397 }
3398 
3399 int
virFileGetHugepageSize(const char * path,unsigned long long * size)3400 virFileGetHugepageSize(const char *path,
3401                        unsigned long long *size)
3402 {
3403     struct statfs fs;
3404 
3405     if (statfs(path, &fs) < 0) {
3406         virReportSystemError(errno,
3407                              _("cannot determine filesystem for '%s'"),
3408                              path);
3409         return -1;
3410     }
3411 
3412     if (fs.f_type != HUGETLBFS_MAGIC) {
3413         virReportError(VIR_ERR_INTERNAL_ERROR,
3414                        _("not a hugetlbfs mount: '%s'"),
3415                        path);
3416         return -1;
3417     }
3418 
3419     *size = fs.f_bsize / 1024; /* we are storing size in KiB */
3420 
3421     return 0;
3422 }
3423 
3424 # define PROC_MEMINFO "/proc/meminfo"
3425 # define HUGEPAGESIZE_STR "Hugepagesize:"
3426 
3427 static int
virFileGetDefaultHugepageSize(unsigned long long * size)3428 virFileGetDefaultHugepageSize(unsigned long long *size)
3429 {
3430     g_autofree char *meminfo = NULL;
3431     char *c;
3432     char *n;
3433     char *unit;
3434 
3435     if (virFileReadAll(PROC_MEMINFO, 4096, &meminfo) < 0)
3436         return -1;
3437 
3438     if (!(c = strstr(meminfo, HUGEPAGESIZE_STR))) {
3439         virReportError(VIR_ERR_NO_SUPPORT,
3440                        _("%s not found in %s"),
3441                        HUGEPAGESIZE_STR,
3442                        PROC_MEMINFO);
3443         return -1;
3444     }
3445     c += strlen(HUGEPAGESIZE_STR);
3446 
3447     if ((n = strchr(c, '\n'))) {
3448         /* Cut off the rest of the meminfo file */
3449         *n = '\0';
3450     }
3451 
3452     if (virStrToLong_ull(c, &unit, 10, size) < 0 || STRNEQ(unit, " kB")) {
3453         virReportError(VIR_ERR_INTERNAL_ERROR,
3454                        _("Unable to parse %s %s"),
3455                        HUGEPAGESIZE_STR, c);
3456         return -1;
3457     }
3458 
3459     return 0;
3460 }
3461 
3462 int
virFileFindHugeTLBFS(virHugeTLBFS ** ret_fs,size_t * ret_nfs)3463 virFileFindHugeTLBFS(virHugeTLBFS **ret_fs,
3464                      size_t *ret_nfs)
3465 {
3466     int ret = -1;
3467     FILE *f = NULL;
3468     struct mntent mb;
3469     char mntbuf[1024];
3470     virHugeTLBFS *fs = NULL;
3471     size_t nfs = 0;
3472     unsigned long long default_hugepagesz = 0;
3473 
3474     if (!(f = setmntent(PROC_MOUNTS, "r"))) {
3475         virReportSystemError(errno,
3476                              _("Unable to open %s"),
3477                              PROC_MOUNTS);
3478         goto cleanup;
3479     }
3480 
3481     while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
3482         virHugeTLBFS *tmp;
3483 
3484         if (STRNEQ(mb.mnt_type, "hugetlbfs"))
3485             continue;
3486 
3487         VIR_EXPAND_N(fs, nfs, 1);
3488 
3489         tmp = &fs[nfs - 1];
3490 
3491         tmp->mnt_dir = g_strdup(mb.mnt_dir);
3492 
3493         if (virFileGetHugepageSize(tmp->mnt_dir, &tmp->size) < 0)
3494             goto cleanup;
3495 
3496         if (!default_hugepagesz &&
3497             virFileGetDefaultHugepageSize(&default_hugepagesz) < 0)
3498             goto cleanup;
3499 
3500         tmp->deflt = tmp->size == default_hugepagesz;
3501     }
3502 
3503     *ret_nfs = nfs;
3504     *ret_fs = g_steal_pointer(&fs);
3505     nfs = 0;
3506     ret = 0;
3507 
3508  cleanup:
3509     endmntent(f);
3510     while (nfs)
3511         VIR_FREE(fs[--nfs].mnt_dir);
3512     VIR_FREE(fs);
3513     return ret;
3514 }
3515 
3516 #else /* defined __linux__ */
3517 
virFileIsSharedFSType(const char * path G_GNUC_UNUSED,int fstypes G_GNUC_UNUSED)3518 int virFileIsSharedFSType(const char *path G_GNUC_UNUSED,
3519                           int fstypes G_GNUC_UNUSED)
3520 {
3521     /* XXX implement me :-) */
3522     return 0;
3523 }
3524 
3525 int
virFileGetHugepageSize(const char * path G_GNUC_UNUSED,unsigned long long * size G_GNUC_UNUSED)3526 virFileGetHugepageSize(const char *path G_GNUC_UNUSED,
3527                        unsigned long long *size G_GNUC_UNUSED)
3528 {
3529     /* XXX implement me :-) */
3530     virReportUnsupportedError();
3531     return -1;
3532 }
3533 
3534 int
virFileFindHugeTLBFS(virHugeTLBFS ** ret_fs G_GNUC_UNUSED,size_t * ret_nfs G_GNUC_UNUSED)3535 virFileFindHugeTLBFS(virHugeTLBFS **ret_fs G_GNUC_UNUSED,
3536                      size_t *ret_nfs G_GNUC_UNUSED)
3537 {
3538     /* XXX implement me :-) */
3539     virReportUnsupportedError();
3540     return -1;
3541 }
3542 #endif /* defined __linux__ */
3543 
3544 /**
3545  * virFileGetDefaultHugepage:
3546  * @fs: array of hugetlbfs mount points
3547  * @nfs: number of items in @fs
3548  *
3549  * In the passed array of hugetlbfs mount points @fs find the
3550  * default one. It's the one which has no '-o pagesize'.
3551  *
3552  * Returns: default hugepage, or
3553  *          NULL if none found
3554  */
3555 virHugeTLBFS *
virFileGetDefaultHugepage(virHugeTLBFS * fs,size_t nfs)3556 virFileGetDefaultHugepage(virHugeTLBFS *fs,
3557                           size_t nfs)
3558 {
3559     size_t i;
3560 
3561     for (i = 0; i < nfs; i++) {
3562         if (fs[i].deflt)
3563             return &fs[i];
3564     }
3565 
3566     return NULL;
3567 }
3568 
virFileIsSharedFS(const char * path)3569 int virFileIsSharedFS(const char *path)
3570 {
3571     return virFileIsSharedFSType(path,
3572                                  VIR_FILE_SHFS_NFS |
3573                                  VIR_FILE_SHFS_GFS2 |
3574                                  VIR_FILE_SHFS_OCFS |
3575                                  VIR_FILE_SHFS_AFS |
3576                                  VIR_FILE_SHFS_SMB |
3577                                  VIR_FILE_SHFS_CIFS |
3578                                  VIR_FILE_SHFS_CEPH |
3579                                  VIR_FILE_SHFS_GPFS|
3580                                  VIR_FILE_SHFS_QB |
3581                                  VIR_FILE_SHFS_ACFS);
3582 }
3583 
3584 
3585 int
virFileIsClusterFS(const char * path)3586 virFileIsClusterFS(const char *path)
3587 {
3588     /* These are coherent cluster filesystems known to be safe for
3589      * migration with cache != none
3590      */
3591     return virFileIsSharedFSType(path,
3592                                  VIR_FILE_SHFS_GFS2 |
3593                                  VIR_FILE_SHFS_OCFS |
3594                                  VIR_FILE_SHFS_CEPH);
3595 }
3596 
3597 
3598 #if defined(__linux__) && defined(WITH_SYS_MOUNT_H)
3599 int
virFileSetupDev(const char * path,const char * mount_options)3600 virFileSetupDev(const char *path,
3601                 const char *mount_options)
3602 {
3603     const unsigned long mount_flags = MS_NOSUID;
3604     const char *mount_fs = "tmpfs";
3605 
3606     if (g_mkdir_with_parents(path, 0777) < 0) {
3607         virReportSystemError(errno,
3608                              _("Failed to make path %s"), path);
3609         return -1;
3610     }
3611 
3612     VIR_DEBUG("Mount devfs on %s type=tmpfs flags=0x%lx, opts=%s",
3613               path, mount_flags, mount_options);
3614     if (mount("devfs", path, mount_fs, mount_flags, mount_options) < 0) {
3615         virReportSystemError(errno,
3616                              _("Failed to mount devfs on %s type %s (%s)"),
3617                              path, mount_fs, mount_options);
3618         return -1;
3619     }
3620 
3621     return 0;
3622 }
3623 
3624 
3625 int
virFileBindMountDevice(const char * src,const char * dst)3626 virFileBindMountDevice(const char *src,
3627                        const char *dst)
3628 {
3629     if (!virFileExists(dst)) {
3630         if (virFileIsDir(src)) {
3631             if (g_mkdir_with_parents(dst, 0777) < 0) {
3632                 virReportSystemError(errno, _("Unable to make dir %s"), dst);
3633                 return -1;
3634             }
3635         } else {
3636             if (virFileTouch(dst, 0666) < 0)
3637                 return -1;
3638         }
3639     }
3640 
3641     if (mount(src, dst, "none", MS_BIND, NULL) < 0) {
3642         virReportSystemError(errno, _("Failed to bind %s on to %s"), src,
3643                              dst);
3644         return -1;
3645     }
3646 
3647     return 0;
3648 }
3649 
3650 
3651 int
virFileMoveMount(const char * src,const char * dst)3652 virFileMoveMount(const char *src,
3653                  const char *dst)
3654 {
3655     const unsigned long mount_flags = MS_MOVE;
3656 
3657     if (mount(src, dst, "none", mount_flags, NULL) < 0) {
3658         virReportSystemError(errno,
3659                              _("Unable to move %s mount to %s"),
3660                              src, dst);
3661         return -1;
3662     }
3663 
3664     return 0;
3665 }
3666 
3667 
3668 #else /* !defined(__linux__) || !defined(WITH_SYS_MOUNT_H) */
3669 
3670 int
virFileSetupDev(const char * path G_GNUC_UNUSED,const char * mount_options G_GNUC_UNUSED)3671 virFileSetupDev(const char *path G_GNUC_UNUSED,
3672                 const char *mount_options G_GNUC_UNUSED)
3673 {
3674     virReportSystemError(ENOSYS, "%s",
3675                          _("mount is not supported on this platform."));
3676     return -1;
3677 }
3678 
3679 
3680 int
virFileBindMountDevice(const char * src G_GNUC_UNUSED,const char * dst G_GNUC_UNUSED)3681 virFileBindMountDevice(const char *src G_GNUC_UNUSED,
3682                        const char *dst G_GNUC_UNUSED)
3683 {
3684     virReportSystemError(ENOSYS, "%s",
3685                          _("mount is not supported on this platform."));
3686     return -1;
3687 }
3688 
3689 
3690 int
virFileMoveMount(const char * src G_GNUC_UNUSED,const char * dst G_GNUC_UNUSED)3691 virFileMoveMount(const char *src G_GNUC_UNUSED,
3692                  const char *dst G_GNUC_UNUSED)
3693 {
3694     virReportSystemError(ENOSYS, "%s",
3695                          _("mount move is not supported on this platform."));
3696     return -1;
3697 }
3698 #endif /* !defined(__linux__) || !defined(WITH_SYS_MOUNT_H) */
3699 
3700 
3701 #if defined(WITH_LIBACL)
3702 int
virFileGetACLs(const char * file,void ** acl)3703 virFileGetACLs(const char *file,
3704                void **acl)
3705 {
3706     if (!(*acl = acl_get_file(file, ACL_TYPE_ACCESS)))
3707         return -1;
3708 
3709     return 0;
3710 }
3711 
3712 
3713 int
virFileSetACLs(const char * file,void * acl)3714 virFileSetACLs(const char *file,
3715                void *acl)
3716 {
3717     if (acl_set_file(file, ACL_TYPE_ACCESS, acl) < 0)
3718         return -1;
3719 
3720     return 0;
3721 }
3722 
3723 
3724 void
virFileFreeACLs(void ** acl)3725 virFileFreeACLs(void **acl)
3726 {
3727     acl_free(*acl);
3728     *acl = NULL;
3729 }
3730 
3731 #else /* !defined(WITH_LIBACL) */
3732 
3733 int
virFileGetACLs(const char * file G_GNUC_UNUSED,void ** acl G_GNUC_UNUSED)3734 virFileGetACLs(const char *file G_GNUC_UNUSED,
3735                void **acl G_GNUC_UNUSED)
3736 {
3737     errno = ENOTSUP;
3738     return -1;
3739 }
3740 
3741 
3742 int
virFileSetACLs(const char * file G_GNUC_UNUSED,void * acl G_GNUC_UNUSED)3743 virFileSetACLs(const char *file G_GNUC_UNUSED,
3744                void *acl G_GNUC_UNUSED)
3745 {
3746     errno = ENOTSUP;
3747     return -1;
3748 }
3749 
3750 
3751 void
virFileFreeACLs(void ** acl)3752 virFileFreeACLs(void **acl)
3753 {
3754     *acl = NULL;
3755 }
3756 
3757 #endif /* !defined(WITH_LIBACL) */
3758 
3759 int
virFileCopyACLs(const char * src,const char * dst)3760 virFileCopyACLs(const char *src,
3761                 const char *dst)
3762 {
3763     void *acl = NULL;
3764     int ret = -1;
3765 
3766     if (virFileGetACLs(src, &acl) < 0)
3767         return ret;
3768 
3769     if (virFileSetACLs(dst, acl) < 0)
3770         goto cleanup;
3771 
3772     ret = 0;
3773  cleanup:
3774     virFileFreeACLs(&acl);
3775     return ret;
3776 }
3777 
3778 /*
3779  * virFileComparePaths:
3780  * @p1: source path 1
3781  * @p2: source path 2
3782  *
3783  * Compares two paths for equality. To do so, it first canonicalizes both paths
3784  * to resolve all symlinks and discard relative path components. If symlinks
3785  * resolution or path canonicalization fails, plain string equality of @p1
3786  * and @p2 is performed.
3787  *
3788  * Returns:
3789  *  1 : Equal
3790  *  0 : Non-Equal
3791  */
3792 int
virFileComparePaths(const char * p1,const char * p2)3793 virFileComparePaths(const char *p1, const char *p2)
3794 {
3795     g_autofree char *res1 = NULL;
3796     g_autofree char *res2 = NULL;
3797 
3798     /* Assume p1 and p2 are symlinks, so try to resolve and canonicalize them.
3799      * Canonicalization fails for example on file systems names like 'proc' or
3800      * 'sysfs', since they're no real paths so fallback to plain string
3801      * comparison.
3802      */
3803     ignore_value(virFileResolveLink(p1, &res1));
3804     if (!res1)
3805         res1 = g_strdup(p1);
3806 
3807     ignore_value(virFileResolveLink(p2, &res2));
3808     if (!res2)
3809         res2 = g_strdup(p2);
3810 
3811     return STREQ_NULLABLE(res1, res2);
3812 }
3813 
3814 
3815 #if WITH_DECL_SEEK_HOLE
3816 /**
3817  * virFileInData:
3818  * @fd: file to check
3819  * @inData: true if current position in the @fd is in data section
3820  * @length: amount of bytes until the end of the current section
3821  *
3822  * With sparse files not every extent has to be physically stored on
3823  * the disk. This results in so called data or hole sections.  This
3824  * function checks whether the current position in the file @fd is
3825  * in a data section (@inData = 1) or in a hole (@inData = 0). Also,
3826  * it sets @length to match the number of bytes remaining until the
3827  * end of the current section.
3828  *
3829  * As a special case, there is an implicit hole at the end of any
3830  * file. In this case, the function sets @inData = 0, @length = 0.
3831  *
3832  * Upon its return, the position in the @fd is left unchanged, i.e.
3833  * despite this function lseek()-ing back and forth it always
3834  * restores the original position in the file.
3835  *
3836  * NB, @length is type of long long because it corresponds to off_t
3837  * the best.
3838  *
3839  * Returns 0 on success,
3840  *        -1 otherwise.
3841  */
3842 int
virFileInData(int fd,int * inData,long long * length)3843 virFileInData(int fd,
3844               int *inData,
3845               long long *length)
3846 {
3847     int ret = -1;
3848     off_t cur, data, hole, end;
3849 
3850     /* Get current position */
3851     cur = lseek(fd, 0, SEEK_CUR);
3852     if (cur == (off_t) -1) {
3853         virReportSystemError(errno, "%s",
3854                              _("Unable to get current position in file"));
3855         goto cleanup;
3856     }
3857 
3858     /* Now try to get data and hole offsets */
3859     data = lseek(fd, cur, SEEK_DATA);
3860 
3861     /* There are four options:
3862      * 1) data == cur;  @cur is in data
3863      * 2) data > cur; @cur is in a hole, next data at @data
3864      * 3) data < 0, errno = ENXIO; either @cur is in trailing hole, or @cur is beyond EOF.
3865      * 4) data < 0, errno != ENXIO; we learned nothing
3866      */
3867 
3868     if (data == (off_t) -1) {
3869         /* cases 3 and 4 */
3870         if (errno != ENXIO) {
3871             virReportSystemError(errno, "%s",
3872                                  _("Unable to seek to data"));
3873             goto cleanup;
3874         }
3875 
3876         *inData = 0;
3877         /* There are two situations now. There is always an
3878          * implicit hole at EOF. However, there might be a
3879          * trailing hole just before EOF too. If that's the case
3880          * report it. */
3881         if ((end = lseek(fd, 0, SEEK_END)) == (off_t) -1) {
3882             virReportSystemError(errno, "%s",
3883                                  _("Unable to seek to EOF"));
3884             goto cleanup;
3885         }
3886         *length = end - cur;
3887     } else if (data > cur) {
3888         /* case 2 */
3889         *inData = 0;
3890         *length = data - cur;
3891     } else {
3892         /* case 1 */
3893         *inData = 1;
3894 
3895         /* We don't know where does the next hole start. Let's
3896          * find out. Here we get the same 4 possibilities as
3897          * described above.*/
3898         hole = lseek(fd, data, SEEK_HOLE);
3899         if (hole == (off_t) -1 || hole == data) {
3900             /* cases 1, 3 and 4 */
3901             /* Wait a second. The reason why we are here is
3902              * because we are in data. But at the same time we
3903              * are in a trailing hole? Wut!? Do the best what we
3904              * can do here. */
3905             virReportSystemError(errno, "%s",
3906                                  _("unable to seek to hole"));
3907             goto cleanup;
3908         } else {
3909             /* case 2 */
3910             *length = (hole - data);
3911         }
3912     }
3913 
3914     ret = 0;
3915  cleanup:
3916     /* At any rate, reposition back to where we started. */
3917     if (cur != (off_t) -1) {
3918         int theerrno = errno;
3919 
3920         if (lseek(fd, cur, SEEK_SET) == (off_t) -1) {
3921             virReportSystemError(errno, "%s",
3922                                  _("unable to restore position in file"));
3923             ret = -1;
3924             if (theerrno == 0)
3925                 theerrno = errno;
3926         }
3927 
3928         errno = theerrno;
3929     }
3930     return ret;
3931 }
3932 
3933 #else /* !WITH_DECL_SEEK_HOLE */
3934 
3935 int
virFileInData(int fd G_GNUC_UNUSED,int * inData G_GNUC_UNUSED,long long * length G_GNUC_UNUSED)3936 virFileInData(int fd G_GNUC_UNUSED,
3937               int *inData G_GNUC_UNUSED,
3938               long long *length G_GNUC_UNUSED)
3939 {
3940     errno = ENOSYS;
3941     virReportSystemError(errno, "%s",
3942                          _("sparse files not supported"));
3943     return -1;
3944 }
3945 
3946 #endif /* !WITH_DECL_SEEK_HOLE */
3947 
3948 
3949 /**
3950  * virFileReadValueInt:
3951  * @value: pointer to int to be filled in with the value
3952  * @format, ...: file to read from
3953  *
3954  * Read int from @format and put it into @value.
3955  *
3956  * Return -2 for non-existing file, -1 on other errors and 0 if everything went
3957  * fine.
3958  */
3959 int
virFileReadValueInt(int * value,const char * format,...)3960 virFileReadValueInt(int *value, const char *format, ...)
3961 {
3962     g_autofree char *str = NULL;
3963     g_autofree char *path = NULL;
3964     va_list ap;
3965 
3966     va_start(ap, format);
3967     path = g_strdup_vprintf(format, ap);
3968     va_end(ap);
3969 
3970     if (!virFileExists(path))
3971         return -2;
3972 
3973     if (virFileReadAll(path, VIR_INT64_STR_BUFLEN, &str) < 0)
3974         return -1;
3975 
3976     virStringTrimOptionalNewline(str);
3977 
3978     if (virStrToLong_i(str, NULL, 10, value) < 0) {
3979         virReportError(VIR_ERR_INTERNAL_ERROR,
3980                        _("Invalid integer value '%s' in file '%s'"),
3981                        str, path);
3982         return -1;
3983     }
3984 
3985     return 0;
3986 }
3987 
3988 
3989 /**
3990  * virFileReadValueUint:
3991  * @value: pointer to int to be filled in with the value
3992  * @format, ...: file to read from
3993  *
3994  * Read unsigned int from @format and put it into @value.
3995  *
3996  * Return -2 for non-existing file, -1 on other errors and 0 if everything went
3997  * fine.
3998  */
3999 int
virFileReadValueUint(unsigned int * value,const char * format,...)4000 virFileReadValueUint(unsigned int *value, const char *format, ...)
4001 {
4002     g_autofree char *str = NULL;
4003     g_autofree char *path = NULL;
4004     va_list ap;
4005 
4006     va_start(ap, format);
4007     path = g_strdup_vprintf(format, ap);
4008     va_end(ap);
4009 
4010     if (!virFileExists(path))
4011         return -2;
4012 
4013     if (virFileReadAll(path, VIR_INT64_STR_BUFLEN, &str) < 0)
4014         return -1;
4015 
4016     virStringTrimOptionalNewline(str);
4017 
4018     if (virStrToLong_uip(str, NULL, 10, value) < 0) {
4019         virReportError(VIR_ERR_INTERNAL_ERROR,
4020                        _("Invalid unsigned integer value '%s' in file '%s'"),
4021                        str, path);
4022         return -1;
4023     }
4024 
4025     return 0;
4026 }
4027 
4028 
4029 /**
4030  * virFileReadValueUllong:
4031  * @value: pointer to unsigned long long to be filled in with the value
4032  * @format, ...: file to read from
4033  *
4034  * Read unsigned int from @format and put it into @value.
4035  *
4036  * Return -2 for non-existing file, -1 on other errors and 0 if everything went
4037  * fine.
4038  */
4039 int
virFileReadValueUllong(unsigned long long * value,const char * format,...)4040 virFileReadValueUllong(unsigned long long *value, const char *format, ...)
4041 {
4042     g_autofree char *str = NULL;
4043     g_autofree char *path = NULL;
4044     va_list ap;
4045 
4046     va_start(ap, format);
4047     path = g_strdup_vprintf(format, ap);
4048     va_end(ap);
4049 
4050     if (!virFileExists(path))
4051         return -2;
4052 
4053     if (virFileReadAll(path, VIR_INT64_STR_BUFLEN, &str) < 0)
4054         return -1;
4055 
4056     virStringTrimOptionalNewline(str);
4057 
4058     if (virStrToLong_ullp(str, NULL, 10, value) < 0) {
4059         virReportError(VIR_ERR_INTERNAL_ERROR,
4060                        _("Invalid unsigned long long value '%s' in file '%s'"),
4061                        str, path);
4062         return -1;
4063     }
4064 
4065     return 0;
4066 }
4067 
4068 int
virFileReadValueUllongQuiet(unsigned long long * value,const char * format,...)4069 virFileReadValueUllongQuiet(unsigned long long *value, const char *format, ...)
4070 {
4071     g_autofree char *str = NULL;
4072     g_autofree char *path = NULL;
4073     va_list ap;
4074 
4075     va_start(ap, format);
4076     path = g_strdup_vprintf(format, ap);
4077     va_end(ap);
4078 
4079     if (!virFileExists(path))
4080         return -2;
4081 
4082     if (virFileReadAllQuiet(path, VIR_INT64_STR_BUFLEN, &str) < 0)
4083         return -1;
4084 
4085     virStringTrimOptionalNewline(str);
4086 
4087     if (virStrToLong_ullp(str, NULL, 10, value) < 0)
4088         return -1;
4089 
4090     return 0;
4091 }
4092 
4093 /**
4094  * virFileReadValueScaledInt:
4095  * @value: pointer to unsigned long long int to be filled in with the value
4096  * @format, ...: file to read from
4097  *
4098  * Read unsigned scaled int from @format and put it into @value.
4099  *
4100  * Return -2 for non-existing file, -1 on other errors and 0 if everything went
4101  * fine.
4102  */
4103 int
virFileReadValueScaledInt(unsigned long long * value,const char * format,...)4104 virFileReadValueScaledInt(unsigned long long *value, const char *format, ...)
4105 {
4106     g_autofree char *str = NULL;
4107     g_autofree char *path = NULL;
4108     char *endp = NULL;
4109     va_list ap;
4110 
4111     va_start(ap, format);
4112     path = g_strdup_vprintf(format, ap);
4113     va_end(ap);
4114 
4115     if (!virFileExists(path))
4116         return -2;
4117 
4118     if (virFileReadAll(path, VIR_INT64_STR_BUFLEN, &str) < 0)
4119         return -1;
4120 
4121     virStringTrimOptionalNewline(str);
4122 
4123     if (virStrToLong_ullp(str, &endp, 10, value) < 0) {
4124         virReportError(VIR_ERR_INTERNAL_ERROR,
4125                        _("Invalid unsigned scaled integer value '%s' in file '%s'"),
4126                        str, path);
4127         return -1;
4128     }
4129 
4130     return virScaleInteger(value, endp, 1024, ULLONG_MAX);
4131 }
4132 
4133 /* Arbitrarily sized number, feel free to change, but the function should be
4134  * used for small, interface-like files, so it should not be huge (subjective) */
4135 #define VIR_FILE_READ_VALUE_STRING_MAX 4096
4136 
4137 /**
4138  * virFileReadValueBitmap:
4139  * @value: pointer to virBitmap * to be allocated and filled in with the value
4140  * @format, ...: file to read from
4141  *
4142  * Read int from @format and put it into @value.
4143  *
4144  * Return -2 for non-existing file, -1 on other errors and 0 if everything went
4145  * fine.
4146  */
4147 int
virFileReadValueBitmap(virBitmap ** value,const char * format,...)4148 virFileReadValueBitmap(virBitmap **value, const char *format, ...)
4149 {
4150     g_autofree char *str = NULL;
4151     g_autofree char *path = NULL;
4152     va_list ap;
4153 
4154     va_start(ap, format);
4155     path = g_strdup_vprintf(format, ap);
4156     va_end(ap);
4157 
4158     if (!virFileExists(path))
4159         return -2;
4160 
4161     if (virFileReadAll(path, VIR_FILE_READ_VALUE_STRING_MAX, &str) < 0)
4162         return -1;
4163 
4164     virStringTrimOptionalNewline(str);
4165 
4166     *value = virBitmapParseUnlimited(str);
4167     if (!*value)
4168         return -1;
4169 
4170     return 0;
4171 }
4172 
4173 /**
4174  * virFileReadValueString:
4175  * @value: pointer to char * to be allocated and filled in with the value
4176  * @format, ...: file to read from
4177  *
4178  * Read string from @format and put it into @value.  Don't get this mixed with
4179  * virFileReadAll().  This function is a wrapper over it with the behaviour
4180  * aligned to other virFileReadValue* functions
4181  *
4182  * Return -2 for non-existing file, -1 on other errors and 0 if everything went
4183  * fine.
4184  */
4185 int
virFileReadValueString(char ** value,const char * format,...)4186 virFileReadValueString(char **value, const char *format, ...)
4187 {
4188     int ret;
4189     g_autofree char *path = NULL;
4190     va_list ap;
4191 
4192     va_start(ap, format);
4193     path = g_strdup_vprintf(format, ap);
4194     va_end(ap);
4195 
4196     if (!virFileExists(path))
4197         return -2;
4198 
4199     ret = virFileReadAll(path, VIR_FILE_READ_VALUE_STRING_MAX, value);
4200 
4201     if (*value)
4202         virStringTrimOptionalNewline(*value);
4203 
4204     return ret;
4205 }
4206 
4207 
4208 /**
4209  * virFileWaitForExists:
4210  * @path: absolute path to a sysfs attribute (can be a symlink)
4211  * @ms: how long to wait (in milliseconds)
4212  * @tries: how many times should we try to wait for @path to become accessible
4213  *
4214  * Checks the existence of @path. In case the file defined by @path
4215  * doesn't exist, we wait for it to appear in @ms milliseconds (for up to
4216  * @tries attempts).
4217  *
4218  * Returns 0 on success, -1 on error, setting errno appropriately.
4219  */
4220 int
virFileWaitForExists(const char * path,size_t ms,size_t tries)4221 virFileWaitForExists(const char *path,
4222                      size_t ms,
4223                      size_t tries)
4224 {
4225     errno = 0;
4226 
4227     /* wait for @path to be accessible in @ms milliseconds, up to @tries */
4228     while (tries-- > 0 && !virFileExists(path)) {
4229         if (tries == 0 || errno != ENOENT)
4230             return -1;
4231 
4232         g_usleep(ms * 1000);
4233     }
4234 
4235     return 0;
4236 }
4237 
4238 
4239 #if WITH_LIBATTR
4240 /**
4241  * virFileGetXAttrQuiet;
4242  * @path: a filename
4243  * @name: name of xattr
4244  * @value: read value
4245  *
4246  * Reads xattr with @name for given @path and stores it into
4247  * @value. Caller is responsible for freeing @value.
4248  *
4249  * Returns: 0 on success,
4250  *         -1 otherwise (with errno set).
4251  */
4252 int
virFileGetXAttrQuiet(const char * path,const char * name,char ** value)4253 virFileGetXAttrQuiet(const char *path,
4254                      const char *name,
4255                      char **value)
4256 {
4257     g_autofree char *buf = NULL;
4258 
4259     /* We might be racing with somebody who sets the same attribute. */
4260     while (1) {
4261         ssize_t need;
4262         ssize_t got;
4263 
4264         /* The first call determines how many bytes we need to allocate. */
4265         if ((need = getxattr(path, name, NULL, 0)) < 0)
4266             return -1;
4267 
4268         buf = g_renew(char, buf, need + 1);
4269 
4270         if ((got = getxattr(path, name, buf, need)) < 0) {
4271             if (errno == ERANGE)
4272                 continue;
4273             return -1;
4274         }
4275 
4276         buf[got] = '\0';
4277         break;
4278     }
4279 
4280     *value = g_steal_pointer(&buf);
4281     return 0;
4282 }
4283 
4284 /**
4285  * virFileSetXAttr:
4286  * @path: a filename
4287  * @name: name of xattr
4288  * @value: value to set
4289  *
4290  * Sets xattr of @name and @value on @path.
4291  *
4292  * Returns: 0 on success,
4293  *         -1 otherwise (with errno set AND error reported).
4294  */
4295 int
virFileSetXAttr(const char * path,const char * name,const char * value)4296 virFileSetXAttr(const char *path,
4297                 const char *name,
4298                 const char *value)
4299 {
4300     if (setxattr(path, name, value, strlen(value), 0) < 0) {
4301         virReportSystemError(errno,
4302                              _("Unable to set XATTR %s on %s"),
4303                              name, path);
4304         return -1;
4305     }
4306 
4307     return 0;
4308 }
4309 
4310 /**
4311  * virFileRemoveXAttr:
4312  * @path: a filename
4313  * @name: name of xattr
4314  *
4315  * Remove xattr of @name on @path.
4316  *
4317  * Returns: 0 on success,
4318  *         -1 otherwise (with errno set AND error reported).
4319  */
4320 int
virFileRemoveXAttr(const char * path,const char * name)4321 virFileRemoveXAttr(const char *path,
4322                    const char *name)
4323 {
4324     if (removexattr(path, name) < 0) {
4325         virReportSystemError(errno,
4326                              _("Unable to remove XATTR %s on %s"),
4327                              name, path);
4328         return -1;
4329     }
4330 
4331     return 0;
4332 }
4333 
4334 #else /* !WITH_LIBATTR */
4335 
4336 int
virFileGetXAttrQuiet(const char * path G_GNUC_UNUSED,const char * name G_GNUC_UNUSED,char ** value G_GNUC_UNUSED)4337 virFileGetXAttrQuiet(const char *path G_GNUC_UNUSED,
4338                      const char *name G_GNUC_UNUSED,
4339                      char **value G_GNUC_UNUSED)
4340 {
4341     errno = ENOSYS;
4342     return -1;
4343 }
4344 
4345 int
virFileSetXAttr(const char * path,const char * name,const char * value G_GNUC_UNUSED)4346 virFileSetXAttr(const char *path,
4347                 const char *name,
4348                 const char *value G_GNUC_UNUSED)
4349 {
4350     errno = ENOSYS;
4351     virReportSystemError(errno,
4352                          _("Unable to set XATTR %s on %s"),
4353                          name, path);
4354     return -1;
4355 }
4356 
4357 int
virFileRemoveXAttr(const char * path,const char * name)4358 virFileRemoveXAttr(const char *path,
4359                    const char *name)
4360 {
4361     errno = ENOSYS;
4362     virReportSystemError(errno,
4363                          _("Unable to remove XATTR %s on %s"),
4364                          name, path);
4365     return -1;
4366 }
4367 
4368 #endif /* WITH_LIBATTR */
4369 
4370 /**
4371  * virFileGetXAttr;
4372  * @path: a filename
4373  * @name: name of xattr
4374  * @value: read value
4375  *
4376  * Reads xattr with @name for given @path and stores it into
4377  * @value. Caller is responsible for freeing @value.
4378  *
4379  * Returns: 0 on success,
4380  *         -1 otherwise (with errno set AND error reported).
4381  */
4382 int
virFileGetXAttr(const char * path,const char * name,char ** value)4383 virFileGetXAttr(const char *path,
4384                 const char *name,
4385                 char **value)
4386 {
4387     int ret;
4388 
4389     if ((ret = virFileGetXAttrQuiet(path, name, value)) < 0) {
4390         virReportSystemError(errno,
4391                              _("Unable to get XATTR %s on %s"),
4392                              name, path);
4393     }
4394 
4395     return ret;
4396 }
4397 
4398 
4399 int
virFileDataSync(int fd)4400 virFileDataSync(int fd)
4401 {
4402 #if defined(__APPLE__) || defined(WIN32)
4403     return g_fsync(fd);
4404 #else
4405     return fsync(fd);
4406 #endif
4407 }
4408 
4409 
4410 /**
4411  * virFileSetCow:
4412  * @path: file or directory to control the COW flag on
4413  * @state: the desired state of the COW flag
4414  *
4415  * When @state is VIR_TRISTATE_BOOL_ABSENT, some helpful
4416  * default logic will be used. Specifically if the filesystem
4417  * containing @path is 'btrfs', then it will attempt to
4418  * disable the COW flag, but errors will be ignored. For
4419  * any other filesystem no change will be made.
4420  *
4421  * When @state is VIR_TRISTATE_BOOL_YES or VIR_TRISTATE_BOOL_NO,
4422  * it will attempt to set the COW flag state to that explicit
4423  * value, and always return an error if it fails. Note this
4424  * means it will always return error if the filesystem is not
4425  * 'btrfs'.
4426  */
4427 int
virFileSetCOW(const char * path,virTristateBool state)4428 virFileSetCOW(const char *path,
4429               virTristateBool state)
4430 {
4431 #if __linux__
4432     int val = 0;
4433     struct statfs buf;
4434     VIR_AUTOCLOSE fd = -1;
4435 
4436     VIR_DEBUG("Setting COW flag on '%s' to '%s'",
4437               path, virTristateBoolTypeToString(state));
4438 
4439     fd = open(path, O_RDONLY|O_NONBLOCK|O_LARGEFILE);
4440     if (fd < 0) {
4441         virReportSystemError(errno, _("unable to open '%s'"),
4442                              path);
4443         return -1;
4444     }
4445 
4446     if (fstatfs(fd, &buf) < 0)  {
4447         virReportSystemError(errno, _("unable query filesystem type on '%s'"),
4448                              path);
4449         return -1;
4450     }
4451 
4452     if (buf.f_type != BTRFS_SUPER_MAGIC) {
4453         if (state != VIR_TRISTATE_BOOL_ABSENT) {
4454             virReportSystemError(ENOSYS,
4455                                  _("unable to control COW flag on '%s', not btrfs"),
4456                                  path);
4457             return -1;
4458         }
4459         return 0;
4460     }
4461 
4462     if (ioctl(fd, FS_IOC_GETFLAGS, &val) < 0) {
4463         virReportSystemError(errno, _("unable get directory flags on '%s'"),
4464                              path);
4465         return -1;
4466     }
4467 
4468     VIR_DEBUG("Current flags on '%s' are 0x%x", path, val);
4469     if (state == VIR_TRISTATE_BOOL_YES) {
4470         val &= ~FS_NOCOW_FL;
4471     } else {
4472         val |= FS_NOCOW_FL;
4473     }
4474 
4475     VIR_DEBUG("New flags on '%s' will be 0x%x", path, val);
4476     if (ioctl(fd, FS_IOC_SETFLAGS, &val) < 0) {
4477         int saved_err = errno;
4478         VIR_DEBUG("Failed to set flags on '%s': %s", path, g_strerror(saved_err));
4479         if (state != VIR_TRISTATE_BOOL_ABSENT) {
4480             virReportSystemError(saved_err,
4481                                  _("unable control COW flag on '%s'"),
4482                                  path);
4483             return -1;
4484         } else {
4485             VIR_DEBUG("Ignoring failure to set COW");
4486         }
4487     }
4488 
4489     return 0;
4490 #else /* ! __linux__ */
4491     if (state != VIR_TRISTATE_BOOL_ABSENT) {
4492         virReportSystemError(ENOSYS,
4493                              _("Unable to set copy-on-write state on '%s' to '%s'"),
4494                              path, virTristateBoolTypeToString(state));
4495         return -1;
4496     }
4497     return 0;
4498 #endif /* ! __linux__ */
4499 }
4500