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 134d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// If |base_filename_template| is neither absolute (starts with "/") nor 135d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// explicitly relative to the current working directory (starts with "./" or 1365aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// "../"), then it is prepended the system's temporary directory. On success, 1375aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// stores the name of the new temporary file in |filename|. If |fd| is 13888b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// non-null, the file descriptor returned by mkstemp is written to it and 13988b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// kept open; otherwise, it is closed. The template must end with "XXXXXX". 14088b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// Returns true on success. 141d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnoldbool MakeTempFile(const std::string& base_filename_template, 142b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes std::string* filename, 143b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes int* fd); 144b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes 1455aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// If |base_dirname_template| is neither absolute (starts with "/") nor 146d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// explicitly relative to the current working directory (starts with "./" or 1475aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// "../"), then it is prepended the system's temporary directory. On success, 1485aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// stores the name of the new temporary directory in |dirname|. The template 1495aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// must end with "XXXXXX". Returns true on success. 150d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnoldbool MakeTempDirectory(const std::string& base_dirname_template, 15109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes std::string* dirname); 15209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 1534f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Splits the partition device name into the block device name and partition 1544f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// number. For example, "/dev/sda3" will be split into {"/dev/sda", 3} and 1554f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// "/dev/mmcblk0p2" into {"/dev/mmcblk0", 2} 1564f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Returns false when malformed device name is passed in. 15788b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// If both output parameters are omitted (null), can be used 1584f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// just to test the validity of the device name. Note that the function 1594f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// simply checks if the device name looks like a valid device, no other 1604f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// checks are performed (i.e. it doesn't check if the device actually exists). 1614f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenkobool SplitPartitionName(const std::string& partition_name, 1624f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko std::string* out_disk_name, 1634f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko int* out_partition_num); 1644f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko 1654f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Builds a partition device name from the block device name and partition 1664f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// number. For example: 1674f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// {"/dev/sda", 1} => "/dev/sda1" 1684f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// {"/dev/mmcblk2", 12} => "/dev/mmcblk2p12" 1694f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Returns empty string when invalid parameters are passed in 1704f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenkostd::string MakePartitionName(const std::string& disk_name, 1714f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko int partition_num); 172f97144334e945a5ec88970b4b28f4e98ce0bbb80Andrew de los Reyes 173a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// Similar to "MakePartitionName" but returns a name that is suitable for 174a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// mounting. On NAND system we can write to "/dev/ubiX_0", which is what 175a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// MakePartitionName returns, but we cannot mount that device. To mount, we 176a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// have to use "/dev/ubiblockX_0" for rootfs. Stateful and OEM partitions are 177a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// mountable with "/dev/ubiX_0". The input is a partition device such as 178a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// /dev/sda3. Return empty string on error. 179a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyenstd::string MakePartitionNameForMount(const std::string& part_name); 180a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen 1812e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo// Set the read-only attribute on the block device |device| to the value passed 1822e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo// in |read_only|. Return whether the operation succeeded. 1832e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymobool SetBlockDeviceReadOnly(const std::string& device, bool read_only); 1842e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo 1853defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Synchronously mount or unmount a filesystem. Return true on success. 186390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// When mounting, it will attempt to mount the device as the passed filesystem 187390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// type |type|, with the passed |flags| options. If |type| is empty, "ext2", 188390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// "ext3", "ext4" and "squashfs" will be tried. 189390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymobool MountFilesystem(const std::string& device, 190390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo const std::string& mountpoint, 191390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo unsigned long flags, // NOLINT(runtime/int) 19214dbd333439f34c648b9f783ffa656ef565de0ccAlex Deymo const std::string& type, 19314dbd333439f34c648b9f783ffa656ef565de0ccAlex Deymo const std::string& fs_mount_options); 1944fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesbool UnmountFilesystem(const std::string& mountpoint); 1953defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 196192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Returns the block count and the block byte size of the file system on 197d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// |device| (which may be a real device or a path to a filesystem image) or on 198d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// an opened file descriptor |fd|. The actual file-system size is |block_count| 199d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// * |block_size| bytes. Returns true on success, false otherwise. 200d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkovbool GetFilesystemSize(const std::string& device, 201d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov int* out_block_count, 202d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov int* out_block_size); 203d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkovbool GetFilesystemSizeFromFD(int fd, 204d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov int* out_block_count, 205d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov int* out_block_size); 206d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov 207192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Determines the block count and block size of the ext3 fs. At least 2048 bytes 208192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// are required to parse the first superblock. Returns whether the buffer 209192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// contains a valid ext3 filesystem and the values were parsed. 210192393ba515e917d06248b6459b20b6547ef496dAlex Deymobool GetExt3Size(const uint8_t* buffer, size_t buffer_size, 211192393ba515e917d06248b6459b20b6547ef496dAlex Deymo int* out_block_count, 212192393ba515e917d06248b6459b20b6547ef496dAlex Deymo int* out_block_size); 213192393ba515e917d06248b6459b20b6547ef496dAlex Deymo 214192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Determines the block count and block size of the squashfs v4 fs. At least 96 215192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// bytes are required to parse the header of the filesystem. Since squashfs 216192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// doesn't define a physical block size, a value of 4096 is used for the block 217192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// size, which is the default padding when creating the filesystem. 218192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Returns whether the buffer contains a valid squashfs v4 header and the size 219192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// was parsed. Only little endian squashfs is supported. 220192393ba515e917d06248b6459b20b6547ef496dAlex Deymobool GetSquashfs4Size(const uint8_t* buffer, size_t buffer_size, 221192393ba515e917d06248b6459b20b6547ef496dAlex Deymo int* out_block_count, 222192393ba515e917d06248b6459b20b6547ef496dAlex Deymo int* out_block_size); 223192393ba515e917d06248b6459b20b6547ef496dAlex Deymo 224de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// Returns whether the filesystem is an ext[234] filesystem. In case of failure, 225de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// such as if the file |device| doesn't exists or can't be read, it returns 226de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// false. 227de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymobool IsExtFilesystem(const std::string& device); 228de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo 229de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// Returns whether the filesystem is a squashfs filesystem. In case of failure, 230de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// such as if the file |device| doesn't exists or can't be read, it returns 231de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// false. 232de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymobool IsSquashfsFilesystem(const std::string& device); 233de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo 234032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo// Returns a human-readable string with the file format based on magic constants 235032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo// on the header of the file. 236032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymostd::string GetFileFormat(const std::string& path); 237032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo 238480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan// Returns the string representation of the given UTC time. 239480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan// such as "11/14/2011 14:05:30 GMT". 240480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasanstd::string ToString(const base::Time utc_time); 241480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan 242ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan// Returns true or false depending on the value of b. 243ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanstd::string ToString(bool b); 244ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan 24519409b74019d787100b768306e75ab3e5882898dJay Srinivasan// Returns a string representation of the given enum. 24619409b74019d787100b768306e75ab3e5882898dJay Srinivasanstd::string ToString(DownloadSource source); 24719409b74019d787100b768306e75ab3e5882898dJay Srinivasan 2481c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo// Returns a string representation of the given enum. 2491c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymostd::string ToString(PayloadType payload_type); 2501c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo 251712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes// Schedules a Main Loop callback to trigger the crash reporter to perform an 252712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes// upload as if this process had crashed. 253712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyesvoid ScheduleCrashReporterUpload(); 254712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes 2555c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov// Fuzzes an integer |value| randomly in the range: 2565c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov// [value - range / 2, value + range - range / 2] 2575c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkovint FuzzInt(int value, unsigned int range); 2585c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov 2593defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Log a string in hex to LOG(INFO). Useful for debugging. 260f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkovoid HexDumpArray(const uint8_t* const arr, const size_t length); 2613defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.cominline void HexDumpString(const std::string& str) { 262f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko HexDumpArray(reinterpret_cast<const uint8_t*>(str.data()), str.size()); 2633defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com} 2643f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkoinline void HexDumpVector(const brillo::Blob& vect) { 265f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko HexDumpArray(vect.data(), vect.size()); 2663defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com} 2673defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 2683defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comtemplate<typename KeyType, typename ValueType> 2693defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.combool MapContainsKey(const std::map<KeyType, ValueType>& m, const KeyType& k) { 2703defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com return m.find(k) != m.end(); 2713defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com} 2724fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyestemplate<typename KeyType> 2734fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesbool SetContainsKey(const std::set<KeyType>& s, const KeyType& k) { 2744fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes return s.find(k) != s.end(); 2754fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes} 2763defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 2770ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyestemplate<typename T> 2780ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyesbool VectorContainsValue(const std::vector<T>& vect, const T& value) { 279c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov return std::find(vect.begin(), vect.end(), value) != vect.end(); 2800ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyes} 2810ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyes 282b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyestemplate<typename T> 283b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyesbool VectorIndexOf(const std::vector<T>& vect, const T& value, 284b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes typename std::vector<T>::size_type* out_index) { 285b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes typename std::vector<T>::const_iterator it = std::find(vect.begin(), 286b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes vect.end(), 287b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes value); 288b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes if (it == vect.end()) { 289b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes return false; 290b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes } else { 291b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes *out_index = it - vect.begin(); 292b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes return true; 293b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes } 294b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes} 295b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes 296d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// Converts seconds into human readable notation including days, hours, minutes 297d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// and seconds. For example, 185 will yield 3m5s, 4300 will yield 1h11m40s, and 298d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// 360000 will yield 4d4h0m0s. Zero padding not applied. Seconds are always 299d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// shown in the result. 300d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnoldstd::string FormatSecs(unsigned secs); 301d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold 302d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// Converts a TimeDelta into human readable notation including days, hours, 303d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// minutes, seconds and fractions of a second down to microsecond granularity, 304d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// as necessary; for example, an output of 5d2h0m15.053s means that the input 305d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// time was precise to the milliseconds only. Zero padding not applied, except 306d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// for fractions. Seconds are always shown, but fractions thereof are only shown 307973449e82eaf611adb911ac1b977baad2e2071e9David Zeuthen// when applicable. If |delta| is negative, the output will have a leading '-' 308973449e82eaf611adb911ac1b977baad2e2071e9David Zeuthen// followed by the absolute duration. 309d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnoldstd::string FormatTimeDelta(base::TimeDelta delta); 3101ebd813ad19214d0b59ade04005c3b84ae765e42Gilad Arnold 3112b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// This method transforms the given error code to be suitable for UMA and 3122b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// for error classification purposes by removing the higher order bits and 3132b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// aggregating error codes beyond the enum range, etc. This method is 3142b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// idempotent, i.e. if called with a value previously returned by this method, 3152b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// it'll return the same value again. 316a99981fda75fe0b17e96c700e3ddc93eca1cebe5David ZeuthenErrorCode GetBaseErrorCode(ErrorCode code); 3172b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan 31830dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold// Creates the powerwash marker file with the appropriate commands in it. Uses 31988b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// |file_path| as the path to the marker file if non-null, otherwise uses the 32030dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold// global default. Returns true if successfully created. False otherwise. 32130dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnoldbool CreatePowerwashMarkerFile(const char* file_path); 32230dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold 32330dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold// Deletes the marker file used to trigger Powerwash using clobber-state. Uses 32488b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// |file_path| as the path to the marker file if non-null, otherwise uses the 32530dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold// global default. Returns true if successfully deleted. False otherwise. 32630dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnoldbool DeletePowerwashMarkerFile(const char* file_path); 3271c0fe79c7ef2b43946d756b54c8505d2bf48b93bJay Srinivasan 328e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// Decodes the data in |base64_encoded| and stores it in a temporary 329e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// file. Returns false if the given data is empty, not well-formed 330e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// base64 or if an error occurred. If true is returned, the decoded 331e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// data is stored in the file returned in |out_path|. The file should 332e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// be deleted when no longer needed. 333e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthenbool DecodeAndStoreBase64String(const std::string& base64_encoded, 334e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen base::FilePath *out_path); 335e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen 336639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// Converts |time| to an Omaha InstallDate which is defined as "the 337639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// number of PST8PDT calendar weeks since Jan 1st 2007 0:00 PST, times 338639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// seven" with PST8PDT defined as "Pacific Time" (e.g. UTC-07:00 if 339639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// daylight savings is observed and UTC-08:00 otherwise.) 340639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// 341639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// If the passed in |time| variable is before Monday January 1st 2007 342639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// 0:00 PST, False is returned and the value returned in 343639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// |out_num_days| is undefined. Otherwise the number of PST8PDT 344639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// calendar weeks since that date times seven is returned in 345639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// |out_num_days| and the function returns True. 346639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// 347639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// (NOTE: This function does not currently take daylight savings time 348639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// into account so the result may up to one hour off. This is because 349639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// the glibc date and timezone routines depend on the TZ environment 3500b3db6b6040f53eb9859e614f7fe4c681213d33aAlex Deymo// variable and changing environment variables is not thread-safe. 351639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthenbool ConvertToOmahaInstallDate(base::Time time, int *out_num_days); 352639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen 353b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo// Look for the minor version value in the passed |store| and set 354b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo// |minor_version| to that value. Return whether the value was found and valid. 3553f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool GetMinorVersion(const brillo::KeyValueStore& store, 356b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo uint32_t* minor_version); 35778750a450ce84b2d335134402d041aa8773ab8efAllie Wood 3583a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiang// Returns whether zlib |fingerprint| is compatible with zlib we are using. 3593a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiangbool IsZlibCompatible(const std::string& fingerprint); 3603a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiang 361568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// This function reads the specified data in |extents| into |out_data|. The 362568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// extents are read from the file at |path|. |out_data_size| is the size of 363568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// |out_data|. Returns false if the number of bytes to read given in 364568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// |extents| does not equal |out_data_size|. 36541e3474eebe3748a45aba4b297a7a313a1006c6cGilad Arnoldbool ReadExtents(const std::string& path, const std::vector<Extent>& extents, 3663f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob* out_data, ssize_t out_data_size, 367568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood size_t block_size); 368568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood 369dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// Read the current boot identifier and store it in |boot_id|. This identifier 370dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// is constants during the same boot of the kernel and is regenerated after 371dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// reboot. Returns whether it succeeded getting the boot_id. 372dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymobool GetBootId(std::string* boot_id); 373dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo 3743defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com} // namespace utils 3753defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 37608fce04e5341c99f308ee7462b1f351f5232eacdJay Srinivasan 3773defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Utility class to close a file descriptor 3783defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comclass ScopedFdCloser { 3793defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com public: 3804600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo explicit ScopedFdCloser(int* fd) : fd_(fd) {} 3813defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com ~ScopedFdCloser() { 3824600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo if (should_close_ && fd_ && (*fd_ >= 0) && !IGNORE_EINTR(close(*fd_))) 3834600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo *fd_ = -1; 3843defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } 3856f03a3b868d4b632931400628763036f79c449f7Darin Petkov void set_should_close(bool should_close) { should_close_ = should_close; } 3863defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com private: 3873defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com int* fd_; 3884600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo bool should_close_ = true; 38909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes DISALLOW_COPY_AND_ASSIGN(ScopedFdCloser); 39009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes}; 39109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 39209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Utility class to delete a file when it goes out of scope. 39309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesclass ScopedPathUnlinker { 39409e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes public: 39552dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov explicit ScopedPathUnlinker(const std::string& path) 39652dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov : path_(path), 39752dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov should_remove_(true) {} 39809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes ~ScopedPathUnlinker() { 39952dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov if (should_remove_ && unlink(path_.c_str()) < 0) { 40018f48aa4e962997a9ff12fac8933c94aac247fd9Alex Deymo PLOG(ERROR) << "Unable to unlink path " << path_; 40109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes } 40209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes } 40352dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov void set_should_remove(bool should_remove) { should_remove_ = should_remove; } 40452dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov 40509e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes private: 40609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes const std::string path_; 40752dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov bool should_remove_; 40809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes DISALLOW_COPY_AND_ASSIGN(ScopedPathUnlinker); 40909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes}; 41009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 41109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Utility class to delete an empty directory when it goes out of scope. 41209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesclass ScopedDirRemover { 41309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes public: 4146f03a3b868d4b632931400628763036f79c449f7Darin Petkov explicit ScopedDirRemover(const std::string& path) 4156f03a3b868d4b632931400628763036f79c449f7Darin Petkov : path_(path), 4166f03a3b868d4b632931400628763036f79c449f7Darin Petkov should_remove_(true) {} 41709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes ~ScopedDirRemover() { 4186f03a3b868d4b632931400628763036f79c449f7Darin Petkov if (should_remove_ && (rmdir(path_.c_str()) < 0)) { 41909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes PLOG(ERROR) << "Unable to remove dir " << path_; 4206f03a3b868d4b632931400628763036f79c449f7Darin Petkov } 42109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes } 4226f03a3b868d4b632931400628763036f79c449f7Darin Petkov void set_should_remove(bool should_remove) { should_remove_ = should_remove; } 4236f03a3b868d4b632931400628763036f79c449f7Darin Petkov 4246f03a3b868d4b632931400628763036f79c449f7Darin Petkov protected: 42509e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes const std::string path_; 4266f03a3b868d4b632931400628763036f79c449f7Darin Petkov 4276f03a3b868d4b632931400628763036f79c449f7Darin Petkov private: 4286f03a3b868d4b632931400628763036f79c449f7Darin Petkov bool should_remove_; 42909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes DISALLOW_COPY_AND_ASSIGN(ScopedDirRemover); 4303defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}; 4313defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4323defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// A little object to call ActionComplete on the ActionProcessor when 4333defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// it's destructed. 4343defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comclass ScopedActionCompleter { 4353defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com public: 4363defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com explicit ScopedActionCompleter(ActionProcessor* processor, 4373defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com AbstractAction* action) 4383defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com : processor_(processor), 4393defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com action_(action), 440d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold code_(ErrorCode::kError), 4413defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com should_complete_(true) {} 4423defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com ~ScopedActionCompleter() { 4433defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com if (should_complete_) 444c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov processor_->ActionComplete(action_, code_); 4453defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } 446a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen void set_code(ErrorCode code) { code_ = code; } 4473defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com void set_should_complete(bool should_complete) { 4483defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com should_complete_ = should_complete; 4493defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } 45033bae491eded4ef4f1eb4f4ef0f01ef0e5463f3aDavid Zeuthen ErrorCode get_code() const { return code_; } 451c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov 4523defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com private: 4533defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com ActionProcessor* processor_; 4543defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com AbstractAction* action_; 455a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen ErrorCode code_; 4563defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com bool should_complete_; 4573defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com DISALLOW_COPY_AND_ASSIGN(ScopedActionCompleter); 4583defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}; 4593defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4603defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com} // namespace chromeos_update_engine 4613defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4623defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_FALSE_ERRNO(_x) \ 4633defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com do { \ 4642b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen bool _success = static_cast<bool>(_x); \ 4653defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com if (!_success) { \ 4663defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com std::string _msg = \ 4673defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com chromeos_update_engine::utils::ErrnoNumberAsString(errno); \ 4683defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com LOG(ERROR) << #_x " failed: " << _msg; \ 4693defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com return false; \ 4703defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } \ 4713defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } while (0) 4723defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4733defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_FALSE(_x) \ 4743defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com do { \ 4752b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen bool _success = static_cast<bool>(_x); \ 4763defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com if (!_success) { \ 4773defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com LOG(ERROR) << #_x " failed."; \ 4783defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com return false; \ 4793defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } \ 4803defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } while (0) 4813defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4823defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_ERRNO(_x) \ 4833defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com do { \ 4842b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen bool _success = static_cast<bool>(_x); \ 4853defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com if (!_success) { \ 4863defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com std::string _msg = \ 4873defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com chromeos_update_engine::utils::ErrnoNumberAsString(errno); \ 4883defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com LOG(ERROR) << #_x " failed: " << _msg; \ 4893defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com return; \ 4903defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } \ 4913defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } while (0) 4923defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 4933defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN(_x) \ 4943defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com do { \ 4952b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen bool _success = static_cast<bool>(_x); \ 4963defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com if (!_success) { \ 4973defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com LOG(ERROR) << #_x " failed."; \ 4983defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com return; \ 4993defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } \ 5003defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com } while (0) 5013defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com 5025c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le#define TEST_AND_RETURN_FALSE_ERRCODE(_x) \ 5035c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le do { \ 5045c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le errcode_t _error = (_x); \ 5055c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le if (_error) { \ 5065c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le errno = _error; \ 5075c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le LOG(ERROR) << #_x " failed: " << _error; \ 5085c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le return false; \ 5095c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le } \ 5105c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le } while (0) 5115c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 51239910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif // UPDATE_ENGINE_COMMON_UTILS_H_ 513