blob: 1cec31e052f279870468e5003c8f9cb9c5a5cfbc [file] [log] [blame]
Darin Petkovc1a8b422010-07-19 11:34:49 -07001// Copyright (c) 2010 The Chromium Authors. All rights reserved.
adlr@google.com3defe6a2009-12-04 20:57:17 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "update_engine/set_bootable_flag_action.h"
6#include <sys/stat.h>
7#include <sys/types.h>
8#include <errno.h>
9#include <fcntl.h>
10#include <string>
Andrew de los Reyesf9714432010-05-04 10:21:23 -070011#include <vector>
12#include "update_engine/subprocess.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000013#include "update_engine/utils.h"
14
15using std::string;
Andrew de los Reyesf9714432010-05-04 10:21:23 -070016using std::vector;
adlr@google.com3defe6a2009-12-04 20:57:17 +000017
18namespace chromeos_update_engine {
19
Andrew de los Reyesf9714432010-05-04 10:21:23 -070020namespace {
21const char* const kGpt = "/usr/bin/gpt";
22const ssize_t kPmbrLength = 512;
23}
24
adlr@google.com3defe6a2009-12-04 20:57:17 +000025void SetBootableFlagAction::PerformAction() {
26 ScopedActionCompleter completer(processor_, this);
27
Andrew de los Reyesf9714432010-05-04 10:21:23 -070028 TEST_AND_RETURN(HasInputObject());
29 const InstallPlan install_plan = GetInputObject();
30 TEST_AND_RETURN(!install_plan.install_path.empty());
31 const string partition = install_plan.install_path;
32 string root_device = utils::RootDevice(partition);
33 string partition_number = utils::PartitionNumber(partition);
34
35 utils::BootLoader boot_loader;
36 TEST_AND_RETURN(utils::GetBootloader(&boot_loader));
37
38 // For now, only support Syslinux bootloader
39 TEST_AND_RETURN(boot_loader == utils::BootLoader_SYSLINUX);
40
41 string temp_file;
42 TEST_AND_RETURN(utils::MakeTempFile("/tmp/pmbr_copy.XXXXXX",
43 &temp_file,
44 NULL));
45 ScopedPathUnlinker temp_file_unlinker(temp_file);
46
47 // Copy existing PMBR to temp file
48 vector<char> buf(kPmbrLength);
49 {
50 int fd = open(root_device.c_str(), O_RDONLY);
51 TEST_AND_RETURN(fd >= 0);
52 ScopedFdCloser fd_closer(&fd);
53 ssize_t bytes_read;
54 TEST_AND_RETURN(utils::PReadAll(fd, &buf[0], buf.size(), 0, &bytes_read));
adlr@google.com3defe6a2009-12-04 20:57:17 +000055 }
Andrew de los Reyesf9714432010-05-04 10:21:23 -070056 TEST_AND_RETURN(utils::WriteFile(temp_file.c_str(), &buf[0], buf.size()));
adlr@google.com3defe6a2009-12-04 20:57:17 +000057
Andrew de los Reyesf9714432010-05-04 10:21:23 -070058 // Call gpt tool to do the work
59 vector<string> command;
60 command.push_back(kGpt);
61 command.push_back("-S");
62 command.push_back("boot");
63 command.push_back("-i");
64 command.push_back(partition_number);
65 command.push_back("-b");
66 command.push_back(temp_file);
67 command.push_back(root_device);
68 int rc = 0;
69 Subprocess::SynchronousExec(command, &rc);
70 TEST_AND_RETURN(rc == 0);
adlr@google.com3defe6a2009-12-04 20:57:17 +000071
Darin Petkovc1a8b422010-07-19 11:34:49 -070072 completer.set_code(kActionCodeSuccess);
Andrew de los Reyesf9714432010-05-04 10:21:23 -070073 if (HasOutputPipe())
74 SetOutputObject(GetInputObject());
adlr@google.com3defe6a2009-12-04 20:57:17 +000075}
76
adlr@google.com3defe6a2009-12-04 20:57:17 +000077} // namespace chromeos_update_engine