main.cc revision 67363ee8c3c542e8799983cc4dd375b77e8252e9
18155d081dc729d407f8ff9e95b4ef91ae14281ceMike Frysinger// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Use of this source code is governed by a BSD-style license that can be
349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// found in the LICENSE file.
449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
567363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo#include <unistd.h>
667363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo
74fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes#include <string>
84fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes#include <vector>
99d65b7b9249124a433b9a018a1952435f7f75c4dDarin Petkov
101023a6029771fb8dea867e14193df8e58a59a662Darin Petkov#include <base/at_exit.h>
111023a6029771fb8dea867e14193df8e58a59a662Darin Petkov#include <base/command_line.h>
1206c76a49bfd29c8abdb8abd5b646a6583783191aBen Chan#include <base/files/file_util.h>
131023a6029771fb8dea867e14193df8e58a59a662Darin Petkov#include <base/logging.h>
1475039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/strings/string_util.h>
1575039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/strings/stringprintf.h>
1667363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo#include <base/time/time.h>
174fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes#include <gflags/gflags.h>
1849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <glib.h>
191023a6029771fb8dea867e14193df8e58a59a662Darin Petkov#include <metrics/metrics_library.h>
204dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone#include <sys/stat.h>
2144666f97392f1f0f8be292fe6a4edcf9237540dfAlex Deymo#include <sys/types.h>
229d65b7b9249124a433b9a018a1952435f7f75c4dDarin Petkov
237f9aea2748370b0a26e1d5c36db7d8bbf3ba1245Bruno Rocha#include "update_engine/certificate_checker.h"
244e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes#include "update_engine/dbus_constants.h"
254e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes#include "update_engine/dbus_service.h"
261b9d6ae00b3c3badf9785584c2c867710f214a62Gilad Arnold#include "update_engine/dbus_wrapper_interface.h"
2744666f97392f1f0f8be292fe6a4edcf9237540dfAlex Deymo#include "update_engine/glib_utils.h"
2855f50c24c2624487b803ba2f93588494cc69e523Jay Srinivasan#include "update_engine/real_system_state.h"
293d6a2099db1d76d17b6bbbc5c8a7ee1e14e93a34Andrew de los Reyes#include "update_engine/subprocess.h"
309c0baf82049efd95230a8389769e1b3e5d001209Darin Petkov#include "update_engine/terminator.h"
314e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes#include "update_engine/update_attempter.h"
324e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyesextern "C" {
334e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes#include "update_engine/update_engine.dbusserver.h"
344e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes}
3544cab30e0ee04b277e8463785ab069e9885a9f2dAlex Vakulenko#include "update_engine/utils.h"
364e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes
374e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los ReyesDEFINE_bool(logtostderr, false,
384e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes            "Write logs to stderr instead of to a file in log_dir.");
396b78e29f80e98c4ad009c830012682220dc9de3bAndrew de los ReyesDEFINE_bool(foreground, false,
406b78e29f80e98c4ad009c830012682220dc9de3bAndrew de los Reyes            "Don't daemon()ize; run in foreground.");
414fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes
424fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesusing std::string;
434fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesusing std::vector;
444fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes
4567363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymonamespace {
4667363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymoconst int kDBusSystemMaxWaitSeconds = 2 * 60;
4767363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo}  // namespace
4867363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo
494fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesnamespace chromeos_update_engine {
504fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes
513d6a2099db1d76d17b6bbbc5c8a7ee1e14e93a34Andrew de los Reyesgboolean UpdateBootFlags(void* arg) {
5261635a95b9e6c62e31ed61fb5738c55bb5c92048Darin Petkov  reinterpret_cast<UpdateAttempter*>(arg)->UpdateBootFlags();
5361635a95b9e6c62e31ed61fb5738c55bb5c92048Darin Petkov  return FALSE;  // Don't call this callback again
5461635a95b9e6c62e31ed61fb5738c55bb5c92048Darin Petkov}
5561635a95b9e6c62e31ed61fb5738c55bb5c92048Darin Petkov
5661635a95b9e6c62e31ed61fb5738c55bb5c92048Darin Petkovgboolean BroadcastStatus(void* arg) {
5761635a95b9e6c62e31ed61fb5738c55bb5c92048Darin Petkov  reinterpret_cast<UpdateAttempter*>(arg)->BroadcastStatus();
583d6a2099db1d76d17b6bbbc5c8a7ee1e14e93a34Andrew de los Reyes  return FALSE;  // Don't call this callback again
593d6a2099db1d76d17b6bbbc5c8a7ee1e14e93a34Andrew de los Reyes}
603d6a2099db1d76d17b6bbbc5c8a7ee1e14e93a34Andrew de los Reyes
61e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthengboolean UpdateEngineStarted(gpointer user_data) {
62e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  reinterpret_cast<UpdateAttempter*>(user_data)->UpdateEngineStarted();
63d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko  return FALSE;  // Remove idle source (e.g. don't do the callback again)
64e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen}
65e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
6673520670492f3358c496698767879adcf6c03aeaAndrew de los Reyesnamespace {
6773520670492f3358c496698767879adcf6c03aeaAndrew de los Reyes
6867363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo// Wait for DBus to be ready by attempting to get the system bus up to
6967363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo// |timeout| time. Returns whether it succeeded to get the bus.
7067363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymobool WaitForDBusSystem(base::TimeDelta timeout) {
7167363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo  GError *error = nullptr;
7267363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo  DBusGConnection *bus = nullptr;
7367363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo  Clock clock;
7467363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo  base::Time deadline = clock.GetMonotonicTime() + timeout;
7567363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo
7667363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo  while (clock.GetMonotonicTime() < deadline) {
7767363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo    bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
7867363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo    if (bus)
7967363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo      return true;
8067363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo    LOG(WARNING) << "Failed to get system bus, waiting: "
8167363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo                 << utils::GetAndFreeGError(&error);
8267363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo    // Wait 1 second.
8367363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo    sleep(1);
8467363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo  }
8567363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo  LOG(ERROR) << "Failed to get system bus after " << timeout.InSeconds()
8667363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo             << " seconds.";
8767363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo  return false;
8867363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo}
8967363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo
9067363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymovoid SetupDBusService(UpdateEngineService* service) {
914e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  DBusGConnection *bus;
924e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  DBusGProxy *proxy;
9375039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko  GError *error = nullptr;
944e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes
954e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
96a0b9e777e2c571546bd6ab55356acb023834cbc3Darin Petkov  LOG_IF(FATAL, !bus) << "Failed to get bus: "
97a0b9e777e2c571546bd6ab55356acb023834cbc3Darin Petkov                      << utils::GetAndFreeGError(&error);
984e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  proxy = dbus_g_proxy_new_for_name(bus,
994e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes                                    DBUS_SERVICE_DBUS,
1004e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes                                    DBUS_PATH_DBUS,
1014e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes                                    DBUS_INTERFACE_DBUS);
1024e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  guint32 request_name_ret;
1034e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  if (!org_freedesktop_DBus_request_name(proxy,
1044e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes                                         kUpdateEngineServiceName,
1054e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes                                         0,
1064e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes                                         &request_name_ret,
1074e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes                                         &error)) {
108a0b9e777e2c571546bd6ab55356acb023834cbc3Darin Petkov    LOG(FATAL) << "Failed to get name: " << utils::GetAndFreeGError(&error);
1094fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes  }
1104e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
1114e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes    g_warning("Got result code %u from requesting name", request_name_ret);
1124e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes    LOG(FATAL) << "Got result code " << request_name_ret
1134e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes               << " from requesting name, but expected "
1144e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes               << DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
1154e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  }
1164e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  dbus_g_connection_register_g_object(bus,
1174e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes                                      "/org/chromium/UpdateEngine",
1184e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes                                      G_OBJECT(service));
1194fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes}
1204fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes
12130291edee8e2f7646b540b00672c81b442386ed6Darin Petkovvoid SetupLogSymlink(const string& symlink_path, const string& log_path) {
12230291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  // TODO(petkov): To ensure a smooth transition between non-timestamped and
12330291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  // timestamped logs, move an existing log to start the first timestamped
12430291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  // one. This code can go away once all clients are switched to this version or
12530291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  // we stop caring about the old-style logs.
12630291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  if (utils::FileExists(symlink_path.c_str()) &&
12730291edee8e2f7646b540b00672c81b442386ed6Darin Petkov      !utils::IsSymlink(symlink_path.c_str())) {
12875039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko    base::ReplaceFile(base::FilePath(symlink_path),
12975039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko                      base::FilePath(log_path),
13075039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko                      nullptr);
13130291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  }
13275039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko  base::DeleteFile(base::FilePath(symlink_path), true);
13330291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  if (symlink(log_path.c_str(), symlink_path.c_str()) == -1) {
13430291edee8e2f7646b540b00672c81b442386ed6Darin Petkov    PLOG(ERROR) << "Unable to create symlink " << symlink_path
13530291edee8e2f7646b540b00672c81b442386ed6Darin Petkov                << " pointing at " << log_path;
13630291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  }
13730291edee8e2f7646b540b00672c81b442386ed6Darin Petkov}
13873520670492f3358c496698767879adcf6c03aeaAndrew de los Reyes
13930291edee8e2f7646b540b00672c81b442386ed6Darin Petkovstring GetTimeAsString(time_t utime) {
14030291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  struct tm tm;
141d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko  CHECK_EQ(localtime_r(&utime, &tm), &tm);
14230291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  char str[16];
143d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko  CHECK_EQ(strftime(str, sizeof(str), "%Y%m%d-%H%M%S", &tm), 15u);
14430291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  return str;
14530291edee8e2f7646b540b00672c81b442386ed6Darin Petkov}
14649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
14730291edee8e2f7646b540b00672c81b442386ed6Darin Petkovstring SetupLogFile(const string& kLogsRoot) {
14830291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  const string kLogSymlink = kLogsRoot + "/update_engine.log";
14930291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  const string kLogsDir = kLogsRoot + "/update_engine";
15030291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  const string kLogPath =
15175039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko      base::StringPrintf("%s/update_engine.%s",
15275039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko                         kLogsDir.c_str(),
15375039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko                         GetTimeAsString(::time(nullptr)).c_str());
15430291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  mkdir(kLogsDir.c_str(), 0755);
15530291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  SetupLogSymlink(kLogSymlink, kLogPath);
15630291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  return kLogSymlink;
15730291edee8e2f7646b540b00672c81b442386ed6Darin Petkov}
15830291edee8e2f7646b540b00672c81b442386ed6Darin Petkov
15930291edee8e2f7646b540b00672c81b442386ed6Darin Petkovvoid SetupLogging() {
16075039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko  logging::LoggingSettings log_settings;
16175039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko  log_settings.lock_log = logging::DONT_LOCK_LOG_FILE;
16275039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko  log_settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE;
16375039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko
16430291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  if (FLAGS_logtostderr) {
16575039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko    // Log to stderr initially.
16675039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko    log_settings.log_file = nullptr;
16775039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko    log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
16875039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko  } else {
16975039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko    const string log_file = SetupLogFile("/var/log");
17075039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko    log_settings.log_file = log_file.c_str();
17175039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko    log_settings.logging_dest = logging::LOG_TO_FILE;
17230291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  }
17375039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko
17475039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko  logging::InitLogging(log_settings);
17530291edee8e2f7646b540b00672c81b442386ed6Darin Petkov}
176000d895da247697f4e4e0c67a3a847f71fca8eb9Andrew de los Reyes
177d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko}  // namespace
17830291edee8e2f7646b540b00672c81b442386ed6Darin Petkov}  // namespace chromeos_update_engine
17949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
18049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comint main(int argc, char** argv) {
1814e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  ::g_type_init();
18246bf5c8663bd0b7be0809d3d5ea6a844f4c6219fBen Chan  dbus_threads_init_default();
1835c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov  base::AtExitManager exit_manager;  // Required for base/rand_util.h.
1849c0baf82049efd95230a8389769e1b3e5d001209Darin Petkov  chromeos_update_engine::Terminator::Init();
185c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  chromeos_update_engine::Subprocess::Init();
1864fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes  google::ParseCommandLineFlags(&argc, &argv, true);
1874e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  CommandLine::Init(argc, argv);
18830291edee8e2f7646b540b00672c81b442386ed6Darin Petkov  chromeos_update_engine::SetupLogging();
1896b78e29f80e98c4ad009c830012682220dc9de3bAndrew de los Reyes  if (!FLAGS_foreground)
1906b78e29f80e98c4ad009c830012682220dc9de3bAndrew de los Reyes    PLOG_IF(FATAL, daemon(0, 0) == 1) << "daemon() failed";
1916b78e29f80e98c4ad009c830012682220dc9de3bAndrew de los Reyes
1924fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes  LOG(INFO) << "Chrome OS Update Engine starting";
193a4a8a8ccc2d9e0285728ed247b43f09433e63323Darin Petkov
1944dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone  // Ensure that all written files have safe permissions.
1954dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone  // This is a mask, so we _block_ execute for the owner, and ALL
1964dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone  // permissions for other users.
1974dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone  // Done _after_ log file creation.
1984dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone  umask(S_IXUSR | S_IRWXG | S_IRWXO);
1994dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone
2004fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes  // Create the single GMainLoop
20163b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
2024fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes
20367363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo  // Wait up to 2 minutes for DBus to be ready.
20467363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo  LOG_IF(FATAL, !chromeos_update_engine::WaitForDBusSystem(
20567363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo      base::TimeDelta::FromSeconds(kDBusSystemMaxWaitSeconds)))
20667363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo      << "Failed to initialize DBus, aborting.";
20767363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo
208f057205065339c54d3403263f049e2ea69417665Jay Srinivasan  chromeos_update_engine::RealSystemState real_system_state;
2097d623ebf9eee346fdeee71f1ccb32ebaf4bd3318Nam T. Nguyen  LOG_IF(ERROR, !real_system_state.Initialize())
2106f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan      << "Failed to initialize system state.";
21155f50c24c2624487b803ba2f93588494cc69e523Jay Srinivasan  chromeos_update_engine::UpdateAttempter *update_attempter =
21255f50c24c2624487b803ba2f93588494cc69e523Jay Srinivasan      real_system_state.update_attempter();
21355f50c24c2624487b803ba2f93588494cc69e523Jay Srinivasan  CHECK(update_attempter);
2149d65b7b9249124a433b9a018a1952435f7f75c4dDarin Petkov
2157f9aea2748370b0a26e1d5c36db7d8bbf3ba1245Bruno Rocha  // Sets static members for the certificate checker.
2166f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan  chromeos_update_engine::CertificateChecker::set_system_state(
2176f6ea00aa8c4cf54b6842be32ca1226854c24f78Jay Srinivasan      &real_system_state);
2187f9aea2748370b0a26e1d5c36db7d8bbf3ba1245Bruno Rocha  chromeos_update_engine::OpenSSLWrapper openssl_wrapper;
2197f9aea2748370b0a26e1d5c36db7d8bbf3ba1245Bruno Rocha  chromeos_update_engine::CertificateChecker::set_openssl_wrapper(
2207f9aea2748370b0a26e1d5c36db7d8bbf3ba1245Bruno Rocha      &openssl_wrapper);
2217f9aea2748370b0a26e1d5c36db7d8bbf3ba1245Bruno Rocha
2224e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  // Create the dbus service object:
2234e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  dbus_g_object_type_install_info(UPDATE_ENGINE_TYPE_SERVICE,
2244e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes                                  &dbus_glib_update_engine_service_object_info);
2257e8ac06833aba4d851257fe287b38c98af4e226bAlex Deymo  UpdateEngineService* service = update_engine_service_new();
226ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  service->system_state_ = &real_system_state;
22755f50c24c2624487b803ba2f93588494cc69e523Jay Srinivasan  update_attempter->set_dbus_service(service);
22867363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo  chromeos_update_engine::SetupDBusService(service);
2294e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes
230ec7f91625b799abf67ea3119490f2f1de8e4e677Gilad Arnold  // Initiate update checks.
231ec7f91625b799abf67ea3119490f2f1de8e4e677Gilad Arnold  update_attempter->ScheduleUpdates();
23273520670492f3358c496698767879adcf6c03aeaAndrew de los Reyes
233eee26eeb4ff86ad3a19cffff22db6325057ed97eDarin Petkov  // Update boot flags after 45 seconds.
234eee26eeb4ff86ad3a19cffff22db6325057ed97eDarin Petkov  g_timeout_add_seconds(45,
235eee26eeb4ff86ad3a19cffff22db6325057ed97eDarin Petkov                        &chromeos_update_engine::UpdateBootFlags,
23655f50c24c2624487b803ba2f93588494cc69e523Jay Srinivasan                        update_attempter);
2373d6a2099db1d76d17b6bbbc5c8a7ee1e14e93a34Andrew de los Reyes
23861635a95b9e6c62e31ed61fb5738c55bb5c92048Darin Petkov  // Broadcast the update engine status on startup to ensure consistent system
23961635a95b9e6c62e31ed61fb5738c55bb5c92048Darin Petkov  // state on crashes.
24055f50c24c2624487b803ba2f93588494cc69e523Jay Srinivasan  g_idle_add(&chromeos_update_engine::BroadcastStatus, update_attempter);
24161635a95b9e6c62e31ed61fb5738c55bb5c92048Darin Petkov
242e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  // Run the UpdateEngineStarted() method on |update_attempter|.
243e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen  g_idle_add(&chromeos_update_engine::UpdateEngineStarted, update_attempter);
244e4c58bf01b6ccc915c6b261007dbb75241ed69b8David Zeuthen
2454e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  // Run the main loop until exit time:
2464fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes  g_main_loop_run(loop);
2474e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes
2484e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  // Cleanup:
2494fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes  g_main_loop_unref(loop);
25075039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko  update_attempter->set_dbus_service(nullptr);
2514e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes  g_object_unref(G_OBJECT(service));
2524fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes
2534fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes  LOG(INFO) << "Chrome OS Update Engine terminating";
25449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  return 0;
25549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}
256