Skip to content

Commit bf2edfc

Browse files
Update cvd start to handle single instances
1 parent d3cf6ee commit bf2edfc

3 files changed

Lines changed: 88 additions & 0 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,7 @@ cf_cc_library(
390390
hdrs = ["start.h"],
391391
clang_format_enabled = False,
392392
deps = [
393+
"//cuttlefish/common/libs/fs",
393394
"//cuttlefish/common/libs/utils:contains",
394395
"//cuttlefish/common/libs/utils:files",
395396
"//cuttlefish/common/libs/utils:json",

base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "cuttlefish/host/commands/cvd/cli/commands/start.h"
1818

19+
#include <fcntl.h>
1920
#include <signal.h> // IWYU pragma: keep
2021
#include <stddef.h>
2122
#include <stdlib.h>
@@ -40,6 +41,7 @@
4041
#include "absl/strings/str_join.h"
4142
#include "absl/strings/str_split.h"
4243

44+
#include "cuttlefish/common/libs/fs/shared_fd.h"
4345
#include "cuttlefish/common/libs/utils/contains.h"
4446
#include "cuttlefish/common/libs/utils/files.h"
4547
#include "cuttlefish/flag_parser/flag.h"
@@ -337,6 +339,21 @@ Result<void> CvdStartCommandHandler::Handle(const CommandRequest& request) {
337339
return CF_ERR(NoGroupMessage(request));
338340
}
339341

342+
if (request.Selectors().instance_names &&
343+
request.Selectors().instance_names->size() == 1) {
344+
auto [instance, group] =
345+
CF_EXPECT(selector::SelectInstance(instance_manager_, request));
346+
347+
if (instance.State() == cvd::INSTANCE_STATE_STOPPED &&
348+
group.StartTime() != TimeStamp{}) {
349+
CF_EXPECT(LaunchSingleInstance(instance, group, request));
350+
return {};
351+
} else {
352+
VLOG(1) << "Instance is not in stopped state. Proceeding with "
353+
"normal group start.";
354+
}
355+
}
356+
340357
CF_EXPECT(ConsumeDaemonModeFlag(subcmd_args));
341358
subcmd_args.push_back("--daemon=true");
342359

@@ -472,6 +489,72 @@ Result<void> CvdStartCommandHandler::LaunchDeviceInterruptible(
472489
return {};
473490
}
474491

492+
Result<void> CvdStartCommandHandler::LaunchSingleInstance(
493+
LocalInstance& instance, LocalInstanceGroup& group,
494+
const CommandRequest& request) {
495+
auto bin_path = group.HostArtifactsPath() + "/bin/run_cvd";
496+
cvd_common::Envs run_cvd_envs = request.Env();
497+
run_cvd_envs[kCuttlefishInstanceEnvVarName] = std::to_string(instance.Id());
498+
run_cvd_envs["HOME"] = group.HomeDir();
499+
run_cvd_envs[kAndroidHostOut] = group.HostArtifactsPath();
500+
run_cvd_envs[kAndroidProductOut] = group.ProductOutPath();
501+
run_cvd_envs[kAndroidSoongHostOut] = group.HostArtifactsPath();
502+
run_cvd_envs[kCvdMarkEnv] = "true";
503+
504+
ConstructCommandParam construct_cmd_param{.bin_path = bin_path,
505+
.home = group.HomeDir(),
506+
.args = cvd_common::Args{},
507+
.envs = run_cvd_envs,
508+
.working_dir = CurrentDirectory(),
509+
.command_name = "run_cvd"};
510+
511+
Command command = CF_EXPECT(ConstructCommand(construct_cmd_param));
512+
command.RedirectStdIO(Subprocess::StdIOChannel::kStdOut,
513+
Subprocess::StdIOChannel::kStdErr);
514+
SharedFD dev_null = SharedFD::Open("/dev/null", O_RDONLY);
515+
if (dev_null->IsOpen()) {
516+
command.RedirectStdIO(Subprocess::StdIOChannel::kStdIn, dev_null);
517+
} else {
518+
LOG(ERROR) << "Failed to open /dev/null: " << dev_null->StrError();
519+
}
520+
521+
auto symlink_config_res = SymlinkPreviousConfig(group.HomeDir());
522+
if (!symlink_config_res.ok()) {
523+
LOG(ERROR) << "Failed to symlink the config file at system wide home: "
524+
<< symlink_config_res.error();
525+
}
526+
527+
auto set_instance_state = [&group, &instance](cvd::InstanceState state) {
528+
for (auto& inst : group.Instances()) {
529+
if (inst.Id() == instance.Id()) {
530+
inst.SetState(state);
531+
break;
532+
}
533+
}
534+
};
535+
536+
set_instance_state(cvd::INSTANCE_STATE_STARTING);
537+
group.SetStartTime(CvdServerClock::now());
538+
CF_EXPECT(instance_manager_.UpdateInstanceGroup(group));
539+
540+
Result<void> start_res =
541+
LaunchDevice(std::move(command), group, run_cvd_envs, request);
542+
543+
if (!start_res.ok()) {
544+
set_instance_state(cvd::INSTANCE_STATE_BOOT_FAILED);
545+
CF_EXPECT(instance_manager_.UpdateInstanceGroup(group));
546+
return start_res;
547+
}
548+
549+
set_instance_state(cvd::INSTANCE_STATE_RUNNING);
550+
CF_EXPECT(instance_manager_.UpdateInstanceGroup(group));
551+
552+
auto group_json = CF_EXPECT(group.FetchStatus());
553+
std::cout << group_json.toStyledString();
554+
555+
return {};
556+
}
557+
475558
std::vector<HelpParagraph> CvdStartCommandHandler::Description() const {
476559
std::vector<HelpParagraph> description;
477560
description.emplace_back(

base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ class CvdStartCommandHandler : public CvdCommandHandler {
4343
bool RequiresDeviceExists() const override { return true; }
4444

4545
private:
46+
Result<void> LaunchSingleInstance(LocalInstance& instance,
47+
LocalInstanceGroup& group,
48+
const CommandRequest& request);
49+
4650
Result<void> LaunchDevice(Command command, LocalInstanceGroup& group,
4751
const cvd_common::Envs& envs,
4852
const CommandRequest& request);

0 commit comments

Comments
 (0)