Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(941)

Unified Diff: src/platform/update_engine/set_bootable_flag_action.cc

Issue 465067: Missed new files in last commit
Patch Set: Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/platform/update_engine/set_bootable_flag_action.cc
diff --git a/src/platform/update_engine/set_bootable_flag_action.cc b/src/platform/update_engine/set_bootable_flag_action.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8075b2cb992ee346def8654171865c4ad85bbdeb
--- /dev/null
+++ b/src/platform/update_engine/set_bootable_flag_action.cc
@@ -0,0 +1,117 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "update_engine/set_bootable_flag_action.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string>
+#include "update_engine/utils.h"
+
+using std::string;
+
+namespace chromeos_update_engine {
+
+void SetBootableFlagAction::PerformAction() {
+ ScopedActionCompleter completer(processor_, this);
+
+ if (!HasInputObject() || GetInputObject().empty()) {
+ LOG(ERROR) << "SetBootableFlagAction: No input object.";
+ return;
+ }
+ string device = GetInputObject();
+
+ if (device.size() < 2) {
+ LOG(ERROR) << "Device name too short: " << device;
+ return;
+ }
+
+ // Make sure device is valid.
+ const char last_char = device[device.size() - 1];
+ if ((last_char < '1') || (last_char > '4')) {
+ LOG(ERROR) << "Bad device:" << device;
+ return;
+ }
+
+ // We were passed the partition_number'th partition; indexed from 1, not 0
+ int partition_number = last_char - '0';
+
+ const char second_to_last_char = device[device.size() - 2];
+ if ((second_to_last_char >= '0') && (second_to_last_char <= '9')) {
+ LOG(ERROR) << "Bad device:" << device;
+ return;
+ }
+
+ // Strip trailing 1-4 off end of device
+ device.resize(device.size() - 1);
+
+ char mbr[512]; // MBR is the first 512 bytes of the device
+ if (!ReadMbr(mbr, sizeof(mbr), device.c_str()))
+ return;
+
+ // Check MBR. Verify that last two byes are 0x55aa. This is the MBR signature.
+ if ((mbr[510] != static_cast<char>(0x55)) ||
+ (mbr[511] != static_cast<char>(0xaa))) {
+ LOG(ERROR) << "Bad MBR signature";
+ return;
+ }
+
+ // Mark partition passed in bootable and all other partitions non bootable.
+ // There are 4 partition table entries, each 16 bytes, stored consecutively
+ // beginning at byte 446. Within each entry, the first byte is the
+ // bootable flag. It's set to 0x80 (bootable) or 0x00 (not bootable).
+ for (int i = 0; i < 4; i++) {
+ int offset = 446 + 16 * i;
+
+ // partition_number is indexed from 1, not 0
+ if ((i + 1) == partition_number)
+ mbr[offset] = 0x80;
+ else
+ mbr[offset] = '\0';
+ }
+
+ // Write MBR back to disk
+ bool success = WriteMbr(mbr, sizeof(mbr), device.c_str());
+ if (success) {
+ completer.set_success(true);
+ if (HasOutputPipe()) {
+ SetOutputObject(GetInputObject());
+ }
+ }
+}
+
+bool SetBootableFlagAction::ReadMbr(char* buffer,
+ int buffer_len,
+ const char* device) {
+ int fd = open(device, O_RDONLY, 0);
+ TEST_AND_RETURN_FALSE(fd >= 0);
+
+ ssize_t r = read(fd, buffer, buffer_len);
+ close(fd);
+ TEST_AND_RETURN_FALSE(r == buffer_len);
+
+ return true;
+}
+
+bool SetBootableFlagAction::WriteMbr(const char* buffer,
+ int buffer_len,
+ const char* device) {
+ int fd = open(device, O_WRONLY, 0666);
+ TEST_AND_RETURN_FALSE(fd >= 0);
+ ScopedFdCloser fd_closer(&fd);
+
+ ssize_t bytes_written = 0;
+ while (bytes_written < buffer_len) {
+ ssize_t r = write(fd, buffer + bytes_written, buffer_len - bytes_written);
+ TEST_AND_RETURN_FALSE_ERRNO(r >= 0);
+ bytes_written += r;
+ }
+ TEST_AND_RETURN_FALSE(bytes_written == buffer_len);
+
+ return true;
+}
+
+
+} // namespace chromeos_update_engine
« no previous file with comments | « src/platform/update_engine/set_bootable_flag_action.h ('k') | src/platform/update_engine/set_bootable_flag_action_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698