sideload_main.cc revision 40a017db5df92ab7f9c3dcd73cd736a645931c93
103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// 203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Copyright (C) 2016 The Android Open Source Project 303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// 403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// you may not use this file except in compliance with the License. 603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// You may obtain a copy of the License at 703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// 803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// 1003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Unless required by applicable law or agreed to in writing, software 1103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 1203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// See the License for the specific language governing permissions and 1403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// limitations under the License. 1503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// 1603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 1703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <xz.h> 1803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 1903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <string> 2003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <vector> 2103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 2203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <base/command_line.h> 2303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <base/logging.h> 2403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <base/strings/string_split.h> 2540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <base/strings/stringprintf.h> 2640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/asynchronous_signal_handler.h> 2703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <brillo/flag_helper.h> 2840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/make_unique_ptr.h> 2903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <brillo/message_loops/base_message_loop.h> 3040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/streams/file_stream.h> 3140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/streams/stream.h> 3203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 3303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/boot_control.h" 3440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include "update_engine/common/error_code_utils.h" 3503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/hardware.h" 3603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/prefs.h" 3740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include "update_engine/common/subprocess.h" 3803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/terminator.h" 3903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/utils.h" 4003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/update_attempter_android.h" 4103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 4203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymousing std::string; 4303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymousing std::vector; 4440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymousing update_engine::UpdateStatus; 4503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 4603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymonamespace chromeos_update_engine { 4703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymonamespace { 4803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 4903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymovoid SetupLogging() { 5003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo string log_file; 5103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo logging::LoggingSettings log_settings; 5203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo log_settings.lock_log = logging::DONT_LOCK_LOG_FILE; 5303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo log_settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE; 5403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo log_settings.log_file = nullptr; 5503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; 5603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 5703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo logging::InitLogging(log_settings); 5803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo} 5903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 6003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymoclass SideloadDaemonState : public DaemonStateInterface, 6103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo public ServiceObserverInterface { 6203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo public: 6340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo explicit SideloadDaemonState(brillo::StreamPtr status_stream) 6440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo : status_stream_(std::move(status_stream)) { 6503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // Add this class as the only observer. 6603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo observers_.insert(this); 6703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 6803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo ~SideloadDaemonState() override = default; 6903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 7003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // DaemonStateInterface overrides. 7103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo bool StartUpdater() override { return true; } 7203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo void AddObserver(ServiceObserverInterface* observer) override {} 7303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo void RemoveObserver(ServiceObserverInterface* observer) override {} 7403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo const std::set<ServiceObserverInterface*>& service_observers() override { 7503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo return observers_; 7603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 7703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 7803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // ServiceObserverInterface overrides. 7903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo void SendStatusUpdate(int64_t last_checked_time, 8003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo double progress, 8140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo UpdateStatus status, 8203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo const string& new_version, 8303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo int64_t new_size) override { 8440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo if (status_ != status && (status == UpdateStatus::DOWNLOADING || 8540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo status == UpdateStatus::FINALIZING)) { 8640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo // Split the progress bar in two parts for the two stages DOWNLOADING and 8740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo // FINALIZING. 8840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo ReportStatus(base::StringPrintf( 8940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo "ui_print Step %d/2", status == UpdateStatus::DOWNLOADING ? 1 : 2)); 9040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo ReportStatus(base::StringPrintf("progress 0.5 0")); 9140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo } 9240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo if (status_ != status || fabs(progress - progress_) > 0.005) { 9340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo ReportStatus(base::StringPrintf("set_progress %.lf", progress)); 9440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo } 9540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo progress_ = progress; 9603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo status_ = status; 9703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 9803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 9903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo void SendPayloadApplicationComplete(ErrorCode error_code) override { 10040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo if (error_code != ErrorCode::kSuccess) { 10140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo ReportStatus( 10240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo base::StringPrintf("ui_print Error applying update: %d (%s)", 10340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo error_code, 10440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo utils::ErrorCodeToString(error_code).c_str())); 10540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo } 10603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo error_code_ = error_code; 10703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo brillo::MessageLoop::current()->BreakLoop(); 10803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 10903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 11003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo void SendChannelChangeUpdate(const string& tracking_channel) override {} 11103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 11203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // Getters. 11340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo UpdateStatus status() { return status_; } 11403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo ErrorCode error_code() { return error_code_; } 11503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 11603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo private: 11740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo // Report a status message in the status_stream_, if any. These messages 11840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo // should conform to the specification defined in the Android recovery. 11940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo void ReportStatus(const string& message) { 12040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo if (!status_stream_) 12140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo return; 12240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo string status_line = message + "\n"; 12340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo status_stream_->WriteAllBlocking( 12440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo status_line.data(), status_line.size(), nullptr); 12540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo } 12640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo 12703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo std::set<ServiceObserverInterface*> observers_; 12840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo brillo::StreamPtr status_stream_; 12903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 13003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // The last status and error code reported. 13140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo UpdateStatus status_{UpdateStatus::IDLE}; 13203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo ErrorCode error_code_{ErrorCode::kSuccess}; 13340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo double progress_{-1.}; 13403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo}; 13503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 13603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Apply an update payload directly from the given payload URI. 13703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymobool ApplyUpdatePayload(const string& payload, 13803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo int64_t payload_offset, 13903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo int64_t payload_size, 14040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo const vector<string>& headers, 14140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo int64_t status_fd) { 14203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo brillo::BaseMessageLoop loop; 14303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo loop.SetAsCurrent(); 14403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 14540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo // Setup the subprocess handler. 14640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo brillo::AsynchronousSignalHandler handler; 14740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo handler.Init(); 14840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo Subprocess subprocess; 14940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo subprocess.Init(&handler); 15040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo 15140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo SideloadDaemonState sideload_daemon_state( 15240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo brillo::FileStream::FromFileDescriptor(status_fd, true, nullptr)); 15303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 15403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // During the sideload we don't access the prefs persisted on disk but instead 15503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // use a temporary memory storage. 15603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo MemoryPrefs prefs; 15703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 15803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo std::unique_ptr<BootControlInterface> boot_control = 15903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo boot_control::CreateBootControl(); 16003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo if (!boot_control) { 16103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo LOG(ERROR) << "Error initializing the BootControlInterface."; 16203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo return false; 16303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 16403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 16503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo std::unique_ptr<HardwareInterface> hardware = hardware::CreateHardware(); 16603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo if (!hardware) { 16703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo LOG(ERROR) << "Error initializing the HardwareInterface."; 16803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo return false; 16903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 17003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 17103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo UpdateAttempterAndroid update_attempter( 17203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo &sideload_daemon_state, &prefs, boot_control.get(), hardware.get()); 17303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo update_attempter.Init(); 17403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 17503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo TEST_AND_RETURN_FALSE(update_attempter.ApplyPayload( 17603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo payload, payload_offset, payload_size, headers, nullptr)); 17703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 17803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo loop.Run(); 17940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo return sideload_daemon_state.status() == UpdateStatus::UPDATED_NEED_REBOOT; 18003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo} 18103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 18203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo} // namespace 18303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo} // namespace chromeos_update_engine 18403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 18503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymoint main(int argc, char** argv) { 18603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo DEFINE_string(payload, 18703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "file:///data/payload.bin", 18803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "The URI to the update payload to use."); 18903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo DEFINE_int64( 19003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo offset, 0, "The offset in the payload where the CrAU update starts. "); 19103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo DEFINE_int64(size, 19203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 0, 19303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "The size of the CrAU part of the payload. If 0 is passed, it " 19403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "will be autodetected."); 19503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo DEFINE_string(headers, 19603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "", 19703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "A list of key-value pairs, one element of the list per line."); 19840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo DEFINE_int64(status_fd, -1, "A file descriptor to notify the update status."); 19903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 20003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo chromeos_update_engine::Terminator::Init(); 20103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo chromeos_update_engine::SetupLogging(); 20203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo brillo::FlagHelper::Init(argc, argv, "Update Engine Sideload"); 20303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 20403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo LOG(INFO) << "Update Engine Sideloading starting"; 20503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 20603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // xz-embedded requires to initialize its CRC-32 table once on startup. 20703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo xz_crc32_init(); 20803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 20903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo vector<string> headers = base::SplitString( 21003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo FLAGS_headers, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); 21103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 21203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo if (!chromeos_update_engine::ApplyUpdatePayload( 21340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo FLAGS_payload, FLAGS_offset, FLAGS_size, headers, FLAGS_status_fd)) 21403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo return 1; 21503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 21603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo return 0; 21703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo} 218