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>
21cbc2274c4160805bf726df872390112654816ca7Alex Deymo#include <fcntl.h>
22cbc2274c4160805bf726df872390112654816ca7Alex Deymo#include <linux/loop.h>
23cbc2274c4160805bf726df872390112654816ca7Alex Deymo#include <linux/major.h>
2449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <stdio.h>
2549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <stdlib.h>
26cbc2274c4160805bf726df872390112654816ca7Alex 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
63f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkoconst uint8_t kRandomString[] = {
6410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xf2, 0xb7, 0x55, 0x92, 0xea, 0xa6, 0xc9, 0x57,
6510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xe0, 0xf8, 0xeb, 0x34, 0x93, 0xd9, 0xc4, 0x8f,
6610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xcb, 0x20, 0xfa, 0x37, 0x4b, 0x40, 0xcf, 0xdc,
6710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xa5, 0x08, 0x70, 0x89, 0x79, 0x35, 0xe2, 0x3d,
6810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x56, 0xa4, 0x75, 0x73, 0xa3, 0x6d, 0xd1, 0xd5,
6910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x26, 0xbb, 0x9c, 0x60, 0xbd, 0x2f, 0x5a, 0xfa,
7010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xb7, 0xd4, 0x3a, 0x50, 0xa7, 0x6b, 0x3e, 0xfd,
7110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x61, 0x2b, 0x3a, 0x31, 0x30, 0x13, 0x33, 0x53,
7210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xdb, 0xd0, 0x32, 0x71, 0x5c, 0x39, 0xed, 0xda,
7310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xb4, 0x84, 0xca, 0xbc, 0xbd, 0x78, 0x1c, 0x0c,
7410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xd8, 0x0b, 0x41, 0xe8, 0xe1, 0xe0, 0x41, 0xad,
7510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x03, 0x12, 0xd3, 0x3d, 0xb8, 0x75, 0x9b, 0xe6,
7610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xd9, 0x01, 0xd0, 0x87, 0xf4, 0x36, 0xfa, 0xa7,
7710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x0a, 0xfa, 0xc5, 0x87, 0x65, 0xab, 0x9a, 0x7b,
7810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xeb, 0x58, 0x23, 0xf0, 0xa8, 0x0a, 0xf2, 0x33,
7910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x3a, 0xe2, 0xe3, 0x35, 0x74, 0x95, 0xdd, 0x3c,
8010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x59, 0x5a, 0xd9, 0x52, 0x3a, 0x3c, 0xac, 0xe5,
8110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x15, 0x87, 0x6d, 0x82, 0xbc, 0xf8, 0x7d, 0xbe,
8210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xca, 0xd3, 0x2c, 0xd6, 0xec, 0x38, 0xeb, 0xe4,
8310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x53, 0xb0, 0x4c, 0x3f, 0x39, 0x29, 0xf7, 0xa4,
8410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x73, 0xa8, 0xcb, 0x32, 0x50, 0x05, 0x8c, 0x1c,
8510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x1c, 0xca, 0xc9, 0x76, 0x0b, 0x8f, 0x6b, 0x57,
8610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x1f, 0x24, 0x2b, 0xba, 0x82, 0xba, 0xed, 0x58,
8710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xd8, 0xbf, 0xec, 0x06, 0x64, 0x52, 0x6a, 0x3f,
8810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xe4, 0xad, 0xce, 0x84, 0xb4, 0x27, 0x55, 0x14,
8910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xe3, 0x75, 0x59, 0x73, 0x71, 0x51, 0xea, 0xe8,
9010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xcc, 0xda, 0x4f, 0x09, 0xaf, 0xa4, 0xbc, 0x0e,
9110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xa6, 0x1f, 0xe2, 0x3a, 0xf8, 0x96, 0x7d, 0x30,
9210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x23, 0xc5, 0x12, 0xb5, 0xd8, 0x73, 0x6b, 0x71,
9310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xab, 0xf1, 0xd7, 0x43, 0x58, 0xa7, 0xc9, 0xf0,
9410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xe4, 0x85, 0x1c, 0xd6, 0x92, 0x50, 0x2c, 0x98,
9510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x36, 0xfe, 0x87, 0xaf, 0x43, 0x8f, 0x8f, 0xf5,
9610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x88, 0x48, 0x18, 0x42, 0xcf, 0x42, 0xc1, 0xa8,
9710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xe8, 0x05, 0x08, 0xa1, 0x45, 0x70, 0x5b, 0x8c,
9810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x39, 0x28, 0xab, 0xe9, 0x6b, 0x51, 0xd2, 0xcb,
9910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x30, 0x04, 0xea, 0x7d, 0x2f, 0x6e, 0x6c, 0x3b,
10010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0x5f, 0x82, 0xd9, 0x5b, 0x89, 0x37, 0x65, 0x65,
10110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  0xbe, 0x9f, 0xa3, 0x5d,
10210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo};
10310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
104d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymostring Readlink(const string& path) {
105d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo  vector<char> buf(PATH_MAX + 1);
106d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo  ssize_t r = readlink(path.c_str(), buf.data(), buf.size());
107d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo  if (r < 0)
108d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo    return "";
109d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo  CHECK_LT(r, static_cast<ssize_t>(buf.size()));
110d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo  return string(buf.begin(), buf.begin() + r);
111d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo}
112d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo
11310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymobool IsXAttrSupported(const base::FilePath& dir_path) {
11410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  char *path = strdup(dir_path.Append("xattr_test_XXXXXX").value().c_str());
11510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
11610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  int fd = mkstemp(path);
11710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  if (fd == -1) {
11810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    PLOG(ERROR) << "Error creating temporary file in " << dir_path.value();
11910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    free(path);
12010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    return false;
12110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  }
12210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
12310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  if (unlink(path) != 0) {
12410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    PLOG(ERROR) << "Error unlinking temporary file " << path;
12510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    close(fd);
12610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    free(path);
12710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    return false;
12810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  }
12910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
13010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  int xattr_res = fsetxattr(fd, "user.xattr-test", "value", strlen("value"), 0);
13110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  if (xattr_res != 0) {
13210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    if (errno == ENOTSUP) {
13310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo      // Leave it to call-sites to warn about non-support.
13410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    } else {
13510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo      PLOG(ERROR) << "Error setting xattr on " << path;
13610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    }
13710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  }
13810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  close(fd);
13910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  free(path);
14010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  return xattr_res == 0;
14110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo}
14210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
1433f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool WriteFileVector(const string& path, const brillo::Blob& data) {
144f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko  return utils::WriteFile(path.c_str(), data.data(), data.size());
145c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com}
146c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
147f329b933db41d26644a97afef928eb1b319d6d99Alex Deymobool WriteFileString(const string& path, const string& data) {
148970bb28905b44bf9f2cb986bb412ecda1095b0b1Andrew de los Reyes  return utils::WriteFile(path.c_str(), data.data(), data.size());
149c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com}
150c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
151cbc2274c4160805bf726df872390112654816ca7Alex Deymobool BindToUnusedLoopDevice(const string& filename,
152cbc2274c4160805bf726df872390112654816ca7Alex Deymo                            bool writable,
153cbc2274c4160805bf726df872390112654816ca7Alex Deymo                            string* out_lo_dev_name) {
154cbc2274c4160805bf726df872390112654816ca7Alex Deymo  CHECK(out_lo_dev_name);
155cbc2274c4160805bf726df872390112654816ca7Alex Deymo  // Get the next available loop-device.
156cbc2274c4160805bf726df872390112654816ca7Alex Deymo  int control_fd =
157cbc2274c4160805bf726df872390112654816ca7Alex Deymo      HANDLE_EINTR(open("/dev/loop-control", O_RDWR | O_LARGEFILE));
158cbc2274c4160805bf726df872390112654816ca7Alex Deymo  TEST_AND_RETURN_FALSE_ERRNO(control_fd >= 0);
159cbc2274c4160805bf726df872390112654816ca7Alex Deymo  int loop_number = ioctl(control_fd, LOOP_CTL_GET_FREE);
160cbc2274c4160805bf726df872390112654816ca7Alex Deymo  IGNORE_EINTR(close(control_fd));
161cbc2274c4160805bf726df872390112654816ca7Alex Deymo  *out_lo_dev_name = StringPrintf("/dev/loop%d", loop_number);
162cbc2274c4160805bf726df872390112654816ca7Alex Deymo
163cbc2274c4160805bf726df872390112654816ca7Alex Deymo  // Double check that the loop exists and is free.
164cbc2274c4160805bf726df872390112654816ca7Alex Deymo  int loop_device_fd =
165cbc2274c4160805bf726df872390112654816ca7Alex Deymo      HANDLE_EINTR(open(out_lo_dev_name->c_str(), O_RDWR | O_LARGEFILE));
166cbc2274c4160805bf726df872390112654816ca7Alex Deymo  if (loop_device_fd == -1 && errno == ENOENT) {
167cbc2274c4160805bf726df872390112654816ca7Alex Deymo    // Workaround the case when the loop device doesn't exist.
168cbc2274c4160805bf726df872390112654816ca7Alex Deymo    TEST_AND_RETURN_FALSE_ERRNO(mknod(out_lo_dev_name->c_str(),
169cbc2274c4160805bf726df872390112654816ca7Alex Deymo                                      S_IFBLK | 0660,
170cbc2274c4160805bf726df872390112654816ca7Alex Deymo                                      makedev(LOOP_MAJOR, loop_number)) == 0);
171cbc2274c4160805bf726df872390112654816ca7Alex Deymo    loop_device_fd =
172cbc2274c4160805bf726df872390112654816ca7Alex Deymo        HANDLE_EINTR(open(out_lo_dev_name->c_str(), O_RDWR | O_LARGEFILE));
173cbc2274c4160805bf726df872390112654816ca7Alex Deymo  }
174cbc2274c4160805bf726df872390112654816ca7Alex Deymo  TEST_AND_RETURN_FALSE_ERRNO(loop_device_fd != -1);
175cbc2274c4160805bf726df872390112654816ca7Alex Deymo  ScopedFdCloser loop_device_fd_closer(&loop_device_fd);
176cbc2274c4160805bf726df872390112654816ca7Alex Deymo
177cbc2274c4160805bf726df872390112654816ca7Alex Deymo  struct loop_info64 device_info;
178cbc2274c4160805bf726df872390112654816ca7Alex Deymo  if (ioctl(loop_device_fd, LOOP_GET_STATUS64, &device_info) != -1 ||
179cbc2274c4160805bf726df872390112654816ca7Alex Deymo      errno != ENXIO) {
180cbc2274c4160805bf726df872390112654816ca7Alex Deymo    PLOG(ERROR) << "Loop device " << out_lo_dev_name->c_str()
181cbc2274c4160805bf726df872390112654816ca7Alex Deymo                << " already in use";
18219a45f0eda0917b7788b925b501e774208474fdeGilad Arnold    return false;
183c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  }
184c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
185cbc2274c4160805bf726df872390112654816ca7Alex Deymo  // Open our data file and assign it to the loop device.
186cbc2274c4160805bf726df872390112654816ca7Alex Deymo  int data_fd = open(filename.c_str(),
187cbc2274c4160805bf726df872390112654816ca7Alex Deymo                     (writable ? O_RDWR : O_RDONLY) | O_LARGEFILE | O_CLOEXEC);
188cbc2274c4160805bf726df872390112654816ca7Alex Deymo  TEST_AND_RETURN_FALSE_ERRNO(data_fd >= 0);
189cbc2274c4160805bf726df872390112654816ca7Alex Deymo  ScopedFdCloser data_fd_closer(&data_fd);
190cbc2274c4160805bf726df872390112654816ca7Alex Deymo  TEST_AND_RETURN_FALSE_ERRNO(ioctl(loop_device_fd, LOOP_SET_FD, data_fd) == 0);
191cbc2274c4160805bf726df872390112654816ca7Alex Deymo
192cbc2274c4160805bf726df872390112654816ca7Alex Deymo  memset(&device_info, 0, sizeof(device_info));
193cbc2274c4160805bf726df872390112654816ca7Alex Deymo  device_info.lo_offset = 0;
194cbc2274c4160805bf726df872390112654816ca7Alex Deymo  device_info.lo_sizelimit = 0;  // 0 means whole file.
195cbc2274c4160805bf726df872390112654816ca7Alex Deymo  device_info.lo_flags = (writable ? 0 : LO_FLAGS_READ_ONLY);
196cbc2274c4160805bf726df872390112654816ca7Alex Deymo  device_info.lo_number = loop_number;
197cbc2274c4160805bf726df872390112654816ca7Alex Deymo  strncpy(reinterpret_cast<char*>(device_info.lo_file_name),
198cbc2274c4160805bf726df872390112654816ca7Alex Deymo          base::FilePath(filename).BaseName().value().c_str(),
199cbc2274c4160805bf726df872390112654816ca7Alex Deymo          LO_NAME_SIZE - 1);
200cbc2274c4160805bf726df872390112654816ca7Alex Deymo  device_info.lo_file_name[LO_NAME_SIZE - 1] = '\0';
201cbc2274c4160805bf726df872390112654816ca7Alex Deymo  TEST_AND_RETURN_FALSE_ERRNO(
202cbc2274c4160805bf726df872390112654816ca7Alex Deymo      ioctl(loop_device_fd, LOOP_SET_STATUS64, &device_info) == 0);
203cbc2274c4160805bf726df872390112654816ca7Alex Deymo  return true;
204cbc2274c4160805bf726df872390112654816ca7Alex Deymo}
205c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
206cbc2274c4160805bf726df872390112654816ca7Alex Deymobool UnbindLoopDevice(const string& lo_dev_name) {
207cbc2274c4160805bf726df872390112654816ca7Alex Deymo  int loop_device_fd =
208cbc2274c4160805bf726df872390112654816ca7Alex Deymo      HANDLE_EINTR(open(lo_dev_name.c_str(), O_RDWR | O_LARGEFILE));
209cbc2274c4160805bf726df872390112654816ca7Alex Deymo  if (loop_device_fd == -1 && errno == ENOENT)
210cbc2274c4160805bf726df872390112654816ca7Alex Deymo    return true;
211cbc2274c4160805bf726df872390112654816ca7Alex Deymo  TEST_AND_RETURN_FALSE_ERRNO(loop_device_fd != -1);
212cbc2274c4160805bf726df872390112654816ca7Alex Deymo  ScopedFdCloser loop_device_fd_closer(&loop_device_fd);
213cbc2274c4160805bf726df872390112654816ca7Alex Deymo
214cbc2274c4160805bf726df872390112654816ca7Alex Deymo  struct loop_info64 device_info;
215cbc2274c4160805bf726df872390112654816ca7Alex Deymo  // Check if the device is bound before trying to unbind it.
216cbc2274c4160805bf726df872390112654816ca7Alex Deymo  int get_stat_err = ioctl(loop_device_fd, LOOP_GET_STATUS64, &device_info);
217cbc2274c4160805bf726df872390112654816ca7Alex Deymo  if (get_stat_err == -1 && errno == ENXIO)
218cbc2274c4160805bf726df872390112654816ca7Alex Deymo    return true;
219cbc2274c4160805bf726df872390112654816ca7Alex Deymo
220cbc2274c4160805bf726df872390112654816ca7Alex Deymo  TEST_AND_RETURN_FALSE_ERRNO(ioctl(loop_device_fd, LOOP_CLR_FD) == 0);
22119a45f0eda0917b7788b925b501e774208474fdeGilad Arnold  return true;
222c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com}
223c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
2243f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool ExpectVectorsEq(const brillo::Blob& expected,
2253f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko                     const brillo::Blob& actual) {
2268006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  EXPECT_EQ(expected.size(), actual.size());
2278006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  if (expected.size() != actual.size())
228c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    return false;
229617bbc23d2cf4cba5881ec54607926393f7245c7Gilad Arnold  bool is_all_eq = true;
2308006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  for (unsigned int i = 0; i < expected.size(); i++) {
2318006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes    EXPECT_EQ(expected[i], actual[i]) << "offset: " << i;
232617bbc23d2cf4cba5881ec54607926393f7245c7Gilad Arnold    is_all_eq = is_all_eq && (expected[i] == actual[i]);
233c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  }
234617bbc23d2cf4cba5881ec54607926393f7245c7Gilad Arnold  return is_all_eq;
235c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com}
236c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
2373f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkovoid FillWithData(brillo::Blob* buffer) {
2388006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  size_t input_counter = 0;
239f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko  for (uint8_t& b : *buffer) {
240f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko    b = kRandomString[input_counter];
2418006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes    input_counter++;
2428006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes    input_counter %= sizeof(kRandomString);
2438006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  }
2448006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes}
2458006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
24658e8b1f8b32b355d879008572648fd621873711dDon GarrettScopedLoopMounter::ScopedLoopMounter(const string& file_path,
24758e8b1f8b32b355d879008572648fd621873711dDon Garrett                                     string* mnt_path,
248d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko                                     unsigned long flags) {  // NOLINT - long
249371615b025bdd8106faf65c1ba7439a1236f21bcSen Jiang  EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
250371615b025bdd8106faf65c1ba7439a1236f21bcSen Jiang  *mnt_path = temp_dir_.path().value();
2515c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le
25258e8b1f8b32b355d879008572648fd621873711dDon Garrett  string loop_dev;
253cbc2274c4160805bf726df872390112654816ca7Alex Deymo  loop_binder_.reset(
254cbc2274c4160805bf726df872390112654816ca7Alex Deymo      new ScopedLoopbackDeviceBinder(file_path, true, &loop_dev));
2555c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le
2562c41357811af9b47e80cf526ec53f4b4e5c351fcSen Jiang  EXPECT_TRUE(utils::MountFilesystem(loop_dev, *mnt_path, flags, "", ""));
2575c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le  unmounter_.reset(new ScopedFilesystemUnmounter(*mnt_path));
2585c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le}
2595c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le
2602b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymobase::FilePath GetBuildArtifactsPath() {
2612b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo  base::FilePath exe_path;
2622b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo  base::ReadSymbolicLink(base::FilePath("/proc/self/exe"), &exe_path);
2632b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo  return exe_path.DirName();
2642b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo}
2652b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo
266260f03bc4d3a3de436e056c686c814444358823aSen Jiangstring GetBuildArtifactsPath(const string& relative_path) {
267260f03bc4d3a3de436e056c686c814444358823aSen Jiang  return GetBuildArtifactsPath().Append(relative_path).value();
268260f03bc4d3a3de436e056c686c814444358823aSen Jiang}
269260f03bc4d3a3de436e056c686c814444358823aSen Jiang
27010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo}  // namespace test_utils
27149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}  // namespace chromeos_update_engine
272