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
27 namespace Flashd {
DoFlash(const uint8_t * buffer,int bufferSize) const28 int Partition::DoFlash(const uint8_t *buffer, int bufferSize) const
29 {
30 if (buffer == nullptr || bufferSize <= 0 || writer_ == nullptr) {
31 FLASHD_LOGE("buffer is null or writer_ is null or bufferSize is invaild");
32 return FLASHING_ARG_INVALID;
33 }
34
35 if (auto ret = writer_->Write(devName_, buffer, bufferSize); ret != 0) {
36 FLASHD_LOGE("Write fail, ret = %d", ret);
37 return ret;
38 }
39 return 0;
40 }
41
DoErase() const42 int Partition::DoErase() const
43 {
44 auto fd = open(Updater::Utils::GetPartitionRealPath(devName_).c_str(), O_RDWR);
45 if (fd < 0) {
46 FLASHD_LOGE("open partition %s fail, error = %d", devName_.c_str(), errno);
47 return FLASHING_OPEN_PART_ERROR;
48 }
49
50 #ifndef UPDATER_UT
51 uint64_t size = GetBlockDeviceSize(fd);
52 uint64_t range[2] = { 0, size };
53 if (ioctl(fd, BLKSECDISCARD, &range) >= 0) {
54 FLASHD_LOGI("BLKSECDISCARD success");
55 }
56
57 range[0] = 0;
58 range[1] = size;
59 if (ioctl(fd, BLKDISCARD, &range) < 0) {
60 close(fd);
61 FLASHD_LOGE("BLKDISCARD fail");
62 return FLASHING_NOPERMISSION;
63 }
64 std::vector<uint8_t> buffer(BLOCK_SIZE, 0);
65 if (!Updater::Utils::WriteFully(fd, buffer.data(), buffer.size())) {
66 close(fd);
67 FLASHD_LOGE("WriteFully fail");
68 return FLASHING_PART_WRITE_ERROR;
69 }
70 fsync(fd);
71 #endif
72 close(fd);
73 return 0;
74 }
75
DoFormat() const76 int Partition::DoFormat() const
77 {
78 auto name = "/" + devName_;
79 if (auto ret = Updater::FormatPartition(name); ret != 0) {
80 FLASHD_LOGE("FormatPartition fail, ret = %d", ret);
81 return ret;
82 }
83
84 if (auto ret = Updater::MountForPath(name); ret != 0) {
85 FLASHD_LOGE("MountForPath fail, ret = %d", ret);
86 return ret;
87 }
88 Updater::Utils::RestoreconPath(name);
89 return 0;
90 }
91
GetBlockDeviceSize(int fd) const92 uint64_t Partition::GetBlockDeviceSize(int fd) const
93 {
94 uint64_t size = 0;
95 return (ioctl(fd, BLKGETSIZE64, &size) == 0) ? size : 0;
96 }
97 }
98