main.cc revision 6b78e29f80e98c4ad009c830012682220dc9de3b
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
3// found in the LICENSE file.
4
5#include <string>
6#include <tr1/memory>
7#include <vector>
8#include <gflags/gflags.h>
9#include <glib.h>
10#include "base/command_line.h"
11#include "chromeos/obsolete_logging.h"
12#include "update_engine/dbus_constants.h"
13#include "update_engine/dbus_service.h"
14#include "update_engine/update_attempter.h"
15
16extern "C" {
17#include "update_engine/update_engine.dbusserver.h"
18}
19
20DEFINE_bool(logtostderr, false,
21            "Write logs to stderr instead of to a file in log_dir.");
22DEFINE_bool(foreground, false,
23            "Don't daemon()ize; run in foreground.");
24
25using std::string;
26using std::tr1::shared_ptr;
27using std::vector;
28
29namespace chromeos_update_engine {
30
31namespace {
32
33struct PeriodicallyUpdateArgs {
34  UpdateAttempter* update_attempter;
35  gboolean should_repeat;
36};
37
38gboolean PeriodicallyUpdate(void* arg) {
39  PeriodicallyUpdateArgs* args = reinterpret_cast<PeriodicallyUpdateArgs*>(arg);
40  args->update_attempter->Update(false);
41  return args->should_repeat;
42}
43
44void SetupDbusService(UpdateEngineService* service) {
45  DBusGConnection *bus;
46  DBusGProxy *proxy;
47  GError *error = NULL;
48
49  bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
50  if (!bus) {
51    LOG(FATAL) << "Failed to get bus";
52  }
53  proxy = dbus_g_proxy_new_for_name(bus,
54                                    DBUS_SERVICE_DBUS,
55                                    DBUS_PATH_DBUS,
56                                    DBUS_INTERFACE_DBUS);
57
58  guint32 request_name_ret;
59  if (!org_freedesktop_DBus_request_name(proxy,
60                                         kUpdateEngineServiceName,
61                                         0,
62                                         &request_name_ret,
63                                         &error)) {
64    LOG(FATAL) << "Failed to get name: " << error->message;
65  }
66  if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
67    g_warning("Got result code %u from requesting name", request_name_ret);
68    g_error_free(error);
69    LOG(FATAL) << "Got result code " << request_name_ret
70               << " from requesting name, but expected "
71               << DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
72  }
73  dbus_g_connection_register_g_object(bus,
74                                      "/org/chromium/UpdateEngine",
75                                      G_OBJECT(service));
76}
77
78}  // namespace {}
79
80}  // namespace chromeos_update_engine
81
82#include "update_engine/subprocess.h"
83
84int main(int argc, char** argv) {
85  ::g_type_init();
86  g_thread_init(NULL);
87  dbus_g_thread_init();
88  chromeos_update_engine::Subprocess::Init();
89  google::ParseCommandLineFlags(&argc, &argv, true);
90  CommandLine::Init(argc, argv);
91  logging::InitLogging("/var/log/update_engine.log",
92                       (FLAGS_logtostderr ?
93                        logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG :
94                        logging::LOG_ONLY_TO_FILE),
95                       logging::DONT_LOCK_LOG_FILE,
96                       logging::APPEND_TO_OLD_LOG_FILE);
97  if (!FLAGS_foreground)
98    PLOG_IF(FATAL, daemon(0, 0) == 1) << "daemon() failed";
99
100  LOG(INFO) << "Chrome OS Update Engine starting";
101
102  // Create the single GMainLoop
103  GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
104
105  // Create the update attempter:
106  chromeos_update_engine::UpdateAttempter update_attempter;
107
108  // Create the dbus service object:
109  dbus_g_object_type_install_info(UPDATE_ENGINE_TYPE_SERVICE,
110                                  &dbus_glib_update_engine_service_object_info);
111  UpdateEngineService* service =
112      UPDATE_ENGINE_SERVICE(g_object_new(UPDATE_ENGINE_TYPE_SERVICE, NULL));
113  service->update_attempter_ = &update_attempter;
114  update_attempter.set_dbus_service(service);
115  chromeos_update_engine::SetupDbusService(service);
116
117  // Kick off periodic updating. First, update after 2 minutes. Also, update
118  // every 30 minutes.
119  chromeos_update_engine::PeriodicallyUpdateArgs two_min_args =
120      {&update_attempter, FALSE};
121  g_timeout_add(2 * 60 * 1000,
122                &chromeos_update_engine::PeriodicallyUpdate,
123                &two_min_args);
124
125  chromeos_update_engine::PeriodicallyUpdateArgs thirty_min_args =
126      {&update_attempter, TRUE};
127  g_timeout_add(30 * 60 * 1000,
128                &chromeos_update_engine::PeriodicallyUpdate,
129                &thirty_min_args);
130
131  // Run the main loop until exit time:
132  g_main_loop_run(loop);
133
134  // Cleanup:
135  g_main_loop_unref(loop);
136  update_attempter.set_dbus_service(NULL);
137  g_object_unref(G_OBJECT(service));
138
139  LOG(INFO) << "Chrome OS Update Engine terminating";
140  return 0;
141}
142