daemon_task.cc revision 5988a853c0faf8b5cf4a9c6a504a29a7098095a9
124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu// Copyright 2015 The Chromium OS Authors. All rights reserved.
224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu// Use of this source code is governed by a BSD-style license that can be
324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu// found in the LICENSE file.
424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/chromeos_daemon.h"
624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include <string>
824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include <base/bind.h>
1024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
1124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/control_interface.h"
1224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/dhcp/dhcp_provider.h"
1324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/diagnostics_reporter.h"
1424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/error.h"
15dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu#include "shill/event_dispatcher.h"
1624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/logging.h"
1724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/manager.h"
1824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/net/ndisc.h"
1924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/net/rtnl_handler.h"
20dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu#include "shill/process_manager.h"
2124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/routing_table.h"
2224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/shill_config.h"
2324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
2424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#if !defined(DISABLE_WIFI)
2524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/net/netlink_manager.h"
2624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/net/nl80211_message.h"
2724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#endif  // DISABLE_WIFI
2824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
2924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiuusing base::Bind;
3024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiuusing base::Unretained;
3124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiuusing std::string;
3224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiuusing std::vector;
3324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
3424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiunamespace shill {
3524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
3624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiunamespace Logging {
3724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiustatic auto kModuleLogScope = ScopeLogger::kDaemon;
3824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiustatic string ObjectID(ChromeosDaemon* d) { return "(shill_daemon)"; }
3924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
4024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
4124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
4224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter QiuChromeosDaemon::ChromeosDaemon(const Settings& settings,
43dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu                               Config* config)
44dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu    : settings_(settings), config_(config) {}
4524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
4624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter QiuChromeosDaemon::~ChromeosDaemon() {}
4724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
48dde57ef146d3868130cd8597e805b42395440c9aPeter Qiuvoid ChromeosDaemon::Init(ControlInterface* control,
49dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu                          EventDispatcher* dispatcher) {
50dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  control_.reset(control);
51dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  dispatcher_ = dispatcher;
52dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  metrics_.reset(new Metrics(dispatcher_));
53dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  rtnl_handler_ = RTNLHandler::GetInstance();
54dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  routing_table_ = RoutingTable::GetInstance();
55dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  dhcp_provider_ = DHCPProvider::GetInstance();
56dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  process_manager_ = ProcessManager::GetInstance();
57dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu#if !defined(DISABLE_WIFI)
58dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  netlink_manager_ = NetlinkManager::GetInstance();
59dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  callback80211_metrics_.reset(new Callback80211Metrics(metrics_.get()));
60dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu#endif
61dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  manager_.reset(new Manager(control_.get(),
62dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu                             dispatcher_,
63dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu                             metrics_.get(),
64dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu                             &glib_,
65dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu                             config_->GetRunDirectory(),
66dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu                             config_->GetStorageDirectory(),
67dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu                             config_->GetUserStorageDirectory()));
68dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  ApplySettings();
69dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu}
70dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu
71dde57ef146d3868130cd8597e805b42395440c9aPeter Qiuvoid ChromeosDaemon::ApplySettings() {
72dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  for (const auto& device_name : settings_.device_blacklist) {
7324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    manager_->AddDeviceToBlackList(device_name);
7424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  }
7524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  Error error;
76dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  manager_->SetTechnologyOrder(settings_.default_technology_order, &error);
7724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  CHECK(error.IsSuccess());  // Command line should have been validated.
78dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  manager_->SetIgnoreUnknownEthernet(settings_.ignore_unknown_ethernet);
79dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  if (settings_.use_portal_list) {
80dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu    manager_->SetStartupPortalList(settings_.portal_list);
8124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  }
82dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  if (settings_.passive_mode) {
8324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    manager_->SetPassiveMode();
8424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  }
85dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  manager_->SetPrependDNSServers(settings_.prepend_dns_servers);
86dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  if (settings_.minimum_mtu) {
87dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu    manager_->SetMinimumMTU(settings_.minimum_mtu);
8824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  }
89dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  manager_->SetAcceptHostnameFrom(settings_.accept_hostname_from);
90dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  manager_->SetDHCPv6EnabledDevices(settings_.dhcpv6_enabled_devices);
9124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
9224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
935988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiuvoid ChromeosDaemon::Quit(const base::Closure& completion_callback) {
9424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  SLOG(this, 1) << "Starting termination actions.";
955988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu  termination_completed_callback_ = completion_callback;
9624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  if (!manager_->RunTerminationActionsAndNotifyMetrics(
9724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu          Bind(&ChromeosDaemon::TerminationActionsCompleted,
9824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu               Unretained(this)))) {
9924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    SLOG(this, 1) << "No termination actions were run";
10024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    StopAndReturnToMain();
10124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  }
10224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
10324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
10424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiuvoid ChromeosDaemon::TerminationActionsCompleted(const Error& error) {
10524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  SLOG(this, 1) << "Finished termination actions.  Result: " << error;
10624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  metrics_->NotifyTerminationActionsCompleted(error.IsSuccess());
10724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
10824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // Daemon::TerminationActionsCompleted() should not directly call
10924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // Daemon::Stop(). Otherwise, it could lead to the call sequence below. That
11024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // is not safe as the HookTable's start callback only holds a weak pointer to
11124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // the Cellular object, which is destroyed in midst of the
11224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // Cellular::OnTerminationCompleted() call. We schedule the
11324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // Daemon::StopAndReturnToMain() call through the message loop instead.
11424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //
11524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // Daemon::Quit
11624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //   -> Manager::RunTerminationActionsAndNotifyMetrics
11724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //     -> Manager::RunTerminationActions
11824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //       -> HookTable::Run
11924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //         ...
12024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //         -> Cellular::OnTerminationCompleted
12124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //           -> Manager::TerminationActionComplete
12224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //             -> HookTable::ActionComplete
12324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //               -> Daemon::TerminationActionsCompleted
12424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //                 -> Daemon::Stop
12524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //                   -> Manager::Stop
12624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //                     -> DeviceInfo::Stop
12724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //                       -> Cellular::~Cellular
12824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //           -> Manager::RemoveTerminationAction
129dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  dispatcher_->PostTask(
13024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu      Bind(&ChromeosDaemon::StopAndReturnToMain, Unretained(this)));
13124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
13224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
13324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiuvoid ChromeosDaemon::StopAndReturnToMain() {
13424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  Stop();
1355988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu  if (!termination_completed_callback_.is_null()) {
1365988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu    termination_completed_callback_.Run();
1375988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu  }
13824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
13924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
14024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiuvoid ChromeosDaemon::Start() {
14124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  glib_.TypeInit();
14224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  metrics_->Start();
14324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  rtnl_handler_->Start(
14424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu      RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
14524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu      RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE | RTMGRP_ND_USEROPT);
14624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  routing_table_->Start();
147dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  dhcp_provider_->Init(control_.get(), dispatcher_, metrics_.get());
148dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  process_manager_->Init(dispatcher_);
14924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#if !defined(DISABLE_WIFI)
15024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  if (netlink_manager_) {
15124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    netlink_manager_->Init();
15224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    uint16_t nl80211_family_id = netlink_manager_->GetFamily(
15324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu        Nl80211Message::kMessageTypeString,
15424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu        Bind(&Nl80211Message::CreateMessage));
15524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    if (nl80211_family_id == NetlinkMessage::kIllegalMessageType) {
15624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu      LOG(FATAL) << "Didn't get a legal message type for 'nl80211' messages.";
15724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    }
15824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    Nl80211Message::SetMessageType(nl80211_family_id);
15924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    netlink_manager_->Start();
16024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
16124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    // Install handlers for NetlinkMessages that don't have specific handlers
16224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    // (which are registered by message sequence number).
16324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    netlink_manager_->AddBroadcastHandler(Bind(
16424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu        &Callback80211Metrics::CollectDisconnectStatistics,
165dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu        callback80211_metrics_->AsWeakPtr()));
16624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  }
16724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#endif  // DISABLE_WIFI
16824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
16924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  manager_->Start();
17024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
17124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
17224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiuvoid ChromeosDaemon::Stop() {
17324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  manager_->Stop();
17424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  manager_ = nullptr;  // Release manager resources, including DBus adaptor.
1755988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu#if !defined(DISABLE_WIFI)
1765988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu  callback80211_metrics_ = nullptr;
1775988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu#endif  // DISABLE_WIFI
17824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  metrics_->Stop();
17924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  dhcp_provider_->Stop();
1805988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu  metrics_ = nullptr;
1815988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu  control_ = nullptr;
18224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
18324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
18424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}  // namespace shill
185