Merge "crash_dump: suggest lldbclient.py rather than gdbclient.py."
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 895c111..4d60ddb 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -1680,6 +1680,24 @@
if (params.free_before_access) free(static_cast<void*>(const_cast<char*>(p)));
p[params.access_offset] = 42;
if (!params.free_before_access) free(static_cast<void*>(const_cast<char*>(p)));
+
+ bool recoverable = std::get<1>(GetParam());
+ ASSERT_TRUE(recoverable); // Non-recoverable should have crashed.
+
+ // As we're in recoverable mode, trigger another 2x use-after-frees (ensuring
+ // we end with at least one in a different slot), make sure the process still
+ // doesn't crash.
+ p = reinterpret_cast<char* volatile>(malloc(params.alloc_size));
+ char* volatile p2 = reinterpret_cast<char* volatile>(malloc(params.alloc_size));
+ free(static_cast<void*>(const_cast<char*>(p)));
+ free(static_cast<void*>(const_cast<char*>(p2)));
+ *p = 42;
+ *p2 = 42;
+
+ // Under clang coverage (which is a default TEST_MAPPING presubmit target), the
+ // recoverable+seccomp tests fail because the minijail prevents some atexit syscalls that clang
+ // coverage does. Thus, skip the atexit handlers.
+ _exit(0);
}
TEST_F(CrasherTest, fdsan_warning_abort_message) {
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 799c9f9..5dac3f5 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -342,30 +342,49 @@
int port;
};
-static Result<NetworkSerial> ParseNetworkSerial(const std::string& serial) {
- const auto serial_parsed = android::base::Tokenize(serial, ":");
- const auto parsed_segments_count = serial_parsed.size();
- if (parsed_segments_count != 2 && parsed_segments_count != 3) {
- return Error() << "invalid network address: " << serial << ". Expected format:\n"
- << "<protocol>:<address>:<port> (tcp:localhost:5554)";
- }
+class ParseNetworkAddressError {
+ public:
+ enum Type { WRONG_PREFIX = 1, WRONG_ADDRESS = 2 };
+ ParseNetworkAddressError(Type&& type) : type_(std::forward<Type>(type)) {}
+
+ Type value() const { return type_; }
+ operator Type() const { return value(); }
+ std::string print() const { return ""; }
+
+ private:
+ Type type_;
+};
+
+static Result<NetworkSerial, ParseNetworkAddressError> ParseNetworkSerial(
+ const std::string& serial) {
Socket::Protocol protocol;
- if (serial_parsed[0] == "tcp") {
+ const char* net_address = nullptr;
+ int port = 0;
+
+ if (android::base::StartsWith(serial, "tcp:")) {
protocol = Socket::Protocol::kTcp;
- } else if (serial_parsed[0] == "udp") {
+ net_address = serial.c_str() + strlen("tcp:");
+ port = tcp::kDefaultPort;
+ } else if (android::base::StartsWith(serial, "udp:")) {
protocol = Socket::Protocol::kUdp;
+ net_address = serial.c_str() + strlen("udp:");
+ port = udp::kDefaultPort;
} else {
- return Error() << "invalid network address: " << serial << ". Expected format:\n"
- << "<protocol>:<address>:<port> (tcp:localhost:5554)";
+ return Error<ParseNetworkAddressError>(ParseNetworkAddressError::Type::WRONG_PREFIX)
+ << "protocol prefix ('tcp:' or 'udp:') is missed: " << serial << ". "
+ << "Expected address format:\n"
+ << "<protocol>:<address>:<port> (tcp:localhost:5554)";
}
- int port = 5554;
- if (parsed_segments_count == 3) {
- android::base::ParseInt(serial_parsed[2], &port, 5554);
+ std::string error;
+ std::string host;
+ if (!android::base::ParseNetAddress(net_address, &host, &port, nullptr, &error)) {
+ return Error<ParseNetworkAddressError>(ParseNetworkAddressError::Type::WRONG_ADDRESS)
+ << "invalid network address '" << net_address << "': " << error;
}
- return NetworkSerial{protocol, serial_parsed[1], port};
+ return NetworkSerial{protocol, host, port};
}
// Opens a new Transport connected to the particular device.
@@ -380,7 +399,8 @@
// object, and the caller should not attempt to delete the returned Transport.
static Transport* open_device(const char* local_serial, bool wait_for_device = true,
bool announce = true) {
- const Result<NetworkSerial> network_serial = ParseNetworkSerial(local_serial);
+ const Result<NetworkSerial, ParseNetworkAddressError> network_serial =
+ ParseNetworkSerial(local_serial);
Transport* transport = nullptr;
while (true) {
@@ -397,8 +417,12 @@
if (transport == nullptr && announce) {
LOG(ERROR) << "error: " << error;
}
- } else {
+ } else if (network_serial.error().code() == ParseNetworkAddressError::Type::WRONG_PREFIX) {
+ // WRONG_PREFIX is special because it happens when user wants to communicate with USB
+ // device
transport = usb_open(match_fastboot(local_serial));
+ } else {
+ Expect(network_serial);
}
if (transport != nullptr) {
@@ -413,7 +437,7 @@
announce = false;
LOG(ERROR) << "< waiting for " << local_serial << ">";
}
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
@@ -476,7 +500,7 @@
announce = false;
LOG(ERROR) << "< waiting for any device >";
}
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
@@ -487,7 +511,7 @@
}
const char* local_serial = *argv;
- EXPECT(ParseNetworkSerial(local_serial));
+ Expect(ParseNetworkSerial(local_serial));
const Transport* transport = open_device(local_serial, false);
if (transport == nullptr) {
@@ -506,7 +530,7 @@
}
static int Disconnect(const char* local_serial) {
- EXPECT(ParseNetworkSerial(local_serial));
+ Expect(ParseNetworkSerial(local_serial));
ConnectedDevicesStorage storage;
{
@@ -1099,7 +1123,9 @@
unique_fd fd(TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_BINARY)));
if (fd == -1) {
- return false;
+ auto path = find_item_given_name(fname);
+ fd = unique_fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_BINARY)));
+ if (fd == -1) return false;
}
struct stat s;
@@ -1555,7 +1581,7 @@
delete old_transport;
// Give the current connection time to close.
- std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+ std::this_thread::sleep_for(std::chrono::seconds(1));
fb->set_transport(open_device());
@@ -2143,10 +2169,6 @@
android::base::InitLogging(argv, FastbootLogger, FastbootAborter);
bool wants_wipe = false;
- bool wants_reboot = false;
- bool wants_reboot_bootloader = false;
- bool wants_reboot_recovery = false;
- bool wants_reboot_fastboot = false;
bool skip_reboot = false;
bool wants_set_active = false;
bool skip_secondary = false;
@@ -2335,7 +2357,7 @@
}
}
}
-
+ std::unique_ptr<Task> reboot_task = nullptr;
std::vector<std::string> args(argv, argv + argc);
while (!args.empty()) {
std::string command = next_arg(&args);
@@ -2387,30 +2409,19 @@
fb->Download("signature", data);
fb->RawCommand("signature", "installing signature");
} else if (command == FB_CMD_REBOOT) {
- wants_reboot = true;
-
if (args.size() == 1) {
- std::string what = next_arg(&args);
- if (what == "bootloader") {
- wants_reboot = false;
- wants_reboot_bootloader = true;
- } else if (what == "recovery") {
- wants_reboot = false;
- wants_reboot_recovery = true;
- } else if (what == "fastboot") {
- wants_reboot = false;
- wants_reboot_fastboot = true;
- } else {
- syntax_error("unknown reboot target %s", what.c_str());
- }
+ std::string reboot_target = next_arg(&args);
+ reboot_task = std::make_unique<RebootTask>(fb, reboot_target);
+ } else {
+ reboot_task = std::make_unique<RebootTask>(fb);
}
if (!args.empty()) syntax_error("junk after reboot command");
} else if (command == FB_CMD_REBOOT_BOOTLOADER) {
- wants_reboot_bootloader = true;
+ reboot_task = std::make_unique<RebootTask>(fb, "bootloader");
} else if (command == FB_CMD_REBOOT_RECOVERY) {
- wants_reboot_recovery = true;
+ reboot_task = std::make_unique<RebootTask>(fb, "recovery");
} else if (command == FB_CMD_REBOOT_FASTBOOT) {
- wants_reboot_fastboot = true;
+ reboot_task = std::make_unique<RebootTask>(fb, "fastboot");
} else if (command == FB_CMD_CONTINUE) {
fb->Continue();
} else if (command == FB_CMD_BOOT) {
@@ -2454,7 +2465,7 @@
} else {
do_flashall(slot_override, skip_secondary, wants_wipe, force_flash);
}
- wants_reboot = true;
+ reboot_task = std::make_unique<RebootTask>(fb);
} else if (command == "update") {
bool slot_all = (slot_override == "all");
if (slot_all) {
@@ -2466,7 +2477,7 @@
filename = next_arg(&args);
}
do_update(filename.c_str(), slot_override, skip_secondary || slot_all, force_flash);
- wants_reboot = true;
+ reboot_task = std::make_unique<RebootTask>(fb);
} else if (command == FB_CMD_SET_ACTIVE) {
std::string slot = verify_slot(next_arg(&args), false);
fb->SetActive(slot);
@@ -2538,7 +2549,6 @@
syntax_error("unknown command %s", command.c_str());
}
}
-
if (wants_wipe) {
if (force_flash) {
CancelSnapshotIfNeeded();
@@ -2557,19 +2567,9 @@
if (wants_set_active) {
fb->SetActive(next_active);
}
- if (wants_reboot && !skip_reboot) {
- fb->Reboot();
- fb->WaitForDisconnect();
- } else if (wants_reboot_bootloader) {
- fb->RebootTo("bootloader");
- fb->WaitForDisconnect();
- } else if (wants_reboot_recovery) {
- fb->RebootTo("recovery");
- fb->WaitForDisconnect();
- } else if (wants_reboot_fastboot) {
- reboot_to_userspace_fastboot();
+ if (reboot_task && !skip_reboot) {
+ reboot_task->Run();
}
-
fprintf(stderr, "Finished. Total time: %.3fs\n", (now() - start));
auto* old_transport = fb->set_transport(nullptr);
diff --git a/fastboot/task.cpp b/fastboot/task.cpp
index 3f33c76..94dd5c3 100644
--- a/fastboot/task.cpp
+++ b/fastboot/task.cpp
@@ -14,6 +14,8 @@
// limitations under the License.
//
#include "task.h"
+#include "fastboot.h"
+#include "util.h"
#include "fastboot.h"
#include "util.h"
@@ -44,3 +46,27 @@
};
do_for_partitions(pname_, slot_, flash, true);
}
+
+RebootTask::RebootTask(fastboot::FastBootDriver* _fb) : fb_(_fb){};
+RebootTask::RebootTask(fastboot::FastBootDriver* _fb, std::string _reboot_target)
+ : reboot_target_(std::move(_reboot_target)), fb_(_fb){};
+
+void RebootTask::Run() {
+ if ((reboot_target_ == "userspace" || reboot_target_ == "fastboot")) {
+ if (!is_userspace_fastboot()) {
+ reboot_to_userspace_fastboot();
+ fb_->WaitForDisconnect();
+ }
+ } else if (reboot_target_ == "recovery") {
+ fb_->RebootTo("recovery");
+ fb_->WaitForDisconnect();
+ } else if (reboot_target_ == "bootloader") {
+ fb_->RebootTo("bootloader");
+ fb_->WaitForDisconnect();
+ } else if (reboot_target_ == "") {
+ fb_->Reboot();
+ fb_->WaitForDisconnect();
+ } else {
+ syntax_error("unknown reboot target %s", reboot_target_.c_str());
+ }
+}
diff --git a/fastboot/task.h b/fastboot/task.h
index 216e658..582fa2f 100644
--- a/fastboot/task.h
+++ b/fastboot/task.h
@@ -18,9 +18,7 @@
#include <sstream>
#include <string>
-#include "fastboot.h"
#include "fastboot_driver.h"
-#include "util.h"
class Task {
public:
@@ -46,3 +44,15 @@
const std::string slot_;
bool force_flash_ = false;
};
+
+class RebootTask : public Task {
+ public:
+ RebootTask(fastboot::FastBootDriver* _fb);
+ RebootTask(fastboot::FastBootDriver* _fb, const std::string _reboot_target);
+ void Run() override;
+ ~RebootTask() {}
+
+ private:
+ const std::string reboot_target_ = "";
+ fastboot::FastBootDriver* fb_;
+};
\ No newline at end of file
diff --git a/fastboot/util.h b/fastboot/util.h
index bc01473..8a79e13 100644
--- a/fastboot/util.h
+++ b/fastboot/util.h
@@ -18,8 +18,16 @@
using android::base::Result;
using android::base::ResultError;
-#define EXPECT(result) \
- (result.ok() ? result.value() : (LOG(FATAL) << result.error().message(), result.value()))
+template <typename T, typename U>
+inline T Expect(Result<T, U> r) {
+ if (r.ok()) {
+ return r.value();
+ }
+
+ LOG(FATAL) << r.error().message();
+
+ return r.value();
+}
using SparsePtr = std::unique_ptr<sparse_file, decltype(&sparse_file_destroy)>;
diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
index b3763ae..fa04c43 100644
--- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
+++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
@@ -108,6 +108,12 @@
// Estimated COW size from OTA manifest.
uint64 estimated_cow_size = 12;
+
+ // Enable multi-threaded compression
+ bool enable_threading = 13;
+
+ // Enable batching for COW writes
+ bool batched_writes = 14;
}
// Next: 8
diff --git a/fs_mgr/libsnapshot/partition_cow_creator.h b/fs_mgr/libsnapshot/partition_cow_creator.h
index 949e6c5..bd5c8cb 100644
--- a/fs_mgr/libsnapshot/partition_cow_creator.h
+++ b/fs_mgr/libsnapshot/partition_cow_creator.h
@@ -60,6 +60,12 @@
bool using_snapuserd = false;
std::string compression_algorithm;
+ // True if multi-threaded compression should be enabled
+ bool enable_threading;
+
+ // True if COW writes should be batched in memory
+ bool batched_writes;
+
struct Return {
SnapshotStatus snapshot_status;
std::vector<Interval> cow_partition_usable_regions;
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 961db02..15f025c 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -400,6 +400,12 @@
status->set_metadata_sectors(0);
status->set_using_snapuserd(cow_creator->using_snapuserd);
status->set_compression_algorithm(cow_creator->compression_algorithm);
+ if (cow_creator->enable_threading) {
+ status->set_enable_threading(cow_creator->enable_threading);
+ }
+ if (cow_creator->batched_writes) {
+ status->set_batched_writes(cow_creator->batched_writes);
+ }
if (!WriteSnapshotStatus(lock, *status)) {
PLOG(ERROR) << "Could not write snapshot status: " << status->name();
@@ -3248,6 +3254,12 @@
.using_snapuserd = using_snapuserd,
.compression_algorithm = compression_algorithm,
};
+ if (dap_metadata.vabc_feature_set().has_threaded()) {
+ cow_creator.enable_threading = dap_metadata.vabc_feature_set().threaded();
+ }
+ if (dap_metadata.vabc_feature_set().has_batch_writes()) {
+ cow_creator.batched_writes = dap_metadata.vabc_feature_set().batch_writes();
+ }
auto ret = CreateUpdateSnapshotsInternal(lock.get(), manifest, &cow_creator, &created_devices,
&all_snapshot_status);
@@ -3635,6 +3647,8 @@
CowOptions cow_options;
cow_options.compression = status.compression_algorithm();
cow_options.max_blocks = {status.device_size() / cow_options.block_size};
+ cow_options.batch_write = status.batched_writes();
+ cow_options.num_compress_threads = status.enable_threading() ? 2 : 0;
// Disable scratch space for vts tests
if (device()->IsTestDevice()) {
cow_options.scratch_space = false;
diff --git a/fs_mgr/libsnapshot/update_engine/update_metadata.proto b/fs_mgr/libsnapshot/update_engine/update_metadata.proto
index 69d72e1..cc12d1d 100644
--- a/fs_mgr/libsnapshot/update_engine/update_metadata.proto
+++ b/fs_mgr/libsnapshot/update_engine/update_metadata.proto
@@ -71,11 +71,18 @@
repeated string partition_names = 3;
}
+message VABCFeatureSet {
+ optional bool threaded = 1;
+ optional bool batch_writes = 2;
+}
+
message DynamicPartitionMetadata {
repeated DynamicPartitionGroup groups = 1;
optional bool vabc_enabled = 3;
optional string vabc_compression_param = 4;
optional uint32 cow_version = 5;
+ // A collection of knobs to tune Virtual AB Compression
+ optional VABCFeatureSet vabc_feature_set = 6;
}
message DeltaArchiveManifest {
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index b180a58..66e1e63 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -392,12 +392,13 @@
mHealthInfo->batteryFullChargeDesignCapacityUah =
getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath);
- if (!mHealthdConfig->batteryStateOfHealthPath.isEmpty())
- mHealthInfo->batteryStateOfHealth = getIntField(mHealthdConfig->batteryStateOfHealthPath);
-
if (!mHealthdConfig->batteryHealthStatusPath.isEmpty())
mBatteryHealthStatus = getIntField(mHealthdConfig->batteryHealthStatusPath);
+ if (!mHealthdConfig->batteryStateOfHealthPath.isEmpty())
+ mHealthInfo->batteryHealthData->batteryStateOfHealth =
+ getIntField(mHealthdConfig->batteryStateOfHealthPath);
+
if (!mHealthdConfig->batteryManufacturingDatePath.isEmpty())
mHealthInfo->batteryHealthData->batteryManufacturingDateSeconds =
getIntField(mHealthdConfig->batteryManufacturingDatePath);
@@ -591,6 +592,10 @@
if (!mHealthdConfig->batteryFirstUsageDatePath.isEmpty())
return getIntField(mHealthdConfig->batteryFirstUsageDatePath);
}
+ if (id == BATTERY_PROP_STATE_OF_HEALTH) {
+ if (!mHealthdConfig->batteryStateOfHealthPath.isEmpty())
+ return getIntField(mHealthdConfig->batteryStateOfHealthPath);
+ }
return 0;
}
@@ -669,6 +674,11 @@
ret = OK;
break;
+ case BATTERY_PROP_STATE_OF_HEALTH:
+ val->valueInt64 = getBatteryHealthData(BATTERY_PROP_STATE_OF_HEALTH);
+ ret = OK;
+ break;
+
default:
break;
}
diff --git a/init/action.cpp b/init/action.cpp
index 1e998ae..18f6360 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -30,7 +30,7 @@
Result<void> RunBuiltinFunction(const BuiltinFunction& function,
const std::vector<std::string>& args, const std::string& context) {
- auto builtin_arguments = BuiltinArguments(context);
+ BuiltinArguments builtin_arguments{.context = context};
builtin_arguments.args.resize(args.size());
builtin_arguments.args[0] = args[0];
@@ -69,7 +69,7 @@
}
Result<void> Command::CheckCommand() const {
- auto builtin_arguments = BuiltinArguments("host_init_verifier");
+ BuiltinArguments builtin_arguments{.context = "host_init_verifier"};
builtin_arguments.args.resize(args_.size());
builtin_arguments.args[0] = args_[0];
diff --git a/init/builtin_arguments.h b/init/builtin_arguments.h
index 1742b78..890a216 100644
--- a/init/builtin_arguments.h
+++ b/init/builtin_arguments.h
@@ -24,10 +24,6 @@
namespace init {
struct BuiltinArguments {
- BuiltinArguments(const std::string& context) : context(context) {}
- BuiltinArguments(std::vector<std::string> args, const std::string& context)
- : args(std::move(args)), context(context) {}
-
const std::string& operator[](std::size_t i) const { return args[i]; }
auto begin() const { return args.begin(); }
auto end() const { return args.end(); }
diff --git a/init/builtins.cpp b/init/builtins.cpp
index a89813e..bc23972 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -1074,7 +1074,7 @@
static Result<void> do_restorecon_recursive(const BuiltinArguments& args) {
std::vector<std::string> non_const_args(args.args);
non_const_args.insert(std::next(non_const_args.begin()), "--recursive");
- return do_restorecon({std::move(non_const_args), args.context});
+ return do_restorecon({.args = std::move(non_const_args), .context = args.context});
}
static Result<void> do_loglevel(const BuiltinArguments& args) {
diff --git a/init/check_builtins.cpp b/init/check_builtins.cpp
index 481fa31..461ed22 100644
--- a/init/check_builtins.cpp
+++ b/init/check_builtins.cpp
@@ -85,7 +85,7 @@
}
Result<void> check_exec_reboot_on_failure(const BuiltinArguments& args) {
- BuiltinArguments remaining_args(args.context);
+ BuiltinArguments remaining_args{.context = args.context};
remaining_args.args = std::vector<std::string>(args.begin() + 1, args.end());
remaining_args.args[0] = args[0];
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 4cc00fe..062ed39 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -897,29 +897,31 @@
continue;
}
- auto system_entry = GetEntryForMountPoint(&fstab, "/system");
- if (!system_entry) {
- LOG(ERROR) << "Could not find mount entry for /system";
- break;
- }
- if (!system_entry->fs_mgr_flags.logical) {
- LOG(INFO) << "Skipping mount of " << name << ", system is not dynamic.";
- break;
- }
+ auto system_entries = GetEntriesForMountPoint(&fstab, "/system");
+ for (auto& system_entry : system_entries) {
+ if (!system_entry) {
+ LOG(ERROR) << "Could not find mount entry for /system";
+ break;
+ }
+ if (!system_entry->fs_mgr_flags.logical) {
+ LOG(INFO) << "Skipping mount of " << name << ", system is not dynamic.";
+ break;
+ }
- auto entry = *system_entry;
- auto partition_name = name + fs_mgr_get_slot_suffix();
- auto replace_name = "system"s + fs_mgr_get_slot_suffix();
+ auto entry = *system_entry;
+ auto partition_name = name + fs_mgr_get_slot_suffix();
+ auto replace_name = "system"s + fs_mgr_get_slot_suffix();
- entry.mount_point = "/"s + name;
- entry.blk_device =
+ entry.mount_point = "/"s + name;
+ entry.blk_device =
android::base::StringReplace(entry.blk_device, replace_name, partition_name, false);
- if (!fs_mgr_update_logical_partition(&entry)) {
- LOG(ERROR) << "Could not update logical partition";
- continue;
- }
+ if (!fs_mgr_update_logical_partition(&entry)) {
+ LOG(ERROR) << "Could not update logical partition";
+ continue;
+ }
- extra_fstab.emplace_back(std::move(entry));
+ extra_fstab.emplace_back(std::move(entry));
+ }
}
SkipMountingPartitions(&extra_fstab, true /* verbose */);
diff --git a/init/service.cpp b/init/service.cpp
index 87d9c3a..cce24c3 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -755,6 +755,9 @@
NotifyStateChange("running");
reboot_on_failure.Disable();
+
+ LOG(INFO) << "... started service '" << name_ << "' has pid " << pid_;
+
return {};
}
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 1da69ba..384a8f0 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -406,18 +406,15 @@
pids.emplace(pid);
}
}
- if (file_is_empty) {
- // This happens when process is already dead
- return 0;
- }
-
- // Erase all pids that will be killed when we kill the process groups.
- for (auto it = pids.begin(); it != pids.end();) {
- pid_t pgid = getpgid(*it);
- if (pgids.count(pgid) == 1) {
- it = pids.erase(it);
- } else {
- ++it;
+ if (!file_is_empty) {
+ // Erase all pids that will be killed when we kill the process groups.
+ for (auto it = pids.begin(); it != pids.end();) {
+ pid_t pgid = getpgid(*it);
+ if (pgids.count(pgid) == 1) {
+ it = pids.erase(it);
+ } else {
+ ++it;
+ }
}
}
}