blob: 727f4051c131bcc6b325b24156643d8dfd6c6f4a [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "vm_tools/common/naming.h"
#include "vm_tools/pstore_dump/persistent_ram_buffer.h"
#include <string>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <brillo/flag_helper.h>
#include <brillo/cryptohome.h>
#include <brillo/dbus/async_event_sequencer.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_proxy.h>
namespace {
bool GetPrimaryUsername(std::string* out_username) {
DCHECK(out_username);
dbus::Bus::Options options;
options.bus_type = dbus::Bus::SYSTEM;
scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
CHECK(bus->Connect()) << "Failed to connect to system D-Bus";
dbus::ObjectProxy* session_manager_proxy = bus->GetObjectProxy(
login_manager::kSessionManagerServiceName,
dbus::ObjectPath(login_manager::kSessionManagerServicePath));
dbus::MethodCall method_call(
login_manager::kSessionManagerInterface,
login_manager::kSessionManagerRetrievePrimarySession);
std::unique_ptr<dbus::Response> response =
session_manager_proxy->CallMethodAndBlock(
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
if (!response.get()) {
LOG(ERROR) << "Cannot retrieve username for primary session.";
bus->ShutdownAndBlock();
return false;
}
dbus::MessageReader response_reader(response.get());
if (!response_reader.PopString(out_username)) {
LOG(ERROR) << "Primary session username bad format.";
bus->ShutdownAndBlock();
return false;
}
bus->ShutdownAndBlock();
return true;
}
bool FindARCVMPstorePath(base::FilePath* out_path) {
DCHECK(out_path);
std::string primary_username;
if (!GetPrimaryUsername(&primary_username)) {
LOG(ERROR) << "Failed to get primary username";
return false;
}
base::FilePath root_path =
brillo::cryptohome::home::GetRootPath(primary_username);
if (root_path.empty()) {
LOG(ERROR) << "Failed to get the cryptohome root path of user of ARCVM";
return false;
}
base::FilePath pstore_path = root_path.Append("crosvm").Append(
vm_tools::GetEncodedName("arcvm") + ".pstore");
if (!base::PathExists(pstore_path)) {
LOG(ERROR) << "The .pstore file doesn't exist: " << pstore_path;
return false;
}
*out_path = pstore_path;
return true;
}
} // namespace
int main(int argc, char** argv) {
DEFINE_string(file, "", "path to a .pstore file (default: ARCVM's .pstore)");
brillo::FlagHelper::Init(
argc, argv,
"A helper to read .pstore files generated by the ARCVM's guest kernel.");
base::FilePath path;
if (!FLAGS_file.empty()) {
path = base::FilePath(FLAGS_file);
} else if (!FindARCVMPstorePath(&path)) {
LOG(ERROR)
<< "Failed to detect the .pstore file. Please use --file option.";
exit(EXIT_FAILURE);
}
if (!vm_tools::pstore_dump::HandlePstore(path)) {
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}