diff options
| author | Enji Cooper <ngie@FreeBSD.org> | 2026-10-07 17:50:26 +0000 |
|---|---|---|
| committer | Enji Cooper <ngie@FreeBSD.org> | 2026-10-07 17:50:26 +0000 |
| commit | eb8f69902f7de8012a31a85db2f88a54584f81af (patch) | |
| tree | 1499ad12948cb1a4dbbc9860c46ec36e988087dc /contrib/kyua/utils/fs/operations.cpp | |
| parent | de2c0f157a9cce0b763da9ae97ada870fa4d1824 (diff) | |
| parent | 144afd05f8a2300361ec30c1c2020e4022ddd943 (diff) | |
contrib/kyua: update to 0.15.0
This new release contains multiple feature updates and bugfixes. Please
see the release notes mentioned in the merge commit for more details.
MFC after: 1 month
Merge commit '144afd05f8a2300361ec30c1c2020e4022ddd943'
Conflicts:
contrib/kyua/cli/cmd_debug.cpp
contrib/kyua/doc/kyua-debug.1.in
contrib/kyua/doc/kyuafile.5.in
contrib/kyua/engine/config.cpp
contrib/kyua/engine/execenv/execenv.cpp
contrib/kyua/engine/execenv/execenv.hpp
contrib/kyua/engine/execenv/execenv_host.hpp
contrib/kyua/engine/requirements.cpp
contrib/kyua/engine/requirements.hpp
contrib/kyua/engine/scheduler.cpp
contrib/kyua/model/metadata.cpp
contrib/kyua/os/freebsd/execenv_jail.hpp
contrib/kyua/os/freebsd/execenv_jail_stub.cpp
contrib/kyua/os/freebsd/main.cpp
contrib/kyua/os/freebsd/reqs_checker_kmods.cpp
contrib/kyua/os/freebsd/utils/jail.hpp
contrib/kyua/utils/fs/directory.cpp
contrib/kyua/utils/process/executor.cpp
Diffstat (limited to 'contrib/kyua/utils/fs/operations.cpp')
| -rw-r--r-- | contrib/kyua/utils/fs/operations.cpp | 120 |
1 files changed, 17 insertions, 103 deletions
diff --git a/contrib/kyua/utils/fs/operations.cpp b/contrib/kyua/utils/fs/operations.cpp index 185d164b88d7..2b80fe317b94 100644 --- a/contrib/kyua/utils/fs/operations.cpp +++ b/contrib/kyua/utils/fs/operations.cpp @@ -104,51 +104,11 @@ static enum os_type current_os = ; -/// Specifies if a real unmount(2) is available. -/// -/// We use this as a constant instead of a macro so that we can compile both -/// versions of the unmount code unconditionally. This is a way to prevent -/// compilation bugs going unnoticed for long. -static const bool have_unmount2 = -#if defined(HAVE_UNMOUNT) - true; -#else - false; -#endif - - -#if !defined(UMOUNT) -/// Fake replacement value to the path to umount(8). -# define UMOUNT "do-not-use-this-value" -#else -# if defined(HAVE_UNMOUNT) -# error "umount(8) detected when unmount(2) is also available" -# endif -#endif - - -#if !defined(HAVE_UNMOUNT) -/// Fake unmount(2) function for systems without it. -/// -/// This is only provided to allow our code to compile in all platforms -/// regardless of whether they actually have an unmount(2) or not. -/// -/// \return -1 to indicate error, although this should never happen. -static int -unmount(const char* /* path */, - const int /* flags */) -{ - PRE(false); - return -1; -} -#endif - - /// Error code returned by subprocess to indicate a controlled failure. const int exit_known_error = 123; -static void run_mount_tmpfs(const fs::path&, const uint64_t) UTILS_NORETURN; +static void run_mount_tmpfs [[noreturn]] (const fs::path&, const uint64_t); /// Executes 'mount -t tmpfs' (or a similar variant). @@ -230,72 +190,30 @@ run_mount_tmpfs(const fs::path& mount_point, const uint64_t size) } -/// Unmounts a file system using unmount(2). +/// Unmounts a file system using unmount(2) or umount(2). /// -/// \pre unmount(2) must be available; i.e. have_unmount2 must be true. +/// This is a thin wrapper around the filesystem implementation for the actual +/// underlying system call which implements filesystem unmounting function. /// /// \param mount_point The file system to unmount. /// -/// \throw fs::system_error If the call to unmount(2) fails. +/// \throw fs::system_error The unmount operation fails. static void -unmount_with_unmount2(const fs::path& mount_point) +unmount_impl(const fs::path& mount_point) { - PRE(have_unmount2); - if (::unmount(mount_point.c_str(), 0) == -1) { - const int original_errno = errno; - throw fs::system_error(F("unmount(%s) failed") % mount_point, - original_errno); - } -} - - -/// Unmounts a file system using umount(8). -/// -/// \pre umount(2) must not be available; i.e. have_unmount2 must be false. -/// -/// \param mount_point The file system to unmount. -/// -/// \throw fs::error If the execution of umount(8) fails. -static void -unmount_with_umount8(const fs::path& mount_point) -{ - PRE(!have_unmount2); - - const pid_t pid = ::fork(); - if (pid == -1) { - const int original_errno = errno; - throw fs::system_error("Cannot fork to execute unmount tool", - original_errno); - } else if (pid == 0) { - const int ret = ::execlp(UMOUNT, "umount", mount_point.c_str(), NULL); - INV(ret == -1); - std::cerr << "Failed to exec " UMOUNT "\n"; - std::exit(EXIT_FAILURE); - } - - int status; -retry: - if (::waitpid(pid, &status, 0) == -1) { - const int original_errno = errno; - if (errno == EINTR) - goto retry; - throw fs::system_error("Failed to wait for unmount subprocess", - original_errno); - } - - if (WIFEXITED(status)) { - if (WEXITSTATUS(status) == EXIT_SUCCESS) - return; - else - throw fs::error(F("Failed to unmount %s; returned exit code %s") - % mount_point % WEXITSTATUS(status)); - } else - throw fs::error(F("Failed to unmount %s; unmount tool received signal") - % mount_point); +#if defined(HAVE_UNMOUNT) + if (::unmount(mount_point.c_str(), 0) == 0) + return; +#elif defined(HAVE_UMOUNT) + if (::umount(mount_point.c_str()) == 0) + return; +#endif + const int original_errno = errno; + throw fs::system_error(F("unmount(%s) failed") % mount_point, + original_errno); } - /// Stats a file, without following links. /// /// \param path The file to stat. @@ -788,11 +706,7 @@ fs::unmount(const fs::path& in_mount_point) int retries = unmount_retries; retry: try { - if (have_unmount2) { - unmount_with_unmount2(mount_point); - } else { - unmount_with_umount8(mount_point); - } + unmount_impl(mount_point); } catch (const fs::system_error& error) { if (error.original_errno() == EBUSY && retries > 0) { LW(F("%s busy; unmount retries left %s") % mount_point % retries); |
