-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
Copyright 2015 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/loop.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
#include <sys/statvfs.h>
-#include <sys/vfs.h>
+#include <unistd.h>
+
+#include "sd-bus-protocol.h"
+#include "sd-bus.h"
+#include "alloc-util.h"
#include "btrfs-util.h"
#include "fd-util.h"
#include "fileio.h"
+#include "fs-util.h"
+#include "label.h"
#include "lockfile-util.h"
+#include "log.h"
#include "machine-pool.h"
+#include "macro.h"
+#include "missing.h"
#include "mkdir.h"
+#include "mount-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
#include "signal-util.h"
+#include "stat-util.h"
#include "string-util.h"
-#include "util.h"
#define VAR_LIB_MACHINES_SIZE_START (1024UL*1024UL*500UL)
#define VAR_LIB_MACHINES_FREE_MIN (1024UL*1024UL*750UL)
_cleanup_close_ int fd = -1;
struct statvfs ss;
pid_t pid = 0;
- siginfo_t si;
int r;
/* We want to be able to make use of btrfs-specific file
* /var/lib/machines. */
fd = open("/var/lib/machines.raw", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
- if (fd >= 0) {
- r = fd;
- fd = -1;
- return r;
- }
+ if (fd >= 0)
+ return TAKE_FD(fd);
if (errno != ENOENT)
return sd_bus_error_set_errnof(error, errno, "Failed to open /var/lib/machines.raw: %m");
goto fail;
}
- pid = fork();
- if (pid < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to fork mkfs.btrfs: %m");
+ r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &pid);
+ if (r < 0) {
+ sd_bus_error_set_errnof(error, r, "Failed to fork mkfs.btrfs: %m");
goto fail;
}
-
- if (pid == 0) {
+ if (r == 0) {
/* Child */
- (void) reset_all_signal_handlers();
- (void) reset_signal_mask();
- assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
-
fd = safe_close(fd);
execlp("mkfs.btrfs", "-Lvar-lib-machines", tmp, NULL);
if (errno == ENOENT)
- return 99;
+ _exit(99);
_exit(EXIT_FAILURE);
}
- r = wait_for_terminate(pid, &si);
- if (r < 0) {
- sd_bus_error_set_errnof(error, r, "Failed to wait for mkfs.btrfs: %m");
- goto fail;
- }
-
+ r = wait_for_terminate_and_check("mkfs", pid, 0);
pid = 0;
- if (si.si_code != CLD_EXITED) {
- r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs died abnormally.");
+ if (r < 0) {
+ sd_bus_error_set_errnof(error, r, "Failed to wait for mkfs.btrfs: %m");
goto fail;
}
- if (si.si_status == 99) {
+ if (r == 99) {
r = sd_bus_error_set_errnof(error, ENOENT, "Cannot set up /var/lib/machines, mkfs.btrfs is missing");
goto fail;
}
- if (si.si_status != 0) {
- r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs failed with error code %i", si.si_status);
+ if (r != EXIT_SUCCESS) {
+ r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs failed with error code %i", r);
goto fail;
}
goto fail;
}
- r = fd;
- fd = -1;
-
- return r;
+ return TAKE_FD(fd);
fail:
unlink_noerrno(tmp);
return 1;
}
- if (path_is_mount_point("/var/lib/machines", AT_SYMLINK_FOLLOW) > 0) {
+ if (path_is_mount_point("/var/lib/machines", NULL, AT_SYMLINK_FOLLOW) > 0) {
log_debug("/var/lib/machines is already a mount point, not creating loopback file for it.");
return 0;
}
}
r = mkfs_exists("btrfs");
- if (r == -ENOENT) {
- log_debug("mkfs.btrfs is missing, cannot create loopback file for /var/lib/machines.");
- return 0;
- }
+ if (r == 0)
+ return sd_bus_error_set_errnof(error, ENOENT, "Cannot set up /var/lib/machines, mkfs.btrfs is missing");
if (r < 0)
return r;
if (b.f_bavail > b.f_blocks / 3)
return 0;
- /* Calculate how much we are willing to add at maximum */
+ /* Calculate how much we are willing to add at most */
max_add = ((uint64_t) a.f_bavail * (uint64_t) a.f_bsize) - VAR_LIB_MACHINES_FREE_MIN;
/* Calculate the old size */