Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2019 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/opal.h"
7 : : #include "spdk/bdev_module.h"
8 : : #include "vbdev_opal.h"
9 : : #include "spdk/log.h"
10 : : #include "spdk/string.h"
11 : :
12 : : /* OPAL locking range only supports operations on nsid=1 for now */
13 : : #define NSID_SUPPORTED 1
14 : :
15 : : struct opal_vbdev {
16 : : char *name;
17 : : struct nvme_ctrlr *nvme_ctrlr;
18 : : struct spdk_opal_dev *opal_dev;
19 : : struct spdk_bdev_part *bdev_part;
20 : :
21 : : uint8_t locking_range_id;
22 : : uint64_t range_start;
23 : : uint64_t range_length;
24 : : struct vbdev_opal_part_base *opal_base;
25 : :
26 : : TAILQ_ENTRY(opal_vbdev) tailq;
27 : : };
28 : :
29 : : static TAILQ_HEAD(, opal_vbdev) g_opal_vbdev =
30 : : TAILQ_HEAD_INITIALIZER(g_opal_vbdev);
31 : :
32 : : struct vbdev_opal_bdev_io {
33 : : struct spdk_io_channel *ch;
34 : : struct spdk_bdev_io *bdev_io;
35 : : struct spdk_bdev_io_wait_entry bdev_io_wait;
36 : : };
37 : :
38 : : struct vbdev_opal_channel {
39 : : struct spdk_bdev_part_channel part_ch;
40 : : };
41 : :
42 : : struct vbdev_opal_part_base {
43 : : char *nvme_ctrlr_name;
44 : : struct spdk_bdev_part_base *part_base;
45 : : SPDK_BDEV_PART_TAILQ part_tailq;
46 : : TAILQ_ENTRY(vbdev_opal_part_base) tailq;
47 : : };
48 : :
49 : : static TAILQ_HEAD(, vbdev_opal_part_base) g_opal_base = TAILQ_HEAD_INITIALIZER(g_opal_base);
50 : :
51 : : static void _vbdev_opal_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io);
52 : :
53 : : static void vbdev_opal_examine(struct spdk_bdev *bdev);
54 : :
55 : : static void
56 : 0 : vbdev_opal_delete(struct opal_vbdev *opal_bdev)
57 : : {
58 [ # # ]: 0 : TAILQ_REMOVE(&g_opal_vbdev, opal_bdev, tailq);
59 : 0 : free(opal_bdev->name);
60 : 0 : free(opal_bdev);
61 : 0 : opal_bdev = NULL;
62 : 0 : }
63 : :
64 : : static void
65 : 1749 : vbdev_opal_clear(void)
66 : : {
67 : : struct opal_vbdev *opal_bdev, *tmp;
68 : :
69 [ - + ]: 1749 : TAILQ_FOREACH_SAFE(opal_bdev, &g_opal_vbdev, tailq, tmp) {
70 : 0 : vbdev_opal_delete(opal_bdev);
71 : : }
72 : 1749 : }
73 : :
74 : : static int
75 : 1749 : vbdev_opal_init(void)
76 : : {
77 : : /* TODO */
78 : 1749 : return 0;
79 : : }
80 : :
81 : : static void
82 : 1749 : vbdev_opal_fini(void)
83 : : {
84 : 1749 : vbdev_opal_clear();
85 : 1749 : }
86 : :
87 : : static int
88 : 2887 : vbdev_opal_get_ctx_size(void)
89 : : {
90 : 2887 : return sizeof(struct vbdev_opal_bdev_io);
91 : : }
92 : :
93 : : /* delete all the config of the same base bdev */
94 : : static void
95 : 0 : vbdev_opal_delete_all_base_config(struct vbdev_opal_part_base *base)
96 : : {
97 : 0 : char *nvme_ctrlr_name = base->nvme_ctrlr_name;
98 : : struct opal_vbdev *bdev, *tmp_bdev;
99 : :
100 [ # # ]: 0 : TAILQ_FOREACH_SAFE(bdev, &g_opal_vbdev, tailq, tmp_bdev) {
101 [ # # # # : 0 : if (!strcmp(nvme_ctrlr_name, bdev->nvme_ctrlr->nbdev_ctrlr->name)) {
# # ]
102 : 0 : vbdev_opal_delete(bdev);
103 : : }
104 : : }
105 : 0 : }
106 : :
107 : : static int
108 : 0 : _vbdev_opal_destruct(void *ctx)
109 : : {
110 : 0 : struct spdk_bdev_part *part = ctx;
111 : :
112 : 0 : return spdk_bdev_part_free(part);
113 : : }
114 : :
115 : : static void
116 : 0 : vbdev_opal_base_free(void *ctx)
117 : : {
118 : 0 : struct vbdev_opal_part_base *base = ctx;
119 : :
120 [ # # ]: 0 : TAILQ_REMOVE(&g_opal_base, base, tailq);
121 : :
122 : 0 : free(base->nvme_ctrlr_name);
123 : 0 : free(base);
124 : 0 : }
125 : :
126 : : static void
127 : 0 : vbdev_opal_resubmit_io(void *arg)
128 : : {
129 : 0 : struct vbdev_opal_bdev_io *io_ctx = (struct vbdev_opal_bdev_io *)arg;
130 : :
131 : 0 : _vbdev_opal_submit_request(io_ctx->ch, io_ctx->bdev_io);
132 : 0 : }
133 : :
134 : : static void
135 : 0 : vbdev_opal_queue_io(struct vbdev_opal_bdev_io *io_ctx)
136 : : {
137 : 0 : struct vbdev_opal_channel *ch = spdk_io_channel_get_ctx(io_ctx->ch);
138 : : int rc;
139 : :
140 : 0 : io_ctx->bdev_io_wait.bdev = io_ctx->bdev_io->bdev;
141 : 0 : io_ctx->bdev_io_wait.cb_fn = vbdev_opal_resubmit_io;
142 : 0 : io_ctx->bdev_io_wait.cb_arg = io_ctx;
143 : :
144 : 0 : rc = spdk_bdev_queue_io_wait(io_ctx->bdev_io->bdev, ch->part_ch.base_ch, &io_ctx->bdev_io_wait);
145 : :
146 [ # # ]: 0 : if (rc != 0) {
147 : 0 : SPDK_ERRLOG("Queue io failed in vbdev_opal_queue_io: %d\n", rc);
148 : 0 : spdk_bdev_io_complete(io_ctx->bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
149 : : }
150 : 0 : }
151 : :
152 : : static void
153 : 0 : _vbdev_opal_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io)
154 : : {
155 : 0 : struct vbdev_opal_channel *ch = spdk_io_channel_get_ctx(_ch);
156 : 0 : struct vbdev_opal_bdev_io *io_ctx = (struct vbdev_opal_bdev_io *)bdev_io->driver_ctx;
157 : : int rc;
158 : :
159 : 0 : rc = spdk_bdev_part_submit_request(&ch->part_ch, bdev_io);
160 [ # # ]: 0 : if (rc) {
161 [ # # ]: 0 : if (rc == -ENOMEM) {
162 [ # # # # ]: 0 : SPDK_DEBUGLOG(vbdev_opal, "opal: no memory, queue io.\n");
163 : 0 : io_ctx->ch = _ch;
164 : 0 : io_ctx->bdev_io = bdev_io;
165 : 0 : vbdev_opal_queue_io(io_ctx);
166 : : } else {
167 : 0 : SPDK_ERRLOG("opal: error on io submission, rc=%d.\n", rc);
168 : 0 : spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
169 : : }
170 : : }
171 : 0 : }
172 : :
173 : : static void
174 : 0 : vbdev_opal_io_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io, bool success)
175 : : {
176 [ # # ]: 0 : if (!success) {
177 : 0 : spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
178 : 0 : return;
179 : : }
180 : :
181 : 0 : _vbdev_opal_submit_request(ch, bdev_io);
182 : : }
183 : :
184 : : static void
185 : 0 : vbdev_opal_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
186 : : {
187 [ # # ]: 0 : switch (bdev_io->type) {
188 : 0 : case SPDK_BDEV_IO_TYPE_READ:
189 : 0 : spdk_bdev_io_get_buf(bdev_io, vbdev_opal_io_get_buf_cb,
190 : 0 : bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
191 : 0 : break;
192 : 0 : default:
193 : 0 : _vbdev_opal_submit_request(ch, bdev_io);
194 : 0 : break;
195 : : }
196 : 0 : }
197 : :
198 : : struct spdk_opal_locking_range_info *
199 : 0 : vbdev_opal_get_info_from_bdev(const char *opal_bdev_name, const char *password)
200 : : {
201 : : struct opal_vbdev *vbdev;
202 : : struct nvme_ctrlr *nvme_ctrlr;
203 : : int locking_range_id;
204 : : int rc;
205 : :
206 [ # # ]: 0 : TAILQ_FOREACH(vbdev, &g_opal_vbdev, tailq) {
207 [ # # # # : 0 : if (strcmp(vbdev->name, opal_bdev_name) == 0) {
# # ]
208 : 0 : break;
209 : : }
210 : : }
211 : :
212 [ # # ]: 0 : if (vbdev == NULL) {
213 : 0 : SPDK_ERRLOG("%s not found\n", opal_bdev_name);
214 : 0 : return NULL;
215 : : }
216 : :
217 : 0 : nvme_ctrlr = vbdev->nvme_ctrlr;
218 [ # # ]: 0 : if (nvme_ctrlr == NULL) {
219 : 0 : SPDK_ERRLOG("can't find nvme_ctrlr of %s\n", vbdev->name);
220 : 0 : return NULL;
221 : : }
222 : :
223 : 0 : locking_range_id = vbdev->locking_range_id;
224 : 0 : rc = spdk_opal_cmd_get_locking_range_info(nvme_ctrlr->opal_dev, password,
225 : : OPAL_ADMIN1, locking_range_id);
226 [ # # ]: 0 : if (rc) {
227 : 0 : SPDK_ERRLOG("Get locking range info error: %d\n", rc);
228 : 0 : return NULL;
229 : : }
230 : :
231 : 0 : return spdk_opal_get_locking_range_info(nvme_ctrlr->opal_dev, locking_range_id);
232 : : }
233 : :
234 : : static int
235 : 0 : vbdev_opal_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
236 : : {
237 : 0 : struct spdk_bdev_part *part = ctx;
238 : 0 : struct spdk_bdev *base_bdev = spdk_bdev_part_get_base_bdev(part);
239 : 0 : uint64_t offset = spdk_bdev_part_get_offset_blocks(part);
240 : :
241 : 0 : spdk_json_write_named_object_begin(w, "opal");
242 : :
243 : 0 : spdk_json_write_named_string(w, "base_bdev", spdk_bdev_get_name(base_bdev));
244 : 0 : spdk_json_write_named_uint64(w, "offset_blocks", offset);
245 : :
246 : 0 : spdk_json_write_object_end(w);
247 : :
248 : 0 : return 0;
249 : : }
250 : :
251 : : static void
252 : 0 : vbdev_opal_base_bdev_hotremove_cb(void *_part_base)
253 : : {
254 : 0 : struct spdk_bdev_part_base *part_base = _part_base;
255 : 0 : struct vbdev_opal_part_base *base = spdk_bdev_part_base_get_ctx(part_base);
256 : :
257 : 0 : spdk_bdev_part_base_hotremove(part_base, spdk_bdev_part_base_get_tailq(part_base));
258 : 0 : vbdev_opal_delete_all_base_config(base);
259 : 0 : }
260 : :
261 : : static bool
262 : 0 : vbdev_opal_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type)
263 : : {
264 : 0 : struct spdk_bdev_part *part = ctx;
265 : 0 : struct spdk_bdev *base_bdev = spdk_bdev_part_get_base_bdev(part);
266 : :
267 : 0 : return spdk_bdev_io_type_supported(base_bdev, io_type);
268 : : }
269 : :
270 : : static struct spdk_bdev_fn_table opal_vbdev_fn_table = {
271 : : .destruct = _vbdev_opal_destruct,
272 : : .submit_request = vbdev_opal_submit_request,
273 : : .io_type_supported = vbdev_opal_io_type_supported,
274 : : .dump_info_json = vbdev_opal_dump_info_json,
275 : : .write_config_json = NULL,
276 : : };
277 : :
278 : : static struct spdk_bdev_module opal_if = {
279 : : .name = "opal",
280 : : .module_init = vbdev_opal_init,
281 : : .module_fini = vbdev_opal_fini,
282 : : .get_ctx_size = vbdev_opal_get_ctx_size,
283 : : .examine_config = vbdev_opal_examine,
284 : : .config_json = NULL,
285 : : };
286 : :
287 : 1905 : SPDK_BDEV_MODULE_REGISTER(opal, &opal_if)
288 : :
289 : : int
290 : 0 : vbdev_opal_create(const char *nvme_ctrlr_name, uint32_t nsid, uint8_t locking_range_id,
291 : : uint64_t range_start, uint64_t range_length, const char *password)
292 : : {
293 : : int rc;
294 : : char *opal_vbdev_name;
295 : : char *base_bdev_name;
296 : : struct nvme_ctrlr *nvme_ctrlr;
297 : : struct opal_vbdev *opal_bdev;
298 : 0 : struct vbdev_opal_part_base *opal_part_base = NULL;
299 : : struct spdk_bdev_part *part_bdev;
300 : : struct nvme_bdev *nvme_bdev;
301 : : struct nvme_ns *nvme_ns;
302 : :
303 [ # # ]: 0 : if (nsid != NSID_SUPPORTED) {
304 : 0 : SPDK_ERRLOG("nsid %d not supported", nsid);
305 : 0 : return -EINVAL;
306 : : }
307 : :
308 : 0 : nvme_ctrlr = nvme_ctrlr_get_by_name(nvme_ctrlr_name);
309 [ # # ]: 0 : if (!nvme_ctrlr) {
310 : 0 : SPDK_ERRLOG("get nvme ctrlr failed\n");
311 : 0 : return -ENODEV;
312 : : }
313 : :
314 [ # # ]: 0 : if (!nvme_ctrlr->opal_dev) {
315 : 0 : SPDK_ERRLOG("Opal not supported\n");
316 : 0 : return -ENOTSUP;
317 : : }
318 : :
319 : 0 : opal_bdev = calloc(1, sizeof(struct opal_vbdev));
320 [ # # ]: 0 : if (!opal_bdev) {
321 : 0 : SPDK_ERRLOG("allocation for opal_bdev failed\n");
322 : 0 : return -ENOMEM;
323 : : }
324 : :
325 : 0 : opal_bdev->locking_range_id = locking_range_id;
326 : 0 : opal_bdev->range_start = range_start;
327 : 0 : opal_bdev->range_length = range_length;
328 : :
329 : 0 : opal_bdev->nvme_ctrlr = nvme_ctrlr;
330 : 0 : opal_bdev->opal_dev = nvme_ctrlr->opal_dev;
331 : :
332 : 0 : nvme_ns = nvme_ctrlr_get_ns(nvme_ctrlr, nsid);
333 [ # # ]: 0 : if (nvme_ns == NULL) {
334 : 0 : free(opal_bdev);
335 : 0 : return -ENODEV;
336 : : }
337 : :
338 : 0 : nvme_bdev = nvme_ns->bdev;
339 [ # # ]: 0 : assert(nvme_bdev != NULL);
340 : 0 : base_bdev_name = nvme_bdev->disk.name;
341 : :
342 : : /* traverse base list to see if part_base is already create for this base bdev */
343 [ # # ]: 0 : TAILQ_FOREACH(opal_part_base, &g_opal_base, tailq) {
344 [ # # # # : 0 : if (!strcmp(spdk_bdev_part_base_get_bdev_name(opal_part_base->part_base), base_bdev_name)) {
# # ]
345 : 0 : break;
346 : : }
347 : : }
348 : :
349 : : /* If there is not a corresponding opal_part_base, a new opal_part_base will be created.
350 : : For each new part_base, there will be one tailq to store all the parts of this base */
351 [ # # ]: 0 : if (opal_part_base == NULL) {
352 : 0 : opal_part_base = calloc(1, sizeof(*opal_part_base));
353 [ # # ]: 0 : if (opal_part_base == NULL) {
354 : 0 : SPDK_ERRLOG("Could not allocate opal_part_base\n");
355 : 0 : free(opal_bdev);
356 : 0 : return -ENOMEM;
357 : : }
358 : 0 : TAILQ_INIT(&opal_part_base->part_tailq);
359 : :
360 : 0 : rc = spdk_bdev_part_base_construct_ext(base_bdev_name,
361 : : vbdev_opal_base_bdev_hotremove_cb, &opal_if,
362 : 0 : &opal_vbdev_fn_table, &opal_part_base->part_tailq,
363 : : vbdev_opal_base_free, opal_part_base,
364 : : sizeof(struct vbdev_opal_channel), NULL, NULL,
365 : : &opal_part_base->part_base);
366 [ # # ]: 0 : if (rc != 0) {
367 [ # # ]: 0 : if (rc != -ENODEV) {
368 : 0 : SPDK_ERRLOG("Could not allocate part_base\n");
369 : : }
370 : 0 : free(opal_bdev);
371 : 0 : free(opal_part_base);
372 : 0 : return rc;
373 : : }
374 [ # # ]: 0 : opal_part_base->nvme_ctrlr_name = strdup(nvme_ctrlr_name);
375 [ # # ]: 0 : if (opal_part_base->nvme_ctrlr_name == NULL) {
376 : 0 : free(opal_bdev);
377 : 0 : spdk_bdev_part_base_free(opal_part_base->part_base);
378 : 0 : return -ENOMEM;
379 : : }
380 : :
381 : 0 : TAILQ_INSERT_TAIL(&g_opal_base, opal_part_base, tailq);
382 : : }
383 [ # # ]: 0 : assert(opal_part_base != NULL);
384 : 0 : opal_bdev->opal_base = opal_part_base;
385 : :
386 : 0 : part_bdev = calloc(1, sizeof(struct spdk_bdev_part));
387 [ # # ]: 0 : if (!part_bdev) {
388 : 0 : SPDK_ERRLOG("Could not allocate part_bdev\n");
389 : 0 : free(opal_bdev);
390 : 0 : return -ENOMEM;
391 : : }
392 : :
393 : 0 : TAILQ_INSERT_TAIL(&g_opal_vbdev, opal_bdev, tailq);
394 : 0 : opal_vbdev_name = spdk_sprintf_alloc("%sr%" PRIu8, base_bdev_name,
395 : 0 : opal_bdev->locking_range_id); /* e.g.: nvme0n1r1 */
396 [ # # ]: 0 : if (opal_vbdev_name == NULL) {
397 : 0 : SPDK_ERRLOG("Could not allocate opal_vbdev_name\n");
398 : 0 : rc = -ENOMEM;
399 : 0 : goto err;
400 : : }
401 : :
402 : 0 : opal_bdev->name = opal_vbdev_name;
403 : 0 : rc = spdk_opal_cmd_setup_locking_range(opal_bdev->opal_dev, OPAL_ADMIN1,
404 : 0 : opal_bdev->locking_range_id, opal_bdev->range_start,
405 : : opal_bdev->range_length, password);
406 [ # # ]: 0 : if (rc) {
407 : 0 : SPDK_ERRLOG("Error construct %s\n", opal_vbdev_name);
408 : 0 : goto err;
409 : : }
410 : :
411 : 0 : rc = spdk_bdev_part_construct(part_bdev, opal_bdev->opal_base->part_base, opal_vbdev_name,
412 : : opal_bdev->range_start, opal_bdev->range_length, "Opal locking range");
413 [ # # ]: 0 : if (rc) {
414 : 0 : SPDK_ERRLOG("Could not allocate bdev part\n");
415 : 0 : goto err;
416 : : }
417 : :
418 : : /* lock this bdev initially */
419 : 0 : rc = spdk_opal_cmd_lock_unlock(opal_bdev->opal_dev, OPAL_ADMIN1, OPAL_RWLOCK, locking_range_id,
420 : : password);
421 [ # # ]: 0 : if (rc) {
422 : 0 : SPDK_ERRLOG("Error lock %s\n", opal_vbdev_name);
423 : 0 : goto err;
424 : : }
425 : :
426 : 0 : opal_bdev->bdev_part = part_bdev;
427 : 0 : return 0;
428 : :
429 : 0 : err:
430 : 0 : vbdev_opal_delete(opal_bdev);
431 : 0 : free(part_bdev);
432 : 0 : return rc;
433 : : }
434 : :
435 : : static void
436 : 0 : vbdev_opal_destruct_bdev(struct opal_vbdev *opal_bdev)
437 : : {
438 : 0 : struct spdk_bdev_part *part = opal_bdev->bdev_part;
439 : :
440 [ # # ]: 0 : assert(opal_bdev->opal_base != NULL);
441 [ # # ]: 0 : assert(part != NULL);
442 : :
443 [ # # ]: 0 : if (opal_bdev->range_start == spdk_bdev_part_get_offset_blocks(part)) {
444 : 0 : spdk_bdev_unregister(spdk_bdev_part_get_bdev(part), NULL, NULL);
445 : : }
446 : 0 : vbdev_opal_delete(opal_bdev);
447 : 0 : }
448 : :
449 : : int
450 : 0 : vbdev_opal_destruct(const char *bdev_name, const char *password)
451 : : {
452 : : struct nvme_ctrlr *nvme_ctrlr;
453 : : int locking_range_id;
454 : : int rc;
455 : : struct opal_vbdev *opal_bdev;
456 : :
457 [ # # ]: 0 : TAILQ_FOREACH(opal_bdev, &g_opal_vbdev, tailq) {
458 [ # # # # : 0 : if (strcmp(opal_bdev->name, bdev_name) == 0) {
# # ]
459 : 0 : break;
460 : : }
461 : : }
462 : :
463 [ # # ]: 0 : if (opal_bdev == NULL) {
464 : 0 : SPDK_ERRLOG("%s not found\n", bdev_name);
465 : 0 : rc = -ENODEV;
466 : 0 : goto err;
467 : : }
468 : :
469 : 0 : locking_range_id = opal_bdev->locking_range_id;
470 : :
471 : 0 : nvme_ctrlr = opal_bdev->nvme_ctrlr;
472 [ # # ]: 0 : if (nvme_ctrlr == NULL) {
473 : 0 : SPDK_ERRLOG("can't find nvme_ctrlr of %s\n", bdev_name);
474 : 0 : return -ENODEV;
475 : : }
476 : :
477 : : /* secure erase locking range */
478 : 0 : rc = spdk_opal_cmd_secure_erase_locking_range(nvme_ctrlr->opal_dev, OPAL_ADMIN1, locking_range_id,
479 : : password);
480 [ # # ]: 0 : if (rc) {
481 : 0 : SPDK_ERRLOG("opal erase locking range failed\n");
482 : 0 : goto err;
483 : : }
484 : :
485 : : /* reset the locking range to 0 */
486 : 0 : rc = spdk_opal_cmd_setup_locking_range(nvme_ctrlr->opal_dev, OPAL_ADMIN1, locking_range_id, 0,
487 : : 0, password);
488 [ # # ]: 0 : if (rc) {
489 : 0 : SPDK_ERRLOG("opal reset locking range failed\n");
490 : 0 : goto err;
491 : : }
492 : :
493 : 0 : spdk_opal_free_locking_range_info(opal_bdev->opal_dev, locking_range_id);
494 : 0 : vbdev_opal_destruct_bdev(opal_bdev);
495 : 0 : return 0;
496 : :
497 : 0 : err:
498 : 0 : return rc;
499 : : }
500 : :
501 : : static void
502 : 5771 : vbdev_opal_examine(struct spdk_bdev *bdev)
503 : : {
504 : : /* TODO */
505 : 5771 : spdk_bdev_module_examine_done(&opal_if);
506 : 5771 : }
507 : :
508 : : int
509 : 0 : vbdev_opal_set_lock_state(const char *bdev_name, uint16_t user_id, const char *password,
510 : : const char *lock_state)
511 : : {
512 : : struct nvme_ctrlr *nvme_ctrlr;
513 : : int locking_range_id;
514 : : int rc;
515 : : enum spdk_opal_lock_state state_flag;
516 : : struct opal_vbdev *opal_bdev;
517 : :
518 [ # # ]: 0 : TAILQ_FOREACH(opal_bdev, &g_opal_vbdev, tailq) {
519 [ # # # # : 0 : if (strcmp(opal_bdev->name, bdev_name) == 0) {
# # ]
520 : 0 : break;
521 : : }
522 : : }
523 : :
524 [ # # ]: 0 : if (opal_bdev == NULL) {
525 : 0 : SPDK_ERRLOG("%s not found\n", bdev_name);
526 : 0 : return -ENODEV;
527 : : }
528 : :
529 : 0 : nvme_ctrlr = opal_bdev->nvme_ctrlr;
530 [ # # ]: 0 : if (nvme_ctrlr == NULL) {
531 : 0 : SPDK_ERRLOG("can't find nvme_ctrlr of %s\n", opal_bdev->name);
532 : 0 : return -ENODEV;
533 : : }
534 : :
535 [ # # # # ]: 0 : if (strcasecmp(lock_state, "READWRITE") == 0) {
536 : 0 : state_flag = OPAL_READWRITE;
537 [ # # # # ]: 0 : } else if (strcasecmp(lock_state, "READONLY") == 0) {
538 : 0 : state_flag = OPAL_READONLY;
539 [ # # # # ]: 0 : } else if (strcasecmp(lock_state, "RWLOCK") == 0) {
540 : 0 : state_flag = OPAL_RWLOCK;
541 : : } else {
542 : 0 : SPDK_ERRLOG("Invalid OPAL lock state input\n");
543 : 0 : return -EINVAL;
544 : : }
545 : :
546 : 0 : locking_range_id = opal_bdev->locking_range_id;
547 : 0 : rc = spdk_opal_cmd_lock_unlock(nvme_ctrlr->opal_dev, user_id, state_flag, locking_range_id,
548 : : password);
549 [ # # ]: 0 : if (rc) {
550 : 0 : SPDK_ERRLOG("%s lock/unlock failure: %d\n", bdev_name, rc);
551 : : }
552 : :
553 : 0 : return rc;
554 : : }
555 : :
556 : : int
557 : 0 : vbdev_opal_enable_new_user(const char *bdev_name, const char *admin_password, uint16_t user_id,
558 : : const char *user_password)
559 : : {
560 : : struct nvme_ctrlr *nvme_ctrlr;
561 : : int locking_range_id;
562 : : int rc;
563 : : struct opal_vbdev *opal_bdev;
564 : :
565 [ # # ]: 0 : TAILQ_FOREACH(opal_bdev, &g_opal_vbdev, tailq) {
566 [ # # # # : 0 : if (strcmp(opal_bdev->name, bdev_name) == 0) {
# # ]
567 : 0 : break;
568 : : }
569 : : }
570 : :
571 [ # # ]: 0 : if (opal_bdev == NULL) {
572 : 0 : SPDK_ERRLOG("%s not found\n", bdev_name);
573 : 0 : return -ENODEV;
574 : : }
575 : :
576 : 0 : nvme_ctrlr = opal_bdev->nvme_ctrlr;
577 [ # # ]: 0 : if (nvme_ctrlr == NULL) {
578 : 0 : SPDK_ERRLOG("can't find nvme_ctrlr of %s\n", opal_bdev->name);
579 : 0 : return -ENODEV;
580 : : }
581 : :
582 : 0 : rc = spdk_opal_cmd_enable_user(nvme_ctrlr->opal_dev, user_id, admin_password);
583 [ # # ]: 0 : if (rc) {
584 : 0 : SPDK_ERRLOG("%s enable user error: %d\n", bdev_name, rc);
585 : 0 : return rc;
586 : : }
587 : :
588 : 0 : rc = spdk_opal_cmd_set_new_passwd(nvme_ctrlr->opal_dev, user_id, user_password, admin_password,
589 : : true);
590 [ # # ]: 0 : if (rc) {
591 : 0 : SPDK_ERRLOG("%s set user password error: %d\n", bdev_name, rc);
592 : 0 : return rc;
593 : : }
594 : :
595 : 0 : locking_range_id = opal_bdev->locking_range_id;
596 : 0 : rc = spdk_opal_cmd_add_user_to_locking_range(nvme_ctrlr->opal_dev, user_id, locking_range_id,
597 : : OPAL_READONLY, admin_password);
598 [ # # ]: 0 : if (rc) {
599 : 0 : SPDK_ERRLOG("%s add user READONLY priority error: %d\n", bdev_name, rc);
600 : 0 : return rc;
601 : : }
602 : :
603 : 0 : rc = spdk_opal_cmd_add_user_to_locking_range(nvme_ctrlr->opal_dev, user_id, locking_range_id,
604 : : OPAL_READWRITE, admin_password);
605 [ # # ]: 0 : if (rc) {
606 : 0 : SPDK_ERRLOG("%s add user READWRITE priority error: %d\n", bdev_name, rc);
607 : 0 : return rc;
608 : : }
609 : :
610 : 0 : return 0;
611 : : }
612 : :
613 : 1905 : SPDK_LOG_REGISTER_COMPONENT(vbdev_opal)
|