LCOV - code coverage report
Current view: top level - module/bdev/nvme - vbdev_opal.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 0 288 0.0 %
Date: 2024-12-08 14:55:45 Functions: 0 25 0.0 %

          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           0 : vbdev_opal_clear(void)
      66             : {
      67             :         struct opal_vbdev *opal_bdev, *tmp;
      68             : 
      69           0 :         TAILQ_FOREACH_SAFE(opal_bdev, &g_opal_vbdev, tailq, tmp) {
      70           0 :                 vbdev_opal_delete(opal_bdev);
      71             :         }
      72           0 : }
      73             : 
      74             : static int
      75           0 : vbdev_opal_init(void)
      76             : {
      77             :         /* TODO */
      78           0 :         return 0;
      79             : }
      80             : 
      81             : static void
      82           0 : vbdev_opal_fini(void)
      83             : {
      84           0 :         vbdev_opal_clear();
      85           0 : }
      86             : 
      87             : static int
      88           0 : vbdev_opal_get_ctx_size(void)
      89             : {
      90           0 :         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           0 : 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           0 : vbdev_opal_examine(struct spdk_bdev *bdev)
     503             : {
     504             :         /* TODO */
     505           0 :         spdk_bdev_module_examine_done(&opal_if);
     506           0 : }
     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           0 : SPDK_LOG_REGISTER_COMPONENT(vbdev_opal)

Generated by: LCOV version 1.15