blob: e8f5cc2135a93e17da862e73b42b7e29028ed718 [file] [log] [blame]
adlr@google.com3defe6a2009-12-04 20:57:17 +00001// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "update_engine/postinstall_runner_action.h"
6#include <sys/mount.h>
7#include <stdlib.h>
Andrew de los Reyesf9714432010-05-04 10:21:23 -07008#include <vector>
9#include "update_engine/subprocess.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000010#include "update_engine/utils.h"
11
12namespace chromeos_update_engine {
13
14using std::string;
Andrew de los Reyesf9714432010-05-04 10:21:23 -070015using std::vector;
adlr@google.com3defe6a2009-12-04 20:57:17 +000016
17namespace {
adlr@google.com3defe6a2009-12-04 20:57:17 +000018const string kPostinstallScript("/postinst");
19}
20
21void PostinstallRunnerAction::PerformAction() {
22 CHECK(HasInputObject());
Andrew de los Reyesf9714432010-05-04 10:21:23 -070023 const InstallPlan install_plan = GetInputObject();
24 const string install_device = install_plan.install_path;
25 ScopedActionCompleter completer(processor_, this);
26
27 utils::BootLoader boot_loader;
28 TEST_AND_RETURN(utils::GetBootloader(&boot_loader));
adlr@google.com3defe6a2009-12-04 20:57:17 +000029
Andrew de los Reyesf9714432010-05-04 10:21:23 -070030 bool read_only = (boot_loader == utils::BootLoader_CHROME_FIRMWARE);
31
32 // Make mountpoint
33 string temp_dir;
34 TEST_AND_RETURN(utils::MakeTempDirectory("/tmp/au_postint_mount.XXXXXX",
35 &temp_dir));
36 ScopedDirRemover temp_dir_remover(temp_dir);
37
38 {
39 // Scope for the mount
40 unsigned long mountflags = read_only ? MS_RDONLY : 0;
41
42 int rc = mount(install_device.c_str(),
43 temp_dir.c_str(),
44 "ext3",
45 mountflags,
46 NULL);
47 if (rc < 0) {
48 LOG(ERROR) << "Unable to mount destination device " << install_device
49 << " onto " << temp_dir;
50 return;
51 }
52 ScopedFilesystemUnmounter unmounter(temp_dir);
53
54 // run postinstall script
55 vector<string> command;
56 command.push_back(temp_dir + kPostinstallScript);
57 command.push_back(install_device);
58 command.push_back(precommit_ ? "" : "--postcommit");
59 rc = 0;
60 TEST_AND_RETURN(Subprocess::SynchronousExec(command, &rc));
61 bool success = (rc == 0);
62 if (!success) {
63 LOG(ERROR) << "Postinst command failed with code: " << rc;
64 return;
65 }
adlr@google.com3defe6a2009-12-04 20:57:17 +000066 }
67
Andrew de los Reyesf9714432010-05-04 10:21:23 -070068 if (HasOutputPipe()) {
69 SetOutputObject(install_plan);
adlr@google.com3defe6a2009-12-04 20:57:17 +000070 }
Andrew de los Reyesf9714432010-05-04 10:21:23 -070071 completer.set_success(true);
adlr@google.com3defe6a2009-12-04 20:57:17 +000072}
73
74} // namespace chromeos_update_engine