From 81a0b3de707b4e00958faf36f41b8f3d7bac6808 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 28 Feb 2013 13:53:09 -0800 Subject: Move CgptManager from vboot_reference to installer The C++ wrapper around various vboot_reference functions doesn't belong in the vboot repo itself. Put it in the installer repo instead. BUG=chromium-os:39228 BRANCH=none TEST=auto CQ-DEPEND=CL:44441, CL:44443 Refactoring only, no new code. Everything should continue to work as before. Change-Id: I15ba416987e38905825fedcc87d7b75ebdc4fd1f Signed-off-by: Bill Richardson Reviewed-on: https://gerrit.chromium.org/gerrit/44442 Reviewed-by: Jay Srinivasan Reviewed-by: Randall Spangler --- Makefile | 137 +++++---------- cgpt/CgptManager.cc | 429 ---------------------------------------------- cgpt/CgptManager.h | 172 ------------------- tests/CgptManagerTests.cc | 403 ------------------------------------------- 4 files changed, 40 insertions(+), 1101 deletions(-) delete mode 100644 cgpt/CgptManager.cc delete mode 100644 cgpt/CgptManager.h delete mode 100644 tests/CgptManagerTests.cc diff --git a/Makefile b/Makefile index 73520a47..49cdab59 100644 --- a/Makefile +++ b/Makefile @@ -185,30 +185,9 @@ endif export BUILD_RUN -# Some things only compile inside the Chromium OS chroot. -# TODO: Those things should be in their own repo, not part of vboot_reference -# TODO: Is there a better way to detect this? -ifneq (${CROS_WORKON_SRCROOT},) -IN_CHROOT := yes -endif - -# TODO: Move to separate repo. -ifneq (${IN_CHROOT},) -PC_BASE_VER ?= 180609 -PC_DEPS := libchrome-${PC_BASE_VER} -PC_CFLAGS := $(shell ${PKG_CONFIG} --cflags ${PC_DEPS}) -PC_LDLIBS := $(shell ${PKG_CONFIG} --libs ${PC_DEPS}) -endif - - ############################################################################## # Now we need to describe everything we might want or need to build -# TODO: This should go in its own repo. -AU_CGPTLIB = ${BUILD}/cgpt/libcgpt-cc.a -# This is just ... Gah. There's no good place for it. -DUMPKERNELCONFIGLIB = ${BUILD}/libdump_kernel_config.a - # Everything wants these headers. INCLUDES += \ -Ifirmware/include \ @@ -308,6 +287,13 @@ ALL_OBJS += ${FWLIB_OBJS} HOSTLIB = ${BUILD}/libvboot_host.a HOSTLIB_SRCS = \ + cgpt/cgpt_create.c \ + cgpt/cgpt_add.c \ + cgpt/cgpt_boot.c \ + cgpt/cgpt_show.c \ + cgpt/cgpt_repair.c \ + cgpt/cgpt_prioritize.c \ + cgpt/cgpt_common.c \ host/arch/${ARCH}/lib/crossystem_arch.c \ host/lib/crossystem.c \ host/lib/file_keys.c \ @@ -317,7 +303,8 @@ HOSTLIB_SRCS = \ host/lib/host_keyblock.c \ host/lib/host_misc.c \ host/lib/host_signature.c \ - host/lib/signature_digest.c + host/lib/signature_digest.c \ + utility/dump_kernel_config_lib.c HOSTLIB_OBJS = ${HOSTLIB_SRCS:%.c=${BUILD}/%.o} ALL_OBJS += ${HOSTLIB_OBJS} @@ -328,6 +315,25 @@ LIBS = $(HOSTLIB) # Might need this too. CRYPTO_LIBS := $(shell ${PKG_CONFIG} --libs libcrypto) +# Sigh. For historical reasons, the autoupdate installer must sometimes be a +# 32-bit executable, even when everything else is 64-bit. But it only needs a +# few functions, so let's just build those. +TINYHOSTLIB = ${BUILD}/libtinyvboot_host.a + +TINYHOSTLIB_SRCS = \ + cgpt/cgpt_create.c \ + cgpt/cgpt_add.c \ + cgpt/cgpt_boot.c \ + cgpt/cgpt_show.c \ + cgpt/cgpt_repair.c \ + cgpt/cgpt_prioritize.c \ + cgpt/cgpt_common.c \ + utility/dump_kernel_config_lib.c \ + firmware/lib/cgptlib/crc32.c \ + firmware/lib/cgptlib/cgptlib_internal.c \ + firmware/stub/utility_stub.c + +TINYHOSTLIB_OBJS = ${TINYHOSTLIB_SRCS:%.c=${BUILD}/%.o} # ---------------------------------------------------------------------------- # Now for the userspace binaries @@ -476,11 +482,6 @@ TEST_NAMES = \ vboot_kernel_tests \ vboot_nvstorage_test -# Grrr -ifneq (${IN_CHROOT},) -TEST_NAMES += CgptManagerTests -endif - # TODO: port these tests to new API, if not already eqivalent # functionality in other tests. These don't even compile at present. # @@ -523,29 +524,6 @@ ALL_DEPS += $(addsuffix .d,${TEST_BINS}) # Directory containing test keys TEST_KEYS = ${SRC_RUN}/tests/testkeys -# ---------------------------------------------------------------------------- -# TODO: why not make this include *all* the cgpt files, and simply have -# cgpt link against it? -# TODO: CgptManager.cc should move to the installer project. Shouldn't be -# in libcgpt-cc.a. -AU_CGPTLIB_SRCS = \ - cgpt/CgptManager.cc \ - cgpt/cgpt_create.c \ - cgpt/cgpt_add.c \ - cgpt/cgpt_boot.c \ - cgpt/cgpt_show.c \ - cgpt/cgpt_repair.c \ - cgpt/cgpt_prioritize.c \ - cgpt/cgpt_common.c \ - firmware/lib/cgptlib/crc32.c \ - firmware/lib/cgptlib/cgptlib_internal.c \ - firmware/stub/utility_stub.c - -AU_CGPTLIB_OBJS = $(filter %.o, \ - ${AU_CGPTLIB_SRCS:%.c=${BUILD}/%.o} \ - ${AU_CGPTLIB_SRCS:%.cc=${BUILD}/%.o}) -ALL_OBJS += ${AU_CGPTLIB_OBJS} - ############################################################################## # Finally, some targets. High-level ones first. @@ -566,10 +544,6 @@ all: fwlib $(if ${FIRMWARE_ARCH},,host_stuff) $(if ${COV},coverage) .PHONY: host_stuff host_stuff: hostlib cgpt utils futil tests -# AU targets -.PHONY: au_stuff -au_stuff: libcgpt_cc libdump_kernel_config cgptmanager_tests - .PHONY: clean clean: ${Q}/bin/rm -rf ${BUILD} @@ -667,6 +641,18 @@ ${HOSTLIB}: ${HOSTLIB_OBJS} ${FWLIB_OBJS} @printf " AR $(subst ${BUILD}/,,$@)\n" ${Q}ar qc $@ $^ + +# Ugh. This is a very cut-down version of HOSTLIB just for the installer. +.PHONY: tinyhostlib +tinyhostlib: ${TINYHOSTLIB} + ${Q}cp -f ${TINYHOSTLIB} ${HOSTLIB} + +${TINYHOSTLIB}: ${TINYHOSTLIB_OBJS} + @printf " RM $(subst ${BUILD}/,,$@)\n" + ${Q}rm -f $@ + @printf " AR $(subst ${BUILD}/,,$@)\n" + ${Q}ar qc $@ $^ + # ---------------------------------------------------------------------------- # CGPT library and utility @@ -751,32 +737,6 @@ update_tlcl_structures: ${BUILD}/utility/tlcl_generator ( echo "%% Updating structures.h %%" && \ cp ${STRUCTURES_TMP} ${STRUCTURES_SRC} ) -# ---------------------------------------------------------------------------- -# Library to dump kernel config -# Used by platform/installer, as well as standalone utility. - -.PHONY: libdump_kernel_config -libdump_kernel_config: ${DUMPKERNELCONFIGLIB} - -${DUMPKERNELCONFIGLIB}: ${BUILD}/utility/dump_kernel_config_lib.o - @printf " RM $(subst ${BUILD}/,,$@)\n" - ${Q}rm -f $@ - @printf " AR $(subst ${BUILD}/,,$@)\n" - ${Q}ar qc $@ $^ - -# ---------------------------------------------------------------------------- -# And this thing. - -.PHONY: libcgpt_cc -libcgpt_cc: ${AU_CGPTLIB} - -${AU_CGPTLIB}: INCLUDES += -Ifirmware/lib/cgptlib/include -${AU_CGPTLIB}: ${AU_CGPTLIB_OBJS} - @printf " RM $(subst ${BUILD}/,,$@)\n" - ${Q}rm -f $@ - @printf " AR $(subst ${BUILD}/,,$@)\n" - ${Q}ar qc $@ $^ - # ---------------------------------------------------------------------------- # Tests @@ -827,10 +787,6 @@ ${BUILD}/%.o: %.cc # Linktest ensures firmware lib doesn't rely on outside libraries ${BUILD}/firmware/linktest/main: LIBS = ${FWLIB} -# Specific dependency here. -${BUILD}/utility/dump_kernel_config: LIBS += ${DUMPKERNELCONFIGLIB} -${BUILD}/utility/dump_kernel_config: ${DUMPKERNELCONFIGLIB} - # GBB utility needs C++ linker. TODO: It shouldn't. ${BUILD}/utility/gbb_utility: LD = ${CXX} @@ -883,15 +839,6 @@ ${BUILD}/tests/vboot_audio_tests: OBJS += \ ${BUILD}/tests/vboot_audio_tests: \ ${BUILD}/firmware/lib/vboot_audio_for_test.o -.PHONY: cgptmanager_tests -cgptmanager_tests: ${BUILD}/tests/CgptManagerTests - -${BUILD}/tests/CgptManagerTests: CFLAGS += ${PC_CFLAGS} -${BUILD}/tests/CgptManagerTests: LD = ${CXX} -${BUILD}/tests/CgptManagerTests: LDLIBS += -lgtest -lgflags ${PC_LDLIBS} -${BUILD}/tests/CgptManagerTests: LIBS = ${AU_CGPTLIB} -${BUILD}/tests/CgptManagerTests: ${AU_CGPTLIB} - ${BUILD}/tests/rollback_index_test: INCLUDES += -I/usr/include ${BUILD}/tests/rollback_index_test: LIBS += -ltlcl @@ -953,10 +900,6 @@ runbmptests: test_setup .PHONY: runcgpttests runcgpttests: test_setup ${RUNTEST} ${BUILD_RUN}/tests/cgptlib_test -# HEY - elsewhere -ifneq (${IN_CHROOT},) - ${RUNTEST} ${BUILD_RUN}/tests/CgptManagerTests --v=1 -endif .PHONY: runtestscripts runtestscripts: test_setup genfuzztestcases diff --git a/cgpt/CgptManager.cc b/cgpt/CgptManager.cc deleted file mode 100644 index a1a018a3..00000000 --- a/cgpt/CgptManager.cc +++ /dev/null @@ -1,429 +0,0 @@ -// Copyright (c) 2012 The Chromium OS 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 - -#include "CgptManager.h" - -extern "C" { -#include "cgpt_params.h" -} - -using std::string; - -// We don't use these variables for the libcgpt version. -const char* progname = ""; -const char* command = ""; -void (*uuid_generator)(uint8_t* buffer) = NULL; - - -// This file implements the C++ wrapper methods over the C cgpt methods. - -CgptManager::CgptManager(): - is_initialized_(false) { -} - -CgptManager::~CgptManager() { -} - -CgptErrorCode CgptManager::Initialize(const string& device_name) { - device_name_ = device_name; - is_initialized_ = true; - return kCgptSuccess; -} - -CgptErrorCode CgptManager::ClearAll() { - if (!is_initialized_) - return kCgptNotInitialized; - - CgptCreateParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.zap = 0; - - int retval = cgpt_create(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - return kCgptSuccess; -} - -CgptErrorCode CgptManager::AddPartition(const string& label, - const Guid& partition_type_guid, - const Guid& unique_id, - uint64_t beginning_offset, - uint64_t num_sectors) { - if (!is_initialized_) - return kCgptNotInitialized; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.label = const_cast(label.c_str()); - - params.type_guid = partition_type_guid; - params.set_type = 1; - - params.begin = beginning_offset; - params.set_begin = 1; - - params.size = num_sectors; - params.set_size = 1; - - if (!IsZero(&unique_id)) { - params.unique_guid = unique_id; - params.set_unique = 1; - } - - int retval = cgpt_add(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - return kCgptSuccess; -} - -CgptErrorCode CgptManager::GetNumNonEmptyPartitions(uint8_t* num_partitions) const { - if (!is_initialized_) - return kCgptNotInitialized; - - if (!num_partitions) - return kCgptInvalidArgument; - - CgptShowParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - int retval = cgpt_get_num_non_empty_partitions(¶ms); - - if (retval != CGPT_OK) - return kCgptUnknownError; - - *num_partitions = params.num_partitions; - return kCgptSuccess; -} - -CgptErrorCode CgptManager::SetPmbr(uint32_t boot_partition_number, - const string& boot_file_name, - bool should_create_legacy_partition) { - if (!is_initialized_) - return kCgptNotInitialized; - - CgptBootParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - if (!boot_file_name.empty()) - params.bootfile = const_cast(boot_file_name.c_str()); - - params.partition = boot_partition_number; - params.create_pmbr = should_create_legacy_partition; - - int retval = cgpt_boot(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - return kCgptSuccess; -} - -CgptErrorCode CgptManager::GetPmbrBootPartitionNumber( - uint32_t* boot_partition) const { - if (!is_initialized_) - return kCgptNotInitialized; - - if (!boot_partition) - return kCgptInvalidArgument; - - CgptBootParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - - int retval = cgpt_get_boot_partition_number(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - *boot_partition = params.partition; - return kCgptSuccess; -} - -CgptErrorCode CgptManager::SetSuccessful( - uint32_t partition_number, - bool is_successful) { - if (!is_initialized_) - return kCgptNotInitialized; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.partition = partition_number; - - params.successful = is_successful; - params.set_successful = true; - - int retval = cgpt_set_attributes(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - return kCgptSuccess; -} - -CgptErrorCode CgptManager::GetSuccessful(uint32_t partition_number, - bool* is_successful) const { - if (!is_initialized_) - return kCgptNotInitialized; - - if (!is_successful) - return kCgptInvalidArgument; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.partition = partition_number; - - int retval = cgpt_get_partition_details(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - *is_successful = params.successful; - return kCgptSuccess; -} - -CgptErrorCode CgptManager::SetNumTriesLeft(uint32_t partition_number, - int numTries) { - if (!is_initialized_) - return kCgptNotInitialized; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.partition = partition_number; - - params.tries = numTries; - params.set_tries = true; - - int retval = cgpt_set_attributes(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - return kCgptSuccess; -} - -CgptErrorCode CgptManager::GetNumTriesLeft(uint32_t partition_number, - int* numTries) const { - if (!is_initialized_) - return kCgptNotInitialized; - - if (!numTries) - return kCgptInvalidArgument; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.partition = partition_number; - - int retval = cgpt_get_partition_details(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - *numTries = params.tries; - return kCgptSuccess; -} - -CgptErrorCode CgptManager::SetPriority(uint32_t partition_number, - uint8_t priority) { - if (!is_initialized_) - return kCgptNotInitialized; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.partition = partition_number; - - params.priority = priority; - params.set_priority = true; - - int retval = cgpt_set_attributes(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - return kCgptSuccess; -} - -CgptErrorCode CgptManager::GetPriority(uint32_t partition_number, - uint8_t* priority) const { - if (!is_initialized_) - return kCgptNotInitialized; - - if (!priority) - return kCgptInvalidArgument; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.partition = partition_number; - - int retval = cgpt_get_partition_details(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - *priority = params.priority; - return kCgptSuccess; -} - -CgptErrorCode CgptManager::GetBeginningOffset(uint32_t partition_number, - uint64_t* offset) const { - if (!is_initialized_) - return kCgptNotInitialized; - - if (!offset) - return kCgptInvalidArgument; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.partition = partition_number; - - int retval = cgpt_get_partition_details(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - *offset = params.begin; - return kCgptSuccess; -} - -CgptErrorCode CgptManager::GetNumSectors(uint32_t partition_number, - uint64_t* num_sectors) const { - if (!is_initialized_) - return kCgptNotInitialized; - - if (!num_sectors) - return kCgptInvalidArgument; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.partition = partition_number; - - int retval = cgpt_get_partition_details(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - *num_sectors = params.size; - return kCgptSuccess; -} - -CgptErrorCode CgptManager::GetPartitionTypeId(uint32_t partition_number, - Guid* type_id) const { - if (!is_initialized_) - return kCgptNotInitialized; - - if (!type_id) - return kCgptInvalidArgument; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.partition = partition_number; - - int retval = cgpt_get_partition_details(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - *type_id = params.type_guid; - return kCgptSuccess; -} - -CgptErrorCode CgptManager::GetPartitionUniqueId(uint32_t partition_number, - Guid* unique_id) const { - if (!is_initialized_) - return kCgptNotInitialized; - - if (!unique_id) - return kCgptInvalidArgument; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.partition = partition_number; - - int retval = cgpt_get_partition_details(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - *unique_id = params.unique_guid; - return kCgptSuccess; -} - -CgptErrorCode CgptManager::GetPartitionNumberByUniqueId( - const Guid& unique_id, - uint32_t* partition_number) const { - if (!is_initialized_) - return kCgptNotInitialized; - - if (!partition_number) - return kCgptInvalidArgument; - - CgptAddParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.unique_guid = unique_id; - params.set_unique = 1; - - int retval = cgpt_get_partition_details(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - *partition_number = params.partition; - return kCgptSuccess; -} - -CgptErrorCode CgptManager::SetHighestPriority(uint32_t partition_number, - uint8_t highest_priority) { - if (!is_initialized_) - return kCgptNotInitialized; - - CgptPrioritizeParams params; - memset(¶ms, 0, sizeof(params)); - - params.drive_name = const_cast(device_name_.c_str()); - params.set_partition = partition_number; - params.max_priority = highest_priority; - - int retval = cgpt_prioritize(¶ms); - if (retval != CGPT_OK) - return kCgptUnknownError; - - return kCgptSuccess; -} - -CgptErrorCode CgptManager::SetHighestPriority(uint32_t partition_number) { - // The internal implementation in cgpt_prioritize automatically computes the - // right priority number if we supply 0 for the highest_priority argument. - return SetHighestPriority(partition_number, 0); -} - -CgptErrorCode CgptManager::Validate() { - if (!is_initialized_) - return kCgptNotInitialized; - - uint8_t num_partitions; - - // GetNumNonEmptyPartitions does the check for GptSanityCheck. - // so call it (ignore the num_partitions result) and just return - // its success/failure result. - return GetNumNonEmptyPartitions(&num_partitions); -} diff --git a/cgpt/CgptManager.h b/cgpt/CgptManager.h deleted file mode 100644 index 2dbca6f2..00000000 --- a/cgpt/CgptManager.h +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef VBOOT_REFERENCE_CGPT_CGPTMANAGER_H_ -#define VBOOT_REFERENCE_CGPT_CGPTMANAGER_H_ - -#include -#include "gpt.h" - -// This file defines a simple C++ wrapper class interface for the cgpt methods. - -// These are the possible error codes that can be returned by the CgptManager. -typedef enum CgptErrorCode -{ - kCgptSuccess = 0, - kCgptNotInitialized = 1, - kCgptUnknownError = 2, - kCgptInvalidArgument = 3, -} CgptErrorCode; - - -// CgptManager exposes methods to manipulate the Guid Partition Table as needed -// for ChromeOS scenarios. -class CgptManager { - public: - // Default constructor. The Initialize method must be called before - // any other method can be called on this class. - CgptManager(); - - // Destructor. Automatically closes any opened device. - ~CgptManager(); - - // Opens the given device_name (e.g. "/dev/sdc") and initializes - // with the Guid Partition Table of that device. This is the first method - // that should be called on this class. Otherwise those methods will - // return kCgptNotInitialized. - // Returns kCgptSuccess or an appropriate error code. - // This device is automatically closed when this object is destructed. - CgptErrorCode Initialize(const std::string& device_name); - - // Clears all the existing contents of the GPT and PMBR on the current - // device. - CgptErrorCode ClearAll(); - - // Adds a new partition at the end of the existing partitions - // with the new label, type, unique Id, offset and size. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode AddPartition(const std::string& label, - const Guid& partition_type_guid, - const Guid& unique_id, - uint64_t beginning_offset, - uint64_t num_sectors); - - // Populates num_partitions parameter with the number of partitions - // that are currently on this device and not empty. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode GetNumNonEmptyPartitions(uint8_t* num_partitions) const; - - // Sets the Protective Master Boot Record on this device with the given - // boot_partition number after populating the MBR with the contents of the - // given boot_file_name. It also creates a legacy partition if - // should_create_legacy_partition is true. - // Note: Strictly speaking, the PMBR is not part of the GPT, but it is - // included here for ease of use. - CgptErrorCode SetPmbr(uint32_t boot_partition_number, - const std::string& boot_file_name, - bool should_create_legacy_partition); - - // Populates boot_partition with the partition number that's set to - // boot in the PMBR. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode GetPmbrBootPartitionNumber(uint32_t* boot_partition) const; - - // Sets the "successful" attribute of the given kernelPartition to 0 or 1 - // based on the value of is_successful being true (1) or false(0) - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode SetSuccessful(uint32_t partition_number, bool is_successful); - - // Populates is_successful to true if the successful attribute in the - // given kernelPartition is non-zero, or to false if it's zero. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode GetSuccessful(uint32_t partition_number, - bool* is_successful) const; - - // Sets the "NumTriesLeft" attribute of the given kernelPartition to - // the given num_tries_left value. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode SetNumTriesLeft(uint32_t partition_number, - int num_tries_left); - - // Populates the num_tries_left parameter with the value of the - // NumTriesLeft attribute of the given kernelPartition. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode GetNumTriesLeft(uint32_t partition_number, - int* num_tries_left) const; - - // Sets the "Priority" attribute of the given kernelPartition to - // the given priority value. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode SetPriority(uint32_t partition_number, - uint8_t priority); - - // Populates the priority parameter with the value of the Priority - // attribute of the given kernelPartition. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode GetPriority(uint32_t partition_number, - uint8_t* priority) const; - - // Populates the offset parameter with the beginning offset of the - // given partition. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode GetBeginningOffset(uint32_t partition_number, - uint64_t* offset) const; - - // Populates the number of sectors in the given partition. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode GetNumSectors(uint32_t partition_number, - uint64_t* num_sectors) const; - - // Populates the type_id parameter with the partition type id - // (these are the standard ids for kernel, rootfs, etc.) - // of the partition corresponding to the given partition_number. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode GetPartitionTypeId(uint32_t partition_number, - Guid* type_id) const; - - // Populates the unique_id parameter with the Guid that uniquely identifies - // the given partition_number. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode GetPartitionUniqueId(uint32_t partition_number, - Guid* unique_id) const; - - // Populates the partition_number parameter with the partition number of - // the partition which is uniquely identified by the given unique_id. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode GetPartitionNumberByUniqueId( - const Guid& unique_id, - uint32_t* partition_number) const; - - // Sets the "Priority" attribute of given kernelPartition to the value - // specified in higestPriority parameter. In addition, also reduces the - // priorities of all the other kernel partitions, if necessary, to ensure - // no other partition has a higher priority. It does preserve the relative - // ordering among the remaining partitions and doesn't touch the partitions - // whose priorities are zero. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode SetHighestPriority(uint32_t partition_number, - uint8_t highest_priority); - - // Same as SetHighestPriority above but works without having to explicitly - // give a value for highest_priority. The internal implementation figures - // out the best highest number that needs to be given depending on the - // existing priorities. - // Returns kCgptSuccess or an appropriate error code. - CgptErrorCode SetHighestPriority(uint32_t partition_number); - - // Runs the sanity checks on the CGPT and MBR and - // Returns kCgptSuccess if everything is valid or an appropriate error code - // if there's anything invalid or if there's any error encountered during - // the validation. - CgptErrorCode Validate(); - - private: - std::string device_name_; - bool is_initialized_; - - CgptManager(const CgptManager &); - void operator=(const CgptManager &); -}; - -#endif // VBOOT_REFERENCE_CGPT_CGPTMANAGER_H_ diff --git a/tests/CgptManagerTests.cc b/tests/CgptManagerTests.cc deleted file mode 100644 index 35da0d09..00000000 --- a/tests/CgptManagerTests.cc +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Unit tests for CgptManager class. -#include - -#include "../cgpt/CgptManager.h" - -// We use some specific GUID constants for some of the tests, -// so pulling in cgpt.h. Make sure this is included after -// CgptManager.h so that we can test the actual usage of -// CgptManager.h as the post-install package would use. -// Example: this would catch an incorrect usage of a GUID -// that's defined only in cgpt.h and being accidentally -// used in CgptManager.h (which should not have any cgpt.h -// dependencies). -extern "C" { -#include "../cgpt/cgpt.h" -} - -#include -#include -#include -#include - -using std::string; - -static const Guid p2guid = {{{0, 1, 2, 3, 4, {2, 2, 2, 2, 2, 2}}}}; -static const Guid p3guid = {{{0, 6, 5, 4, 2, {3, 3, 3, 3, 3, 3}}}}; - -#define EXPECT_SUCCESS(c) EXPECT_EQ(kCgptSuccess, c) - -// The --v flag controls the log verbosity level. -DEFINE_int32(v, 0, 0); - -// This class unit tests the CgptManager class. -class CgptManagerUnitTest : public ::testing::Test { -public: - CgptManagerUnitTest() { - // Even though the post-installer doesn't use any methods that require - // uuid_generate, for the unit test we use those methods, so we need to - // set the uuid_generator. - uuid_generator = uuid_generate; - } - - void SetUp() { - const string device_name = "/tmp/DummyFileForCgptManagerTests.bin"; - - CreateDummyDevice(device_name); - - LOG(INFO) << "Initializing cgpt with " << device_name; - EXPECT_SUCCESS(cgpt_manager.Initialize(device_name)); - EXPECT_SUCCESS(cgpt_manager.ClearAll()); - - CheckPartitionCount(0); - } - - virtual ~CgptManagerUnitTest() { } - -protected: - CgptManager cgpt_manager; - - void CreateDummyDevice(const string& dummy_device) { - FILE* fp = fopen(dummy_device.c_str(), "w"); - - ASSERT_TRUE(fp != NULL); - - const int kNumSectors = 1000; - const int kSectorSize = 512; - const char kFillChar = '7'; // Some character, value doesn't matter. - - for(int i = 0; i < kNumSectors * kSectorSize; i++) { - EXPECT_EQ(kFillChar, fputc(kFillChar, fp)); - } - - fclose(fp); - } - - void CheckEquality(string field, - uint64_t expected, - uint64_t actual) { - - - VLOG(1) << field << ":" - << "Expected = " << expected - << ";Actual = " << actual; - - EXPECT_EQ(expected, actual); - } - - - void CheckGuidEquality(string field, - const Guid& expected_id, - const Guid& actual_id) { - char expected_id_str[GUID_STRLEN]; - GuidToStr(&expected_id, expected_id_str, sizeof(expected_id_str)); - - char actual_id_str[GUID_STRLEN]; - GuidToStr(&actual_id, actual_id_str, sizeof(actual_id_str)); - - VLOG(1) << field << ":" - << "Expected = " << expected_id_str - << ";Actual = " << actual_id_str; - - EXPECT_TRUE(GuidEqual(&expected_id, &actual_id)); - } - - // Checks if the current number of partitions in the device matches - // the value of expected_num_partitions. - void CheckPartitionCount(uint8 expected_num_partitions) { - uint8_t actual_num_partitions; - EXPECT_SUCCESS(cgpt_manager.GetNumNonEmptyPartitions( - &actual_num_partitions)); - - CheckEquality("NumPartitions", - expected_num_partitions, - actual_num_partitions); - } - - void SetAndCheckSuccessfulBit(uint32_t partition_number, - bool expected_is_successful) { - EXPECT_SUCCESS(cgpt_manager.SetSuccessful(partition_number, - expected_is_successful)); - - bool actual_is_successful; - EXPECT_SUCCESS(cgpt_manager.GetSuccessful(partition_number, - &actual_is_successful)); - EXPECT_EQ(expected_is_successful, actual_is_successful); - } - - - void SetAndCheckNumTriesLeft(uint32_t partition_number, - int expected_num_tries) { - EXPECT_SUCCESS(cgpt_manager.SetNumTriesLeft(partition_number, - expected_num_tries)); - - int actual_num_tries; - EXPECT_SUCCESS(cgpt_manager.GetNumTriesLeft(partition_number, - &actual_num_tries)); - CheckEquality("NumTries", expected_num_tries, actual_num_tries); - } - - void SetAndCheckPriority(uint32_t partition_number, - uint8_t expected_priority) { - EXPECT_SUCCESS(cgpt_manager.SetPriority(partition_number, - expected_priority)); - - uint8_t actual_priority; - EXPECT_SUCCESS(cgpt_manager.GetPriority(partition_number, - &actual_priority)); - CheckEquality("Priority", expected_priority, actual_priority); - } - - void CheckPriority(uint32_t partition_number, - uint8_t expected_priority) { - uint8_t actual_priority; - EXPECT_SUCCESS(cgpt_manager.GetPriority(partition_number, - &actual_priority)); - CheckEquality("Priority", expected_priority, actual_priority); - } - - - void CheckBeginningOffset(uint32_t partition_number, - uint64_t expected_offset) { - uint64_t actual_offset; - EXPECT_SUCCESS(cgpt_manager.GetBeginningOffset(partition_number, - &actual_offset)); - CheckEquality("Beginning Offset", expected_offset, actual_offset); - } - - - void CheckNumSectors(uint32_t partition_number, - uint64_t expected_num_sectors) { - uint64_t actual_num_sectors; - EXPECT_SUCCESS(cgpt_manager.GetNumSectors(partition_number, - &actual_num_sectors)); - CheckEquality("Num Sectors", expected_num_sectors, actual_num_sectors); - } - - - void CheckPartitionTypeId(int partition_number, - const Guid& expected_partition_type_id) { - // Get the partition type id and check if it matches the expected value. - Guid actual_partition_type_id; - EXPECT_SUCCESS(cgpt_manager.GetPartitionTypeId(partition_number, - &actual_partition_type_id)); - - CheckGuidEquality("PartitionTypeId", - expected_partition_type_id, - actual_partition_type_id); - } - - void CheckPartitionUniqueId(int partition_number, - const Guid& expected_partition_unique_id) { - // Get the partition unique id and check if it matches the expected value. - Guid actual_partition_unique_id; - EXPECT_SUCCESS(cgpt_manager.GetPartitionUniqueId( - partition_number, - &actual_partition_unique_id)); - - CheckGuidEquality("PartitionUniqueId", - expected_partition_unique_id, - actual_partition_unique_id); - } - - void CheckPartitionNumberByUniqueId(const Guid& unique_id, - uint32_t expected_partition_number) { - // Get the partition number for the unique id and check - // if it matches the expected value. - uint32_t actual_partition_number; - EXPECT_SUCCESS(cgpt_manager.GetPartitionNumberByUniqueId( - unique_id, - &actual_partition_number)); - - CheckEquality("PartitionNumberForUniqueId", - expected_partition_number, - actual_partition_number); - } - - - void CreateBootFile(const string& boot_file_name) { - FILE* fp = fopen(boot_file_name.c_str(), "w"); - - ASSERT_TRUE(fp != NULL); - - const int kNumSectors = 1; - const int kSectorSize = 512; - const char kFillChar = '8'; // Some character, value doesn't matter. - - for(int i = 0; i < kNumSectors * kSectorSize; i++) { - EXPECT_EQ(kFillChar, fputc(kFillChar, fp)); - } - - fclose(fp); - } - -private: - DISALLOW_COPY_AND_ASSIGN(CgptManagerUnitTest); -}; - -TEST_F(CgptManagerUnitTest, AutoPrioritizationTest) { - EXPECT_SUCCESS(cgpt_manager.AddPartition("k1", - guid_chromeos_kernel, - guid_unused, - 100, - 10)); - CheckPartitionCount(1); - - EXPECT_SUCCESS(cgpt_manager.AddPartition("k2", - guid_chromeos_kernel, - p2guid, - 200, - 20)); - CheckPartitionCount(2); - - EXPECT_SUCCESS(cgpt_manager.AddPartition("k3", - guid_chromeos_kernel, - p3guid, - 300, - 30)); - CheckPartitionCount(3); - - uint8_t expectedk1Priority = 1; - uint8_t expectedk2Priority = 2; - uint8_t expectedk3Priority = 0; - - // Calling SetAndCheckPriority will do a set and get of the above priorities. - SetAndCheckPriority(1, expectedk1Priority); - SetAndCheckPriority(2, expectedk2Priority); - SetAndCheckPriority(3, expectedk3Priority); - - EXPECT_SUCCESS(cgpt_manager.SetHighestPriority(1)); - - expectedk1Priority = 2; - expectedk2Priority = 1; - - CheckPriority(1, expectedk1Priority); - CheckPriority(2, expectedk2Priority); - CheckPriority(3, expectedk3Priority); -} - - -TEST_F(CgptManagerUnitTest, AddPartitionTest) { - int p2_offset = 200; - int p2_size = 20; - int p3_offset = 300; - int p3_size = 30; - - VLOG(1) << "Adding various types of partitions ... "; - EXPECT_SUCCESS(cgpt_manager.AddPartition("data stuff", - guid_linux_data, - guid_unused, - 100, - 10)); - CheckPartitionCount(1); - - EXPECT_SUCCESS(cgpt_manager.AddPartition("kernel stuff", - guid_chromeos_kernel, - p2guid, - p2_offset, - p2_size)); - CheckPartitionCount(2); - - EXPECT_SUCCESS(cgpt_manager.AddPartition("rootfs stuff", - guid_chromeos_rootfs, - p3guid, - p3_offset, - p3_size)); - CheckPartitionCount(3); - - uint32_t pmbr_boot_partition_number = 4; - EXPECT_SUCCESS(cgpt_manager.AddPartition("ESP stuff", - guid_efi, - guid_unused, - 400, - 40)); - CheckPartitionCount(4); - - EXPECT_SUCCESS(cgpt_manager.AddPartition("fture stuff", - guid_chromeos_reserved, - guid_unused, - 500, - 50)); - CheckPartitionCount(5); - - Guid guid_random = {{{0x2364a860, 0xbf63, 0x42fb, 0xa8, 0x3d, - {0x9a, 0xd3, 0xe0, 0x57, 0xfc, 0xf5}}}}; - - EXPECT_SUCCESS(cgpt_manager.AddPartition("random stuff", - guid_random, - guid_unused, - 600, - 60)); - - CheckPartitionCount(6); - - string boot_file_name = "/tmp/BootFileForCgptManagerTests.bin"; - LOG(INFO) << "Adding EFI partition to PMBR with bootfile: " - << boot_file_name; - - CreateBootFile(boot_file_name); - EXPECT_SUCCESS(cgpt_manager.SetPmbr(pmbr_boot_partition_number, - boot_file_name, - true)); - - VLOG(1) << "Checking if contents of GPT match values set in AddPartition."; - - uint32_t actual_boot_partition_number; - EXPECT_SUCCESS(cgpt_manager.GetPmbrBootPartitionNumber( - &actual_boot_partition_number)); - EXPECT_EQ(pmbr_boot_partition_number, actual_boot_partition_number); - - // Set the successful attribute for some partition to various Values - // and check if the settings are preserved. - SetAndCheckSuccessfulBit(2, true); - SetAndCheckSuccessfulBit(2, false); - - // Set the number of tries for some partition to various Values - // and check if the settings are preserved. - SetAndCheckNumTriesLeft(2, 6); - SetAndCheckNumTriesLeft(2, 5); - - // Set the priority for some partition to various Values - // and check if the settings are preserved. - SetAndCheckPriority(2, 2); - SetAndCheckPriority(2, 0); - - // Check if the beginning offset for some of the partitions - // are the same as what was set in AddPartition. - CheckBeginningOffset(2, p2_offset); - CheckBeginningOffset(3, p3_offset); - - // Check if the number of sectors for some of the partitions - // are same as what was set in AddPartition. - CheckNumSectors(2, p2_size); - CheckNumSectors(3, p3_size); - - // Check if the partition type IDs for some of the partitions - // are same as what was set in AddPartition. - CheckPartitionTypeId(2, guid_chromeos_kernel); - CheckPartitionTypeId(4, guid_efi); - - // Check if the partition unique IDs for some of the partitions - // same as what was set in AddPartition. - CheckPartitionUniqueId(2, p2guid); - CheckPartitionUniqueId(3, p3guid); - - // Check if the partition numbers for some of the partitions are - // retrievable by their unique IDs set in AddPartition. - CheckPartitionNumberByUniqueId(p2guid, 2); - CheckPartitionNumberByUniqueId(p3guid, 3); -} - -int main(int argc, char **argv) { - google::ParseCommandLineFlags(&argc, &argv, true); - ::testing::InitGoogleTest(&argc, argv); - - // VLOG(2) logs at level -2. So if user gives --v=2, we should - // set MinLogLevel to -2, so VLOG(2) and VLOG(1) will show up. - logging::SetMinLogLevel(-FLAGS_v); - return RUN_ALL_TESTS(); -} -- cgit v1.2.1