Opal: Add locking range support

Change-Id: I4974d4134aed3b63e204b79c9292ce940e32d40c
Signed-off-by: Chunyang Hui <chunyang.hui@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/455175
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Chunyang Hui 2019-05-21 21:27:31 +08:00 committed by Changpeng Liu
parent 755b4390f9
commit 505dbf59ff
5 changed files with 491 additions and 30 deletions

View File

@ -50,6 +50,8 @@ Nvme Opal library spdk_opal_cmd deprecated. Adding seperate command APIs.
NVMe Opal library add support for activating locking SP which will make the transaction NVMe Opal library add support for activating locking SP which will make the transaction
from "Manufactured-Inactive" state to "Manufactured" state. Upon successfully invoking from "Manufactured-Inactive" state to "Manufactured" state. Upon successfully invoking
of this method, lock and unlock features will be enabled. of this method, lock and unlock features will be enabled.
NVMe Opal library add support for locking/unlocking range.
Added spdk_nvme_ctrlr_io_cmd_raw_no_payload_build() allowing a caller to pass Added spdk_nvme_ctrlr_io_cmd_raw_no_payload_build() allowing a caller to pass
a completely formed command to an NVMe submission queue (buffer addresses and all). a completely formed command to an NVMe submission queue (buffer addresses and all).

View File

