1 /*
2 * Copyright (c) 2022 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
16 #include "partition.h"
17
18 #include <linux/fs.h>
19 #include <sys/ioctl.h>
20 #include <sys/mount.h>
21 #include <vector>
22 #include "flashd_define.h"
23 #include "flashd_utils.h"
24 #include "fs_manager/mount.h"
25 #include "utils.h"
26 #include "ptable_manager.h"
27 #include "applypatch/data_writer.h"
28
29 namespace Flashd {
DoFlash(const uint8_t * buffer,int bufferSize) const30 int Partition::DoFlash(const uint8_t *buffer, int bufferSize) const
31 {
32 if (buffer == nullptr || bufferSize <= 0 || writer_ == nullptr) {
33 FLASHD_LOGE("buffer is null or writer_ is null or bufferSize is invaild");
34 return FLASHING_ARG_INVALID;
35 }
36
37 if (auto ret = writer_->Write(devName_, buffer, bufferSize); ret != 0) {
38 FLASHD_LOGE("Write fail, ret = %d", ret);
39 return ret;
40 }
41 return 0;
42 }
43
DoErase() const44 int Partition::DoErase() const
45 {
46 #ifdef UPDATER_USE_PTABLE
47 if (!DevicePtable::GetInstance().LoadPartitionInfo()) {
48 return FLASHING_ARG_INVALID;
49 }
50 DevicePtable &devicePtb = DevicePtable::GetInstance();
51 Ptable::PtnInfo ptnInfo;
52
53 if (!devicePtb.GetPartionInfoByName(devName_, ptnInfo)) {
54 FLASHD_LOGE("DoErase: cannot find the lun index of partition: %s", devName_.c_str());
55 return FLASHING_ARG_INVALID;
56 }
57 if (ptnInfo.writeMode == "WRITE_IOCTL") {
58 FLASHD_LOGI("erase ext partition");
59 return DoEraseExt(ptnInfo);
60 }
61 #endif
62 return DoErasePartition();
63 }
64
DoErasePartition() const65 int Partition::DoErasePartition() const
66 {
67 auto fd = open(Updater::Utils::GetPartitionRealPath(devName_).c_str(), O_RDWR);
68 if (fd < 0) {
69 FLASHD_LOGE("open partition %s fail, error = %d", devName_.c_str(), errno);
70 return FLASHING_OPEN_PART_ERROR;
71 }
72
73 #ifndef UPDATER_UT
74 uint64_t size = GetBlockDeviceSize(fd);
75 uint64_t range[2] = { 0, size };
76 if (ioctl(fd, BLKSECDISCARD, &range) >= 0) {
77 FLASHD_LOGI("BLKDISCARD success");
78 }
79
80 range[0] = 0;
81 range[1] = size;
82 if (ioctl(fd, BLKDISCARD, &range) < 0) {
83 close(fd);
84 FLASHD_LOGE("BLKDISCARD fail");
85 return FLASHING_NOPERMISSION;
86 }
87 std::vector<uint8_t> buffer(BLOCK_SIZE, 0);
88 if (!Updater::Utils::WriteFully(fd, buffer.data(), buffer.size())) {
89 close(fd);
90 FLASHD_LOGE("WriteFully fail");
91 return FLASHING_PART_WRITE_ERROR;
92 }
93 fsync(fd);
94 #endif
95 close(fd);
96 return 0;
97 }
98
99 #ifdef UPDATER_USE_PTABLE
DoEraseExt(const Ptable::PtnInfo & ptnInfo) const100 int Partition::DoEraseExt(const Ptable::PtnInfo &ptnInfo) const
101 {
102 uint64_t partitionSize = ptnInfo.partitionSize;
103 std::unique_ptr<DataWriter> dataWriter = DataWriter::CreateDataWriter(ptnInfo.writeMode,
104 ptnInfo.writePath, devName_, ptnInfo.startAddr);
105
106 if (!dataWriter) {
107 FLASHD_LOGE("DataWriter creation failed");
108 return FLASHING_ARG_INVALID;
109 }
110 std::vector<uint8_t> zeroBuffer(partitionSize, 0);
111 if (!dataWriter->Write(zeroBuffer.data(), partitionSize, nullptr)) {
112 FLASHD_LOGE("erase %s failed", devName_.c_str());
113 return FLASHING_PART_WRITE_ERROR;
114 }
115
116 return 0;
117 }
118 #endif
119
DoFormat() const120 int Partition::DoFormat() const
121 {
122 auto name = "/" + devName_;
123 if (auto ret = Updater::FormatPartition(name); ret != 0) {
124 FLASHD_LOGE("FormatPartition fail, ret = %d", ret);
125 return ret;
126 }
127
128 if (auto ret = Updater::MountForPath(name); ret != 0) {
129 FLASHD_LOGE("MountForPath fail, ret = %d", ret);
130 return ret;
131 }
132 Updater::Utils::RestoreconPath(name);
133 return 0;
134 }
135
GetBlockDeviceSize(int fd) const136 uint64_t Partition::GetBlockDeviceSize(int fd) const
137 {
138 uint64_t size = 0;
139 return (ioctl(fd, BLKGETSIZE64, &size) == 0) ? size : 0;
140 }
141 }
142