main.cc revision aea4c1cea20dda7ae7e85fc8924a2d784f70d806
1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2012 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 1767363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo#include <unistd.h> 1867363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo 194fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes#include <string> 209d65b7b9249124a433b9a018a1952435f7f75c4dDarin Petkov 211023a6029771fb8dea867e14193df8e58a59a662Darin Petkov#include <base/at_exit.h> 221023a6029771fb8dea867e14193df8e58a59a662Darin Petkov#include <base/command_line.h> 2306c76a49bfd29c8abdb8abd5b646a6583783191aBen Chan#include <base/files/file_util.h> 241023a6029771fb8dea867e14193df8e58a59a662Darin Petkov#include <base/logging.h> 2575039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/strings/string_util.h> 2675039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/strings/stringprintf.h> 27d570820920e030fefd9644fb5427b538160af1a1Steve Fung#include <chromeos/flag_helper.h> 28b7ca096f98a43ebbf412f1b2d3d15bb184f871f8Alex Deymo#include <chromeos/message_loops/base_message_loop.h> 291023a6029771fb8dea867e14193df8e58a59a662Darin Petkov#include <metrics/metrics_library.h> 304dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone#include <sys/stat.h> 3144666f97392f1f0f8be292fe6a4edcf9237540dfAlex Deymo#include <sys/types.h> 329d65b7b9249124a433b9a018a1952435f7f75c4dDarin Petkov 33b7ca096f98a43ebbf412f1b2d3d15bb184f871f8Alex Deymo#include "update_engine/daemon.h" 349c0baf82049efd95230a8389769e1b3e5d001209Darin Petkov#include "update_engine/terminator.h" 3544cab30e0ee04b277e8463785ab069e9885a9f2dAlex Vakulenko#include "update_engine/utils.h" 364e9b9f4d57a0c95fb1b9281077f0eef5fdf5e345Andrew de los Reyes 374fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesusing std::string; 3867363ee8c3c542e8799983cc4dd375b77e8252e9Alex Deymo 394fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesnamespace chromeos_update_engine { 4073520670492f3358c496698767879adcf6c03aeaAndrew de los Reyesnamespace { 4173520670492f3358c496698767879adcf6c03aeaAndrew de los Reyes 4230291edee8e2f7646b540b00672c81b442386ed6Darin Petkovvoid SetupLogSymlink(const string& symlink_path, const string& log_path) { 4330291edee8e2f7646b540b00672c81b442386ed6Darin Petkov // TODO(petkov): To ensure a smooth transition between non-timestamped and 4430291edee8e2f7646b540b00672c81b442386ed6Darin Petkov // timestamped logs, move an existing log to start the first timestamped 4530291edee8e2f7646b540b00672c81b442386ed6Darin Petkov // one. This code can go away once all clients are switched to this version or 4630291edee8e2f7646b540b00672c81b442386ed6Darin Petkov // we stop caring about the old-style logs. 4730291edee8e2f7646b540b00672c81b442386ed6Darin Petkov if (utils::FileExists(symlink_path.c_str()) && 4830291edee8e2f7646b540b00672c81b442386ed6Darin Petkov !utils::IsSymlink(symlink_path.c_str())) { 4975039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko base::ReplaceFile(base::FilePath(symlink_path), 5075039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko base::FilePath(log_path), 5175039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko nullptr); 5230291edee8e2f7646b540b00672c81b442386ed6Darin Petkov } 5375039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko base::DeleteFile(base::FilePath(symlink_path), true); 5430291edee8e2f7646b540b00672c81b442386ed6Darin Petkov if (symlink(log_path.c_str(), symlink_path.c_str()) == -1) { 5530291edee8e2f7646b540b00672c81b442386ed6Darin Petkov PLOG(ERROR) << "Unable to create symlink " << symlink_path 5630291edee8e2f7646b540b00672c81b442386ed6Darin Petkov << " pointing at " << log_path; 5730291edee8e2f7646b540b00672c81b442386ed6Darin Petkov } 5830291edee8e2f7646b540b00672c81b442386ed6Darin Petkov} 5973520670492f3358c496698767879adcf6c03aeaAndrew de los Reyes 6030291edee8e2f7646b540b00672c81b442386ed6Darin Petkovstring GetTimeAsString(time_t utime) { 6130291edee8e2f7646b540b00672c81b442386ed6Darin Petkov struct tm tm; 62d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko CHECK_EQ(localtime_r(&utime, &tm), &tm); 6330291edee8e2f7646b540b00672c81b442386ed6Darin Petkov char str[16]; 64d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko CHECK_EQ(strftime(str, sizeof(str), "%Y%m%d-%H%M%S", &tm), 15u); 6530291edee8e2f7646b540b00672c81b442386ed6Darin Petkov return str; 6630291edee8e2f7646b540b00672c81b442386ed6Darin Petkov} 6749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 6830291edee8e2f7646b540b00672c81b442386ed6Darin Petkovstring SetupLogFile(const string& kLogsRoot) { 6930291edee8e2f7646b540b00672c81b442386ed6Darin Petkov const string kLogSymlink = kLogsRoot + "/update_engine.log"; 7030291edee8e2f7646b540b00672c81b442386ed6Darin Petkov const string kLogsDir = kLogsRoot + "/update_engine"; 7130291edee8e2f7646b540b00672c81b442386ed6Darin Petkov const string kLogPath = 7275039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko base::StringPrintf("%s/update_engine.%s", 7375039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko kLogsDir.c_str(), 7475039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko GetTimeAsString(::time(nullptr)).c_str()); 7530291edee8e2f7646b540b00672c81b442386ed6Darin Petkov mkdir(kLogsDir.c_str(), 0755); 7630291edee8e2f7646b540b00672c81b442386ed6Darin Petkov SetupLogSymlink(kLogSymlink, kLogPath); 7730291edee8e2f7646b540b00672c81b442386ed6Darin Petkov return kLogSymlink; 7830291edee8e2f7646b540b00672c81b442386ed6Darin Petkov} 7930291edee8e2f7646b540b00672c81b442386ed6Darin Petkov 80d570820920e030fefd9644fb5427b538160af1a1Steve Fungvoid SetupLogging(bool log_to_std_err) { 81d603ba9ff52c72a68556495245e1069c991866d4Alex Deymo string log_file; 8275039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko logging::LoggingSettings log_settings; 8375039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko log_settings.lock_log = logging::DONT_LOCK_LOG_FILE; 8475039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko log_settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE; 8575039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko 86d570820920e030fefd9644fb5427b538160af1a1Steve Fung if (log_to_std_err) { 8775039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko // Log to stderr initially. 8875039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko log_settings.log_file = nullptr; 8975039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; 9075039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko } else { 91d603ba9ff52c72a68556495245e1069c991866d4Alex Deymo log_file = SetupLogFile("/var/log"); 9275039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko log_settings.log_file = log_file.c_str(); 9375039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko log_settings.logging_dest = logging::LOG_TO_FILE; 9430291edee8e2f7646b540b00672c81b442386ed6Darin Petkov } 9575039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko 9675039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko logging::InitLogging(log_settings); 9730291edee8e2f7646b540b00672c81b442386ed6Darin Petkov} 98000d895da247697f4e4e0c67a3a847f71fca8eb9Andrew de los Reyes 99d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko} // namespace 10030291edee8e2f7646b540b00672c81b442386ed6Darin Petkov} // namespace chromeos_update_engine 10149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 10249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comint main(int argc, char** argv) { 103d570820920e030fefd9644fb5427b538160af1a1Steve Fung DEFINE_bool(logtostderr, false, 104d570820920e030fefd9644fb5427b538160af1a1Steve Fung "Write logs to stderr instead of to a file in log_dir."); 105d570820920e030fefd9644fb5427b538160af1a1Steve Fung DEFINE_bool(foreground, false, 106d570820920e030fefd9644fb5427b538160af1a1Steve Fung "Don't daemon()ize; run in foreground."); 107d570820920e030fefd9644fb5427b538160af1a1Steve Fung 1089c0baf82049efd95230a8389769e1b3e5d001209Darin Petkov chromeos_update_engine::Terminator::Init(); 109d570820920e030fefd9644fb5427b538160af1a1Steve Fung chromeos::FlagHelper::Init(argc, argv, "Chromium OS Update Engine"); 110d570820920e030fefd9644fb5427b538160af1a1Steve Fung chromeos_update_engine::SetupLogging(FLAGS_logtostderr); 1116b78e29f80e98c4ad009c830012682220dc9de3bAndrew de los Reyes if (!FLAGS_foreground) 1126b78e29f80e98c4ad009c830012682220dc9de3bAndrew de los Reyes PLOG_IF(FATAL, daemon(0, 0) == 1) << "daemon() failed"; 1136b78e29f80e98c4ad009c830012682220dc9de3bAndrew de los Reyes 1144fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes LOG(INFO) << "Chrome OS Update Engine starting"; 115a4a8a8ccc2d9e0285728ed247b43f09433e63323Darin Petkov 1164dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone // Ensure that all written files have safe permissions. 1174dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone // This is a mask, so we _block_ execute for the owner, and ALL 1184dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone // permissions for other users. 1194dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone // Done _after_ log file creation. 1204dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone umask(S_IXUSR | S_IRWXG | S_IRWXO); 1214dc2ada660d3f7cd50d624b6bf102d806cf8997fChris Masone 122b7ca096f98a43ebbf412f1b2d3d15bb184f871f8Alex Deymo chromeos_update_engine::UpdateEngineDaemon update_engine_daemon; 123b7ca096f98a43ebbf412f1b2d3d15bb184f871f8Alex Deymo int exit_code = update_engine_daemon.Run(); 1244fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes 125b7ca096f98a43ebbf412f1b2d3d15bb184f871f8Alex Deymo LOG(INFO) << "Chrome OS Update Engine terminating with exit code " 126b7ca096f98a43ebbf412f1b2d3d15bb184f871f8Alex Deymo << exit_code; 127b7ca096f98a43ebbf412f1b2d3d15bb184f871f8Alex Deymo return exit_code; 12849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com} 129