| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "update_engine/postinstall_runner_action.h" | 5 #include "update_engine/postinstall_runner_action.h" |
| 6 #include <sys/mount.h> | 6 #include <sys/mount.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <vector> | 8 #include <vector> |
| 9 #include "update_engine/subprocess.h" | 9 #include "update_engine/subprocess.h" |
| 10 #include "update_engine/utils.h" | 10 #include "update_engine/utils.h" |
| 11 | 11 |
| 12 namespace chromeos_update_engine { | 12 namespace chromeos_update_engine { |
| 13 | 13 |
| 14 using std::string; | 14 using std::string; |
| 15 using std::vector; | 15 using std::vector; |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 const string kPostinstallScript("/postinst"); | 18 const char kPostinstallScript[] = "/postinst"; |
| 19 } | 19 } |
| 20 | 20 |
| 21 void PostinstallRunnerAction::PerformAction() { | 21 void PostinstallRunnerAction::PerformAction() { |
| 22 CHECK(HasInputObject()); | 22 CHECK(HasInputObject()); |
| 23 const InstallPlan install_plan = GetInputObject(); | 23 const InstallPlan install_plan = GetInputObject(); |
| 24 const string install_device = install_plan.install_path; | 24 const string install_device = install_plan.install_path; |
| 25 ScopedActionCompleter completer(processor_, this); | 25 ScopedActionCompleter completer(processor_, this); |
| 26 | 26 |
| 27 // Make mountpoint | 27 // Make mountpoint. |
| 28 string temp_dir; | |
| 29 TEST_AND_RETURN(utils::MakeTempDirectory("/tmp/au_postint_mount.XXXXXX", | 28 TEST_AND_RETURN(utils::MakeTempDirectory("/tmp/au_postint_mount.XXXXXX", |
| 30 &temp_dir)); | 29 &temp_rootfs_dir_)); |
| 31 ScopedDirRemover temp_dir_remover(temp_dir); | 30 ScopedDirRemover temp_dir_remover(temp_rootfs_dir_); |
| 32 | 31 |
| 33 { | 32 unsigned long mountflags = MS_RDONLY; |
| 34 // Scope for the mount | 33 int rc = mount(install_device.c_str(), |
| 35 unsigned long mountflags = MS_RDONLY; | 34 temp_rootfs_dir_.c_str(), |
| 36 | 35 "ext4", |
| 37 int rc = mount(install_device.c_str(), | |
| 38 temp_dir.c_str(), | |
| 39 "ext4", | |
| 40 mountflags, | |
| 41 NULL); | |
| 42 if (rc < 0) { | |
| 43 LOG(INFO) << "Failed to mount install part as ext4. Trying ext3."; | |
| 44 rc = mount(install_device.c_str(), | |
| 45 temp_dir.c_str(), | |
| 46 "ext3", | |
| 47 mountflags, | 36 mountflags, |
| 48 NULL); | 37 NULL); |
| 49 } | 38 if (rc < 0) { |
| 50 if (rc < 0) { | 39 LOG(INFO) << "Failed to mount install part as ext4. Trying ext3."; |
| 51 LOG(ERROR) << "Unable to mount destination device " << install_device | 40 rc = mount(install_device.c_str(), |
| 52 << " onto " << temp_dir; | 41 temp_rootfs_dir_.c_str(), |
| 53 return; | 42 "ext3", |
| 54 } | 43 mountflags, |
| 55 ScopedFilesystemUnmounter unmounter(temp_dir); | 44 NULL); |
| 56 | 45 } |
| 57 // run postinstall script | 46 if (rc < 0) { |
| 58 vector<string> command; | 47 LOG(ERROR) << "Unable to mount destination device " << install_device |
| 59 command.push_back(temp_dir + kPostinstallScript); | 48 << " onto " << temp_rootfs_dir_; |
| 60 command.push_back(install_device); | 49 return; |
| 61 rc = 0; | |
| 62 TEST_AND_RETURN(Subprocess::SynchronousExec(command, &rc)); | |
| 63 bool success = (rc == 0); | |
| 64 if (!success) { | |
| 65 LOG(ERROR) << "Postinst command failed with code: " << rc; | |
| 66 return; | |
| 67 } | |
| 68 } | 50 } |
| 69 | 51 |
| 52 temp_dir_remover.set_should_remove(false); |
| 53 completer.set_should_complete(false); |
| 54 |
| 55 // Runs the postinstall script asynchronously to free up the main loop while |
| 56 // it's running. |
| 57 vector<string> command; |
| 58 command.push_back(temp_rootfs_dir_ + kPostinstallScript); |
| 59 command.push_back(install_device); |
| 60 Subprocess::Get().Exec(command, StaticCompletePostinstall, this); |
| 61 } |
| 62 |
| 63 void PostinstallRunnerAction::CompletePostinstall(int return_code) { |
| 64 ScopedActionCompleter completer(processor_, this); |
| 65 ScopedTempUnmounter temp_unmounter(temp_rootfs_dir_); |
| 66 if (return_code != 0) { |
| 67 LOG(ERROR) << "Postinst command failed with code: " << return_code; |
| 68 return; |
| 69 } |
| 70 if (HasOutputPipe()) { | 70 if (HasOutputPipe()) { |
| 71 SetOutputObject(install_plan); | 71 CHECK(HasInputObject()); |
| 72 SetOutputObject(GetInputObject()); |
| 72 } | 73 } |
| 73 completer.set_code(kActionCodeSuccess); | 74 completer.set_code(kActionCodeSuccess); |
| 74 } | 75 } |
| 75 | 76 |
| 77 void PostinstallRunnerAction::StaticCompletePostinstall(int return_code, |
| 78 const string& output, |
| 79 void* p) { |
| 80 reinterpret_cast<PostinstallRunnerAction*>(p)->CompletePostinstall( |
| 81 return_code); |
| 82 } |
| 83 |
| 76 } // namespace chromeos_update_engine | 84 } // namespace chromeos_update_engine |
| OLD | NEW |