blob: 88e2207cee60c2cfb4c2c5ac780f6de934ccbedb [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
14#include <base/logging.h>
15#include <base/process/launch.h>
16#include <brillo/syslog_logging.h>
17
Garrick Evans3388a032020-03-24 11:25:55 +090018namespace patchpanel {
Garrick Evans4c042572019-12-17 13:42:25 +090019namespace {
20constexpr int kMaxRestarts = 5;
21} // namespace
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080022
23void HelperProcess::Start(int argc, char* argv[], const std::string& fd_arg) {
Garrick Evans4c042572019-12-17 13:42:25 +090024 CHECK_GE(argc, 1);
25 for (int i = 0; i < argc; i++) {
26 argv_.push_back(argv[i]);
27 }
28 fd_arg_ = fd_arg;
29 Launch();
30}
31
32bool HelperProcess::Restart() {
33 if (++restarts_ > kMaxRestarts) {
34 LOG(ERROR) << "Maximum number of restarts exceeded";
35 return false;
36 }
37 LOG(INFO) << "Restarting...";
38 Launch();
39 return true;
40}
41
42void HelperProcess::Launch() {
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080043 int control[2];
44
45 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, control) != 0) {
46 PLOG(FATAL) << "socketpair failed";
47 }
48
Taoyu Liaf944c92019-10-01 12:22:31 +090049 base::ScopedFD control_fd(control[0]);
50 msg_dispatcher_ =
51 std::make_unique<MessageDispatcher>(std::move(control_fd), false);
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080052 const int subprocess_fd = control[1];
53
Garrick Evans4c042572019-12-17 13:42:25 +090054 std::vector<std::string> child_argv = argv_;
55 child_argv.push_back(fd_arg_ + "=" + std::to_string(subprocess_fd));
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080056
57 base::FileHandleMappingVector fd_mapping;
58 fd_mapping.push_back({subprocess_fd, subprocess_fd});
59
60 base::LaunchOptions options;
Qijiang Fanc98268c2019-10-31 20:54:42 +090061 options.fds_to_remap = std::move(fd_mapping);
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080062
63 base::Process p = base::LaunchProcess(child_argv, options);
64 CHECK(p.IsValid());
65 pid_ = p.Pid();
66}
67
Garrick Evans49879532018-12-03 13:15:36 +090068void HelperProcess::SendMessage(
69 const google::protobuf::MessageLite& proto) const {
Taoyu Li77011cb2020-01-21 15:00:09 +090070 if (!msg_dispatcher_) {
71 return;
72 }
Taoyu Liaf944c92019-10-01 12:22:31 +090073 msg_dispatcher_->SendMessage(proto);
74}
75
76void HelperProcess::Listen() {
Taoyu Li77011cb2020-01-21 15:00:09 +090077 if (!msg_dispatcher_) {
78 return;
79 }
Taoyu Liaf944c92019-10-01 12:22:31 +090080 msg_dispatcher_->Start();
81}
82
Taoyu Lia0727dc2020-09-24 19:54:59 +090083void HelperProcess::RegisterNDProxyMessageHandler(
84 const base::Callback<void(const NDProxyMessage&)>& handler) {
Taoyu Li77011cb2020-01-21 15:00:09 +090085 if (!msg_dispatcher_) {
86 return;
87 }
Taoyu Lia0727dc2020-09-24 19:54:59 +090088 msg_dispatcher_->RegisterNDProxyMessageHandler(handler);
Kevin Cernekee27bcaa62016-12-03 11:16:26 -080089}
90
Garrick Evans3388a032020-03-24 11:25:55 +090091} // namespace patchpanel