blob: 6017069795b69d9535411befdfce638b390280de [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2010 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
adlr@google.com3defe6a2009-12-04 20:57:17 +000016
Alex Deymo39910dc2015-11-09 17:04:30 -080017#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_
18#define UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_
adlr@google.com3defe6a2009-12-04 20:57:17 +000019
Hidehiko Abe493fecb2019-07-10 23:30:50 +090020#include <memory>
adlr@google.com3defe6a2009-12-04 20:57:17 +000021#include <string>
Kelvin Zhange9def4e2020-12-02 14:04:09 -050022#include <utility>
Alex Deymo0d298542016-03-30 18:31:49 -070023#include <vector>
24
Hidehiko Abe493fecb2019-07-10 23:30:50 +090025#include <base/files/file_descriptor_watcher_posix.h>
Alex Deymo0d298542016-03-30 18:31:49 -070026#include <brillo/message_loops/message_loop.h>
27#include <gtest/gtest_prod.h>
Darin Petkov6f03a3b2010-11-10 14:27:14 -080028
Alex Deymo39910dc2015-11-09 17:04:30 -080029#include "update_engine/common/action.h"
Alex Deymofb905d92016-06-03 19:26:58 -070030#include "update_engine/common/boot_control_interface.h"
31#include "update_engine/common/hardware_interface.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080032#include "update_engine/payload_consumer/install_plan.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000033
34// The Postinstall Runner Action is responsible for running the postinstall
35// script of a successfully downloaded update.
36
37namespace chromeos_update_engine {
38
Alex Deymob15a0b82015-11-25 20:30:40 -030039class BootControlInterface;
40
Chris Sosad317e402013-06-12 13:47:09 -070041class PostinstallRunnerAction : public InstallPlanAction {
adlr@google.com3defe6a2009-12-04 20:57:17 +000042 public:
Alex Deymofb905d92016-06-03 19:26:58 -070043 PostinstallRunnerAction(BootControlInterface* boot_control,
Kelvin Zhange9def4e2020-12-02 14:04:09 -050044 HardwareInterface* hardware);
Kelvin Zhang19acf4f2024-01-08 21:18:28 +000045 ~PostinstallRunnerAction();
adlr@google.com3defe6a2009-12-04 20:57:17 +000046
Alex Deymod15c5462016-03-09 18:11:12 -080047 // InstallPlanAction overrides.
Alex Deymocbc22742016-03-04 17:53:02 -080048 void PerformAction() override;
Alex Deymod15c5462016-03-09 18:11:12 -080049 void SuspendAction() override;
50 void ResumeAction() override;
51 void TerminateProcessing() override;
adlr@google.com3defe6a2009-12-04 20:57:17 +000052
Alex Deymo0d298542016-03-30 18:31:49 -070053 class DelegateInterface {
54 public:
55 virtual ~DelegateInterface() = default;
56
57 // Called whenever there is an overall progress update from the postinstall
58 // programs.
59 virtual void ProgressUpdate(double progress) = 0;
60 };
61
62 void set_delegate(DelegateInterface* delegate) { delegate_ = delegate; }
63
adlr@google.com3defe6a2009-12-04 20:57:17 +000064 // Debugging/logging
65 static std::string StaticType() { return "PostinstallRunnerAction"; }
Alex Deymocbc22742016-03-04 17:53:02 -080066 std::string Type() const override { return StaticType(); }
adlr@google.com3defe6a2009-12-04 20:57:17 +000067
68 private:
Alex Deymo31d95ac2015-09-17 11:56:18 -070069 friend class PostinstallRunnerActionTest;
Alex Deymo0d298542016-03-30 18:31:49 -070070 FRIEND_TEST(PostinstallRunnerActionTest, ProcessProgressLineTest);
Alex Deymo31d95ac2015-09-17 11:56:18 -070071
Kelvin Zhange9def4e2020-12-02 14:04:09 -050072 // exposed for testing purposes only
73 void SetMountDir(std::string dir) { fs_mount_dir_ = std::move(dir); }
Kelvin Zhang1df000a2022-02-09 16:00:17 -080074 void EnsureUnmounted();
Kelvin Zhange9def4e2020-12-02 14:04:09 -050075
Alex Deymoe5e5fe92015-10-05 09:28:19 -070076 void PerformPartitionPostinstall();
Kelvin Zhang06e654a2021-09-10 13:21:00 -070077 [[nodiscard]] bool MountPartition(
78 const InstallPlan::Partition& partition) noexcept;
Alex Deymoe5e5fe92015-10-05 09:28:19 -070079
Alex Deymo0d298542016-03-30 18:31:49 -070080 // Called whenever the |progress_fd_| has data available to read.
81 void OnProgressFdReady();
82
83 // Updates the action progress according to the |line| passed from the
84 // postinstall program. Valid lines are:
85 // global_progress <frac>
86 // <frac> should be between 0.0 and 1.0; sets the progress to the
87 // <frac> value.
88 bool ProcessProgressLine(const std::string& line);
89
90 // Report the progress to the delegate given that the postinstall operation
91 // for |current_partition_| has a current progress of |frac|, a value between
92 // 0 and 1 for that step.
93 void ReportProgress(double frac);
94
95 // Cleanup the setup made when running postinstall for a given partition.
96 // Unmount and remove the mountpoint directory if needed and cleanup the
97 // status file descriptor and message loop task watching for it.
98 void Cleanup();
Alex Deymod15c5462016-03-09 18:11:12 -080099
Darin Petkov6f03a3b2010-11-10 14:27:14 -0800100 // Subprocess::Exec callback.
Amin Hassani008c4582019-01-13 16:22:47 -0800101 void CompletePartitionPostinstall(int return_code, const std::string& output);
Alex Deymoe5e5fe92015-10-05 09:28:19 -0700102
Alex Deymob15a0b82015-11-25 20:30:40 -0300103 // Complete the Action with the passed |error_code| and mark the new slot as
104 // ready. Called when the post-install script was run for all the partitions.
Alex Deymoe5e5fe92015-10-05 09:28:19 -0700105 void CompletePostinstall(ErrorCode error_code);
Darin Petkov6f03a3b2010-11-10 14:27:14 -0800106
Alex Deymo390efed2016-02-18 11:00:40 -0800107 // The path where the filesystem will be mounted during post-install.
108 std::string fs_mount_dir_;
Darin Petkov6f03a3b2010-11-10 14:27:14 -0800109
Alex Deymoe5e5fe92015-10-05 09:28:19 -0700110 // The partition being processed on the list of partitions specified in the
111 // InstallPlan.
112 size_t current_partition_{0};
113
Alex Deymo0d298542016-03-30 18:31:49 -0700114 // A non-negative value representing the estimated weight of each partition
115 // passed in the install plan. The weight is used to predict the overall
116 // progress from the individual progress of each partition and should
117 // correspond to the time it takes to run it.
118 std::vector<double> partition_weight_;
119
120 // The sum of all the weights in |partition_weight_|.
121 double total_weight_{0};
122
123 // The sum of all the weights in |partition_weight_| up to but not including
124 // the |current_partition_|.
125 double accumulated_weight_{0};
126
127 // The delegate used to notify of progress updates, if any.
128 DelegateInterface* delegate_{nullptr};
129
Alex Deymob15a0b82015-11-25 20:30:40 -0300130 // The BootControlInerface used to mark the new slot as ready.
131 BootControlInterface* boot_control_;
Alex Deymo31d95ac2015-09-17 11:56:18 -0700132
Alex Deymofb905d92016-06-03 19:26:58 -0700133 // HardwareInterface used to signal powerwash.
134 HardwareInterface* hardware_;
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700135
Alex Deymofb905d92016-06-03 19:26:58 -0700136 // Whether the Powerwash was scheduled before invoking post-install script.
137 // Used for cleaning up if post-install fails.
138 bool powerwash_scheduled_{false};
Gilad Arnold30dedd82013-07-03 06:19:09 -0700139
Alex Deymod15c5462016-03-09 18:11:12 -0800140 // Postinstall command currently running, or 0 if no program running.
141 pid_t current_command_{0};
142
Ben Chan7f4bc3f2017-01-10 15:32:11 -0800143 // True if |current_command_| has been suspended by SuspendAction().
144 bool is_current_command_suspended_{false};
145
Alex Deymo0d298542016-03-30 18:31:49 -0700146 // The parent progress file descriptor used to watch for progress reports from
147 // the postinstall program and the task watching for them.
148 int progress_fd_{-1};
Tianjie55abd3c2020-06-19 00:22:59 -0700149
Hidehiko Abe493fecb2019-07-10 23:30:50 +0900150 std::unique_ptr<base::FileDescriptorWatcher::Controller> progress_controller_;
Alex Deymo0d298542016-03-30 18:31:49 -0700151
152 // A buffer of a partial read line from the progress file descriptor.
153 std::string progress_buffer_;
154
adlr@google.com3defe6a2009-12-04 20:57:17 +0000155 DISALLOW_COPY_AND_ASSIGN(PostinstallRunnerAction);
156};
157
158} // namespace chromeos_update_engine
159
Alex Deymo39910dc2015-11-09 17:04:30 -0800160#endif // UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_