1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2012 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/test_utils.h" 1809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 196b9e38ef1180efe55e4a82bb18536d1b53fe493dAlex Deymo#include <dirent.h> 20c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <errno.h> 21c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo#include <fcntl.h> 22c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo#include <linux/loop.h> 23c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo#include <linux/major.h> 2449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <stdio.h> 2549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <stdlib.h> 26c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo#include <sys/ioctl.h> 27161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo#include <sys/stat.h> 28161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo#include <sys/types.h> 296f20dd4fc8861d93d188cd27323d2f9746464aafAlex Deymo#include <sys/xattr.h> 3049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <unistd.h> 3109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 32c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <set> 3349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <string> 3449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <vector> 3509e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes 362b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo#include <base/files/file_util.h> 37c00c98a1dad941e5cc04ce0b0e766d40b3b384e1Alex Deymo#include <base/format_macros.h> 38161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo#include <base/logging.h> 392b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo#include <base/strings/string_util.h> 40305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo#include <base/strings/stringprintf.h> 41161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymo 4264d9878470aa7b388e971862181daf6260851602Alex Deymo#include "update_engine/common/error_code_utils.h" 4339910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/utils.h" 4439910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/payload_consumer/file_writer.h" 4549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 46161c4a132743f15fc4757112b673085c2a7a7f29Alex Deymousing base::StringPrintf; 47c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comusing std::set; 4849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comusing std::string; 4949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comusing std::vector; 5049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 5149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine { 5249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 5352490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymovoid PrintTo(const Extent& extent, ::std::ostream* os) { 5452490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo *os << "(" << extent.start_block() << ", " << extent.num_blocks() << ")"; 5552490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo} 5652490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo 5764d9878470aa7b388e971862181daf6260851602Alex Deymovoid PrintTo(const ErrorCode& error_code, ::std::ostream* os) { 5864d9878470aa7b388e971862181daf6260851602Alex Deymo *os << utils::ErrorCodeToString(error_code); 5964d9878470aa7b388e971862181daf6260851602Alex Deymo} 6064d9878470aa7b388e971862181daf6260851602Alex Deymo 6110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymonamespace test_utils { 6210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 63a6742b35938b6f58e24e3f1c550fe92d4d33eb74Gilad Arnoldconst char* const kMountPathTemplate = "UpdateEngineTests_mnt-XXXXXX"; 6461d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold 65f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkoconst uint8_t kRandomString[] = { 6610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xf2, 0xb7, 0x55, 0x92, 0xea, 0xa6, 0xc9, 0x57, 6710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xe0, 0xf8, 0xeb, 0x34, 0x93, 0xd9, 0xc4, 0x8f, 6810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xcb, 0x20, 0xfa, 0x37, 0x4b, 0x40, 0xcf, 0xdc, 6910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xa5, 0x08, 0x70, 0x89, 0x79, 0x35, 0xe2, 0x3d, 7010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x56, 0xa4, 0x75, 0x73, 0xa3, 0x6d, 0xd1, 0xd5, 7110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x26, 0xbb, 0x9c, 0x60, 0xbd, 0x2f, 0x5a, 0xfa, 7210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xb7, 0xd4, 0x3a, 0x50, 0xa7, 0x6b, 0x3e, 0xfd, 7310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x61, 0x2b, 0x3a, 0x31, 0x30, 0x13, 0x33, 0x53, 7410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xdb, 0xd0, 0x32, 0x71, 0x5c, 0x39, 0xed, 0xda, 7510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xb4, 0x84, 0xca, 0xbc, 0xbd, 0x78, 0x1c, 0x0c, 7610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xd8, 0x0b, 0x41, 0xe8, 0xe1, 0xe0, 0x41, 0xad, 7710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x03, 0x12, 0xd3, 0x3d, 0xb8, 0x75, 0x9b, 0xe6, 7810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xd9, 0x01, 0xd0, 0x87, 0xf4, 0x36, 0xfa, 0xa7, 7910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x0a, 0xfa, 0xc5, 0x87, 0x65, 0xab, 0x9a, 0x7b, 8010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xeb, 0x58, 0x23, 0xf0, 0xa8, 0x0a, 0xf2, 0x33, 8110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x3a, 0xe2, 0xe3, 0x35, 0x74, 0x95, 0xdd, 0x3c, 8210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x59, 0x5a, 0xd9, 0x52, 0x3a, 0x3c, 0xac, 0xe5, 8310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x15, 0x87, 0x6d, 0x82, 0xbc, 0xf8, 0x7d, 0xbe, 8410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xca, 0xd3, 0x2c, 0xd6, 0xec, 0x38, 0xeb, 0xe4, 8510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x53, 0xb0, 0x4c, 0x3f, 0x39, 0x29, 0xf7, 0xa4, 8610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x73, 0xa8, 0xcb, 0x32, 0x50, 0x05, 0x8c, 0x1c, 8710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x1c, 0xca, 0xc9, 0x76, 0x0b, 0x8f, 0x6b, 0x57, 8810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x1f, 0x24, 0x2b, 0xba, 0x82, 0xba, 0xed, 0x58, 8910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xd8, 0xbf, 0xec, 0x06, 0x64, 0x52, 0x6a, 0x3f, 9010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xe4, 0xad, 0xce, 0x84, 0xb4, 0x27, 0x55, 0x14, 9110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xe3, 0x75, 0x59, 0x73, 0x71, 0x51, 0xea, 0xe8, 9210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xcc, 0xda, 0x4f, 0x09, 0xaf, 0xa4, 0xbc, 0x0e, 9310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xa6, 0x1f, 0xe2, 0x3a, 0xf8, 0x96, 0x7d, 0x30, 9410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x23, 0xc5, 0x12, 0xb5, 0xd8, 0x73, 0x6b, 0x71, 9510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xab, 0xf1, 0xd7, 0x43, 0x58, 0xa7, 0xc9, 0xf0, 9610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xe4, 0x85, 0x1c, 0xd6, 0x92, 0x50, 0x2c, 0x98, 9710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x36, 0xfe, 0x87, 0xaf, 0x43, 0x8f, 0x8f, 0xf5, 9810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x88, 0x48, 0x18, 0x42, 0xcf, 0x42, 0xc1, 0xa8, 9910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xe8, 0x05, 0x08, 0xa1, 0x45, 0x70, 0x5b, 0x8c, 10010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x39, 0x28, 0xab, 0xe9, 0x6b, 0x51, 0xd2, 0xcb, 10110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x30, 0x04, 0xea, 0x7d, 0x2f, 0x6e, 0x6c, 0x3b, 10210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0x5f, 0x82, 0xd9, 0x5b, 0x89, 0x37, 0x65, 0x65, 10310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 0xbe, 0x9f, 0xa3, 0x5d, 10410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo}; 10510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 106bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymostring Readlink(const string& path) { 107bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymo vector<char> buf(PATH_MAX + 1); 108bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymo ssize_t r = readlink(path.c_str(), buf.data(), buf.size()); 109bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymo if (r < 0) 110bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymo return ""; 111bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymo CHECK_LT(r, static_cast<ssize_t>(buf.size())); 112bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymo return string(buf.begin(), buf.begin() + r); 113bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymo} 114bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymo 11510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymobool IsXAttrSupported(const base::FilePath& dir_path) { 11610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo char *path = strdup(dir_path.Append("xattr_test_XXXXXX").value().c_str()); 11710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 11810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo int fd = mkstemp(path); 11910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (fd == -1) { 12010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo PLOG(ERROR) << "Error creating temporary file in " << dir_path.value(); 12110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo free(path); 12210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return false; 12310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 12410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 12510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (unlink(path) != 0) { 12610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo PLOG(ERROR) << "Error unlinking temporary file " << path; 12710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo close(fd); 12810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo free(path); 12910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return false; 13010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 13110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 13210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo int xattr_res = fsetxattr(fd, "user.xattr-test", "value", strlen("value"), 0); 13310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (xattr_res != 0) { 13410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo if (errno == ENOTSUP) { 13510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo // Leave it to call-sites to warn about non-support. 13610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } else { 13710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo PLOG(ERROR) << "Error setting xattr on " << path; 13810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 13910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo } 14010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo close(fd); 14110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo free(path); 14210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo return xattr_res == 0; 14310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo} 14410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo 1453f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool WriteFileVector(const string& path, const brillo::Blob& data) { 146f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko return utils::WriteFile(path.c_str(), data.data(), data.size()); 147c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com} 148c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 149f329b933db41d26644a97afef928eb1b319d6d99Alex Deymobool WriteFileString(const string& path, const string& data) { 150970bb28905b44bf9f2cb986bb412ecda1095b0b1Andrew de los Reyes return utils::WriteFile(path.c_str(), data.data(), data.size()); 151c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com} 152c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 153c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymobool BindToUnusedLoopDevice(const string& filename, 154c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo bool writable, 155c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo string* out_lo_dev_name) { 156c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo CHECK(out_lo_dev_name); 157c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo // Get the next available loop-device. 158c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo int control_fd = 159c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo HANDLE_EINTR(open("/dev/loop-control", O_RDWR | O_LARGEFILE)); 160c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo TEST_AND_RETURN_FALSE_ERRNO(control_fd >= 0); 161c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo int loop_number = ioctl(control_fd, LOOP_CTL_GET_FREE); 162c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo IGNORE_EINTR(close(control_fd)); 163c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo *out_lo_dev_name = StringPrintf("/dev/loop%d", loop_number); 164c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo 165c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo // Double check that the loop exists and is free. 166c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo int loop_device_fd = 167c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo HANDLE_EINTR(open(out_lo_dev_name->c_str(), O_RDWR | O_LARGEFILE)); 168c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo if (loop_device_fd == -1 && errno == ENOENT) { 169c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo // Workaround the case when the loop device doesn't exist. 170c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo TEST_AND_RETURN_FALSE_ERRNO(mknod(out_lo_dev_name->c_str(), 171c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo S_IFBLK | 0660, 172c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo makedev(LOOP_MAJOR, loop_number)) == 0); 173c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo loop_device_fd = 174c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo HANDLE_EINTR(open(out_lo_dev_name->c_str(), O_RDWR | O_LARGEFILE)); 175c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo } 176c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo TEST_AND_RETURN_FALSE_ERRNO(loop_device_fd != -1); 177c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo ScopedFdCloser loop_device_fd_closer(&loop_device_fd); 178c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo 179c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo struct loop_info64 device_info; 180c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo if (ioctl(loop_device_fd, LOOP_GET_STATUS64, &device_info) != -1 || 181c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo errno != ENXIO) { 182c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo PLOG(ERROR) << "Loop device " << out_lo_dev_name->c_str() 183c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo << " already in use"; 18419a45f0eda0917b7788b925b501e774208474fdeGilad Arnold return false; 185c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com } 186c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 187c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo // Open our data file and assign it to the loop device. 188c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo int data_fd = open(filename.c_str(), 189c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo (writable ? O_RDWR : O_RDONLY) | O_LARGEFILE | O_CLOEXEC); 190c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo TEST_AND_RETURN_FALSE_ERRNO(data_fd >= 0); 191c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo ScopedFdCloser data_fd_closer(&data_fd); 192c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo TEST_AND_RETURN_FALSE_ERRNO(ioctl(loop_device_fd, LOOP_SET_FD, data_fd) == 0); 193c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo 194c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo memset(&device_info, 0, sizeof(device_info)); 195c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo device_info.lo_offset = 0; 196c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo device_info.lo_sizelimit = 0; // 0 means whole file. 197c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo device_info.lo_flags = (writable ? 0 : LO_FLAGS_READ_ONLY); 198c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo device_info.lo_number = loop_number; 199c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo strncpy(reinterpret_cast<char*>(device_info.lo_file_name), 200c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo base::FilePath(filename).BaseName().value().c_str(), 201c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo LO_NAME_SIZE - 1); 202c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo device_info.lo_file_name[LO_NAME_SIZE - 1] = '\0'; 203c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo TEST_AND_RETURN_FALSE_ERRNO( 204c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo ioctl(loop_device_fd, LOOP_SET_STATUS64, &device_info) == 0); 205c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo return true; 206c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo} 207c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 208c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymobool UnbindLoopDevice(const string& lo_dev_name) { 209c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo int loop_device_fd = 210c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo HANDLE_EINTR(open(lo_dev_name.c_str(), O_RDWR | O_LARGEFILE)); 211c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo if (loop_device_fd == -1 && errno == ENOENT) 212c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo return true; 213c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo TEST_AND_RETURN_FALSE_ERRNO(loop_device_fd != -1); 214c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo ScopedFdCloser loop_device_fd_closer(&loop_device_fd); 215c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo 216c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo struct loop_info64 device_info; 217c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo // Check if the device is bound before trying to unbind it. 218c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo int get_stat_err = ioctl(loop_device_fd, LOOP_GET_STATUS64, &device_info); 219c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo if (get_stat_err == -1 && errno == ENXIO) 220c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo return true; 221c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo 222c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo TEST_AND_RETURN_FALSE_ERRNO(ioctl(loop_device_fd, LOOP_CLR_FD) == 0); 22319a45f0eda0917b7788b925b501e774208474fdeGilad Arnold return true; 224c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com} 225c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 2263f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool ExpectVectorsEq(const brillo::Blob& expected, 2273f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko const brillo::Blob& actual) { 2288006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes EXPECT_EQ(expected.size(), actual.size()); 2298006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes if (expected.size() != actual.size()) 230c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com return false; 231617bbc23d2cf4cba5881ec54607926393f7245c7Gilad Arnold bool is_all_eq = true; 2328006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes for (unsigned int i = 0; i < expected.size(); i++) { 2338006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes EXPECT_EQ(expected[i], actual[i]) << "offset: " << i; 234617bbc23d2cf4cba5881ec54607926393f7245c7Gilad Arnold is_all_eq = is_all_eq && (expected[i] == actual[i]); 235c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com } 236617bbc23d2cf4cba5881ec54607926393f7245c7Gilad Arnold return is_all_eq; 237c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com} 238c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 2393f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkovoid FillWithData(brillo::Blob* buffer) { 2408006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes size_t input_counter = 0; 241f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko for (uint8_t& b : *buffer) { 242f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko b = kRandomString[input_counter]; 2438006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes input_counter++; 2448006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes input_counter %= sizeof(kRandomString); 2458006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes } 2468006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes} 2478006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 2485c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Levoid CreateEmptyExtImageAtPath(const string& path, 2495c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le size_t size, 2505c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le int block_size) { 2515c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le EXPECT_EQ(0, System(StringPrintf("dd if=/dev/zero of=%s" 252c00c98a1dad941e5cc04ce0b0e766d40b3b384e1Alex Deymo " seek=%" PRIuS " bs=1 count=1 status=none", 2535c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le path.c_str(), size))); 2546ded6548c4d3606923d606981dd29f224bcfc723Alex Deymo EXPECT_EQ(0, System(StringPrintf("mkfs.ext3 -q -b %d -F %s", 2555c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le block_size, path.c_str()))); 2565c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le} 2575c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 258c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comvoid CreateExtImageAtPath(const string& path, vector<string>* out_paths) { 25961d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold // create 10MiB sparse file, mounted at a unique location. 26061d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold string mount_path; 26161d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold CHECK(utils::MakeTempDirectory(kMountPathTemplate, &mount_path)); 262a58b62a57eb2fe4070ed7efbf869b37037fbeaa7Alex Deymo ScopedDirRemover mount_path_unlinker(mount_path); 26361d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold 264c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_EQ(0, System(StringPrintf("dd if=/dev/zero of=%s" 2651f93d031baa4c0c4f390fcf5784b5179d15f289dAlex Deymo " seek=10485759 bs=1 count=1 status=none", 266c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com path.c_str()))); 2676ded6548c4d3606923d606981dd29f224bcfc723Alex Deymo EXPECT_EQ(0, System(StringPrintf("mkfs.ext3 -q -b 4096 -F %s", 2686ded6548c4d3606923d606981dd29f224bcfc723Alex Deymo path.c_str()))); 269c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_EQ(0, System(StringPrintf("mount -o loop %s %s", path.c_str(), 27061d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 27161d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("echo hi > %s/hi", mount_path.c_str()))); 27261d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("echo hello > %s/hello", 27361d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 27461d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir", mount_path.c_str()))); 27561d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir/empty_dir", 27661d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 27761d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir/mnt", 27861d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 27961d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("echo T > %s/some_dir/test", 28061d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 28161d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("mkfifo %s/some_dir/fifo", 28261d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 28361d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("mknod %s/cdev c 2 3", mount_path.c_str()))); 28461d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("ln -s /some/target %s/sym", 28561d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 286c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com EXPECT_EQ(0, System(StringPrintf("ln %s/some_dir/test %s/testlink", 28761d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str(), mount_path.c_str()))); 28861d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_EQ(0, System(StringPrintf("echo T > %s/srchardlink0", 28961d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 29029da8aafd5da32ebfb57c7f3cf1b89ce3e5d60cbAndrew de los Reyes EXPECT_EQ(0, System(StringPrintf("ln %s/srchardlink0 %s/srchardlink1", 29161d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str(), mount_path.c_str()))); 29248a0a4826c47fe097d7ff31ad830911c1f288dbfAndrew de los Reyes EXPECT_EQ(0, System(StringPrintf("ln -s bogus %s/boguslink", 29361d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold mount_path.c_str()))); 29461d9d2c93ffd65818c5aae21791099842a5d4938Gilad Arnold EXPECT_TRUE(utils::UnmountFilesystem(mount_path.c_str())); 2955c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 296c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com if (out_paths) { 297c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->clear(); 298c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back(""); 299c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/hi"); 30048a0a4826c47fe097d7ff31ad830911c1f288dbfAndrew de los Reyes out_paths->push_back("/boguslink"); 301c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/hello"); 302c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/some_dir"); 303c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/some_dir/empty_dir"); 304c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/some_dir/mnt"); 305c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/some_dir/test"); 306c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/some_dir/fifo"); 307c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/cdev"); 308c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/testlink"); 309c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/sym"); 31029da8aafd5da32ebfb57c7f3cf1b89ce3e5d60cbAndrew de los Reyes out_paths->push_back("/srchardlink0"); 31129da8aafd5da32ebfb57c7f3cf1b89ce3e5d60cbAndrew de los Reyes out_paths->push_back("/srchardlink1"); 312c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com out_paths->push_back("/lost+found"); 313c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com } 314c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com} 315c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 31658e8b1f8b32b355d879008572648fd621873711dDon GarrettScopedLoopMounter::ScopedLoopMounter(const string& file_path, 31758e8b1f8b32b355d879008572648fd621873711dDon Garrett string* mnt_path, 318d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko unsigned long flags) { // NOLINT - long 319a6742b35938b6f58e24e3f1c550fe92d4d33eb74Gilad Arnold EXPECT_TRUE(utils::MakeTempDirectory("mnt.XXXXXX", mnt_path)); 3205c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le dir_remover_.reset(new ScopedDirRemover(*mnt_path)); 3215c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 32258e8b1f8b32b355d879008572648fd621873711dDon Garrett string loop_dev; 323c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo loop_binder_.reset( 324c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo new ScopedLoopbackDeviceBinder(file_path, true, &loop_dev)); 3255c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 32614dbd333439f34c648b9f783ffa656ef565de0ccAlex Deymo EXPECT_TRUE(utils::MountFilesystem(loop_dev, *mnt_path, flags, "", nullptr)); 3275c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le unmounter_.reset(new ScopedFilesystemUnmounter(*mnt_path)); 3285c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le} 3295c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le 3302b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymobase::FilePath GetBuildArtifactsPath() { 3312b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo base::FilePath exe_path; 3322b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo base::ReadSymbolicLink(base::FilePath("/proc/self/exe"), &exe_path); 3332b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo return exe_path.DirName(); 3342b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo} 3352b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo 33610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo} // namespace test_utils 33749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com} // namespace chromeos_update_engine 338