@ -939,7 +939,8 @@ opal_usage(void)
printf("\n"); printf("\n");
printf("\t[1: scan device]\n"); printf("\t[1: scan device]\n");
printf("\t[2: init - take ownership and activate locking]\n"); printf("\t[2: init - take ownership and activate locking]\n");
printf("\t[3: revert tper]\n"); printf("\t[3: lock/unlock the range]\n");
printf("\t[9: revert tper]\n");
printf("\t[0: quit]\n"); printf("\t[0: quit]\n");
} }
@ -1009,6 +1010,91 @@ opal_init(struct dev *iter)
} }
} }
static void
opal_locking_usage(void)
{
printf("Choose Opal locking state:\n");
printf("\n");
printf("\t[1: read write lock]\n");
printf("\t[2: read only]\n");
printf("\t[3: read write unlock]\n");
}
static void
opal_lock_range(struct dev *iter)
{
char passwd[MAX_PASSWORD_SIZE] = {0};
char *passwd_p;
int ret;
int ch;
int state;
enum spdk_opal_lock_state state_flag;
if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) {
iter->opal_dev = spdk_opal_init_dev(iter->ctrlr);
if (iter->opal_dev == NULL) {
return;
}
if (spdk_opal_supported(iter->opal_dev)) {
printf("Please input the password for locking the range:\n");
while ((ch = getchar()) != '\n' && ch != EOF);
passwd_p = getpass(passwd);
if (passwd_p) {
ret = spdk_opal_cmd_lock_unlock(iter->opal_dev, OPAL_ADMIN1, OPAL_READWRITE,
OPAL_LOCKING_RANGE_GLOBAL, passwd_p);
if (ret) {
printf("Unlock range failure: %d\n", ret);
return;
}
ret = spdk_opal_cmd_setup_locking_range(iter->opal_dev,
OPAL_ADMIN1, OPAL_LOCKING_RANGE_GLOBAL, 0, 0, passwd_p); /* just put here for testing */
if (ret) {
printf("Setup locking range failure: %d\n", ret);
return;
}
opal_locking_usage();
ret = scanf("%d", &state);
if (ret != 1) {
printf("Invalid input\n");
return;
}
switch (state) {
case 1:
state_flag = OPAL_RWLOCK;
break;
case 2:
state_flag = OPAL_READONLY;
break;
case 3:
state_flag = OPAL_READWRITE;
break;
default:
printf("Invalid options\n");
return;
}
ret = spdk_opal_cmd_lock_unlock(iter->opal_dev, OPAL_ADMIN1, state_flag,
OPAL_LOCKING_RANGE_GLOBAL, passwd_p);
if (ret) {
printf("lock range failure: %d\n", ret);
return;
}
printf("...\n...\nOpal setup locking range success\n");
} else {
printf("Input password invalid. Opal setup locking range failure\n");
}
}
spdk_opal_close(iter->opal_dev);
} else {
printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n",
iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func);
}
}
static void static void
opal_revert_tper(struct dev *iter) opal_revert_tper(struct dev *iter)
{ {
@ -1062,7 +1148,7 @@ test_opal(void)
while (!exit_flag) { while (!exit_flag) {
int cmd; int cmd;
if (!scanf("%d", &cmd)) { if (!scanf("%d", &cmd)) {
printf("Invalid Command: command must be number 0-2\n"); printf("Invalid Command: command must be number 0-9\n");
while (getchar() != '\n'); while (getchar() != '\n');
opal_usage(); opal_usage();
continue; continue;
@ -1079,6 +1165,9 @@ test_opal(void)
opal_init(ctrlr); /* Take ownership, Activate Locking SP */ opal_init(ctrlr); /* Take ownership, Activate Locking SP */
break; break;
case 3: case 3:
opal_lock_range(ctrlr);
break;
case 9:
opal_revert_tper(ctrlr); opal_revert_tper(ctrlr);
break; break;

View File

@ -119,10 +119,9 @@ struct spdk_opal_info {
}; };
enum spdk_opal_lock_state { enum spdk_opal_lock_state {
OPAL_LS_DISALBELOCKING = 0x00, OPAL_READONLY = 0x01,
OPAL_LS_READLOCK_ENABLE = 0x01, OPAL_RWLOCK = 0x02,
OPAL_LS_WRITELOCK_ENABLE = 0x02, OPAL_READWRITE = 0x04,
OPAL_LS_RWLOCK_ENABLE = 0x04,
}; };
enum spdk_opal_user { enum spdk_opal_user {
@ -165,5 +164,11 @@ int spdk_opal_cmd_scan(struct spdk_opal_dev *dev);
int spdk_opal_cmd_take_ownership(struct spdk_opal_dev *dev, char *new_passwd); int spdk_opal_cmd_take_ownership(struct spdk_opal_dev *dev, char *new_passwd);
int spdk_opal_cmd_revert_tper(struct spdk_opal_dev *dev, const char *passwd); int spdk_opal_cmd_revert_tper(struct spdk_opal_dev *dev, const char *passwd);
int spdk_opal_cmd_activate_locking_sp(struct spdk_opal_dev *dev, const char *passwd); int spdk_opal_cmd_activate_locking_sp(struct spdk_opal_dev *dev, const char *passwd);
int spdk_opal_cmd_lock_unlock(struct spdk_opal_dev *dev, enum spdk_opal_user user,
enum spdk_opal_lock_state flag, enum spdk_opal_locking_range locking_range,
const char *passwd);
int spdk_opal_cmd_setup_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user,
enum spdk_opal_locking_range locking_range_id, uint64_t range_start,
uint64_t range_length, const char *passwd);
#endif #endif

View File

@ -37,8 +37,6 @@
#include "nvme_opal_internal.h" #include "nvme_opal_internal.h"
typedef int (spdk_opal_cb)(struct spdk_opal_dev *dev);
static const char * static const char *
opal_error_to_human(int error) opal_error_to_human(int error)
{ {
@ -98,7 +96,7 @@ opal_recv_cmd(struct spdk_opal_dev *dev)
} }
static int static int
opal_send_recv(struct spdk_opal_dev *dev, spdk_opal_cb *cb) opal_send_recv(struct spdk_opal_dev *dev, spdk_opal_cb *cb, void *data)
{ {
int ret; int ret;
@ -110,7 +108,7 @@ opal_send_recv(struct spdk_opal_dev *dev, spdk_opal_cb *cb)
if (ret) { if (ret) {
return ret; return ret;
} }
return cb(dev); return cb(dev, data);
} }
static void static void
@ -279,7 +277,7 @@ opal_cmd_finalize(struct spdk_opal_dev *dev, uint32_t hsn, uint32_t tsn, bool eo
} }
static int static int
opal_finalize_and_send(struct spdk_opal_dev *dev, bool eod, spdk_opal_cb cb) opal_finalize_and_send(struct spdk_opal_dev *dev, bool eod, spdk_opal_cb cb, void *data)
{ {
int ret; int ret;
@ -289,7 +287,7 @@ opal_finalize_and_send(struct spdk_opal_dev *dev, bool eod, spdk_opal_cb cb)
return ret; return ret;
} }
return opal_send_recv(dev, cb); return opal_send_recv(dev, cb, NULL);
} }
static size_t static size_t
@ -582,7 +580,7 @@ opal_response_status(const struct spdk_opal_resp_parsed *resp)
} }
static int static int
opal_parse_and_check_status(struct spdk_opal_dev *dev) opal_parse_and_check_status(struct spdk_opal_dev *dev, void *data)
{ {
int error; int error;
@ -638,6 +636,42 @@ opal_init_key(struct spdk_opal_key *opal_key, const char *passwd,
return 0; return 0;
} }
static int
opal_build_locking_user(uint8_t *buffer, size_t length, uint8_t user)
{
if (length < OPAL_UID_LENGTH) {
SPDK_ERRLOG("Can't build locking range user, buffer overflow\n");
return -ERANGE;
}
memcpy(buffer, spdk_opal_uid[UID_USER1], OPAL_UID_LENGTH);
buffer[7] = user;
return 0;
}
static int
opal_build_locking_range(uint8_t *buffer, size_t length, uint8_t locking_range)
{
if (length < OPAL_UID_LENGTH) {
SPDK_ERRLOG("Can't build locking range. Buffer overflow\n");
return -ERANGE;
}
memcpy(buffer, spdk_opal_uid[UID_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH);
/* global */
if (locking_range == 0) {
return 0;
}
/* non-global */
buffer[5] = LOCKING_RANGE_NON_GLOBAL;
buffer[7] = locking_range;
return 0;
}
static void static void
opal_check_tper(struct spdk_opal_dev *dev, const void *data) opal_check_tper(struct spdk_opal_dev *dev, const void *data)
{ {
@ -856,11 +890,11 @@ opal_setup_dev(struct spdk_opal_dev *dev)
} }
static int static int
opal_end_session_cb(struct spdk_opal_dev *dev) opal_end_session_cb(struct spdk_opal_dev *dev, void *data)
{ {
dev->hsn = 0; dev->hsn = 0;
dev->tsn = 0; dev->tsn = 0;
return opal_parse_and_check_status(dev); return opal_parse_and_check_status(dev, NULL);
} }
static int static int
@ -876,7 +910,7 @@ opal_end_session(struct spdk_opal_dev *dev)
if (err < 0) { if (err < 0) {
return err; return err;
} }
return opal_finalize_and_send(dev, eod, opal_end_session_cb); return opal_finalize_and_send(dev, eod, opal_end_session_cb, NULL);
} }
static int static int
@ -901,12 +935,12 @@ spdk_opal_close(struct spdk_opal_dev *dev)
} }
static int static int
opal_start_session_cb(struct spdk_opal_dev *dev) opal_start_session_cb(struct spdk_opal_dev *dev, void *data)
{ {
uint32_t hsn, tsn; uint32_t hsn, tsn;
int error = 0; int error = 0;
error = opal_parse_and_check_status(dev); error = opal_parse_and_check_status(dev, NULL);
if (error) { if (error) {
return error; return error;
} }
@ -981,7 +1015,7 @@ opal_start_generic_session(struct spdk_opal_dev *dev,
return err; return err;
} }
return opal_finalize_and_send(dev, 1, opal_start_session_cb); return opal_finalize_and_send(dev, 1, opal_start_session_cb, NULL);
} }
@ -993,13 +1027,13 @@ opal_start_anybody_adminsp_session(struct spdk_opal_dev *dev)
} }
static int static int
opal_get_msid_cpin_pin_cb(struct spdk_opal_dev *dev) opal_get_msid_cpin_pin_cb(struct spdk_opal_dev *dev, void *data)
{ {
const char *msid_pin; const char *msid_pin;
size_t strlen; size_t strlen;
int error = 0; int error = 0;
error = opal_parse_and_check_status(dev); error = opal_parse_and_check_status(dev, NULL);
if (error) { if (error) {
return error; return error;
} }
@ -1053,7 +1087,7 @@ opal_get_msid_cpin_pin(struct spdk_opal_dev *dev)
return err; return err;
} }
return opal_finalize_and_send(dev, 1, opal_get_msid_cpin_pin_cb); return opal_finalize_and_send(dev, 1, opal_get_msid_cpin_pin_cb, NULL);
} }
static int static int
@ -1114,12 +1148,12 @@ opal_generic_pw_cmd(uint8_t *key, size_t key_len, uint8_t *cpin_uid,
} }
static int static int
opal_get_locking_sp_lifecycle_cb(struct spdk_opal_dev *dev) opal_get_locking_sp_lifecycle_cb(struct spdk_opal_dev *dev, void *data)
{ {
uint8_t lifecycle; uint8_t lifecycle;
int error = 0; int error = 0;
error = opal_parse_and_check_status(dev); error = opal_parse_and_check_status(dev, NULL);
if (error) { if (error) {
return error; return error;
} }
@ -1164,7 +1198,7 @@ opal_get_locking_sp_lifecycle(struct spdk_opal_dev *dev)
return err; return err;
} }
return opal_finalize_and_send(dev, 1, opal_get_locking_sp_lifecycle_cb); return opal_finalize_and_send(dev, 1, opal_get_locking_sp_lifecycle_cb, NULL);
} }
static int static int
@ -1190,7 +1224,237 @@ opal_activate(struct spdk_opal_dev *dev)
/* TODO: Single User Mode for activatation */ /* TODO: Single User Mode for activatation */
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status); return opal_finalize_and_send(dev, 1, opal_parse_and_check_status, NULL);
}
static int
opal_start_auth_session(struct spdk_opal_dev *dev, struct opal_common_session *session)
{
uint8_t uid_user[OPAL_UID_LENGTH];
size_t keylen = session->opal_key->key_len;
int err = 0;
uint8_t *key = session->opal_key->key;
uint32_t hsn = GENERIC_HOST_SESSION_NUM;
opal_clear_cmd(dev);
opal_set_comid(dev, dev->comid);
if (session->who != OPAL_ADMIN1) {
err = opal_build_locking_user(uid_user, sizeof(uid_user),
session->who);
if (err) {
return err;
}
} else {
memcpy(uid_user, spdk_opal_uid[UID_ADMIN1], OPAL_UID_LENGTH);
}
opal_add_token_u8(&err, dev, SPDK_OPAL_CALL);
opal_add_token_bytestring(&err, dev, spdk_opal_uid[UID_SMUID],
OPAL_UID_LENGTH);
opal_add_token_bytestring(&err, dev, spdk_opal_method[STARTSESSION_METHOD],
OPAL_UID_LENGTH);
opal_add_token_u8(&err, dev, SPDK_OPAL_STARTLIST);
opal_add_token_u64(&err, dev, hsn);
opal_add_token_bytestring(&err, dev, spdk_opal_uid[UID_LOCKINGSP],
OPAL_UID_LENGTH);
opal_add_tokens(&err, dev, 3, SPDK_OPAL_TRUE, SPDK_OPAL_STARTNAME,
0); /* True for a Read-Write session */
opal_add_token_bytestring(&err, dev, key, keylen);
opal_add_tokens(&err, dev, 3, SPDK_OPAL_ENDNAME, SPDK_OPAL_STARTNAME, 3); /* HostSignAuth */
opal_add_token_bytestring(&err, dev, uid_user, OPAL_UID_LENGTH);
opal_add_tokens(&err, dev, 2, SPDK_OPAL_ENDNAME, SPDK_OPAL_ENDLIST);
if (err) {
SPDK_ERRLOG("Error building STARTSESSION command.\n");
return err;
}
return opal_finalize_and_send(dev, 1, opal_start_session_cb, NULL);
}
static int
opal_lock_unlock_range(struct spdk_opal_dev *dev, struct spdk_opal_locking_session *locking_session)
{
uint8_t uid_locking_range[OPAL_UID_LENGTH];
uint8_t read_locked, write_locked;
int err = 0;
opal_clear_cmd(dev);
opal_set_comid(dev, dev->comid);
if (opal_build_locking_range(uid_locking_range, sizeof(uid_locking_range),
locking_session->session.opal_key->locking_range) < 0) {
return -ERANGE;
}
switch (locking_session->l_state) {
case OPAL_READONLY:
read_locked = 0;
write_locked = 1;
break;
case OPAL_READWRITE:
read_locked = 0;
write_locked = 0;
break;
case OPAL_RWLOCK:
read_locked = 1;
write_locked = 1;
break;
default:
SPDK_ERRLOG("Tried to set an invalid locking state.\n");
return -EINVAL;
}
opal_add_token_u8(&err, dev, SPDK_OPAL_CALL);
opal_add_token_bytestring(&err, dev, uid_locking_range, OPAL_UID_LENGTH);
opal_add_token_bytestring(&err, dev, spdk_opal_method[SET_METHOD], OPAL_UID_LENGTH);
opal_add_tokens(&err, dev, 15, SPDK_OPAL_STARTLIST,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_VALUES,
SPDK_OPAL_STARTLIST,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_READLOCKED,
read_locked,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_WRITELOCKED,
write_locked,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_ENDLIST,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_ENDLIST);
if (err) {
SPDK_ERRLOG("Error building SET command.\n");
return err;
}
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status, NULL);
}
static int opal_generic_locking_range_enable_disable(struct spdk_opal_dev *dev,
uint8_t *uid, bool read_lock_enabled, bool write_lock_enabled,
bool read_locked, bool write_locked)
{
int err = 0;
opal_add_token_u8(&err, dev, SPDK_OPAL_CALL);
opal_add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
opal_add_token_bytestring(&err, dev, spdk_opal_method[SET_METHOD], OPAL_UID_LENGTH);
opal_add_tokens(&err, dev, 23, SPDK_OPAL_STARTLIST,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_VALUES,
SPDK_OPAL_STARTLIST,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_READLOCKENABLED,
read_lock_enabled,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_WRITELOCKENABLED,
write_lock_enabled,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_READLOCKED,
read_locked,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_WRITELOCKED,
write_locked,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_ENDLIST,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_ENDLIST);
if (err) {
SPDK_ERRLOG("Error building locking range enable/disable command.\n");
}
return err;
}
static int
spdk_enable_global_locking_range(struct spdk_opal_dev *dev, uint8_t *locking_range,
struct opal_locking_range_setup_session *setup_session)
{
int err;
err = opal_generic_locking_range_enable_disable(dev, locking_range,
setup_session->read_lock_enabled,
setup_session->write_lock_enabled,
0, 0);
if (err) {
SPDK_ERRLOG("Failed to create enable global locking range command\n");
}
return err;
}
static int
opal_setup_locking_range(struct spdk_opal_dev *dev,
struct opal_locking_range_setup_session *setup_session)
{
uint8_t uid_locking_range[OPAL_UID_LENGTH];
uint8_t locking_range_id;
int err = 0;
opal_clear_cmd(dev);
opal_set_comid(dev, dev->comid);
locking_range_id = setup_session->session.opal_key->locking_range;
err = opal_build_locking_range(uid_locking_range, OPAL_UID_LENGTH, locking_range_id);
if (err) {
return err;
}
if (locking_range_id == 0) {
err = spdk_enable_global_locking_range(dev, uid_locking_range, setup_session);
} else {
opal_add_token_u8(&err, dev, SPDK_OPAL_CALL);
opal_add_token_bytestring(&err, dev, uid_locking_range, OPAL_UID_LENGTH);
opal_add_token_bytestring(&err, dev, spdk_opal_method[SET_METHOD],
OPAL_UID_LENGTH);
opal_add_tokens(&err, dev, 6,
SPDK_OPAL_STARTLIST,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_VALUES,
SPDK_OPAL_STARTLIST,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_RANGESTART);
opal_add_token_u64(&err, dev, setup_session->range_start);
opal_add_tokens(&err, dev, 3,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_RANGELENGTH);
opal_add_token_u64(&err, dev, setup_session->range_length);
opal_add_tokens(&err, dev, 3,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_READLOCKENABLED);
opal_add_token_u64(&err, dev, setup_session->read_lock_enabled);
opal_add_tokens(&err, dev, 3,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_WRITELOCKENABLED);
opal_add_token_u64(&err, dev, setup_session->write_lock_enabled);
opal_add_tokens(&err, dev, 4,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_ENDLIST,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_ENDLIST);
}
if (err) {
SPDK_ERRLOG("Error building Setup Locking range command.\n");
return err;
}
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status, NULL);
} }
static int static int
@ -1212,7 +1476,7 @@ opal_set_sid_cpin_pin(struct spdk_opal_dev *dev, void *data)
SPDK_ERRLOG("Error building Set SID cpin\n"); SPDK_ERRLOG("Error building Set SID cpin\n");
return -ERANGE; return -ERANGE;
} }
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status); return opal_finalize_and_send(dev, 1, opal_parse_and_check_status, NULL);
} }
int int
@ -1347,7 +1611,7 @@ opal_revert_tper(struct spdk_opal_dev *dev)
return err; return err;
} }
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status); return opal_finalize_and_send(dev, 1, opal_parse_and_check_status, NULL);
} }
int int
@ -1436,6 +1700,105 @@ end:
return ret; return ret;
} }
int
spdk_opal_cmd_lock_unlock(struct spdk_opal_dev *dev, enum spdk_opal_user user,
enum spdk_opal_lock_state flag, enum spdk_opal_locking_range locking_range,
const char *passwd)
{
struct spdk_opal_locking_session locking_session;
struct spdk_opal_key opal_key;
int ret;
if (!dev || dev->supported == false) {
return -ENODEV;
}
ret = opal_init_key(&opal_key, passwd, locking_range);
if (ret != 0) {
return ret;
}
memset(&locking_session, 0, sizeof(struct spdk_opal_locking_session));
locking_session.l_state = flag;
locking_session.session.who = user;
locking_session.session.opal_key = &opal_key;
pthread_mutex_lock(&dev->mutex_lock);
ret = opal_start_auth_session(dev, &locking_session.session);
if (ret) {
SPDK_ERRLOG("start authenticate session error %d: %s\n", ret, opal_error_to_human(ret));
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
ret = opal_lock_unlock_range(dev, &locking_session);
if (ret) {
SPDK_ERRLOG("lock unlock range error %d: %s\n", ret, opal_error_to_human(ret));
goto end;
}
end:
ret += opal_end_session(dev);
if (ret) {
SPDK_ERRLOG("end session error %d: %s\n", ret, opal_error_to_human(ret));
}
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
int
spdk_opal_cmd_setup_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user,
enum spdk_opal_locking_range locking_range_id, uint64_t range_start,
uint64_t range_length, const char *passwd)
{
struct opal_locking_range_setup_session setup_session;
struct spdk_opal_key opal_key;
int ret;
if (!dev || dev->supported == false) {
return -ENODEV;
}
ret = opal_init_key(&opal_key, passwd, locking_range_id);
if (ret != 0) {
return ret;
}
memset(&setup_session, 0, sizeof(struct opal_locking_range_setup_session));
setup_session.session.opal_key = &opal_key;
setup_session.session.who = user;
setup_session.id = locking_range_id;
setup_session.range_length = range_length;
setup_session.range_start = range_start;
setup_session.read_lock_enabled = true;
setup_session.write_lock_enabled = true;
pthread_mutex_lock(&dev->mutex_lock);
ret = opal_start_auth_session(dev, &setup_session.session);
if (ret) {
SPDK_ERRLOG("start authenticate session error %d: %s\n", ret, opal_error_to_human(ret));
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
ret = opal_setup_locking_range(dev, &setup_session);
if (ret) {
SPDK_ERRLOG("setup locking range error %d: %s\n", ret, opal_error_to_human(ret));
goto end;
}
end:
ret += opal_end_session(dev);
if (ret) {
SPDK_ERRLOG("end session error %d: %s\n", ret, opal_error_to_human(ret));
}
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
struct spdk_opal_info * struct spdk_opal_info *
spdk_opal_get_info(struct spdk_opal_dev *dev) spdk_opal_get_info(struct spdk_opal_dev *dev)
{ {

View File

@ -52,6 +52,8 @@
#define SPDK_DTAERROR_NO_METHOD_STATUS 0x89 #define SPDK_DTAERROR_NO_METHOD_STATUS 0x89
typedef int (spdk_opal_cb)(struct spdk_opal_dev *dev, void *data);
enum opal_token_type { enum opal_token_type {
OPAL_DTA_TOKENID_BYTESTRING = 0xE0, OPAL_DTA_TOKENID_BYTESTRING = 0xE0,
OPAL_DTA_TOKENID_SINT = 0xE1, OPAL_DTA_TOKENID_SINT = 0xE1,
@ -264,8 +266,8 @@ struct opal_locking_range_setup_session {
uint8_t _padding[7]; uint8_t _padding[7];
uint64_t range_start; uint64_t range_start;
uint64_t range_length; uint64_t range_length;
bool RLE; /* Read Lock enabled */ bool read_lock_enabled;
bool WLE; /* Write Lock Enabled */ bool write_lock_enabled;
struct opal_common_session session; struct opal_common_session session;
}; };