Merge changes from topic "fdr_merge" into rvc-dev
* changes:
libsnapshot: Allow forward merge on FDR
libsnapshot: Place forward merge indicator for wipe
libsnapshot: Add allow-forward-merge indicator.
libsnapshot: Fix DataWipeAfterRollback test
libsnapshot: Fix intermittent test failure due to missing null check.
libsnapshot: dump rollback indicator
diff --git a/init/init.cpp b/init/init.cpp
index 9eac473..cadd5c5 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -22,6 +22,7 @@
#include <signal.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/eventfd.h>
#include <sys/mount.h>
#include <sys/signalfd.h>
#include <sys/types.h>
@@ -114,30 +115,26 @@
// to fill that socket and deadlock the system. Now we use locks to handle the property changes
// directly in the property thread, however we still must wake the epoll to inform init that there
// is a change to process, so we use this FD. It is non-blocking, since we do not care how many
-// times WakeEpoll() is called, only that the epoll will wake.
-static int wake_epoll_fd = -1;
+// times WakeMainInitThread() is called, only that the epoll will wake.
+static int wake_main_thread_fd = -1;
static void InstallInitNotifier(Epoll* epoll) {
- int sockets[2];
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, sockets) != 0) {
- PLOG(FATAL) << "Failed to socketpair() between property_service and init";
+ wake_main_thread_fd = eventfd(0, EFD_CLOEXEC);
+ if (wake_main_thread_fd == -1) {
+ PLOG(FATAL) << "Failed to create eventfd for waking init";
}
- int epoll_fd = sockets[0];
- wake_epoll_fd = sockets[1];
-
- auto drain_socket = [epoll_fd] {
- char buf[512];
- while (read(epoll_fd, buf, sizeof(buf)) > 0) {
- }
+ auto clear_eventfd = [] {
+ uint64_t counter;
+ TEMP_FAILURE_RETRY(read(wake_main_thread_fd, &counter, sizeof(counter)));
};
- if (auto result = epoll->RegisterHandler(epoll_fd, drain_socket); !result.ok()) {
+ if (auto result = epoll->RegisterHandler(wake_main_thread_fd, clear_eventfd); !result.ok()) {
LOG(FATAL) << result.error();
}
}
-static void WakeEpoll() {
- constexpr char value[] = "1";
- TEMP_FAILURE_RETRY(write(wake_epoll_fd, value, sizeof(value)));
+static void WakeMainInitThread() {
+ uint64_t counter = 1;
+ TEMP_FAILURE_RETRY(write(wake_main_thread_fd, &counter, sizeof(counter)));
}
static class PropWaiterState {
@@ -181,7 +178,7 @@
LOG(INFO) << "Wait for property '" << wait_prop_name_ << "=" << wait_prop_value_
<< "' took " << *waiting_for_prop_;
ResetWaitForPropLocked();
- WakeEpoll();
+ WakeMainInitThread();
}
}
}
@@ -229,7 +226,7 @@
auto lock = std::lock_guard{shutdown_command_lock_};
shutdown_command_ = command;
do_shutdown_ = true;
- WakeEpoll();
+ WakeMainInitThread();
}
std::optional<std::string> CheckShutdown() {
@@ -313,7 +310,7 @@
if (property_triggers_enabled) {
ActionManager::GetInstance().QueuePropertyChange(name, value);
- WakeEpoll();
+ WakeMainInitThread();
}
prop_waiter_state.CheckAndResetWait(name, value);
@@ -439,7 +436,7 @@
return false;
}
pending_control_messages.push({message, name, pid, fd});
- WakeEpoll();
+ WakeMainInitThread();
return true;
}
@@ -465,7 +462,7 @@
}
// If we still have items to process, make sure we wake back up to do so.
if (!pending_control_messages.empty()) {
- WakeEpoll();
+ WakeMainInitThread();
}
}
@@ -882,7 +879,9 @@
(*function)();
}
}
- HandleControlMessages();
+ if (!IsShuttingDown()) {
+ HandleControlMessages();
+ }
}
return 0;
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 8206522..a5fea7c 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -125,7 +125,7 @@
void StopSendingMessages() {
auto lock = std::lock_guard{accept_messages_lock};
- accept_messages = true;
+ accept_messages = false;
}
bool CanReadProperty(const std::string& source_context, const std::string& name) {