blob: 2a5861ca720e887c646b91cc09709571dce8bd88 [file] [log] [blame] [edit]
// Copyright 2024 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SHILL_NETWORK_TC_PROCESS_H_
#define SHILL_NETWORK_TC_PROCESS_H_
#include <memory>
#include <string>
#include <string_view>
#include <vector>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/memory/weak_ptr.h>
#include <net-base/process_manager.h>
namespace shill {
// This class represents a 'tc' process spawned in a minijail, and is used to
// write commands to its stdin.
class TCProcess {
public:
using ExitCallback = net_base::ProcessManager::ExitCallback;
static constexpr std::string_view kTCUser = "nobody";
static constexpr std::string_view kTCGroup = "nobody";
static constexpr std::string_view kTCPath = "/sbin/tc";
// Spawns a TC process in minijail and writes |commands| to the process. Once
// the process is exited, |exit_callback| will be called with the status.
// If the instance is destroyed before the process is exited, |exit_callback|
// won't be executed.
static std::unique_ptr<TCProcess> Create(
const std::vector<std::string>& commands,
ExitCallback exit_callback,
net_base::ProcessManager* process_manager =
net_base::ProcessManager::GetInstance());
virtual ~TCProcess();
protected:
TCProcess(net_base::ProcessManager* process_manager,
const std::vector<std::string>& commands,
ExitCallback exit_callback);
private:
bool Initialize();
void OnTCProcessWritable();
void OnProcessExited(int exit_status);
net_base::ProcessManager* process_manager_;
std::vector<std::string> commands_;
ExitCallback exit_callback_;
pid_t tc_pid_ = net_base::ProcessManager::kInvalidPID;
// The fd of TC process's stdin. It only contains value until the TC process
// able to send commands via it.
base::ScopedFD tc_stdin_;
// Watcher to wait for |tc_stdin_| ready to write. It should be
// destructed prior than |tc_stdin_| is closed.
std::unique_ptr<base::FileDescriptorWatcher::Controller> tc_stdin_watcher_;
base::WeakPtrFactory<TCProcess> weak_factory_{this};
};
// Creates the TCProcess instance. It's used for injecting MockTCProcessFactory
// at testing to create the mock TCProcess instance.
class TCProcessFactory {
public:
TCProcessFactory() = default;
virtual ~TCProcessFactory() = default;
virtual std::unique_ptr<TCProcess> Create(
const std::vector<std::string>& commands,
TCProcess::ExitCallback exit_callback,
net_base::ProcessManager* process_manager =
net_base::ProcessManager::GetInstance());
};
} // namespace shill
#endif // SHILL_NETWORK_TC_PROCESS_H_