1fb299fa2Sopenharmony_ci/* 2fb299fa2Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at 6fb299fa2Sopenharmony_ci * 7fb299fa2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb299fa2Sopenharmony_ci * 9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and 13fb299fa2Sopenharmony_ci * limitations under the License. 14fb299fa2Sopenharmony_ci */ 15fb299fa2Sopenharmony_ci#include "applypatch/store.h" 16fb299fa2Sopenharmony_ci#include <algorithm> 17fb299fa2Sopenharmony_ci#include <cstdio> 18fb299fa2Sopenharmony_ci#include <fcntl.h> 19fb299fa2Sopenharmony_ci#include <limits> 20fb299fa2Sopenharmony_ci#include <sys/stat.h> 21fb299fa2Sopenharmony_ci#include <sys/types.h> 22fb299fa2Sopenharmony_ci#include <sys/vfs.h> 23fb299fa2Sopenharmony_ci#include <unistd.h> 24fb299fa2Sopenharmony_ci#include "applypatch/transfer_manager.h" 25fb299fa2Sopenharmony_ci#include "log/log.h" 26fb299fa2Sopenharmony_ci#include "utils.h" 27fb299fa2Sopenharmony_ci 28fb299fa2Sopenharmony_ciusing namespace Updater::Utils; 29fb299fa2Sopenharmony_ci 30fb299fa2Sopenharmony_cinamespace Updater { 31fb299fa2Sopenharmony_civoid Store::DoFreeSpace(const std::string &directoryPath) 32fb299fa2Sopenharmony_ci{ 33fb299fa2Sopenharmony_ci std::vector<std::string> files; 34fb299fa2Sopenharmony_ci if (GetFilesFromDirectory(directoryPath, files, true) <= 0) { 35fb299fa2Sopenharmony_ci LOG(WARNING) << "Failed to get files for free space"; 36fb299fa2Sopenharmony_ci return; 37fb299fa2Sopenharmony_ci } 38fb299fa2Sopenharmony_ci for (const auto &file : files) { 39fb299fa2Sopenharmony_ci if (DeleteFile(file.c_str()) == -1) { 40fb299fa2Sopenharmony_ci LOG(ERROR) << "Failed to delete in do free space"; 41fb299fa2Sopenharmony_ci continue; 42fb299fa2Sopenharmony_ci } 43fb299fa2Sopenharmony_ci } 44fb299fa2Sopenharmony_ci} 45fb299fa2Sopenharmony_ci 46fb299fa2Sopenharmony_ciint32_t Store::FreeStore(const std::string &dirPath, const std::string &fileName) 47fb299fa2Sopenharmony_ci{ 48fb299fa2Sopenharmony_ci if (dirPath.empty() || fileName.empty()) { 49fb299fa2Sopenharmony_ci return -1; 50fb299fa2Sopenharmony_ci } 51fb299fa2Sopenharmony_ci std::string path = dirPath + "/" + fileName; 52fb299fa2Sopenharmony_ci if (DeleteFile(path.c_str()) != -1) { 53fb299fa2Sopenharmony_ci return 0; 54fb299fa2Sopenharmony_ci } 55fb299fa2Sopenharmony_ci LOG(ERROR) << "Failed to delete " << path; 56fb299fa2Sopenharmony_ci return -1; 57fb299fa2Sopenharmony_ci} 58fb299fa2Sopenharmony_ci 59fb299fa2Sopenharmony_ciint32_t Store::CreateNewSpace(const std::string &path, bool needClear) 60fb299fa2Sopenharmony_ci{ 61fb299fa2Sopenharmony_ci if (path.empty()) { 62fb299fa2Sopenharmony_ci LOG(ERROR) << "path is empty."; 63fb299fa2Sopenharmony_ci } 64fb299fa2Sopenharmony_ci std::string dirPath = path + '/'; 65fb299fa2Sopenharmony_ci struct stat fileStat {}; 66fb299fa2Sopenharmony_ci LOG(INFO) << "Create dir " << dirPath; 67fb299fa2Sopenharmony_ci if (stat(dirPath.c_str(), &fileStat) == -1) { 68fb299fa2Sopenharmony_ci if (errno != ENOENT) { 69fb299fa2Sopenharmony_ci LOG(ERROR) << "Create new space, failed to stat"; 70fb299fa2Sopenharmony_ci return -1; 71fb299fa2Sopenharmony_ci } 72fb299fa2Sopenharmony_ci if (MkdirRecursive(dirPath, S_IRWXU) != 0) { 73fb299fa2Sopenharmony_ci LOG(ERROR) << "Failed to make store"; 74fb299fa2Sopenharmony_ci return -1; 75fb299fa2Sopenharmony_ci } 76fb299fa2Sopenharmony_ci } else { 77fb299fa2Sopenharmony_ci if (!needClear) { 78fb299fa2Sopenharmony_ci return 0; 79fb299fa2Sopenharmony_ci } 80fb299fa2Sopenharmony_ci std::vector<std::string> files {}; 81fb299fa2Sopenharmony_ci if (GetFilesFromDirectory(dirPath, files) < 0) { 82fb299fa2Sopenharmony_ci return -1; 83fb299fa2Sopenharmony_ci } 84fb299fa2Sopenharmony_ci if (files.empty()) { 85fb299fa2Sopenharmony_ci return 0; 86fb299fa2Sopenharmony_ci } 87fb299fa2Sopenharmony_ci std::vector<std::string>::iterator iter = files.begin(); 88fb299fa2Sopenharmony_ci while (iter != files.end()) { 89fb299fa2Sopenharmony_ci if (DeleteFile(*iter) == 0) { 90fb299fa2Sopenharmony_ci LOG(INFO) << "Delete " << *iter; 91fb299fa2Sopenharmony_ci } 92fb299fa2Sopenharmony_ci iter++; 93fb299fa2Sopenharmony_ci } 94fb299fa2Sopenharmony_ci files.clear(); 95fb299fa2Sopenharmony_ci } 96fb299fa2Sopenharmony_ci return 0; 97fb299fa2Sopenharmony_ci} 98fb299fa2Sopenharmony_ci 99fb299fa2Sopenharmony_ciint32_t Store::WriteDataToStore(const std::string &dirPath, const std::string &fileName, 100fb299fa2Sopenharmony_ci const std::vector<uint8_t> &buffer, int size) 101fb299fa2Sopenharmony_ci{ 102fb299fa2Sopenharmony_ci if (dirPath.empty()) { 103fb299fa2Sopenharmony_ci return -1; 104fb299fa2Sopenharmony_ci } 105fb299fa2Sopenharmony_ci std::string pathTmp; 106fb299fa2Sopenharmony_ci if (!fileName.empty()) { 107fb299fa2Sopenharmony_ci pathTmp = dirPath + "/"; 108fb299fa2Sopenharmony_ci } 109fb299fa2Sopenharmony_ci std::string path = pathTmp + fileName; 110fb299fa2Sopenharmony_ci pathTmp = pathTmp + fileName; 111fb299fa2Sopenharmony_ci 112fb299fa2Sopenharmony_ci int fd = open(pathTmp.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); 113fb299fa2Sopenharmony_ci if (fd == -1) { 114fb299fa2Sopenharmony_ci LOG(ERROR) << "Failed to create store, " << strerror(errno); 115fb299fa2Sopenharmony_ci return -1; 116fb299fa2Sopenharmony_ci } 117fb299fa2Sopenharmony_ci if (size < 0 || !WriteFully(fd, buffer.data(), static_cast<size_t>(size))) { 118fb299fa2Sopenharmony_ci if (errno == EIO) { 119fb299fa2Sopenharmony_ci close(fd); 120fb299fa2Sopenharmony_ci return 1; 121fb299fa2Sopenharmony_ci } 122fb299fa2Sopenharmony_ci LOG(ERROR) << "Write to stash failed, " << size << " blocks to " << path; 123fb299fa2Sopenharmony_ci close(fd); 124fb299fa2Sopenharmony_ci return -1; 125fb299fa2Sopenharmony_ci } 126fb299fa2Sopenharmony_ci if (fsync(fd) == -1) { 127fb299fa2Sopenharmony_ci LOG(WARNING) << "Failed to fsync :" << strerror(errno); 128fb299fa2Sopenharmony_ci } 129fb299fa2Sopenharmony_ci close(fd); 130fb299fa2Sopenharmony_ci 131fb299fa2Sopenharmony_ci int fdd = open(dirPath.c_str(), O_RDONLY | O_DIRECTORY); 132fb299fa2Sopenharmony_ci if (fdd == -1) { 133fb299fa2Sopenharmony_ci LOG(ERROR) << "Failed to open"; 134fb299fa2Sopenharmony_ci return -1; 135fb299fa2Sopenharmony_ci } 136fb299fa2Sopenharmony_ci close(fdd); 137fb299fa2Sopenharmony_ci return 0; 138fb299fa2Sopenharmony_ci} 139fb299fa2Sopenharmony_ci 140fb299fa2Sopenharmony_ciint32_t Store::LoadDataFromStore(const std::string &dirPath, const std::string &fileName, 141fb299fa2Sopenharmony_ci std::vector<uint8_t> &buffer) 142fb299fa2Sopenharmony_ci{ 143fb299fa2Sopenharmony_ci LOG(INFO) << "Store base is " << dirPath << "/" << fileName; 144fb299fa2Sopenharmony_ci std::string path = dirPath; 145fb299fa2Sopenharmony_ci if (!fileName.empty()) { 146fb299fa2Sopenharmony_ci path = path + "/" + fileName; 147fb299fa2Sopenharmony_ci } 148fb299fa2Sopenharmony_ci struct stat fileStat {}; 149fb299fa2Sopenharmony_ci if (stat(path.c_str(), &fileStat) == -1) { 150fb299fa2Sopenharmony_ci LOG(DEBUG) << "Failed to stat"; 151fb299fa2Sopenharmony_ci return -1; 152fb299fa2Sopenharmony_ci } 153fb299fa2Sopenharmony_ci if (fileStat.st_size % H_BLOCK_SIZE != 0) { 154fb299fa2Sopenharmony_ci LOG(ERROR) << "Not multiple of block size 4096"; 155fb299fa2Sopenharmony_ci return -1; 156fb299fa2Sopenharmony_ci } 157fb299fa2Sopenharmony_ci 158fb299fa2Sopenharmony_ci int fd = open(path.c_str(), O_RDONLY); 159fb299fa2Sopenharmony_ci if (fd == -1) { 160fb299fa2Sopenharmony_ci LOG(ERROR) << "Failed to create"; 161fb299fa2Sopenharmony_ci return -1; 162fb299fa2Sopenharmony_ci } 163fb299fa2Sopenharmony_ci buffer.resize(fileStat.st_size); 164fb299fa2Sopenharmony_ci if (!ReadFully(fd, buffer.data(), fileStat.st_size)) { 165fb299fa2Sopenharmony_ci LOG(ERROR) << "Failed to read store data"; 166fb299fa2Sopenharmony_ci close(fd); 167fb299fa2Sopenharmony_ci fd = -1; 168fb299fa2Sopenharmony_ci return -1; 169fb299fa2Sopenharmony_ci } 170fb299fa2Sopenharmony_ci close(fd); 171fb299fa2Sopenharmony_ci fd = -1; 172fb299fa2Sopenharmony_ci return 0; 173fb299fa2Sopenharmony_ci} 174fb299fa2Sopenharmony_ci} // namespace Updater 175