AU: Many minor cleanup changes
postinstall: Run postinst twice, once for pre-commit (ie, before we
mark the install partition bootable in the partition table), and
post-commit (for after we do). This behavior is needed for specific
types of firmware update.
download action: flush caches, as we found was necessary in
memento_updater.sh
omaha request prep action: update the names of keys we look for in
lsb-release, also get the AU server url from a file, rather than
hard-code it.
set bootable flag action: GPT support.
also, some misc utility functions.
BUG=None
TEST=attached unittests
Review URL: http://codereview.chromium.org/1881001
diff --git a/postinstall_runner_action.cc b/postinstall_runner_action.cc
index 98de1bd..e8f5cc2 100644
--- a/postinstall_runner_action.cc
+++ b/postinstall_runner_action.cc
@@ -5,45 +5,70 @@
#include "update_engine/postinstall_runner_action.h"
#include <sys/mount.h>
#include <stdlib.h>
+#include <vector>
+#include "update_engine/subprocess.h"
#include "update_engine/utils.h"
namespace chromeos_update_engine {
using std::string;
+using std::vector;
namespace {
-const string kMountPath(string(utils::kStatefulPartition) + "/au_destination");
const string kPostinstallScript("/postinst");
}
void PostinstallRunnerAction::PerformAction() {
CHECK(HasInputObject());
- const string install_device = GetInputObject();
+ const InstallPlan install_plan = GetInputObject();
+ const string install_device = install_plan.install_path;
+ ScopedActionCompleter completer(processor_, this);
+
+ utils::BootLoader boot_loader;
+ TEST_AND_RETURN(utils::GetBootloader(&boot_loader));
- int rc = mount(install_device.c_str(), kMountPath.c_str(), "ext3", 0, NULL);
- if (rc < 0) {
- LOG(ERROR) << "Unable to mount destination device " << install_device
- << " onto " << kMountPath;
- processor_->ActionComplete(this, false);
- return;
+ bool read_only = (boot_loader == utils::BootLoader_CHROME_FIRMWARE);
+
+ // Make mountpoint
+ string temp_dir;
+ TEST_AND_RETURN(utils::MakeTempDirectory("/tmp/au_postint_mount.XXXXXX",
+ &temp_dir));
+ ScopedDirRemover temp_dir_remover(temp_dir);
+
+ {
+ // Scope for the mount
+ unsigned long mountflags = read_only ? MS_RDONLY : 0;
+
+ int rc = mount(install_device.c_str(),
+ temp_dir.c_str(),
+ "ext3",
+ mountflags,
+ NULL);
+ if (rc < 0) {
+ LOG(ERROR) << "Unable to mount destination device " << install_device
+ << " onto " << temp_dir;
+ return;
+ }
+ ScopedFilesystemUnmounter unmounter(temp_dir);
+
+ // run postinstall script
+ vector<string> command;
+ command.push_back(temp_dir + kPostinstallScript);
+ command.push_back(install_device);
+ command.push_back(precommit_ ? "" : "--postcommit");
+ rc = 0;
+ TEST_AND_RETURN(Subprocess::SynchronousExec(command, &rc));
+ bool success = (rc == 0);
+ if (!success) {
+ LOG(ERROR) << "Postinst command failed with code: " << rc;
+ return;
+ }
}
- // run postinstall script
- rc = system((kMountPath + kPostinstallScript + " " + install_device).c_str());
- bool success = (rc == 0);
- if (!success) {
- LOG(ERROR) << "Postinst command failed with code: " << rc;
+ if (HasOutputPipe()) {
+ SetOutputObject(install_plan);
}
-
- rc = umount(kMountPath.c_str());
- if (rc < 0) {
- // non-fatal
- LOG(ERROR) << "Unable to umount destination device";
- }
- if (success && HasOutputPipe()) {
- SetOutputObject(install_device);
- }
- processor_->ActionComplete(this, success);
+ completer.set_success(true);
}
} // namespace chromeos_update_engine