blob: faaa8ac7a8c746b6fdbbc3169b3c2c50a234444b [file] [log] [blame]
// Copyright 2018 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include <sys/types.h>
#include <map>
#include <memory>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/files/scoped_file.h>
#include <base/files/scoped_temp_dir.h>
#include <base/functional/callback.h>
#include <base/memory/ref_counted.h>
#include <base/memory/weak_ptr.h>
#include <dbus/bus.h>
#include <dbus/exported_object.h>
#include <dbus/message.h>
namespace vm_tools::seneschal {
class Service final {
// Creates a new Service instance. |quit_closure| is posted to the TaskRunner
// for the current thread when this process receives a SIGTERM.
static std::unique_ptr<Service> Create(base::OnceClosure quit_closure);
~Service() = default;
// Relevant information about a currently running server.
class ServerInfo final {
ServerInfo(pid_t pid, base::FilePath root_dir);
// Make sure this type can be moved. Unfortunately we cannot use the
// default move constructor because ScopedTempDir doesn't have a move
// constructor.
ServerInfo(ServerInfo&& other) noexcept;
ServerInfo(const ServerInfo&) = delete;
ServerInfo& operator=(const ServerInfo&) = delete;
ServerInfo& operator=(ServerInfo&& other) noexcept;
pid_t pid() const { return pid_; }
const base::ScopedTempDir& root_dir() const { return root_dir_; }
// The process id for this server.
pid_t pid_;
// The root of this server.
base::ScopedTempDir root_dir_;
explicit Service(base::OnceClosure quit_closure);
Service(const Service&) = delete;
Service& operator=(const Service&) = delete;
// Initializes the service by connecting to the system DBus daemon, exporting
// its methods, and taking ownership of it's name.
bool Init();
// Handles the termination of a child process.
void HandleChildExit();
// Handles a SIGTERM.
void HandleSigterm();
void OnSignalReadable();
// Handles a request to start a new 9p server.
std::unique_ptr<dbus::Response> StartServer(dbus::MethodCall* method_call);
// Handles a request to stop a running 9p server.
std::unique_ptr<dbus::Response> StopServer(dbus::MethodCall* method_call);
// Handles a request to share a path with a running server.
std::unique_ptr<dbus::Response> SharePath(dbus::MethodCall* method_call);
// Handles a request to share a path with a running server.
std::unique_ptr<dbus::Response> UnsharePath(dbus::MethodCall* method_call);
// Forcibly kills a server if it hasn't already exited.
void KillServer(uint32_t handle);
// The currently active 9p servers.
std::map<uint32_t, ServerInfo> servers_;
uint32_t next_server_handle_ = 1;
// File descriptor on which we will watch for signals.
base::ScopedFD signal_fd_;
std::unique_ptr<base::FileDescriptorWatcher::Controller> watcher_;
// Connection to the system bus.
scoped_refptr<dbus::Bus> bus_;
dbus::ExportedObject* exported_object_; // Owned by |bus_|.
// Closure to be posted to the task runner when we receive a SIGTERM.
base::OnceClosure quit_closure_;
base::WeakPtrFactory<Service> weak_factory_;
} // namespace vm_tools::seneschal