blob: fae54c0526c5542cf24411b13b6cb73e47b84d0e [file] [log] [blame]
Kevin Cernekee27bcaa62016-12-03 11:16:26 -08001// Copyright 2016 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#include "patchpanel/helper_process.h"
Kevin Cernekee27bcaa62016-12-03 11:16:26 -08006
7#include <signal.h>
8#include <string.h>
9#include <sys/socket.h>
10#include <unistd.h>
11
12#include <utility>
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080013
Qijiang Fan713061e2021-03-08 15:45:12 +090014#include <base/check.h>
15#include <base/check_op.h>
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080016#include <base/logging.h>
17#include <base/process/launch.h>
18#include <brillo/syslog_logging.h>
19
Garrick Evans3388a032020-03-24 11:25:55 +090020namespace patchpanel {
Garrick Evans4c042572019-12-17 13:42:25 +090021namespace {
22constexpr int kMaxRestarts = 5;
23} // namespace
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080024
25void HelperProcess::Start(int argc, char* argv[], const std::string& fd_arg) {
Garrick Evans4c042572019-12-17 13:42:25 +090026 CHECK_GE(argc, 1);
27 for (int i = 0; i < argc; i++) {
28 argv_.push_back(argv[i]);
29 }
30 fd_arg_ = fd_arg;
31 Launch();
32}
33
34bool HelperProcess::Restart() {
35 if (++restarts_ > kMaxRestarts) {
36 LOG(ERROR) << "Maximum number of restarts exceeded";
37 return false;
38 }
39 LOG(INFO) << "Restarting...";
40 Launch();
41 return true;
42}
43
44void HelperProcess::Launch() {
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080045 int control[2];
46
47 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, control) != 0) {
48 PLOG(FATAL) << "socketpair failed";
49 }
50
Taoyu Liaf944c92019-10-01 12:22:31 +090051 base::ScopedFD control_fd(control[0]);
52 msg_dispatcher_ =
53 std::make_unique<MessageDispatcher>(std::move(control_fd), false);
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080054 const int subprocess_fd = control[1];
55
Garrick Evans4c042572019-12-17 13:42:25 +090056 std::vector<std::string> child_argv = argv_;
57 child_argv.push_back(fd_arg_ + "=" + std::to_string(subprocess_fd));
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080058
59 base::FileHandleMappingVector fd_mapping;
60 fd_mapping.push_back({subprocess_fd, subprocess_fd});
61
62 base::LaunchOptions options;
Qijiang Fanc98268c2019-10-31 20:54:42 +090063 options.fds_to_remap = std::move(fd_mapping);
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080064
65 base::Process p = base::LaunchProcess(child_argv, options);
66 CHECK(p.IsValid());
67 pid_ = p.Pid();
68}
69
Garrick Evans49879532018-12-03 13:15:36 +090070void HelperProcess::SendMessage(
71 const google::protobuf::MessageLite& proto) const {
Taoyu Li77011cb2020-01-21 15:00:09 +090072 if (!msg_dispatcher_) {
73 return;
74 }
Taoyu Liaf944c92019-10-01 12:22:31 +090075 msg_dispatcher_->SendMessage(proto);
76}
77
78void HelperProcess::Listen() {
Taoyu Li77011cb2020-01-21 15:00:09 +090079 if (!msg_dispatcher_) {
80 return;
81 }
Taoyu Liaf944c92019-10-01 12:22:31 +090082 msg_dispatcher_->Start();
83}
84
Taoyu Lia0727dc2020-09-24 19:54:59 +090085void HelperProcess::RegisterNDProxyMessageHandler(
86 const base::Callback<void(const NDProxyMessage&)>& handler) {
Taoyu Li77011cb2020-01-21 15:00:09 +090087 if (!msg_dispatcher_) {
88 return;
89 }
Taoyu Lia0727dc2020-09-24 19:54:59 +090090 msg_dispatcher_->RegisterNDProxyMessageHandler(handler);
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080091}
92
Garrick Evans3388a032020-03-24 11:25:55 +090093} // namespace patchpanel