Skip to content

Commit a52622b

Browse files
committed
When cvd_internal_start is invoked directly, invoke cvd
We plan to make the implementation of `cvd_internal_start` aka `launch_cvd` in the Android source tree invoke `cvd`. There is a problem with this: after the first invocation of `cvd`, it will run executable substitution in the build directory and replace the forwarding `cvd_internal_start` with the implementation in this repository. That means if we want the forward functionality to persist past one invocation, we need the `cvd_internal_start` implementation here to be forwarding as well. The forwarding is only applied when the invoking executable is not a `cvd` executable. This relies on the new flags `--reuse` and `--daemon=false` to be supported, which are in other outstanding PRs. Users calling `launch_cvd` will expect to see the behavior from these flags. Bug: b/519304405
1 parent 285e149 commit a52622b

2 files changed

Lines changed: 49 additions & 4 deletions

File tree

base/cvd/cuttlefish/host/commands/start/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ cf_cc_binary(
3737
"//cuttlefish/host/libs/log_names",
3838
"//cuttlefish/host/libs/metrics:notification",
3939
"//cuttlefish/host/libs/vm_manager",
40+
"//cuttlefish/posix:readlink",
41+
"//cuttlefish/posix:symlink",
4042
"//libbase",
4143
"@abseil-cpp//absl/base:no_destructor",
4244
"@abseil-cpp//absl/log",

base/cvd/cuttlefish/host/commands/start/main.cc

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,21 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515

16+
#include <unistd.h>
17+
1618
#include <iostream>
1719
#include <optional>
1820
#include <sstream>
1921
#include <unordered_set>
2022

21-
#include <android-base/file.h>
2223
#include "absl/base/no_destructor.h"
23-
#include "absl/strings/str_split.h"
24-
#include <fmt/format.h>
25-
#include <gflags/gflags.h>
2624
#include "absl/log/check.h"
2725
#include "absl/log/log.h"
2826
#include "absl/strings/match.h"
27+
#include "absl/strings/str_split.h"
28+
#include "android-base/file.h"
29+
#include "fmt/format.h"
30+
#include "gflags/gflags.h"
2931

3032
#include "cuttlefish/common/libs/fs/shared_fd.h"
3133
#include "cuttlefish/common/libs/utils/environment.h"
@@ -47,6 +49,7 @@
4749
#include "cuttlefish/host/libs/config/host_tools_version.h"
4850
#include "cuttlefish/host/libs/config/instance_nums.h"
4951
#include "cuttlefish/host/libs/log_names/log_names.h"
52+
#include "cuttlefish/posix/readlink.h"
5053
#include "cuttlefish/posix/symlink.h"
5154

5255
namespace cuttlefish {
@@ -206,9 +209,49 @@ Result<void> LinkLogs2InstanceDir(
206209
return {};
207210
}
208211

212+
bool ParentIsCvd() {
213+
const std::string exe_link = absl::StrCat("/proc/", getppid(), "/exe");
214+
const Result<std::string> exe_path = ReadLink(exe_link);
215+
CHECK(exe_path.ok()) << exe_path.error();
216+
return exe_path->ends_with("/cvd");
217+
}
218+
219+
std::string CvdPath() {
220+
const Result<std::string> exe_path_res = ReadLink("/proc/self/exe");
221+
CHECK(exe_path_res.ok()) << exe_path_res.error();
222+
std::string_view exe_path = *exe_path_res;
223+
CHECK(absl::ConsumeSuffix(&exe_path, "/cvd_internal_start"));
224+
return absl::StrCat(exe_path, "/cvd");
225+
}
226+
227+
void ExecCvd(std::vector<std::string> args) {
228+
bool daemon = false;
229+
const Result<void> res = ConsumeFlags({GflagsCompatFlag("daemon", daemon)}, args);
230+
CHECK(res.ok()) << res.error();
231+
232+
const std::string daemon_val = daemon ? "true" : "false";
233+
const std::string daemon_str = absl::StrCat("--daemon=", daemon_val);
234+
args.insert(args.begin(), {"cvd", "create", daemon_str, "--reuse=true"});
235+
236+
std::vector<char*> args_cstr;
237+
args_cstr.reserve(args.size());
238+
for (std::string& arg : args) {
239+
args_cstr.push_back(arg.data());
240+
}
241+
args_cstr.push_back(nullptr);
242+
243+
const std::string cvd_path = CvdPath();
244+
execv(cvd_path.c_str(), args_cstr.data());
245+
PLOG(FATAL) << "execv(cvd) failed";
246+
}
247+
209248
int CvdInternalStartMain(int argc, char** argv) {
210249
LogToStderr();
250+
211251
std::vector<std::string> args(argv + 1, argv + argc);
252+
if (!ParentIsCvd()) {
253+
ExecCvd(args);
254+
}
212255

213256
std::vector<std::string> assemble_args;
214257
std::string image_dir;

0 commit comments

Comments
 (0)