1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2010 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 163defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_ 1839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#define UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_ 193defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 203defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include <string> 210d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo#include <vector> 220d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 230d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo#include <brillo/message_loops/message_loop.h> 240d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo#include <gtest/gtest_prod.h> 256f03a3b868d4b632931400628763036f79c449f7Darin Petkov 2639910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/action.h" 27fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo#include "update_engine/common/boot_control_interface.h" 28fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo#include "update_engine/common/hardware_interface.h" 2939910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/payload_consumer/install_plan.h" 303defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 313defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// The Postinstall Runner Action is responsible for running the postinstall 323defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// script of a successfully downloaded update. 333defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 343defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comnamespace chromeos_update_engine { 353defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 36b15a0b8eaf18c9e9341706df9f4ab59ce595a67cAlex Deymoclass BootControlInterface; 37b15a0b8eaf18c9e9341706df9f4ab59ce595a67cAlex Deymo 38d317e40be46e1b69f624a8165472c99fe6346a1eChris Sosaclass PostinstallRunnerAction : public InstallPlanAction { 393defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com public: 40fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo PostinstallRunnerAction(BootControlInterface* boot_control, 41fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo HardwareInterface* hardware) 42fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo : boot_control_(boot_control), hardware_(hardware) {} 431c0fe79c7ef2b43946d756b54c8505d2bf48b93bJay Srinivasan 44d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo // InstallPlanAction overrides. 45cbc2274c4160805bf726df872390112654816ca7Alex Deymo void PerformAction() override; 46d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo void SuspendAction() override; 47d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo void ResumeAction() override; 48d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo void TerminateProcessing() override; 493defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 500d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo class DelegateInterface { 510d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo public: 520d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo virtual ~DelegateInterface() = default; 530d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 540d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // Called whenever there is an overall progress update from the postinstall 550d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // programs. 560d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo virtual void ProgressUpdate(double progress) = 0; 570d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo }; 580d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 590d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo void set_delegate(DelegateInterface* delegate) { delegate_ = delegate; } 600d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 613defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com // Debugging/logging 623defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com static std::string StaticType() { return "PostinstallRunnerAction"; } 63cbc2274c4160805bf726df872390112654816ca7Alex Deymo std::string Type() const override { return StaticType(); } 643defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 653defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com private: 6631d95ac85d294b2b1bfa293835013e66c010fbcfAlex Deymo friend class PostinstallRunnerActionTest; 670d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo FRIEND_TEST(PostinstallRunnerActionTest, ProcessProgressLineTest); 6831d95ac85d294b2b1bfa293835013e66c010fbcfAlex Deymo 69e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo void PerformPartitionPostinstall(); 70e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo 710d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // Called whenever the |progress_fd_| has data available to read. 720d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo void OnProgressFdReady(); 730d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 740d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // Updates the action progress according to the |line| passed from the 750d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // postinstall program. Valid lines are: 760d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // global_progress <frac> 770d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // <frac> should be between 0.0 and 1.0; sets the progress to the 780d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // <frac> value. 790d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo bool ProcessProgressLine(const std::string& line); 800d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 810d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // Report the progress to the delegate given that the postinstall operation 820d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // for |current_partition_| has a current progress of |frac|, a value between 830d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // 0 and 1 for that step. 840d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo void ReportProgress(double frac); 850d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 860d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // Cleanup the setup made when running postinstall for a given partition. 870d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // Unmount and remove the mountpoint directory if needed and cleanup the 880d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // status file descriptor and message loop task watching for it. 890d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo void Cleanup(); 90d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo 916f03a3b868d4b632931400628763036f79c449f7Darin Petkov // Subprocess::Exec callback. 92e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo void CompletePartitionPostinstall(int return_code, 93e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo const std::string& output); 94e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo 95b15a0b8eaf18c9e9341706df9f4ab59ce595a67cAlex Deymo // Complete the Action with the passed |error_code| and mark the new slot as 96b15a0b8eaf18c9e9341706df9f4ab59ce595a67cAlex Deymo // ready. Called when the post-install script was run for all the partitions. 97e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo void CompletePostinstall(ErrorCode error_code); 986f03a3b868d4b632931400628763036f79c449f7Darin Petkov 99d317e40be46e1b69f624a8165472c99fe6346a1eChris Sosa InstallPlan install_plan_; 100390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo 101390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo // The path where the filesystem will be mounted during post-install. 102390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo std::string fs_mount_dir_; 1036f03a3b868d4b632931400628763036f79c449f7Darin Petkov 104e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo // The partition being processed on the list of partitions specified in the 105e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo // InstallPlan. 106e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo size_t current_partition_{0}; 107e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo 1080d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // A non-negative value representing the estimated weight of each partition 1090d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // passed in the install plan. The weight is used to predict the overall 1100d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // progress from the individual progress of each partition and should 1110d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // correspond to the time it takes to run it. 1120d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo std::vector<double> partition_weight_; 1130d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 1140d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // The sum of all the weights in |partition_weight_|. 1150d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo double total_weight_{0}; 1160d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 1170d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // The sum of all the weights in |partition_weight_| up to but not including 1180d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // the |current_partition_|. 1190d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo double accumulated_weight_{0}; 1200d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 1210d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // The delegate used to notify of progress updates, if any. 1220d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo DelegateInterface* delegate_{nullptr}; 1230d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 124b15a0b8eaf18c9e9341706df9f4ab59ce595a67cAlex Deymo // The BootControlInerface used to mark the new slot as ready. 125b15a0b8eaf18c9e9341706df9f4ab59ce595a67cAlex Deymo BootControlInterface* boot_control_; 12631d95ac85d294b2b1bfa293835013e66c010fbcfAlex Deymo 127fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo // HardwareInterface used to signal powerwash. 128fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo HardwareInterface* hardware_; 1291c0fe79c7ef2b43946d756b54c8505d2bf48b93bJay Srinivasan 130fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo // Whether the Powerwash was scheduled before invoking post-install script. 131fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo // Used for cleaning up if post-install fails. 132fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo bool powerwash_scheduled_{false}; 13330dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold 134d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo // Postinstall command currently running, or 0 if no program running. 135d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo pid_t current_command_{0}; 136d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo 1377f4bc3f009c711b5bd1bd145f7f53cd837ed6414Ben Chan // True if |current_command_| has been suspended by SuspendAction(). 1387f4bc3f009c711b5bd1bd145f7f53cd837ed6414Ben Chan bool is_current_command_suspended_{false}; 1397f4bc3f009c711b5bd1bd145f7f53cd837ed6414Ben Chan 1400d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // The parent progress file descriptor used to watch for progress reports from 1410d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // the postinstall program and the task watching for them. 1420d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo int progress_fd_{-1}; 1430d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo brillo::MessageLoop::TaskId progress_task_{brillo::MessageLoop::kTaskIdNull}; 1440d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 1450d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo // A buffer of a partial read line from the progress file descriptor. 1460d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo std::string progress_buffer_; 1470d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo 1483defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com DISALLOW_COPY_AND_ASSIGN(PostinstallRunnerAction); 1493defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}; 1503defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 1513defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com} // namespace chromeos_update_engine 1523defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 15339910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif // UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_ 154