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// 163defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#ifndef UPDATE_ENGINE_COMMON_UTILS_H_ 1839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#define UPDATE_ENGINE_COMMON_UTILS_H_ 193defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 202643cb7494baa29bbd6b956b93967c6e33ae0350Han Shen#include <errno.h> 21d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko#include <unistd.h> 22d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko 23d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko#include <algorithm> 24d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko#include <map> 2502f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan#include <memory> 263defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include <set> 273defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include <string> 283defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include <vector> 29c6c135c3e555a856b762e4f383d1d2768363589dDarin Petkov 3075039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/files/file_path.h> 31fc661a18c07822f1700b870d8435189d5d809f3bChris Sosa#include <base/posix/eintr_wrapper.h> 3275039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/time/time.h> 333f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/key_value_store.h> 343f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/secure_blob.h> 35c6c135c3e555a856b762e4f383d1d2768363589dDarin Petkov 3639910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/action.h" 3739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/action_processor.h" 3839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/constants.h" 3939910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/payload_consumer/file_descriptor.h" 40568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood#include "update_engine/update_metadata.pb.h" 413defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 423defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comnamespace chromeos_update_engine { 433defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 443defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comnamespace utils { 453defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4627a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen// Converts a struct timespec representing a number of seconds since 4727a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen// the Unix epoch to a base::Time. Sub-microsecond time is rounded 4827a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen// down. 4927a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthenbase::Time TimeFromStructTimespec(struct timespec *ts); 5027a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen 51f329b933db41d26644a97afef928eb1b319d6d99Alex Deymo// Formats |vec_str| as a string of the form ["<elem1>", "<elem2>"]. 5227a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen// Does no escaping, only use this for presentation in error messages. 53f329b933db41d26644a97afef928eb1b319d6d99Alex Deymostd::string StringVectorToString(const std::vector<std::string> &vec_str); 5427a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen 558f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen// Calculates the p2p file id from payload hash and size 568f191b22a1a1ab2b803d65ee488729206e648695David Zeuthenstd::string CalculateP2PFileId(const std::string& payload_hash, 578f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen size_t payload_size); 588f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen 5963137e5ded659c02eb70d59ef38f99aecac4d076J. Richard Barnette// Parse the firmware version from one line of output from the 6063137e5ded659c02eb70d59ef38f99aecac4d076J. Richard Barnette// "mosys" command. 6163137e5ded659c02eb70d59ef38f99aecac4d076J. Richard Barnettestd::string ParseECVersion(std::string input_line); 6263137e5ded659c02eb70d59ef38f99aecac4d076J. Richard Barnette 63970bb28905b44bf9f2cb986bb412ecda1095b0b1Andrew de los Reyes// Writes the data passed to path. The file at path will be overwritten if it 64970bb28905b44bf9f2cb986bb412ecda1095b0b1Andrew de los Reyes// exists. Returns true on success, false otherwise. 65f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkobool WriteFile(const char* path, const void* data, int data_len); 66970bb28905b44bf9f2cb986bb412ecda1095b0b1Andrew de los Reyes 6709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Calls write() or pwrite() repeatedly until all count bytes at buf are 6809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// written to fd or an error occurs. Returns true on success. 6909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesbool WriteAll(int fd, const void* buf, size_t count); 7009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesbool PWriteAll(int fd, const void* buf, size_t count, off_t offset); 7109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 72f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyenbool WriteAll(FileDescriptorPtr fd, const void* buf, size_t count); 73f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyenbool PWriteAll(FileDescriptorPtr fd, 74f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen const void* buf, 75f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen size_t count, 76f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen off_t offset); 77f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen 7872ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo// Calls read() repeatedly until |count| bytes are read or EOF or EWOULDBLOCK 7972ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo// is reached. Returns whether all read() calls succeeded (including EWOULDBLOCK 8072ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo// as a success case), sets |eof| to whether the eof was reached and sets 8172ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo// |out_bytes_read| to the actual number of bytes read regardless of the return 8272ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo// value. 8372ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymobool ReadAll( 8472ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo int fd, void* buf, size_t count, size_t* out_bytes_read, bool* eof); 8572ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo 8609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Calls pread() repeatedly until count bytes are read, or EOF is reached. 8709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Returns number of bytes read in *bytes_read. Returns true on success. 8809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesbool PReadAll(int fd, void* buf, size_t count, off_t offset, 8909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes ssize_t* out_bytes_read); 90b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes 91f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyenbool PReadAll(FileDescriptorPtr fd, void* buf, size_t count, off_t offset, 92f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen ssize_t* out_bytes_read); 93f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen 9419a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// Opens |path| for reading and appends its entire content to the container 9519a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// pointed to by |out_p|. Returns true upon successfully reading all of the 9619a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// file's content, false otherwise, in which case the state of the output 978e447e02eb60955bc1f982f0d20b7f0d2689e0dbDarin Petkov// container is unknown. ReadFileChunk starts reading the file from |offset|; if 988e447e02eb60955bc1f982f0d20b7f0d2689e0dbDarin Petkov// |size| is not -1, only up to |size| bytes are read in. 993f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool ReadFile(const std::string& path, brillo::Blob* out_p); 10019a45f0eda0917b7788b925b501e774208474fdeGilad Arnoldbool ReadFile(const std::string& path, std::string* out_p); 1018e447e02eb60955bc1f982f0d20b7f0d2689e0dbDarin Petkovbool ReadFileChunk(const std::string& path, off_t offset, off_t size, 1023f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob* out_p); 10319a45f0eda0917b7788b925b501e774208474fdeGilad Arnold 10419a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// Invokes |cmd| in a pipe and appends its stdout to the container pointed to by 10519a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// |out_p|. Returns true upon successfully reading all of the output, false 10619a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// otherwise, in which case the state of the output container is unknown. 10719a45f0eda0917b7788b925b501e774208474fdeGilad Arnoldbool ReadPipe(const std::string& cmd, std::string* out_p); 1083defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 1091016ae1251f9e9f82389194c2175b3dd024b7ddbAlex Deymo// Returns the size of the block device at the file descriptor fd. If an error 1101016ae1251f9e9f82389194c2175b3dd024b7ddbAlex Deymo// occurs, -1 is returned. 111b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Blackoff_t BlockDevSize(int fd); 112b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Black 113b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Black// Returns the size of the file at path, or the file desciptor fd. If the file 114b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Black// is actually a block device, this function will automatically call 115b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Black// BlockDevSize. If the file doesn't exist or some error occurrs, -1 is 116b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Black// returned. 117f4c7ef1bc239890d8bee30e6823f88814fef8ce5Andrew de los Reyesoff_t FileSize(const std::string& path); 118b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Blackoff_t FileSize(int fd); 119f4c7ef1bc239890d8bee30e6823f88814fef8ce5Andrew de los Reyes 1203defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comstd::string ErrnoNumberAsString(int err); 1213defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 1223defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Returns true if the file exists for sure. Returns false if it doesn't exist, 1233defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// or an error occurs. 1243defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.combool FileExists(const char* path); 1253defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 12630291edee8e2f7646b540b00672c81b442386ed6Darin Petkov// Returns true if |path| exists and is a symbolic link. 12730291edee8e2f7646b540b00672c81b442386ed6Darin Petkovbool IsSymlink(const char* path); 12830291edee8e2f7646b540b00672c81b442386ed6Darin Petkov 129a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// Try attaching UBI |volume_num|. If there is any error executing required 130a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// commands to attach the volume, this function returns false. This function 131a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// only returns true if "/dev/ubi%d_0" becomes available in |timeout| seconds. 132a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyenbool TryAttachingUbiVolume(int volume_num, int timeout); 133a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen 1349629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo// Setup the directory |new_root_temp_dir| to be used as the root directory for 1359629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo// temporary files instead of the system's default. If the directory doesn't 1369629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo// exists, it will be created when first used. 1379629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo// NOTE: The memory pointed by |new_root_temp_dir| must be available until this 1389629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo// function is called again with a different value. 1399629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymovoid SetRootTempDir(const char* new_root_temp_dir); 1409629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo 141d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// If |base_filename_template| is neither absolute (starts with "/") nor 142d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// explicitly relative to the current working directory (starts with "./" or 1435aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// "../"), then it is prepended the system's temporary directory. On success, 1445aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// stores the name of the new temporary file in |filename|. If |fd| is 14588b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// non-null, the file descriptor returned by mkstemp is written to it and 14688b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// kept open; otherwise, it is closed. The template must end with "XXXXXX". 14788b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// Returns true on success. 148d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnoldbool MakeTempFile(const std::string& base_filename_template, 149b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes std::string* filename, 150b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes int* fd); 151b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes 1525aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// If |base_dirname_template| is neither absolute (starts with "/") nor 153d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// explicitly relative to the current working directory (starts with "./" or 1545aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// "../"), then it is prepended the system's temporary directory. On success, 1555aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// stores the name of the new temporary directory in |dirname|. The template 1565aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// must end with "XXXXXX". Returns true on success. 157d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnoldbool MakeTempDirectory(const std::string& base_dirname_template, 15809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes std::string* dirname); 15909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 1604f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Splits the partition device name into the block device name and partition 1614f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// number. For example, "/dev/sda3" will be split into {"/dev/sda", 3} and 1624f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// "/dev/mmcblk0p2" into {"/dev/mmcblk0", 2} 1634f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Returns false when malformed device name is passed in. 16488b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// If both output parameters are omitted (null), can be used 1654f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// just to test the validity of the device name. Note that the function 1664f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// simply checks if the device name looks like a valid device, no other 1674f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// checks are performed (i.e. it doesn't check if the device actually exists). 1684f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenkobool SplitPartitionName(const std::string& partition_name, 1694f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko std::string* out_disk_name, 1704f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko int* out_partition_num); 1714f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko 1724f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Builds a partition device name from the block device name and partition 1734f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// number. For example: 1744f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// {"/dev/sda", 1} => "/dev/sda1" 1754f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// {"/dev/mmcblk2", 12} => "/dev/mmcblk2p12" 1764f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Returns empty string when invalid parameters are passed in 1774f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenkostd::string MakePartitionName(const std::string& disk_name, 1784f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko int partition_num); 179f97144334e945a5ec88970b4b28f4e98ce0bbb80Andrew de los Reyes 180a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// Similar to "MakePartitionName" but returns a name that is suitable for 181a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// mounting. On NAND system we can write to "/dev/ubiX_0", which is what 182a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// MakePartitionName returns, but we cannot mount that device. To mount, we 183a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// have to use "/dev/ubiblockX_0" for rootfs. Stateful and OEM partitions are 184a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// mountable with "/dev/ubiX_0". The input is a partition device such as 185a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// /dev/sda3. Return empty string on error. 186a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyenstd::string MakePartitionNameForMount(const std::string& part_name); 187a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen 1882e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo// Set the read-only attribute on the block device |device| to the value passed 1892e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo// in |read_only|. Return whether the operation succeeded. 1902e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymobool SetBlockDeviceReadOnly(const std::string& device, bool read_only); 1912e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo 1923defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Synchronously mount or unmount a filesystem. Return true on success. 193390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// When mounting, it will attempt to mount the device as the passed filesystem 194390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// type |type|, with the passed |flags| options. If |type| is empty, "ext2", 195390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// "ext3", "ext4" and "squashfs" will be tried. 196390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymobool MountFilesystem(const std::string& device, 197390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo const std::string& mountpoint, 198390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo unsigned long flags, // NOLINT(runtime/int) 19914dbd333439f34c648b9f783ffa656ef565de0ccAlex Deymo const std::string& type, 20014dbd333439f34c648b9f783ffa656ef565de0ccAlex Deymo const std::string& fs_mount_options); 2014fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesbool UnmountFilesystem(const std::string& mountpoint); 2023defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 203192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Returns the block count and the block byte size of the file system on 204d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// |device| (which may be a real device or a path to a filesystem image) or on 205d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// an opened file descriptor |fd|. The actual file-system size is |block_count| 206d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// * |block_size| bytes. Returns true on success, false otherwise. 207d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkovbool GetFilesystemSize(const std::string& device, 208d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov int* out_block_count, 209d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov int* out_block_size); 210d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkovbool GetFilesystemSizeFromFD(int fd, 211d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov int* out_block_count, 212d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov int* out_block_size); 213d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov 214192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Determines the block count and block size of the ext3 fs. At least 2048 bytes 215192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// are required to parse the first superblock. Returns whether the buffer 216192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// contains a valid ext3 filesystem and the values were parsed. 217192393ba515e917d06248b6459b20b6547ef496dAlex Deymobool GetExt3Size(const uint8_t* buffer, size_t buffer_size, 218192393ba515e917d06248b6459b20b6547ef496dAlex Deymo int* out_block_count, 219192393ba515e917d06248b6459b20b6547ef496dAlex Deymo int* out_block_size); 220192393ba515e917d06248b6459b20b6547ef496dAlex Deymo 221192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Determines the block count and block size of the squashfs v4 fs. At least 96 222192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// bytes are required to parse the header of the filesystem. Since squashfs 223192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// doesn't define a physical block size, a value of 4096 is used for the block 224192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// size, which is the default padding when creating the filesystem. 225192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Returns whether the buffer contains a valid squashfs v4 header and the size 226192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// was parsed. Only little endian squashfs is supported. 227192393ba515e917d06248b6459b20b6547ef496dAlex Deymobool GetSquashfs4Size(const uint8_t* buffer, size_t buffer_size, 228192393ba515e917d06248b6459b20b6547ef496dAlex Deymo int* out_block_count, 229192393ba515e917d06248b6459b20b6547ef496dAlex Deymo int* out_block_size); 230192393ba515e917d06248b6459b20b6547ef496dAlex Deymo 231de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// Returns whether the filesystem is an ext[234] filesystem. In case of failure, 232de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// such as if the file |device| doesn't exists or can't be read, it returns 233de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// false. 234de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymobool IsExtFilesystem(const std::string& device); 235de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo 236de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// Returns whether the filesystem is a squashfs filesystem. In case of failure, 237de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// such as if the file |device| doesn't exists or can't be read, it returns 238de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// false. 239de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymobool IsSquashfsFilesystem(const std::string& device); 240de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo 241032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo// Returns a human-readable string with the file format based on magic constants 242032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo// on the header of the file. 243032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymostd::string GetFileFormat(const std::string& path); 244032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo 245480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan// Returns the string representation of the given UTC time. 246480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan// such as "11/14/2011 14:05:30 GMT". 247480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasanstd::string ToString(const base::Time utc_time); 248480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan 249ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan// Returns true or false depending on the value of b. 250ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanstd::string ToString(bool b); 251ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan 25219409b74019d787100b768306e75ab3e5882898dJay Srinivasan// Returns a string representation of the given enum. 25319409b74019d787100b768306e75ab3e5882898dJay Srinivasanstd::string ToString(DownloadSource source); 25419409b74019d787100b768306e75ab3e5882898dJay Srinivasan 2551c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo// Returns a string representation of the given enum. 2561c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymostd::string ToString(PayloadType payload_type); 2571c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo 258712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes// Schedules a Main Loop callback to trigger the crash reporter to perform an 259712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes// upload as if this process had crashed. 260712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyesvoid ScheduleCrashReporterUpload(); 261712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes 2625c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov// Fuzzes an integer |value| randomly in the range: 2635c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov// [value - range / 2, value + range - range / 2] 2645c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkovint FuzzInt(int value, unsigned int range); 2655c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov 2663defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Log a string in hex to LOG(INFO). Useful for debugging. 267f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkovoid HexDumpArray(const uint8_t* const arr, const size_t length); 2683defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.cominline void HexDumpString(const std::string& str) { 269f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko HexDumpArray(reinterpret_cast<const uint8_t*>(str.data()), str.size()); 2703defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com} 2713f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkoinline void HexDumpVector(const brillo::Blob& vect) { 272f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko HexDumpArray(vect.data(), vect.size()); 2733defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com} 2743defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 2753defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comtemplate<typename KeyType, typename ValueType> 2763defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.combool MapContainsKey(const std::map<KeyType, ValueType>& m, const KeyType& k) { 2773defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com return m.find(k) != m.end(); 2783defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com} 2794fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyestemplate<typename KeyType> 2804fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesbool SetContainsKey(const std::set<KeyType>& s, const KeyType& k) { 2814fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes return s.find(k) != s.end(); 2824fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes} 2833defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 2840ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyestemplate<typename T> 2850ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyesbool VectorContainsValue(const std::vector<T>& vect, const T& value) { 286c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov return std::find(vect.begin(), vect.end(), value) != vect.end(); 2870ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyes} 2880ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyes 289b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyestemplate<typename T> 290b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyesbool VectorIndexOf(const std::vector<T>& vect, const T& value, 291b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes typename std::vector<T>::size_type* out_index) { 292b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes typename std::vector<T>::const_iterator it = std::find(vect.begin(), 293b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes vect.end(), 294b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes value); 295b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes if (it == vect.end()) { 296b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes return false; 297b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes } else { 298b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes *out_index = it - vect.begin(); 299b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes return true; 300b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes } 301b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes} 302b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes 303d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// Converts seconds into human readable notation including days, hours, minutes 304d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// and seconds. For example, 185 will yield 3m5s, 4300 will yield 1h11m40s, and 305d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// 360000 will yield 4d4h0m0s. Zero padding not applied. Seconds are always 306d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// shown in the result. 307d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnoldstd::string FormatSecs(unsigned secs); 308d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold 309d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// Converts a TimeDelta into human readable notation including days, hours, 310d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// minutes, seconds and fractions of a second down to microsecond granularity, 311d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// as necessary; for example, an output of 5d2h0m15.053s means that the input 312d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// time was precise to the milliseconds only. Zero padding not applied, except 313d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// for fractions. Seconds are always shown, but fractions thereof are only shown 314973449e82eaf611adb911ac1b977baad2e2071e9David Zeuthen// when applicable. If |delta| is negative, the output will have a leading '-' 315973449e82eaf611adb911ac1b977baad2e2071e9David Zeuthen// followed by the absolute duration. 316d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnoldstd::string FormatTimeDelta(base::TimeDelta delta); 3171ebd813ad19214d0b59ade04005c3b84ae765e42Gilad Arnold 3182b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// This method transforms the given error code to be suitable for UMA and 3192b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// for error classification purposes by removing the higher order bits and 3202b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// aggregating error codes beyond the enum range, etc. This method is 3212b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// idempotent, i.e. if called with a value previously returned by this method, 3222b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// it'll return the same value again. 323a99981fda75fe0b17e96c700e3ddc93eca1cebe5David ZeuthenErrorCode GetBaseErrorCode(ErrorCode code); 3242b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan 325e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// Decodes the data in |base64_encoded| and stores it in a temporary 326e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// file. Returns false if the given data is empty, not well-formed 327e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// base64 or if an error occurred. If true is returned, the decoded 328e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// data is stored in the file returned in |out_path|. The file should 329e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// be deleted when no longer needed. 330e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthenbool DecodeAndStoreBase64String(const std::string& base64_encoded, 331e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen base::FilePath *out_path); 332e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen 333639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// Converts |time| to an Omaha InstallDate which is defined as "the 334639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// number of PST8PDT calendar weeks since Jan 1st 2007 0:00 PST, times 335639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// seven" with PST8PDT defined as "Pacific Time" (e.g. UTC-07:00 if 336639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// daylight savings is observed and UTC-08:00 otherwise.) 337639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// 338639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// If the passed in |time| variable is before Monday January 1st 2007 339639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// 0:00 PST, False is returned and the value returned in 340639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// |out_num_days| is undefined. Otherwise the number of PST8PDT 341639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// calendar weeks since that date times seven is returned in 342639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// |out_num_days| and the function returns True. 343639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// 344639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// (NOTE: This function does not currently take daylight savings time 345639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// into account so the result may up to one hour off. This is because 346639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// the glibc date and timezone routines depend on the TZ environment 3470b3db6b6040f53eb9859e614f7fe4c681213d33aAlex Deymo// variable and changing environment variables is not thread-safe. 348639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthenbool ConvertToOmahaInstallDate(base::Time time, int *out_num_days); 349639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen 350b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo// Look for the minor version value in the passed |store| and set 351b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo// |minor_version| to that value. Return whether the value was found and valid. 3523f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool GetMinorVersion(const brillo::KeyValueStore& store, 353b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo uint32_t* minor_version); 35478750a450ce84b2d335134402d041aa8773ab8efAllie Wood 3553a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiang// Returns whether zlib |fingerprint| is compatible with zlib we are using. 3563a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiangbool IsZlibCompatible(const std::string& fingerprint); 3573a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiang 358568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// This function reads the specified data in |extents| into |out_data|. The 359568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// extents are read from the file at |path|. |out_data_size| is the size of 360568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// |out_data|. Returns false if the number of bytes to read given in 361568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// |extents| does not equal |out_data_size|. 36241e3474eebe3748a45aba4b297a7a313a1006c6cGilad Arnoldbool ReadExtents(const std::string& path, const std::vector<Extent>& extents, 3633f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob* out_data, ssize_t out_data_size, 364568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood size_t block_size); 365568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood 366dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// Read the current boot identifier and store it in |boot_id|. This identifier 367dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// is constants during the same boot of the kernel and is regenerated after 368dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// reboot. Returns whether it succeeded getting the boot_id. 369dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymobool GetBootId(std::string* boot_id); 370dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo 3713defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com} // namespace utils 3723defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 37308fce04e5341c99f308ee7462b1f351f5232eacdJay Srinivasan 3743defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Utility class to close a file descriptor 3753defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comclass ScopedFdCloser { 3763defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com public: 3774600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo explicit ScopedFdCloser(int* fd) : fd_(fd) {} 3783defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com ~ScopedFdCloser() { 3794600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo if (should_close_ && fd_ && (*fd_ >= 0) && !IGNORE_EINTR(close(*fd_))) 3804600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo *fd_ = -1; 3813defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } 3826f03a3b868d4b632931400628763036f79c449f7Darin Petkov void set_should_close(bool should_close) { should_close_ = should_close; } 3833defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com private: 3843defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com int* fd_; 3854600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo bool should_close_ = true; 38609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes DISALLOW_COPY_AND_ASSIGN(ScopedFdCloser); 38709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes}; 38809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 38909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Utility class to delete a file when it goes out of scope. 39009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesclass ScopedPathUnlinker { 39109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes public: 39252dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov explicit ScopedPathUnlinker(const std::string& path) 39352dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov : path_(path), 39452dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov should_remove_(true) {} 39509e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes ~ScopedPathUnlinker() { 39652dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov if (should_remove_ && unlink(path_.c_str()) < 0) { 39718f48aa4e962997a9ff12fac8933c94aac247fd9Alex Deymo PLOG(ERROR) << "Unable to unlink path " << path_; 39809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes } 39909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes } 40052dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov void set_should_remove(bool should_remove) { should_remove_ = should_remove; } 40152dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov 40209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes private: 40309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes const std::string path_; 40452dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov bool should_remove_; 40509e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes DISALLOW_COPY_AND_ASSIGN(ScopedPathUnlinker); 40609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes}; 40709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 40809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Utility class to delete an empty directory when it goes out of scope. 40909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesclass ScopedDirRemover { 41009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes public: 4116f03a3b868d4b632931400628763036f79c449f7Darin Petkov explicit ScopedDirRemover(const std::string& path) 4126f03a3b868d4b632931400628763036f79c449f7Darin Petkov : path_(path), 4136f03a3b868d4b632931400628763036f79c449f7Darin Petkov should_remove_(true) {} 41409e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes ~ScopedDirRemover() { 4156f03a3b868d4b632931400628763036f79c449f7Darin Petkov if (should_remove_ && (rmdir(path_.c_str()) < 0)) { 41609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes PLOG(ERROR) << "Unable to remove dir " << path_; 4176f03a3b868d4b632931400628763036f79c449f7Darin Petkov } 41809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes } 4196f03a3b868d4b632931400628763036f79c449f7Darin Petkov void set_should_remove(bool should_remove) { should_remove_ = should_remove; } 4206f03a3b868d4b632931400628763036f79c449f7Darin Petkov 4216f03a3b868d4b632931400628763036f79c449f7Darin Petkov protected: 42209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes const std::string path_; 4236f03a3b868d4b632931400628763036f79c449f7Darin Petkov 4246f03a3b868d4b632931400628763036f79c449f7Darin Petkov private: 4256f03a3b868d4b632931400628763036f79c449f7Darin Petkov bool should_remove_; 42609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes DISALLOW_COPY_AND_ASSIGN(ScopedDirRemover); 4273defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}; 4283defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4293defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// A little object to call ActionComplete on the ActionProcessor when 4303defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// it's destructed. 4313defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comclass ScopedActionCompleter { 4323defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com public: 4333defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com explicit ScopedActionCompleter(ActionProcessor* processor, 4343defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com AbstractAction* action) 4353defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com : processor_(processor), 4363defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com action_(action), 437d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold code_(ErrorCode::kError), 4383defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com should_complete_(true) {} 4393defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com ~ScopedActionCompleter() { 4403defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com if (should_complete_) 441c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov processor_->ActionComplete(action_, code_); 4423defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } 443a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen void set_code(ErrorCode code) { code_ = code; } 4443defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com void set_should_complete(bool should_complete) { 4453defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com should_complete_ = should_complete; 4463defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } 44733bae491eded4ef4f1eb4f4ef0f01ef0e5463f3aDavid Zeuthen ErrorCode get_code() const { return code_; } 448c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov 4493defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com private: 4503defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com ActionProcessor* processor_; 4513defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com AbstractAction* action_; 452a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen ErrorCode code_; 4533defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com bool should_complete_; 4543defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com DISALLOW_COPY_AND_ASSIGN(ScopedActionCompleter); 4553defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}; 4563defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4573defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com} // namespace chromeos_update_engine 4583defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4593defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_FALSE_ERRNO(_x) \ 4603defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com do { \ 4612b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen bool _success = static_cast<bool>(_x); \ 4623defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com if (!_success) { \ 4633defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com std::string _msg = \ 4643defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com chromeos_update_engine::utils::ErrnoNumberAsString(errno); \ 4653defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com LOG(ERROR) << #_x " failed: " << _msg; \ 4663defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com return false; \ 4673defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } \ 4683defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } while (0) 4693defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4703defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_FALSE(_x) \ 4713defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com do { \ 4722b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen bool _success = static_cast<bool>(_x); \ 4733defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com if (!_success) { \ 4743defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com LOG(ERROR) << #_x " failed."; \ 4753defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com return false; \ 4763defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } \ 4773defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } while (0) 4783defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4793defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_ERRNO(_x) \ 4803defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com do { \ 4812b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen bool _success = static_cast<bool>(_x); \ 4823defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com if (!_success) { \ 4833defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com std::string _msg = \ 4843defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com chromeos_update_engine::utils::ErrnoNumberAsString(errno); \ 4853defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com LOG(ERROR) << #_x " failed: " << _msg; \ 4863defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com return; \ 4873defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } \ 4883defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } while (0) 4893defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4903defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN(_x) \ 4913defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com do { \ 4922b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen bool _success = static_cast<bool>(_x); \ 4933defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com if (!_success) { \ 4943defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com LOG(ERROR) << #_x " failed."; \ 4953defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com return; \ 4963defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } \ 4973defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } while (0) 4983defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4995c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le#define TEST_AND_RETURN_FALSE_ERRCODE(_x) \ 5005c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le do { \ 5015c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le errcode_t _error = (_x); \ 5025c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le if (_error) { \ 5035c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le errno = _error; \ 5045c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le LOG(ERROR) << #_x " failed: " << _error; \ 5055c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le return false; \ 5065c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le } \ 5075c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le } while (0) 5085c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 50939910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif // UPDATE_ENGINE_COMMON_UTILS_H_ 510