diff --git a/ohos.build b/ohos.build index 123b489adaf876cedec1c72cb1bf46d39393a32d..bfdc7c2ac1f95646950bb25d12cd5838badee44a 100644 --- a/ohos.build +++ b/ohos.build @@ -11,7 +11,6 @@ "//base/update/updater/services/updater_binary:updater_binary", "//base/update/updater/services:updater", "//base/update/updater/services/applypatch:libapplypatch", - "//base/update/updater/services/sparse_image:libsparseimage", "//base/update/updater/services/fs_manager:libfsmanager", "//base/update/updater/utils:libutils", "//base/update/updater/utils:updater_reboot", diff --git a/services/applypatch/BUILD.gn b/services/applypatch/BUILD.gn index 085b8ad256c275c6d068219f679a0fbec57e9027..8d8d872562b1d86440ffb7b5216ae2a3a32e0266 100644 --- a/services/applypatch/BUILD.gn +++ b/services/applypatch/BUILD.gn @@ -23,7 +23,6 @@ ohos_static_library("libapplypatch") { "data_writer.cpp", "partition_record.cpp", "raw_writer.cpp", - "sparse_writer.cpp", "store.cpp", "transfer_manager.cpp", ] @@ -45,7 +44,6 @@ ohos_static_library("libapplypatch") { deps = [ "//base/update/updater/services/diffpatch/patch:libpatch", "//base/update/updater/services/fs_manager:libfsmanager", - "//base/update/updater/services/sparse_image:libsparseimage", "//third_party/bounds_checking_function:libsec_static", "//third_party/bzip2:libbz2", ] diff --git a/services/applypatch/block_writer.cpp b/services/applypatch/block_writer.cpp index 8a1326f2ffa780112fb33183c26669339c272400..88e86e44e9533993738e047906b51164a15f1bce 100644 --- a/services/applypatch/block_writer.cpp +++ b/services/applypatch/block_writer.cpp @@ -85,8 +85,8 @@ bool BlockWriter::Write(const uint8_t *addr, size_t len, WriteMode mode, const s } if (fsync(fd_) == -1) { - LOG(ERROR) << "Failed to fsync "; - return -1; + LOG(ERROR) << "Failed to fsync"; + return false; } return true; diff --git a/services/applypatch/data_writer.cpp b/services/applypatch/data_writer.cpp index 8618aeb073fe46296dbd6cde907b339804643886..602fdd749e5d6ccd1abf691d9bb310b8c0551b2f 100644 --- a/services/applypatch/data_writer.cpp +++ b/services/applypatch/data_writer.cpp @@ -23,7 +23,6 @@ #include "fs_manager/mount.h" #include "log/log.h" #include "raw_writer.h" -#include "sparse_writer.h" namespace updater { int DataWriter::OpenPartition(const std::string &partitionName) @@ -53,11 +52,6 @@ int DataWriter::OpenPartition(const std::string &partitionName) std::unique_ptr DataWriter::CreateDataWriter(WriteMode mode, const std::string &partitionName) { switch (mode) { - case WRITE_SPARSE: - { - std::unique_ptr writer(std::make_unique(partitionName)); - return std::move(writer); - } case WRITE_RAW: { std::unique_ptr writer(std::make_unique(partitionName)); diff --git a/services/applypatch/sparse_writer.cpp b/services/applypatch/sparse_writer.cpp deleted file mode 100644 index b6358cdf03590821f375c734bc1659c351f8fd31..0000000000000000000000000000000000000000 --- a/services/applypatch/sparse_writer.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "sparse_writer.h" -#include -#include -#include -#include -#include "log/log.h" -#include "sparse_image/sparse_image_api.h" - -namespace updater { -constexpr uint32_t SPARSE_HEADER_MAGIC = 0XED26FF3A; -SparseWriter::~SparseWriter() -{ - if (sf_ != nullptr) { - DeallocateSparseImage(sf_); - } -} - -bool SparseWriter::Write(const uint8_t *addr, size_t len, WriteMode mode, const std::string &partitionName) -{ - if (addr == nullptr) { - LOG(ERROR) << "SparseWrite: invalid address."; - return false; - } - - if (len == 0) { - LOG(WARNING) << "SparseWrite: write length is 0, skip."; - return false; - } - if ((len <= sizeof(SPARSE_HEADER_MAGIC)) || (*reinterpret_cast(addr) != SPARSE_HEADER_MAGIC)) { - LOG(ERROR) << "SparseWrite: Invalid sparse image."; - return false; - } - - auto p = const_cast(addr); - sf_ = CreateSparseImageFromBuffer(reinterpret_cast(p)); - UPDATER_ERROR_CHECK(sf_ != nullptr, "Sparsewrite: cannot get sparse file descriptor.", return false); - int fd = OpenPartition(partitionName_); - UPDATER_CHECK_ONLY_RETURN(fd >= 0, return false); - int ret = SparseImageRestore(fd, sf_); - UPDATER_ERROR_CHECK(ret >= 0, "Sparsewrite: write sparse image failed.", close(fd); return false); - LOG(INFO) << "Sparsewrite: write sparse image successfully."; - close(fd); - return true; -} -} // updater diff --git a/services/applypatch/sparse_writer.h b/services/applypatch/sparse_writer.h deleted file mode 100644 index 2ef2ea045dbe443253f0e96d2f3101eea0c4dd38..0000000000000000000000000000000000000000 --- a/services/applypatch/sparse_writer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef UPDATE_SPARSE_WRITER_H -#define UPDATE_SPARSE_WRITER_H - -#include -#include -#include "applypatch/data_writer.h" -#include "sparse_image/sparse_image_api.h" - -namespace updater { -class SparseWriter : public DataWriter { -public: - virtual bool Write(const uint8_t *addr, size_t len, WriteMode mode, const std::string &partitionName); - - explicit SparseWriter(const std::string &partitionName) : sf_(nullptr), partitionName_(partitionName) {} - - virtual ~SparseWriter(); -private: - struct SparseImage *sf_; - - SparseWriter(const SparseWriter&) = delete; - - const SparseWriter& operator=(const SparseWriter&) = delete; - std::string partitionName_; -}; -} // updater -#endif // UPDATE_SPARSE_WRITER_H diff --git a/services/sparse_image/BUILD.gn b/services/sparse_image/BUILD.gn deleted file mode 100644 index 252c79bcf8eed6835e7bf7778f270e7efb954861..0000000000000000000000000000000000000000 --- a/services/sparse_image/BUILD.gn +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build/ohos.gni") - -ohos_static_library("libsparseimage") { - sources = [ - "sparse_block.cpp", - "sparse_chunk.cpp", - "sparse_image.cpp", - "sparse_image_writer.cpp", - ] - - include_dirs = [ - "//base/update/updater/services/include", - "//base/update/updater/utils/include", - "//third_party/bounds_checking_function/include", - ] - - deps = [ - "//base/update/updater/services/log:libupdaterlog", - "//third_party/bounds_checking_function:libsec_static", - ] -} diff --git a/services/sparse_image/sparse_block.cpp b/services/sparse_image/sparse_block.cpp deleted file mode 100644 index a0dcc14fa886186928f74f7e66df417cffc25ee8..0000000000000000000000000000000000000000 --- a/services/sparse_image/sparse_block.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "sparse_block.h" - -#include -#include "log/log.h" -#include "securec.h" - -namespace updater { -void DeallocateBlockList(struct BlockList *bl) -{ - SparseImageBlock *imageBlocks = bl->imageBlocks; - while (imageBlocks != nullptr) { - SparseImageBlock *next = imageBlocks->next; - if (imageBlocks->type == BLOCK_TYPE_FILE) { - free(imageBlocks->file.fileName); - } - free(imageBlocks); - imageBlocks = next; - } - free(bl); - bl = nullptr; -} - -static void MergeBlocks(unsigned int blockSize, SparseImageBlock *prev, SparseImageBlock *next) -{ - // sanity checks - if (prev == nullptr || next == nullptr) { // Do not need to merge - return; - } - - if (prev->type != next->type) { // block with different type - LOG(WARNING) << "SparseBlock: try to merge blocks with different type: " << - " previous block with type: " << prev->type << - " while next block with type: " << next->type; - return; - } - - // should never happen - if (blockSize == 0) { - LOG(ERROR) << "SparseBlock: block size is zero"; - return; - } - // check if these two blocks adjacent - unsigned int blockCounts = prev->size / blockSize; - if (prev->blockIndex + blockCounts != next->blockIndex) { - LOG(WARNING) << "SparseBlock: try to merge two block nonadjacent: " << - " previous block index: " << prev->blockIndex << " size: " << prev->size << - " while next block index: " << next->blockIndex; - return; - } - - if (prev->type == BLOCK_TYPE_FILE) { - if (strcmp(prev->file.fileName, next->file.fileName) != 0 || - prev->file.offset + prev->size != next->file.offset) { - return; - } - } else if (prev->type == BLOCK_TYPE_FD) { - if (prev->fd.fd != next->fd.fd || prev->fd.offset + prev->size != next->fd.offset) { - return; - } - } else if (prev->type == BLOCK_TYPE_FILL) { - if (prev->fill.value != next->fill.value) { - return; - } - } else { // BLOCK_TYPE_DATA, do not need to merge - return; - } - - // OK, we've done all checks, now merge next to prev. - prev->size += next->size; - prev->next = next->next; - // free next; - if (next->type == BLOCK_TYPE_FILE) { - free(next->file.fileName); - } - free(next); - return; -} - -static int InsertToBlockList(struct BlockList *bl, SparseImageBlock *sib) -{ - if (bl->imageBlocks == nullptr) { - bl->imageBlocks = sib; - bl->imageBlocks->next = nullptr; - return 0; - } - - // block list is not empty, insert @sib to block list in order. - if (bl->imageBlocks->blockIndex > sib->blockIndex) { - // Insert @sib at front of bl - sib->next = bl->imageBlocks; - bl->imageBlocks = sib; - return 0; - } - - // @sib->blockIndex is larger. find a appropriate place - SparseImageBlock *tmp = nullptr; - for (tmp = bl->imageBlocks; tmp->next != nullptr; tmp = tmp->next) { - if (tmp->next->blockIndex > sib->blockIndex) { - break; - } - } - - // Insert @sib to the appropriate place. - if (tmp->next == nullptr) { - tmp->next = sib; - } else { - sib->next = tmp->next; - tmp->next = sib; - } - - // adjacent block may have the same property, merge them. - // 1. merge sib with next one - MergeBlocks(bl->blockSize, sib, sib->next); - MergeBlocks(bl->blockSize, tmp, sib); - return 0; -} - -int AddRawDataToSparseImage(struct BlockList *bl, void *buffer, int64_t size, uint32_t blockIndex) -{ - SparseImageBlock *sib = static_cast(calloc(1, sizeof(SparseImageBlock))); - if (sib == nullptr) { - LOG(ERROR) << "SparseBlock: Failed to allocate memory for sparse block"; - return -ENOMEM; - } - sib->blockIndex = blockIndex; - sib->size = static_cast(size); // maybe the size should be unsigned int - sib->type = BLOCK_TYPE_DATA; - sib->data.data = buffer; - sib->next = nullptr; - - // insert into block list. - return InsertToBlockList(bl, sib); -} - -int AddFillValueToSparseImage(struct BlockList *bl, uint32_t value, int64_t size, uint32_t blockIndex) -{ - SparseImageBlock *sib = static_cast(calloc(1, sizeof(SparseImageBlock))); - if (sib == nullptr) { - LOG(ERROR) << "SparseBlock: Failed to allocate memory for sparse block"; - return -ENOMEM; - } - - sib->blockIndex = blockIndex; - sib->size = static_cast(size); - sib->type = BLOCK_TYPE_FILL; - sib->fill.value = value; - sib->next = nullptr; - - return InsertToBlockList(bl, sib); -} -} // namespace updater diff --git a/services/sparse_image/sparse_block.h b/services/sparse_image/sparse_block.h deleted file mode 100644 index 3d32630f99a32bc5b0e01f8254f5bfc2a65ae23a..0000000000000000000000000000000000000000 --- a/services/sparse_image/sparse_block.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef UPDATER_SPARSE_BLOCK_H -#define UPDATER_SPARSE_BLOCK_H -#include - -namespace updater { -enum BLOCKTYPE { - BLOCK_TYPE_DATA, - BLOCK_TYPE_FILE, - BLOCK_TYPE_FD, - BLOCK_TYPE_FILL, -}; - -// Sparse image combined by many -// blocks. each block has different type -struct SparseImageBlock { - unsigned int blockIndex; - unsigned int size; - BLOCKTYPE type; - union { - struct { - void *data; - } data; - struct { - char *fileName; - int64_t offset; - } file; - struct { - int fd; - int64_t offset; - } fd; - struct { - uint32_t value; - } fill; - }; - SparseImageBlock *next; -}; - -struct BlockList { - SparseImageBlock *imageBlocks; - unsigned int blockSize; -}; - -void DeallocateBlockList(struct BlockList *bl); -int AddFillValueToSparseImage(struct BlockList *bl, uint32_t value, int64_t size, uint32_t blockIndex); -int AddRawDataToSparseImage(struct BlockList *bl, void *buffer, int64_t size, uint32_t blockIndex); -} // namespace updater -#endif - diff --git a/services/sparse_image/sparse_chunk.cpp b/services/sparse_image/sparse_chunk.cpp deleted file mode 100644 index 54d7589b25288e2ba513b14bc5bd63b365f58714..0000000000000000000000000000000000000000 --- a/services/sparse_image/sparse_chunk.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "sparse_chunk.h" - -#include - -#include "log/log.h" - -namespace updater { -static bool IsValidChunk(uint32_t chunkContentSize, uint32_t chunkSize, uint32_t blockSize) -{ - // should never happen - if (blockSize == 0) { - LOG(ERROR) << "SparseImage: block size is zero"; - return false; - } - // check if chunk content size align with block size. - if (chunkContentSize % blockSize != 0) { - LOG(ERROR) << "SparseImage: invalid chunk " << - " chunk content is not aligned with " << blockSize; - return false; - } - - if (chunkContentSize / blockSize != chunkSize) { - LOG(ERROR) << "SparseImage: invalid chunk " << - " chunk content size is " << chunkContentSize << - " while chunk size record in chunk header is " << chunkSize * blockSize; - return false; - } - return true; -} - -static int HandleRawChunk(struct SparseImage *si, SparseImageHandlerFromBuffer &imageBuffer, - const SparseImageChunkHeader &chunkHeader, const SparseImageHeader &imageHeader, uint32_t currentBlock) -{ - int64_t outputContentSize = chunkHeader.chunkSize * imageHeader.blockSize; - uint32_t chunkContentSize = chunkHeader.totalSize - static_cast(imageHeader.chunkHeaderSize); - - if (!IsValidChunk(chunkContentSize, chunkHeader.chunkSize, imageHeader.blockSize)) { - return -EINVAL; - } - - int ret = imageBuffer.CopyToSparseImage(si, outputContentSize, currentBlock); - if (ret == 0) { - imageBuffer.Seek(outputContentSize); - } - return (ret < 0) ? -EINVAL : 0; -} - -static int HandleFillChunk(struct SparseImage *si, SparseImageHandlerFromBuffer &imageBuffer, - const SparseImageChunkHeader &chunkHeader, const SparseImageHeader &imageHeader, uint32_t currentBlock) -{ - int64_t outputContentSize = chunkHeader.chunkSize * imageHeader.blockSize; - uint32_t chunkContentSize = chunkHeader.totalSize - static_cast(imageHeader.chunkHeaderSize); - uint32_t value; - - if (chunkContentSize != sizeof(value)) { - LOG(ERROR) << "SparseImage: invalid fill chunk"; - return -EINVAL; - } - - int ret = imageBuffer.ReadContent(&value, sizeof(value)); - if (ret < 0) { - LOG(ERROR) << "SparseImage: failed to read value from fill chunk"; - return -EINVAL; - } - - ret = AddFillValueToSparseImage(si->bl, value, outputContentSize, currentBlock); - return (ret < 0) ? -EINVAL : 0; -} - -int HandleChunks(struct SparseImage *si, SparseImageHandlerFromBuffer &imageBuffer, - const SparseImageChunkHeader &chunkHeader, const SparseImageHeader &imageHeader, uint32_t ¤tBlock) -{ - int ret = 0; - switch (chunkHeader.type) { - case CHUNK_TYPE_RAW: - ret = HandleRawChunk(si, imageBuffer, chunkHeader, imageHeader, currentBlock); - if (ret < 0) { - LOG(ERROR) << "SparseImage: handle raw chunk failed"; - return -EINVAL; - } - currentBlock += chunkHeader.chunkSize; - break; - case CHUNK_TYPE_FILL: - ret = HandleFillChunk(si, imageBuffer, chunkHeader, imageHeader, currentBlock); - if (ret < 0) { - LOG(ERROR) << "SparseImage: handle fill chunk failed"; - return -EINVAL; - } - currentBlock += chunkHeader.chunkSize; - break; - case CHUNK_TYPE_DONT_CARE: - { - int64_t chunkContentSize = chunkHeader.totalSize - sizeof(SparseImageChunkHeader); - if (chunkContentSize != 0) { // For don't care chunk, chunk content size should be zero. - LOG(ERROR) << "SparseImage: dont care chunk with non-zero chunk size"; - return -EINVAL; - } - currentBlock += chunkHeader.chunkSize; - break; - } - case CHUNK_TYPE_CRC32: - LOG(WARNING) << "SparseImage: crc32 chunk is unsupported it for now"; - return -EINVAL; - default: - LOG(ERROR) << "SparseImage: unexpected chunk type: " << std::hex << chunkHeader.type << std::dec; - return -EINVAL; - } - return ret; -} -} // namespace updater diff --git a/services/sparse_image/sparse_chunk.h b/services/sparse_image/sparse_chunk.h deleted file mode 100644 index ceb4afc9225ab75262ae669e17646d48b2d001fe..0000000000000000000000000000000000000000 --- a/services/sparse_image/sparse_chunk.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef UPDATER_SPARSE_CHUNK_H -#define UPDATER_SPARSE_CHUNK_H -#include - -#include "log/log.h" -#include "sparse_image.h" -#include "sparse_image_handler.h" - -namespace updater { -int HandleChunks(struct SparseImage *si, SparseImageHandlerFromBuffer &imageBuffer, - const SparseImageChunkHeader &chunkHeader, const SparseImageHeader &imageHeader, uint32_t ¤tBlock); -} // namespace updater -#endif // UPDATER_SPARSE_CHUNK_H diff --git a/services/sparse_image/sparse_image.cpp b/services/sparse_image/sparse_image.cpp deleted file mode 100644 index 0c3f89fd306cca0b8be67cacca4d118e5a03df31..0000000000000000000000000000000000000000 --- a/services/sparse_image/sparse_image.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "sparse_image.h" -#include -#include "log/log.h" -#include "securec.h" -#include "sparse_chunk.h" -#include "sparse_image_handler.h" - -namespace updater { -// Check if sparse image header is valid. -// returns true is sparse image header is valid, -// otherwise, returns false. -static bool IsValidSparseImageHeader(const SparseImageHeader &header) -{ - if (header.magicNumber != SPARSE_IMAGE_MAGIC) { - LOG(ERROR) << "SparseImage: invalid sparse image magic number"; - return false; - } - - // Only check if major version is expected. - if (header.majorVersion != SPARSE_IMAGE_MAJOR_VERSIOIN) { - LOG(ERROR) << "SparseImage: sparse image with incorrect version"; - return false; - } - - // Check if sparse image size is sufficient - if (header.fileHeaderSize < sizeof(SparseImageHeader)) { - LOG(ERROR) << "SparseImage: sparse image header size is invalid"; - return false; - } - - if (header.chunkHeaderSize < sizeof(SparseImageChunkHeader)) { - LOG(ERROR) << "SparseImage: sparse image chunk header size is invalid"; - return false; - } - - // Everything seems OK. - return true; -} - -static struct SparseImage *AllocateSparseImage(int64_t totalSize, uint32_t blockSize) -{ - struct SparseImage *si = static_cast(calloc(1, sizeof(struct SparseImage))); - if (si == nullptr) { - LOG(ERROR) << "SparseImage: allocate memory for sparse image failed: " << errno; - return nullptr; - } - - si->bl = static_cast(calloc(1, sizeof(struct BlockList))); - if (si->bl == nullptr) { - LOG(ERROR) << "SparseImage: allocate memory for block list failed: " << errno; - free(si); - } - - si->blockSize = blockSize; - si->totalSize = totalSize; - si->bl->blockSize = blockSize; - return si; -} - -void DeallocateSparseImage(struct SparseImage *si) -{ - if (si == nullptr) { - return; - } - DeallocateBlockList(si->bl); - free(si); - si = nullptr; -} - -static int ReadSparseImageFromBuffer(struct SparseImage *si, SparseImageHandlerFromBuffer &imageBuffer) -{ - SparseImageHeader imageHeader {}; - SparseImageChunkHeader chunkHeader {}; - uint32_t currentBlock = 0; - - int ret = imageBuffer.ReadContent(&imageHeader, sizeof(SparseImageHeader)); - if (ret < 0) { - LOG(ERROR) << "SparseImage: Read sparse image header failed"; - return ret; - } - - if (!IsValidSparseImageHeader(imageHeader)) { - return -EINVAL; - } - // check if there is a gab between SparseImageHeader::fileHeaderSize and length of SparseImageHeader - if (imageHeader.fileHeaderSize > sizeof(SparseImageHeader)) { - imageBuffer.Seek(imageHeader.fileHeaderSize - sizeof(SparseImageHeader)); - } - - for (uint32_t i = 0; i < imageHeader.totalChunks; i++) { - ret = imageBuffer.ReadContent(&chunkHeader, sizeof(SparseImageChunkHeader)); - if (ret < 0) { - LOG(ERROR) << "SparseImage: Read sparse image chunk header failed"; - return ret; - } - - if (imageHeader.chunkHeaderSize > sizeof(SparseImageChunkHeader)) { - imageBuffer.Seek(imageHeader.chunkHeaderSize - sizeof(SparseImageChunkHeader)); - } - ret = HandleChunks(si, imageBuffer, chunkHeader, imageHeader, currentBlock); - if (ret < 0) { - return -EINVAL; - } - } - - // Check if all chunks handled - if (imageHeader.totalBlocks != currentBlock) { - LOG(ERROR) << "SparseImage: read sparse image failed: " << " expected " << imageHeader.totalBlocks << - " actual handled blocks: " << currentBlock; - return -EINVAL; - } - return 0; -} - -struct SparseImage *CreateSparseImageFromBuffer(char *buff) -{ - SparseImageHandlerFromBuffer imageBuffer(buff); - SparseImageHeader imageHeader {}; - struct SparseImage *si = nullptr; - - // Read sparse image header from buffer. - int ret = imageBuffer.ReadContent(&imageHeader, sizeof(SparseImageHeader)); - if (ret < 0) { - LOG(ERROR) << "SparseImage: Read sparse image header failed"; - return nullptr; - } - - if (!IsValidSparseImageHeader(imageHeader)) { - return nullptr; - } - - // Well, the sparse image header looks fine. - // Get total size of sparse image. - auto sparseImageSize = static_cast(imageHeader.totalBlocks * imageHeader.blockSize); - si = AllocateSparseImage(sparseImageSize, imageHeader.blockSize); - if (si == nullptr) { - return nullptr; - } - - imageBuffer.SetOffset(0); - ret = ReadSparseImageFromBuffer(si, imageBuffer); - if (ret < 0) { - DeallocateSparseImage(si); - return nullptr; - } - return si; -} -} // namespace updater diff --git a/services/sparse_image/sparse_image.h b/services/sparse_image/sparse_image.h deleted file mode 100644 index f311bbe1398f7f0433d7164242546ed71ab2c5ed..0000000000000000000000000000000000000000 --- a/services/sparse_image/sparse_image.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef UPDATER_SPARSE_IMAGE_H -#define UPDATER_SPARSE_IMAGE_H -#include -#include "sparse_block.h" - -namespace updater { -constexpr uint32_t SPARSE_IMAGE_MAGIC = 0xED26FF3A; -constexpr uint16_t SPARSE_IMAGE_MAJOR_VERSIOIN = 0x1; -constexpr uint16_t SPARSE_IMAGE_MINOR_VERSIOIN = 0x0; - -struct SparseImageHeader { - // Magic number of sparse image is 0xed26ff3a - uint32_t magicNumber; - // major versoin of sparse image is 0x1 - uint16_t majorVersion; - // minor versoin of sparse image is 0x0 - uint16_t minorVersion; - // file header size, 28 bytes - uint16_t fileHeaderSize; - // chunk header size, 12 bytes - uint16_t chunkHeaderSize; - // block size in bytes, default is 4096 bytes - uint32_t blockSize; - // total blocks of non-sparse image. - uint32_t totalBlocks; - // total chunks of sparse image. - uint32_t totalChunks; - // CRC32 checksum of original data. - uint32_t checkSum; -}; - -// chunk type definition -constexpr uint16_t CHUNK_TYPE_RAW = 0xCAC1; -constexpr uint16_t CHUNK_TYPE_FILL = 0xCAC2; -constexpr uint16_t CHUNK_TYPE_DONT_CARE = 0xCAC3; -constexpr uint16_t CHUNK_TYPE_CRC32 = 0xCAC4; - -struct SparseImageChunkHeader { - uint16_t type; // chunk type: raw, fill or don't care - uint16_t reserved1; - uint32_t chunkSize; // size in blocks of output image. - uint32_t totalSize; // size in bytes, include chunk header and data -}; - -struct SparseImage { - // size in bock - unsigned int blockSize; - // total size of sparse image - int64_t totalSize; - // block list - struct BlockList *bl; -}; -} // namespace updater -#endif // UPDATER_SPARSE_IMAGE_H diff --git a/services/sparse_image/sparse_image_handler.h b/services/sparse_image/sparse_image_handler.h deleted file mode 100644 index dd537f6806b04018b3039e0945693a5967125ca8..0000000000000000000000000000000000000000 --- a/services/sparse_image/sparse_image_handler.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef UPDATER_SPARSE_IMAGE_HANDLER_H -#define UPDATER_SPARSE_IMAGE_HANDLER_H -#include - -#include "log/log.h" -#include "securec.h" -#include "sparse_image.h" - -namespace updater { -class ISparseImageHandler { -public: - // Seek sparse image to specific offset. - virtual void Seek(int64_t offset) = 0; - virtual int64_t GetOffset() const = 0; - virtual void SetOffset(int64_t offset) = 0; - virtual int CopyToSparseImage(struct SparseImage *si, int64_t size, uint32_t blockIndex) = 0; - virtual int ReadContent(void *buff, int64_t len) = 0; - virtual ~ISparseImageHandler() {} -}; - -class SparseImageHandlerFromBuffer : public ISparseImageHandler { -public: - explicit SparseImageHandlerFromBuffer(char *buff) : buff_(buff), offset_(0) {} - ~SparseImageHandlerFromBuffer() override {} - void Seek(int64_t offset) override - { - buff_ += offset; - offset_ += offset; - } - - int64_t GetOffset() const override - { - return offset_; - } - - void SetOffset(int64_t offset) override - { - buff_ -= offset_; // Move buff_ back to beginning. - buff_ += offset; - offset_ = offset; - } - - int CopyToSparseImage(struct SparseImage *si, int64_t size, uint32_t blockIndex) override - { - // block list should not be null. - struct BlockList *bl = si->bl; - char *buffer = buff_; - return AddRawDataToSparseImage(bl, buffer, size, blockIndex); - } - - int ReadContent(void *buff, int64_t size) override - { - if (memcpy_s(buff, static_cast(size), buff_, static_cast(size)) != EOK) { - return -EINVAL; - } - Seek(size); - return 0; - } - -private: - char *buff_; - int64_t offset_; -}; -} // namespace updater -#endif // UPDATER_SPARSE_IMAGE_HANDLER_H diff --git a/services/sparse_image/sparse_image_writer.cpp b/services/sparse_image/sparse_image_writer.cpp deleted file mode 100644 index a542af665ac7929b9b434fe2156213615572ccfb..0000000000000000000000000000000000000000 --- a/services/sparse_image/sparse_image_writer.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include -#include -#include -#include "log/log.h" -#include "sparse_block.h" -#include "sparse_image.h" - -namespace updater { -#define ROUNDUPWITH(a, b) (((a) + (b) - 1) / (b)) -#define ALIGNWITH(a, b) ((b) * ROUNDUPWITH((a), (b))) -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -// When write file block, will map file to memory, -// the mapped memory size should be aligned. -constexpr unsigned int MMAP_ALIGNED_MASK = (4096 - 1); - -static int WriteToFd(int fd, void *data, size_t size) -{ - ssize_t written = 0; - size_t rest = size; - - while (rest > 0) { - written = write(fd, data, rest); - if (written < 0) { - if (errno == EINTR) { - continue; - } - LOG(ERROR) << "SparseImage: write to fd failed: " << errno; - return -1; - } - data = static_cast(data) + written; - rest -= written; - } - return 0; -} - -static int SkipChunks(int fd, int64_t offset) -{ - off64_t rc = 0; - rc = lseek64(fd, offset, SEEK_CUR); - if (rc < 0) { - LOG(ERROR) << "SparseImage: seek file to " << offset << " failed: " << errno; - return -1; - } - return 0; -} - -static int WriteFdBlockToFd(int out, int in, int64_t offset, unsigned int size, unsigned int blockSize) -{ - int64_t alignedOffset = offset & MMAP_ALIGNED_MASK; - int alignedGap = static_cast(offset - alignedOffset); - int64_t mapSize = static_cast(size) + static_cast(alignedGap); - - if (mapSize < 0) { // overflow - LOG(ERROR) << "SparseImage: file size too big. overflow."; - return -1; - } - - char *ptr = static_cast(mmap64(nullptr, mapSize, PROT_READ, MAP_SHARED, in, alignedOffset)); - if (ptr == MAP_FAILED) { - LOG(ERROR) << "SparseImage: map file failed: " << errno; - return -1; - } - - char *p = ptr + alignedGap; - int ret = WriteToFd(out, p, size); - if (ret < 0) { - munmap(ptr, mapSize); - return ret; - } - - // Written data should be aligned with @blockSize. - // if not so, skip reset size. - unsigned int alignedSize = ALIGNWITH(size, blockSize); - if (alignedSize > size) { - ret = SkipChunks(out, alignedSize - size); - if (ret < 0) { - munmap(ptr, mapSize); - return ret; - } - } - munmap(ptr, mapSize); - return 0; -} - -static int WriteFileBlockToFd(int out, const char *fileName, int64_t offset, unsigned int size, unsigned int blockSize) -{ - int in = open(fileName, O_RDONLY); - if (in < 0) { - LOG(ERROR) << "SparseImage: open " << fileName << " failed: " << errno; - return -1; - } - int ret = WriteFdBlockToFd(out, in, offset, size, blockSize); - close(in); - in = -1; - return ret; -} - -static int WriteDataBlockToFd(int fd, void *data, unsigned int size, unsigned int blockSize) -{ - unsigned int alignedSize = ALIGNWITH(size, blockSize); - - int ret = WriteToFd(fd, data, size); - if (ret < 0) { - return ret; - } - // Written data should be aligned with @blockSize. - // if not so, skip reset size. - if (alignedSize > size) { - ret = SkipChunks(fd, alignedSize - size); - if (ret < 0) { - return -1; - } - } - return 0; -} - -static int WriteFillBlockToFd(int fd, uint32_t value, unsigned int size, unsigned int blockSize) -{ - // should never happen - if (blockSize == 0) { - LOG(ERROR) << "SparseImage: block size is zero"; - return -1; - } - auto buffer = static_cast(calloc(blockSize, 1)); - uint32_t toWrite = 0; - if (buffer == nullptr) { - LOG(ERROR) << "SparseImage: allocate memory for fill block failed: " << errno; - return -1; - } - - for (int i = 0; i < static_cast(blockSize / sizeof(uint32_t)); i++) { - buffer[i] = value; - } - - while (size) { - toWrite = MIN(size, blockSize); - int ret = WriteToFd(fd, buffer, toWrite); - if (ret < 0) { - free(buffer); - buffer = nullptr; - return ret; - } - size -= toWrite; - } - free(buffer); - buffer = nullptr; - return 0; -} - -static int WriteBlockToFd(int fd, SparseImageBlock *sib, unsigned int blockSize) -{ - BLOCKTYPE type = sib->type; - int ret = -EINVAL; - switch (type) { - case BLOCK_TYPE_DATA: - ret = WriteDataBlockToFd(fd, sib->data.data, sib->size, blockSize); - if (ret) { - LOG(ERROR) << "SparseImage: write data block to file failed"; - } - break; - case BLOCK_TYPE_FILE: - ret = WriteFileBlockToFd(fd, sib->file.fileName, sib->file.offset, sib->size, blockSize); - if (ret) { - LOG(ERROR) << "SparseImage: write file block to file failed"; - } - break; - case BLOCK_TYPE_FD: - ret = WriteFdBlockToFd(fd, sib->fd.fd, sib->fd.offset, sib->size, blockSize); - if (ret) { - LOG(ERROR) << "SparseImage: write fd block to file failed"; - } - break; - case BLOCK_TYPE_FILL: - ret = WriteFillBlockToFd(fd, sib->fill.value, sib->size, blockSize); - if (ret) { - LOG(ERROR) << "SparseImage: write fill block to file failed"; - } - break; - default: - LOG(ERROR) << "SparseImage: Unsupported block type " << std::hex << type << std::dec; - break; - } - return ret; -} - -// Write Block to fd. -// Write all blocks in sparse image to the -// file bind to fd. -static int WriteBlocksToFd(int fd, struct BlockList *bl, int64_t totalSize) -{ - SparseImageBlock *sib = nullptr; - uint32_t proceedBlocks = 0; - int ret = 0; - - for (sib = bl->imageBlocks; sib != nullptr; sib = sib->next) { - // There is a gap between blocks. - // maybe there are don't care chunks - // Just skip it. - if (sib->blockIndex > proceedBlocks) { - uint32_t skippedBlocks = sib->blockIndex - proceedBlocks; - ret = SkipChunks(fd, skippedBlocks * bl->blockSize); - if (ret < 0) { - LOG(ERROR) << "SparseImage: Skip chunks failed"; - return ret; - } - } - ret = WriteBlockToFd(fd, sib, bl->blockSize); - if (ret < 0) { - return ret; - } - proceedBlocks = sib->blockIndex + ROUNDUPWITH(sib->size, bl->blockSize); - } - - // We've written all blocks - // check if there is a gap between totalSize and proceed blocks - int64_t gap = totalSize - proceedBlocks * bl->blockSize; - ret = SkipChunks(fd, gap); - if (ret < 0) { - LOG(ERROR) << "SparseImage: Skip chunks failed"; - } - return ret; -} - -int SparseImageRestore(int fd, struct SparseImage *si) -{ - if (si == nullptr || fd < 0) { - LOG(ERROR) << "SparseImage: invalid arguments"; - return -1; - } - - // We don't need to check if SparseImage is valid here. - struct BlockList *bl = si->bl; - int ret = WriteBlocksToFd(fd, bl, si->totalSize); - if (ret < 0) { - LOG(ERROR) << "SparseImage: failed to write blocks to fd"; - return -1; - } - // truncate the file to sparse image size. - ret = ftruncate64(fd, si->totalSize); - if (ret < 0) { - LOG(WARNING) << "SparseImage: failed to truncate file: " << errno; - } - return 0; -} -} // namespace updater