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