Commit 1850b0d5 authored by Fergus Dall's avatar Fergus Dall Committed by Commit Bot

Add AnomalyDetectorClient to //chromeos/dbus

This will be used to detect VM filesystem corruption.

Bug: 1018093
Change-Id: Icf95a14e6d106a7e7f391e15a3f2e9cd648c4499
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1915649
Commit-Queue: Fergus Dall <sidereal@google.com>
Reviewed-by: default avatarRyo Hashimoto <hashimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#718016}
parent de4a565f
...@@ -23,6 +23,7 @@ component("dbus") { ...@@ -23,6 +23,7 @@ component("dbus") {
"//dbus", "//dbus",
] ]
deps = [ deps = [
":anomaly_detector_proto",
":cicerone_proto", ":cicerone_proto",
":concierge_proto", ":concierge_proto",
":metrics_event_proto", ":metrics_event_proto",
...@@ -42,6 +43,8 @@ component("dbus") { ...@@ -42,6 +43,8 @@ component("dbus") {
"//url", "//url",
] ]
sources = [ sources = [
"anomaly_detector_client.cc",
"anomaly_detector_client.h",
"arc_appfuse_provider_client.cc", "arc_appfuse_provider_client.cc",
"arc_appfuse_provider_client.h", "arc_appfuse_provider_client.h",
"arc_camera_client.cc", "arc_camera_client.cc",
...@@ -69,6 +72,8 @@ component("dbus") { ...@@ -69,6 +72,8 @@ component("dbus") {
"dbus_thread_manager.h", "dbus_thread_manager.h",
"easy_unlock_client.cc", "easy_unlock_client.cc",
"easy_unlock_client.h", "easy_unlock_client.h",
"fake_anomaly_detector_client.cc",
"fake_anomaly_detector_client.h",
"fake_arc_appfuse_provider_client.cc", "fake_arc_appfuse_provider_client.cc",
"fake_arc_appfuse_provider_client.h", "fake_arc_appfuse_provider_client.h",
"fake_arc_camera_client.cc", "fake_arc_camera_client.cc",
...@@ -241,6 +246,14 @@ source_set("unit_tests") { ...@@ -241,6 +246,14 @@ source_set("unit_tests") {
] ]
} }
proto_library("anomaly_detector_proto") {
sources = [
"//third_party/cros_system_api/dbus/anomaly_detector/anomaly_detector.proto",
]
proto_out_dir = "chromeos/dbus/anomaly_detector"
}
proto_library("cicerone_proto") { proto_library("cicerone_proto") {
sources = [ sources = [
"//third_party/cros_system_api/dbus/vm_cicerone/cicerone_service.proto", "//third_party/cros_system_api/dbus/vm_cicerone/cicerone_service.proto",
......
// Copyright 2019 The Chromium 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 "chromeos/dbus/anomaly_detector_client.h"
#include <memory>
#include "base/bind.h"
#include "base/observer_list.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "third_party/cros_system_api/dbus/anomaly_detector/dbus-constants.h"
namespace chromeos {
class AnomalyDetectorClientImpl : public AnomalyDetectorClient {
public:
AnomalyDetectorClientImpl() = default;
AnomalyDetectorClientImpl(const AnomalyDetectorClientImpl&) = delete;
AnomalyDetectorClientImpl& operator=(const AnomalyDetectorClientImpl&) =
delete;
~AnomalyDetectorClientImpl() override = default;
void AddObserver(Observer* observer) override {
observer_list_.AddObserver(observer);
}
void RemoveObserver(Observer* observer) override {
observer_list_.RemoveObserver(observer);
}
bool IsGuestFileCorruptionSignalConnected() override {
return is_guest_file_corruption_signal_connected_;
}
protected:
void Init(dbus::Bus* bus) override {
anomaly_detector_proxy_ = bus->GetObjectProxy(
anomaly_detector::kAnomalyEventServiceName,
dbus::ObjectPath(anomaly_detector::kAnomalyEventServicePath));
if (!anomaly_detector_proxy_) {
LOG(ERROR) << "Unable to get dbus proxy for "
<< anomaly_detector::kAnomalyEventServiceName;
}
anomaly_detector_proxy_->ConnectToSignal(
anomaly_detector::kAnomalyEventServiceInterface,
anomaly_detector::kAnomalyGuestFileCorruptionSignalName,
base::BindRepeating(
&AnomalyDetectorClientImpl::OnGuestFileCorruptionSignal,
weak_ptr_factory_.GetWeakPtr()),
base::BindOnce(&AnomalyDetectorClientImpl::OnSignalConnected,
weak_ptr_factory_.GetWeakPtr()));
}
private:
void OnGuestFileCorruptionSignal(dbus::Signal* signal) {
anomaly_detector::GuestFileCorruptionSignal proto_signal;
dbus::MessageReader reader(signal);
if (!reader.PopArrayOfBytesAsProto(&proto_signal)) {
LOG(ERROR) << "Failed to parse proto from DBus Signal";
return;
}
for (auto& observer : observer_list_) {
observer.OnGuestFileCorruption(proto_signal);
}
}
void OnSignalConnected(const std::string& interface_name,
const std::string& signal_name,
bool is_connected) {
if (!is_connected) {
LOG(ERROR) << "Failed to connect to signal " << signal_name;
}
DCHECK_EQ(interface_name, anomaly_detector::kAnomalyEventServiceInterface);
if (signal_name ==
anomaly_detector::kAnomalyGuestFileCorruptionSignalName) {
is_guest_file_corruption_signal_connected_ = is_connected;
} else {
NOTREACHED();
}
}
dbus::ObjectProxy* anomaly_detector_proxy_ = nullptr;
base::ObserverList<Observer> observer_list_;
bool is_guest_file_corruption_signal_connected_ = false;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<AnomalyDetectorClientImpl> weak_ptr_factory_{this};
};
AnomalyDetectorClient::AnomalyDetectorClient() = default;
AnomalyDetectorClient::~AnomalyDetectorClient() = default;
std::unique_ptr<AnomalyDetectorClient> AnomalyDetectorClient::Create() {
return std::make_unique<AnomalyDetectorClientImpl>();
}
} // namespace chromeos
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_DBUS_ANOMALY_DETECTOR_CLIENT_H_
#define CHROMEOS_DBUS_ANOMALY_DETECTOR_CLIENT_H_
#include <memory>
#include "base/component_export.h"
#include "base/observer_list_types.h"
#include "chromeos/dbus/anomaly_detector/anomaly_detector.pb.h"
#include "chromeos/dbus/dbus_client.h"
namespace chromeos {
// AnomalyDetectorClient is used to communicate with anomaly_detector.
// Currently this just amounts to listening to signals it sends.
class COMPONENT_EXPORT(CHROMEOS_DBUS) AnomalyDetectorClient
: public DBusClient {
public:
class Observer : public base::CheckedObserver {
public:
// OnGuestFileCorruption is signaled by anomaly_detector when it detects
// that a VM has encountered filesystem corruption.
virtual void OnGuestFileCorruption(
const anomaly_detector::GuestFileCorruptionSignal& signal) = 0;
};
AnomalyDetectorClient(const AnomalyDetectorClient&) = delete;
AnomalyDetectorClient& operator=(const AnomalyDetectorClient&) = delete;
~AnomalyDetectorClient() override;
// Adds an observer.
virtual void AddObserver(Observer* observer) = 0;
// Removes an observer if added.
virtual void RemoveObserver(Observer* observer) = 0;
// IsGuestFileCorruptionSignalConnected must return true before starting a VM,
// or we will be unable to detect if it's filesystem is corrupt.
virtual bool IsGuestFileCorruptionSignalConnected() = 0;
// Creates an instance of AnomalyDetectorClient.
static std::unique_ptr<AnomalyDetectorClient> Create();
protected:
// Create() should be used instead.
AnomalyDetectorClient();
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_ANOMALY_DETECTOR_CLIENT_H_
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chromeos/dbus/dbus_clients_browser.h" #include "chromeos/dbus/dbus_clients_browser.h"
#include "base/logging.h" #include "base/logging.h"
#include "chromeos/dbus/anomaly_detector_client.h"
#include "chromeos/dbus/arc_appfuse_provider_client.h" #include "chromeos/dbus/arc_appfuse_provider_client.h"
#include "chromeos/dbus/arc_keymaster_client.h" #include "chromeos/dbus/arc_keymaster_client.h"
#include "chromeos/dbus/arc_midis_client.h" #include "chromeos/dbus/arc_midis_client.h"
...@@ -19,6 +20,7 @@ ...@@ -19,6 +20,7 @@
#include "chromeos/dbus/debug_daemon/debug_daemon_client.h" #include "chromeos/dbus/debug_daemon/debug_daemon_client.h"
#include "chromeos/dbus/debug_daemon/fake_debug_daemon_client.h" #include "chromeos/dbus/debug_daemon/fake_debug_daemon_client.h"
#include "chromeos/dbus/easy_unlock_client.h" #include "chromeos/dbus/easy_unlock_client.h"
#include "chromeos/dbus/fake_anomaly_detector_client.h"
#include "chromeos/dbus/fake_arc_appfuse_provider_client.h" #include "chromeos/dbus/fake_arc_appfuse_provider_client.h"
#include "chromeos/dbus/fake_arc_keymaster_client.h" #include "chromeos/dbus/fake_arc_keymaster_client.h"
#include "chromeos/dbus/fake_arc_midis_client.h" #include "chromeos/dbus/fake_arc_midis_client.h"
...@@ -73,6 +75,8 @@ DBusClientsBrowser::DBusClientsBrowser(bool use_real_clients) { ...@@ -73,6 +75,8 @@ DBusClientsBrowser::DBusClientsBrowser(bool use_real_clients) {
use_real_clients ? REAL_DBUS_CLIENT_IMPLEMENTATION use_real_clients ? REAL_DBUS_CLIENT_IMPLEMENTATION
: FAKE_DBUS_CLIENT_IMPLEMENTATION; : FAKE_DBUS_CLIENT_IMPLEMENTATION;
anomaly_detector_client_ =
CREATE_DBUS_CLIENT(AnomalyDetectorClient, use_real_clients);
arc_appfuse_provider_client_ = arc_appfuse_provider_client_ =
CREATE_DBUS_CLIENT(ArcAppfuseProviderClient, use_real_clients); CREATE_DBUS_CLIENT(ArcAppfuseProviderClient, use_real_clients);
arc_keymaster_client_ = arc_keymaster_client_ =
...@@ -115,6 +119,7 @@ DBusClientsBrowser::~DBusClientsBrowser() = default; ...@@ -115,6 +119,7 @@ DBusClientsBrowser::~DBusClientsBrowser() = default;
void DBusClientsBrowser::Initialize(dbus::Bus* system_bus) { void DBusClientsBrowser::Initialize(dbus::Bus* system_bus) {
DCHECK(DBusThreadManager::IsInitialized()); DCHECK(DBusThreadManager::IsInitialized());
anomaly_detector_client_->Init(system_bus);
arc_appfuse_provider_client_->Init(system_bus); arc_appfuse_provider_client_->Init(system_bus);
arc_keymaster_client_->Init(system_bus); arc_keymaster_client_->Init(system_bus);
arc_midis_client_->Init(system_bus); arc_midis_client_->Init(system_bus);
......
...@@ -16,6 +16,7 @@ class Bus; ...@@ -16,6 +16,7 @@ class Bus;
namespace chromeos { namespace chromeos {
class AnomalyDetectorClient;
class ArcAppfuseProviderClient; class ArcAppfuseProviderClient;
class ArcKeymasterClient; class ArcKeymasterClient;
class ArcMidisClient; class ArcMidisClient;
...@@ -54,6 +55,7 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS) DBusClientsBrowser { ...@@ -54,6 +55,7 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS) DBusClientsBrowser {
friend class DBusThreadManager; friend class DBusThreadManager;
friend class DBusThreadManagerSetter; friend class DBusThreadManagerSetter;
std::unique_ptr<AnomalyDetectorClient> anomaly_detector_client_;
std::unique_ptr<ArcAppfuseProviderClient> arc_appfuse_provider_client_; std::unique_ptr<ArcAppfuseProviderClient> arc_appfuse_provider_client_;
std::unique_ptr<ArcKeymasterClient> arc_keymaster_client_; std::unique_ptr<ArcKeymasterClient> arc_keymaster_client_;
std::unique_ptr<ArcMidisClient> arc_midis_client_; std::unique_ptr<ArcMidisClient> arc_midis_client_;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/message_loop/message_pump_type.h" #include "base/message_loop/message_pump_type.h"
#include "base/system/sys_info.h" #include "base/system/sys_info.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "chromeos/dbus/anomaly_detector_client.h"
#include "chromeos/dbus/arc_keymaster_client.h" #include "chromeos/dbus/arc_keymaster_client.h"
#include "chromeos/dbus/arc_midis_client.h" #include "chromeos/dbus/arc_midis_client.h"
#include "chromeos/dbus/arc_obb_mounter_client.h" #include "chromeos/dbus/arc_obb_mounter_client.h"
...@@ -107,6 +108,11 @@ dbus::Bus* DBusThreadManager::GetSystemBus() { ...@@ -107,6 +108,11 @@ dbus::Bus* DBusThreadManager::GetSystemBus() {
return system_bus_.get(); return system_bus_.get();
} }
AnomalyDetectorClient* DBusThreadManager::GetAnomalyDetectorClient() {
return clients_browser_ ? clients_browser_->anomaly_detector_client_.get()
: nullptr;
}
ArcAppfuseProviderClient* DBusThreadManager::GetArcAppfuseProviderClient() { ArcAppfuseProviderClient* DBusThreadManager::GetArcAppfuseProviderClient() {
return clients_browser_ ? clients_browser_->arc_appfuse_provider_client_.get() return clients_browser_ ? clients_browser_->arc_appfuse_provider_client_.get()
: nullptr; : nullptr;
......
...@@ -24,6 +24,7 @@ class Bus; ...@@ -24,6 +24,7 @@ class Bus;
namespace chromeos { namespace chromeos {
// Style Note: Clients are sorted by names. // Style Note: Clients are sorted by names.
class AnomalyDetectorClient;
class ArcAppfuseProviderClient; class ArcAppfuseProviderClient;
class ArcKeymasterClient; class ArcKeymasterClient;
class ArcMidisClient; class ArcMidisClient;
...@@ -115,6 +116,7 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS) DBusThreadManager { ...@@ -115,6 +116,7 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS) DBusThreadManager {
// pointers after DBusThreadManager has been shut down. // pointers after DBusThreadManager has been shut down.
// TODO(jamescook): Replace this with calls to FooClient::Get(). // TODO(jamescook): Replace this with calls to FooClient::Get().
// http://crbug.com/647367 // http://crbug.com/647367
AnomalyDetectorClient* GetAnomalyDetectorClient();
ArcAppfuseProviderClient* GetArcAppfuseProviderClient(); ArcAppfuseProviderClient* GetArcAppfuseProviderClient();
ArcKeymasterClient* GetArcKeymasterClient(); ArcKeymasterClient* GetArcKeymasterClient();
ArcMidisClient* GetArcMidisClient(); ArcMidisClient* GetArcMidisClient();
......
...@@ -20,6 +20,7 @@ TEST(DBusThreadManagerTest, Initialize) { ...@@ -20,6 +20,7 @@ TEST(DBusThreadManagerTest, Initialize) {
EXPECT_TRUE(manager->IsUsingFakes()); EXPECT_TRUE(manager->IsUsingFakes());
// Clients were created. // Clients were created.
EXPECT_TRUE(manager->GetAnomalyDetectorClient());
EXPECT_TRUE(manager->GetArcMidisClient()); EXPECT_TRUE(manager->GetArcMidisClient());
EXPECT_TRUE(manager->GetArcObbMounterClient()); EXPECT_TRUE(manager->GetArcObbMounterClient());
EXPECT_TRUE(manager->GetArcOemCryptoClient()); EXPECT_TRUE(manager->GetArcOemCryptoClient());
...@@ -63,6 +64,7 @@ TEST(DBusThreadManagerTest, InitializeForBrowser) { ...@@ -63,6 +64,7 @@ TEST(DBusThreadManagerTest, InitializeForBrowser) {
EXPECT_TRUE(manager->GetUpdateEngineClient()); EXPECT_TRUE(manager->GetUpdateEngineClient());
// Clients for the browser were created. // Clients for the browser were created.
EXPECT_TRUE(manager->GetAnomalyDetectorClient());
EXPECT_TRUE(manager->GetArcMidisClient()); EXPECT_TRUE(manager->GetArcMidisClient());
EXPECT_TRUE(manager->GetArcObbMounterClient()); EXPECT_TRUE(manager->GetArcObbMounterClient());
EXPECT_TRUE(manager->GetArcOemCryptoClient()); EXPECT_TRUE(manager->GetArcOemCryptoClient());
...@@ -95,6 +97,7 @@ TEST(DBusThreadManagerTest, InitializeForAsh) { ...@@ -95,6 +97,7 @@ TEST(DBusThreadManagerTest, InitializeForAsh) {
EXPECT_TRUE(manager->GetSMSClient()); EXPECT_TRUE(manager->GetSMSClient());
// Clients for other processes were not created. // Clients for other processes were not created.
EXPECT_FALSE(manager->GetAnomalyDetectorClient());
EXPECT_FALSE(manager->GetArcMidisClient()); EXPECT_FALSE(manager->GetArcMidisClient());
EXPECT_FALSE(manager->GetArcObbMounterClient()); EXPECT_FALSE(manager->GetArcObbMounterClient());
EXPECT_FALSE(manager->GetArcOemCryptoClient()); EXPECT_FALSE(manager->GetArcOemCryptoClient());
......
// Copyright 2019 The Chromium 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 "chromeos/dbus/fake_anomaly_detector_client.h"
namespace chromeos {
FakeAnomalyDetectorClient::FakeAnomalyDetectorClient() = default;
FakeAnomalyDetectorClient::~FakeAnomalyDetectorClient() = default;
void FakeAnomalyDetectorClient::Init(dbus::Bus* bus) {}
void FakeAnomalyDetectorClient::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
}
void FakeAnomalyDetectorClient::RemoveObserver(Observer* observer) {
observer_list_.RemoveObserver(observer);
}
bool FakeAnomalyDetectorClient::IsGuestFileCorruptionSignalConnected() {
return is_container_started_signal_connected_;
}
void FakeAnomalyDetectorClient::set_guest_file_corruption_signal_connected(
bool connected) {
is_container_started_signal_connected_ = connected;
}
void FakeAnomalyDetectorClient::NotifyGuestFileCorruption(
const anomaly_detector::GuestFileCorruptionSignal& signal) {
for (auto& observer : observer_list_) {
observer.OnGuestFileCorruption(signal);
}
}
} // namespace chromeos
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_DBUS_FAKE_ANOMALY_DETECTOR_CLIENT_H_
#define CHROMEOS_DBUS_FAKE_ANOMALY_DETECTOR_CLIENT_H_
#include "base/observer_list.h"
#include "chromeos/dbus/anomaly_detector_client.h"
namespace chromeos {
// FakeAnomalyDetectorClient is a fake implementation of AnomalyDetectorClient
// used for testing.
class COMPONENT_EXPORT(CHROMEOS_DBUS) FakeAnomalyDetectorClient
: public AnomalyDetectorClient {
public:
FakeAnomalyDetectorClient();
FakeAnomalyDetectorClient(const FakeAnomalyDetectorClient&) = delete;
FakeAnomalyDetectorClient& operator=(const FakeAnomalyDetectorClient&) =
delete;
~FakeAnomalyDetectorClient() override;
// AnomalyDetectorClient:
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
bool IsGuestFileCorruptionSignalConnected() override;
void set_guest_file_corruption_signal_connected(bool connected);
void NotifyGuestFileCorruption(
const anomaly_detector::GuestFileCorruptionSignal& signal);
protected:
void Init(dbus::Bus* bus) override;
private:
bool is_container_started_signal_connected_ = true;
base::ObserverList<Observer> observer_list_;
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_FAKE_ANOMALY_DETECTOR_CLIENT_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment