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