Skip to content

Commit f7b6843

Browse files
committed
Kernel+CrashDaemon: Use a ".partial" suffix for incomplete coredumps
The Kernel will now write to a .partial file until it is done writing, and then rename the file by removing the extension. This makes the final coredump appear atomically on the file system and thus remove the need for special handling of partial files in CrashDaemon.
1 parent 64f08ba commit f7b6843

File tree

2 files changed

+19
-28
lines changed

2 files changed

+19
-28
lines changed

Kernel/Tasks/Process.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -831,10 +831,21 @@ ErrorOr<void> Process::dump_core()
831831
return {};
832832
}
833833
auto coredump_path = TRY(name().with([&](auto& process_name) {
834-
return KString::formatted("{}/{}_{}_{}", coredump_directory_path->view(), process_name.representable_view(), pid().value(), kgettimeofday().seconds_since_epoch());
834+
return KString::formatted("{}/{}_{}_{}.partial", coredump_directory_path->view(), process_name.representable_view(), pid().value(), kgettimeofday().seconds_since_epoch());
835835
}));
836836
auto coredump = TRY(Coredump::try_create(*this, coredump_path->view()));
837-
return coredump->write();
837+
TRY(coredump->write());
838+
839+
auto output_directory = KLexicalPath::dirname(coredump_path->view());
840+
auto vfs_root_context_root_custody = vfs_root_context()->root_custody().with([](auto& custody) -> NonnullRefPtr<Custody> {
841+
return custody;
842+
});
843+
auto dump_directory = TRY(VirtualFileSystem::open_directory(vfs_root_context(), credentials(), output_directory, *vfs_root_context_root_custody));
844+
845+
auto new_path = TRY(KString::try_create(coredump_path->view().trim(".partial"sv)));
846+
TRY(VirtualFileSystem::rename(vfs_root_context(), credentials(), dump_directory, coredump_path->view(), dump_directory, new_path->view()));
847+
848+
return {};
838849
}
839850

840851
ErrorOr<void> Process::dump_perfcore()

Userland/Services/CrashDaemon/main.cpp

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,11 @@
44
* SPDX-License-Identifier: BSD-2-Clause
55
*/
66

7-
#include <AK/LexicalPath.h>
8-
#include <Kernel/API/InodeWatcherEvent.h>
97
#include <LibCore/FileWatcher.h>
108
#include <LibCore/MappedFile.h>
119
#include <LibCore/Process.h>
1210
#include <LibCore/System.h>
1311
#include <LibMain/Main.h>
14-
#include <spawn.h>
15-
#include <sys/stat.h>
16-
#include <time.h>
17-
#include <unistd.h>
18-
19-
static void wait_until_coredump_is_ready(ByteString const& coredump_path)
20-
{
21-
while (true) {
22-
struct stat statbuf;
23-
if (stat(coredump_path.characters(), &statbuf) < 0) {
24-
perror("stat");
25-
VERIFY_NOT_REACHED();
26-
}
27-
if (statbuf.st_mode & 0400) // Check if readable
28-
break;
29-
30-
usleep(10000); // sleep for 10ms
31-
}
32-
}
3312

3413
static void launch_crash_reporter(ByteString const& coredump_path, bool unlink_on_exit)
3514
{
@@ -49,13 +28,14 @@ ErrorOr<int> serenity_main(Main::Arguments)
4928
TRY(watcher.add_watch("/tmp/coredump", Core::FileWatcherEvent::Type::ChildCreated));
5029

5130
while (true) {
52-
auto event = watcher.wait_for_event();
53-
VERIFY(event.has_value());
54-
if (event.value().type != Core::FileWatcherEvent::Type::ChildCreated)
31+
auto event = watcher.wait_for_event().value();
32+
if (event.type != Core::FileWatcherEvent::Type::ChildCreated)
5533
continue;
56-
auto& coredump_path = event.value().event_path;
34+
auto& coredump_path = event.event_path;
35+
if (coredump_path.ends_with(".partial"sv))
36+
continue;
37+
5738
dbgln("New coredump file: {}", coredump_path);
58-
wait_until_coredump_is_ready(coredump_path);
5939

6040
auto file_or_error = Core::MappedFile::map(coredump_path);
6141
if (file_or_error.is_error()) {

0 commit comments

Comments
 (0)