1 //
2 // Copyright (C) 2021 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 #include "host/libs/vm_manager/crosvm_builder.h"
17
18 #include <android-base/logging.h>
19
20 #include <string>
21
22 #include "common/libs/utils/network.h"
23 #include "common/libs/utils/subprocess.h"
24
25 namespace cuttlefish {
26
CrosvmBuilder()27 CrosvmBuilder::CrosvmBuilder() : command_("crosvm") {
28 command_.AddParameter("run");
29 }
30
SetBinary(const std::string & binary)31 void CrosvmBuilder::SetBinary(const std::string& binary) {
32 command_.SetExecutable(binary);
33 }
34
AddControlSocket(const std::string & control_socket)35 void CrosvmBuilder::AddControlSocket(const std::string& control_socket) {
36 // Store this value so it persists after std::move(this->Cmd())
37 auto crosvm = command_.Executable();
38 command_.SetStopper([crosvm, control_socket](Subprocess* proc) {
39 Command stop_cmd(crosvm);
40 stop_cmd.AddParameter("stop");
41 stop_cmd.AddParameter(control_socket);
42 if (stop_cmd.Start().Wait() == 0) {
43 return StopperResult::kStopSuccess;
44 }
45 LOG(WARNING) << "Failed to stop VMM nicely, attempting to KILL";
46 return KillSubprocess(proc) == StopperResult::kStopSuccess
47 ? StopperResult::kStopCrash
48 : StopperResult::kStopFailure;
49 });
50 command_.AddParameter("--socket=", control_socket);
51 }
52
AddHvcSink()53 void CrosvmBuilder::AddHvcSink() {
54 command_.AddParameter("--serial=hardware=virtio-console,num=", ++hvc_num_,
55 ",type=sink");
56 }
AddHvcConsoleReadOnly(const std::string & output)57 void CrosvmBuilder::AddHvcConsoleReadOnly(const std::string& output) {
58 command_.AddParameter("--serial=hardware=virtio-console,num=", ++hvc_num_,
59 ",type=file,path=", output, ",console=true");
60 }
AddHvcReadOnly(const std::string & output)61 void CrosvmBuilder::AddHvcReadOnly(const std::string& output) {
62 command_.AddParameter("--serial=hardware=virtio-console,num=", ++hvc_num_,
63 ",type=file,path=", output);
64 }
AddHvcReadWrite(const std::string & output,const std::string & input)65 void CrosvmBuilder::AddHvcReadWrite(const std::string& output,
66 const std::string& input) {
67 command_.AddParameter("--serial=hardware=virtio-console,num=", ++hvc_num_,
68 ",type=file,path=", output, ",input=", input);
69 }
70
AddSerialSink()71 void CrosvmBuilder::AddSerialSink() {
72 command_.AddParameter("--serial=hardware=serial,num=", ++serial_num_,
73 ",type=sink");
74 }
AddSerialConsoleReadOnly(const std::string & output)75 void CrosvmBuilder::AddSerialConsoleReadOnly(const std::string& output) {
76 command_.AddParameter("--serial=hardware=serial,num=", ++serial_num_,
77 ",type=file,path=", output, ",earlycon=true");
78 }
AddSerialConsoleReadWrite(const std::string & output,const std::string & input)79 void CrosvmBuilder::AddSerialConsoleReadWrite(const std::string& output,
80 const std::string& input) {
81 command_.AddParameter("--serial=hardware=serial,num=", ++serial_num_,
82 ",type=file,path=", output, ",input=", input,
83 ",earlycon=true");
84 }
AddSerial(const std::string & output,const std::string & input)85 void CrosvmBuilder::AddSerial(const std::string& output,
86 const std::string& input) {
87 command_.AddParameter("--serial=hardware=serial,num=", ++serial_num_,
88 ",type=file,path=", output, ",input=", input);
89 }
90
AddTap(const std::string & tap_name)91 SharedFD CrosvmBuilder::AddTap(const std::string& tap_name) {
92 auto tap_fd = OpenTapInterface(tap_name);
93 if (tap_fd->IsOpen()) {
94 command_.AddParameter("--tap-fd=", tap_fd);
95 } else {
96 LOG(ERROR) << "Unable to connect to \"" << tap_name
97 << "\": " << tap_fd->StrError();
98 }
99 return tap_fd;
100 }
101
HvcNum()102 int CrosvmBuilder::HvcNum() { return hvc_num_; }
103
Cmd()104 Command& CrosvmBuilder::Cmd() { return command_; }
105
106 } // namespace cuttlefish
107