1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15#include "applypatch/data_writer.h" 16#include <cerrno> 17#include <cstdio> 18#include <fcntl.h> 19#include <memory> 20#include <string> 21#include <unistd.h> 22#include "applypatch/block_writer.h" 23#include "fs_manager/mount.h" 24#include "log/log.h" 25#include "raw_writer.h" 26 27namespace Updater { 28UpdaterEnv *DataWriter::env_ = nullptr; 29int DataWriter::OpenPath(const std::string &path) 30{ 31 if (path.empty()) { 32 LOG(ERROR) << "Datawriter: partition name is empty."; 33 return -1; 34 } 35 36 if (access(path.c_str(), W_OK) < 0) { 37 LOG(ERROR) << "Datawriter: " << path << " is not writable."; 38 return -1; 39 } 40 char *realPath = realpath(path.c_str(), NULL); 41 if (realPath == nullptr) { 42 LOG(ERROR) << "realPath is NULL" << " : " << strerror(errno); 43 return -1; 44 } 45 int fd = open(realPath, O_RDWR | O_LARGEFILE); 46 free(realPath); 47 if (fd < 0) { 48 LOG(ERROR) << "Datawriter: open block device " << path << " failed " << " : " << strerror(errno); 49 return fd; 50 } 51 if (lseek(fd, 0, SEEK_SET) == -1) { 52 LOG(ERROR) << "Datawriter: seek " << path << "failed " << " : " << strerror(errno); 53 close(fd); 54 fd = -1; 55 } 56 return fd; 57} 58 59std::unique_ptr<DataWriter> DataWriter::CreateDataWriter(WriteMode mode, const std::string &path, 60 uint64_t offset) 61{ 62 switch (mode) { 63 case WRITE_RAW: 64 return std::make_unique<RawWriter>(path, offset); 65 case WRITE_DECRYPT: 66 LOG(WARNING) << "Unsupported writer mode."; 67 break; 68 default: 69 break; 70 } 71 return nullptr; 72} 73 74UpdaterEnv *DataWriter::GetUpdaterEnv() 75{ 76 return env_; 77} 78 79void DataWriter::SetUpdaterEnv(UpdaterEnv *env) 80{ 81 env_ = env; 82} 83 84std::unique_ptr<DataWriter> DataWriter::CreateDataWriter(WriteMode mode, const std::string &path, 85 UpdaterEnv *env, uint64_t offset) 86{ 87 env_ = env; 88 return CreateDataWriter(mode, path, offset); 89} 90 91std::unique_ptr<DataWriter> DataWriter::CreateDataWriter(const std::string &mode, const std::string &path, 92 const std::string &partName, uint64_t startAddr, uint64_t offset) 93{ 94 if (auto it = constructorMap_.find(mode); it != constructorMap_.end()) { 95 return it->second(path, partName, startAddr, offset); 96 } 97 LOG(ERROR) << "create writer failed, can not find writer mode: " << mode; 98 return nullptr; 99} 100 101void DataWriter::ReleaseDataWriter(std::unique_ptr<DataWriter> &writer) 102{ 103 writer.reset(); 104} 105 106void DataWriter::RegisterDataWriter(const std::string &mode, WriterConstructor constructor) 107{ 108 if (mode.empty() || constructor == nullptr) { 109 LOG(ERROR) << "invalid input"; 110 return; 111 } 112 if (!constructorMap_.emplace(mode, constructor).second) { 113 LOG(ERROR) << "register writer failed, mode: " << mode; 114 } 115} 116} // namespace Updater 117