• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2025 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 <fcntl.h>
17 #include <stdlib.h>
18 #include <errno.h>
19 #include <limits.h>
20 #include <sys/types.h>
21 #include <sys/sysmacros.h>
22 
23 #include "securec.h"
24 #include "beget_ext.h"
25 #include "fs_dm_linear.h"
26 
27 #ifdef __cplusplus
28 #if __cplusplus
29 extern "C" {
30 #endif
31 #endif
32 
LoadDmLinearDeviceTable(int fd,const char * devName,DmLinearTarget * target,uint32_t targetNum)33 static int LoadDmLinearDeviceTable(int fd, const char *devName, DmLinearTarget *target, uint32_t targetNum)
34 {
35     struct dm_ioctl *io = NULL;
36     struct dm_target_spec *ts = NULL;
37     size_t parasTotalSize = DM_ALIGN(sizeof(*io) + sizeof(*ts) * targetNum);
38     for (uint32_t index = 0; index < targetNum; index++) {
39         parasTotalSize += target[index].paras_len + 1;
40     }
41 
42     char *parasBuf = calloc(1, parasTotalSize);
43     BEGET_ERROR_CHECK(parasBuf != NULL, return -1, "error, calloc dm table fail");
44     io = (struct dm_ioctl *)parasBuf;
45     int rc = InitDmIo(io, devName);
46     BEGET_ERROR_CHECK(rc == 0, free(parasBuf); return rc, "error %d, init dm io", rc);
47     io->data_size = parasTotalSize;
48     io->data_start = sizeof(*io);
49     io->target_count = targetNum;
50     uint32_t i = 0;
51     uint32_t len = 0;
52     char *paras = NULL;
53     do {
54         FS_DM_RETURN_ERR_IF_NULL(target[i].paras);
55         ts = (struct dm_target_spec *)(parasBuf + sizeof(*io) + len);
56         ts->status = 0;
57         ts->sector_start = target[i].start;
58         ts->length = target[i].length;
59 
60         rc = strcpy_s(ts->target_type, sizeof(ts->target_type), "linear");
61         BEGET_ERROR_CHECK(rc == EOK, free(parasBuf); return -1, "error %d, cp target type", rc);
62         len += sizeof((*ts));
63         paras = parasBuf + sizeof(*io) + len;
64         rc = strcpy_s(paras, target[i].paras_len + 1, target[i].paras);
65         BEGET_ERROR_CHECK(rc == EOK, free(parasBuf); return -1, "error %d, cp target paras", rc);
66         BEGET_LOGI("linear target.paras = %s, ts->target_type = %s", target[i].paras, ts->target_type);
67         len += target[i].paras_len + 1;
68         ts->next = target[i].paras_len + 1 + sizeof((*ts));
69         i++;
70     } while (i < targetNum);
71 
72     rc = ioctl(fd, DM_TABLE_LOAD, io);
73     if (rc != 0) {
74         BEGET_LOGE("error %d, DM_TABLE_LOAD failed for %s", rc, devName);
75     }
76     free(parasBuf);
77     BEGET_LOGI("LoadDmLinearDeviceTable end, dev is [%s] rc is [%d]", devName, rc);
78     return rc;
79 }
80 
FsDmCreateMultiTargetLinearDevice(const char * devName,char * dmDevPath,uint64_t dmDevPathLen,DmLinearTarget * target,uint32_t targetNum)81 int FsDmCreateMultiTargetLinearDevice(const char *devName, char *dmDevPath, uint64_t dmDevPathLen,
82     DmLinearTarget *target, uint32_t targetNum)
83 {
84     if (devName == NULL || dmDevPath == NULL || target == NULL) {
85         BEGET_LOGE("argc is null");
86         return -1;
87     }
88     if (targetNum == 0 || targetNum > MAX_TARGET_NUM) {
89         BEGET_LOGE("targetNum:%u is invalid", targetNum);
90         return -1;
91     }
92 
93     int fd = open(DEVICE_MAPPER_PATH, O_RDWR | O_CLOEXEC);
94     if (fd < 0) {
95         BEGET_LOGE("open mapper path failed errno %d", errno);
96         return -1;
97     }
98 
99     int rc = 0;
100 
101     do {
102         rc = CreateDmDev(fd, devName);
103         if (rc != 0) {
104             BEGET_LOGE("create dm device failed %d", rc);
105             break;
106         }
107         rc = DmGetDeviceName(fd, devName, dmDevPath, dmDevPathLen);
108         if (rc != 0) {
109             BEGET_LOGE("get dm device name failed");
110             break;
111         }
112         rc = LoadDmLinearDeviceTable(fd, devName, target, targetNum);
113         if (rc != 0) {
114             BEGET_LOGE("load dm device name failed");
115             break;
116         }
117 
118         rc = ActiveDmDevice(fd, devName);
119         if (rc != 0) {
120             BEGET_LOGE("active dm device name failed");
121             break;
122         }
123 
124         BEGET_LOGI("fs create linear device success, dev is [%s] dmDevPath is [%s]", devName, dmDevPath);
125     } while (0);
126 
127     close(fd);
128     return rc;
129 }
130 
FsDmSwitchToLinearDevice(const char * devName,DmLinearTarget * target,uint32_t targetNum)131 int FsDmSwitchToLinearDevice(const char *devName, DmLinearTarget *target, uint32_t targetNum)
132 {
133     if (devName == NULL || target == NULL) {
134         BEGET_LOGE("argc is null");
135         return -1;
136     }
137     if (targetNum == 0 || targetNum > MAX_TARGET_NUM) {
138         BEGET_LOGE("targetNum:%u is invalid", targetNum);
139         return -1;
140     }
141 
142     int fd = open(DEVICE_MAPPER_PATH, O_RDWR | O_CLOEXEC);
143     if (fd < 0) {
144         BEGET_LOGE("open mapper path failed errno %d", errno);
145         return -1;
146     }
147 
148     int rc = 0;
149 
150     do {
151         rc = LoadDmLinearDeviceTable(fd, devName, target, targetNum);
152         if (rc != 0) {
153             BEGET_LOGE("load dm device name failed");
154             break;
155         }
156         rc = ActiveDmDevice(fd, devName);
157         if (rc != 0) {
158             BEGET_LOGE("active dm device name failed");
159             break;
160         }
161 
162         BEGET_LOGI("fs switch linear device success, dev is [%s]", devName);
163     } while (0);
164 
165     close(fd);
166     return rc;
167 }
168 
169 #ifdef __cplusplus
170 #if __cplusplus
171 }
172 #endif
173 #endif