blob: 358358e400c2e2896335da2012f6f7dd63fd852b [file] [log] [blame]
Chris Sosa45d9f102014-03-24 11:18:54 -07001// Copyright 2014 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
7#include <base/at_exit.h>
8#include <base/command_line.h>
9#include <base/file_util.h>
10#include <base/files/file_path.h>
11#include <base/logging.h>
12#include <base/message_loop/message_loop.h>
13#include <base/strings/string_util.h>
14#include <base/strings/stringprintf.h>
Christopher Wileyb76eb292014-05-05 16:09:16 -070015#include <dbus/bus.h>
Chris Sosaababc5c2014-04-09 15:42:01 -070016#include <sysexits.h>
Chris Sosa45d9f102014-03-24 11:18:54 -070017
Christopher Wiley90016242014-04-01 17:33:29 -070018#include "buffet/async_event_sequencer.h"
Christopher Wileyadb901d2014-05-07 09:58:45 -070019#include "buffet/dbus_constants.h"
20#include "buffet/exported_object_manager.h"
Christopher Wileya4915c42014-03-27 14:45:37 -070021#include "buffet/manager.h"
Chris Sosa45d9f102014-03-24 11:18:54 -070022
Christopher Wiley90016242014-04-01 17:33:29 -070023using buffet::dbus_utils::AsyncEventSequencer;
Christopher Wileyadb901d2014-05-07 09:58:45 -070024using buffet::dbus_utils::ExportedObjectManager;
Christopher Wiley90016242014-04-01 17:33:29 -070025
Chris Sosa45d9f102014-03-24 11:18:54 -070026namespace {
27
Chris Sosaababc5c2014-04-09 15:42:01 -070028static const char kLogRoot[] = "logroot";
29static const char kHelp[] = "help";
30static const char kDefaultLogRoot[] = "/var/log";
31
32// The help message shown if help flag is passed to the program.
33static const char kHelpMessage[] = "\n"
34 "Available Switches: \n"
35 " --logroot=/path/to/logroot\n"
36 " Specifies parent directory to put buffet logs in.\n";
37
Chris Sosa45d9f102014-03-24 11:18:54 -070038// Returns |utime| as a string
39std::string GetTimeAsString(time_t utime) {
40 struct tm tm;
41 CHECK_EQ(localtime_r(&utime, &tm), &tm);
42 char str[16];
43 CHECK_EQ(strftime(str, sizeof(str), "%Y%m%d-%H%M%S", &tm), 15UL);
44 return std::string(str);
45}
46
47// Sets up a symlink to point to log file.
48void SetupLogSymlink(const std::string& symlink_path,
49 const std::string& log_path) {
50 base::DeleteFile(base::FilePath(symlink_path), true);
51 if (symlink(log_path.c_str(), symlink_path.c_str()) == -1) {
52 LOG(ERROR) << "Unable to create symlink " << symlink_path
53 << " pointing at " << log_path;
54 }
55}
56
Chris Sosaababc5c2014-04-09 15:42:01 -070057// Creates new log file based on timestamp in |log_root|/buffet.
58std::string SetupLogFile(const std::string& log_root) {
59 const auto log_symlink = log_root + "/buffet.log";
60 const auto logs_dir = log_root + "/buffet";
Chris Sosa45d9f102014-03-24 11:18:54 -070061 const auto log_path =
62 base::StringPrintf("%s/buffet.%s",
63 logs_dir.c_str(),
64 GetTimeAsString(::time(NULL)).c_str());
65 mkdir(logs_dir.c_str(), 0755);
66 SetupLogSymlink(log_symlink, log_path);
67 return log_symlink;
68}
69
70// Sets up logging for buffet.
Chris Sosaababc5c2014-04-09 15:42:01 -070071void SetupLogging(const std::string& log_root) {
72 const auto log_file = SetupLogFile(log_root);
Chris Sosa45d9f102014-03-24 11:18:54 -070073 logging::LoggingSettings settings;
74 settings.logging_dest = logging::LOG_TO_ALL;
75 settings.log_file = log_file.c_str();
76 settings.lock_log = logging::DONT_LOCK_LOG_FILE;
77 settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE;
78 logging::InitLogging(settings);
79}
80
Christopher Wiley90016242014-04-01 17:33:29 -070081void TakeServiceOwnership(scoped_refptr<dbus::Bus> bus, bool success) {
82 // Success should always be true since we've said that failures are
83 // fatal.
84 CHECK(success) << "Init of one or more objects has failed.";
85 CHECK(bus->RequestOwnershipAndBlock(buffet::dbus_constants::kServiceName,
86 dbus::Bus::REQUIRE_PRIMARY))
87 << "Unable to take ownership of " << buffet::dbus_constants::kServiceName;
88}
89
90void EnterMainLoop(base::MessageLoopForIO* message_loop,
91 scoped_refptr<dbus::Bus> bus) {
92 scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer());
Christopher Wileyadb901d2014-05-07 09:58:45 -070093 ExportedObjectManager object_manager(
94 bus, dbus::ObjectPath(buffet::dbus_constants::kRootServicePath));
95 buffet::Manager manager(bus, object_manager.AsWeakPtr());
96 object_manager.Init(
97 sequencer->GetHandler("ObjectManager.Init() failed.", true));
Christopher Wiley90016242014-04-01 17:33:29 -070098 manager.Init(sequencer->GetHandler("Manager.Init() failed.", true));
99 sequencer->OnAllTasksCompletedCall(
100 {base::Bind(&TakeServiceOwnership, bus)});
101 // Release our handle on the sequencer so that it gets deleted after
102 // both callbacks return.
103 sequencer = nullptr;
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -0700104
Christopher Wiley90016242014-04-01 17:33:29 -0700105 LOG(INFO) << "Entering mainloop.";
106 message_loop->Run();
107}
108
Chris Sosa45d9f102014-03-24 11:18:54 -0700109} // namespace
110
111int main(int argc, char* argv[]) {
112 // Parse the args and check for extra args.
113 CommandLine::Init(argc, argv);
Chris Sosaababc5c2014-04-09 15:42:01 -0700114 CommandLine* cl = CommandLine::ForCurrentProcess();
Chris Sosa45d9f102014-03-24 11:18:54 -0700115
Chris Sosaababc5c2014-04-09 15:42:01 -0700116 if (cl->HasSwitch(kHelp)) {
117 LOG(INFO) << kHelpMessage;
118 return EX_USAGE;
119 }
120
121 std::string log_root = std::string(kDefaultLogRoot);
122 if (cl->HasSwitch(kLogRoot)) {
123 log_root = cl->GetSwitchValueASCII(kLogRoot);
124 }
125
126 SetupLogging(log_root);
Chris Sosa45d9f102014-03-24 11:18:54 -0700127
128 base::AtExitManager at_exit_manager;
129 base::MessageLoopForIO message_loop;
130
Christopher Wiley90016242014-04-01 17:33:29 -0700131 dbus::Bus::Options options;
132 // TODO(sosa): Should this be on the system bus?
133 options.bus_type = dbus::Bus::SYSTEM;
134 scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
135 CHECK(bus->Connect());
136 // Our top level objects expect the bus to exist in a connected state for
137 // the duration of their lifetimes.
138 EnterMainLoop(&message_loop, bus);
139 bus->ShutdownAndBlock();
Chris Sosa45d9f102014-03-24 11:18:54 -0700140
Chris Sosaababc5c2014-04-09 15:42:01 -0700141 return EX_OK;
Chris Sosa45d9f102014-03-24 11:18:54 -0700142}