Opal: Add revert tper cmd option

Reset the device to its factory defaults.

Change-Id: I43f7dc8fb7bd5226283a4762beac0e2cf016f698
Signed-off-by: Chunyang Hui <chunyang.hui@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/445253
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Chunyang Hui 2019-02-19 23:22:56 +08:00 committed by Jim Harris
parent 84c550f3cb
commit 6b48e743a3
3 changed files with 115 additions and 6 deletions

View File

@ -100,7 +100,8 @@ is specified, use that specified nbd device. If it's not specified, pick availab
### Opal ### Opal
Add Opal scan support for NVMe to check whether it supports SED Opal and dump Add Opal scan support for NVMe to check whether it supports SED Opal and dump
device info. Add Opal take ownership command support. nvme_manage tool can be used to invoke this. device info. Add Opal take ownership command support, revert TPer command support.
nvme_manage tool can be used to invoke this.
This module should be considered experimental pending additional features and tests. This module should be considered experimental pending additional features and tests.
### iSCSI target ### iSCSI target

View File

@ -939,6 +939,7 @@ opal_usage(void)
printf("\n"); printf("\n");
printf("\t[1: scan device]\n"); printf("\t[1: scan device]\n");
printf("\t[2: take ownership]\n"); printf("\t[2: take ownership]\n");
printf("\t[3: revert tper]\n");
printf("\t[0: quit]\n"); printf("\t[0: quit]\n");
} }
@ -969,7 +970,7 @@ opal_scan(struct dev *iter)
static void static void
opal_take_ownership(struct dev *iter) opal_take_ownership(struct dev *iter)
{ {
char new_passwd[MAX_PASSWORD_SIZE]; char new_passwd[MAX_PASSWORD_SIZE] = {0};
char *passwd_p; char *passwd_p;
int ret; int ret;
int ch; int ch;
@ -980,7 +981,6 @@ opal_take_ownership(struct dev *iter)
return; return;
} }
if (spdk_opal_supported(iter->opal_dev)) { if (spdk_opal_supported(iter->opal_dev)) {
memset(new_passwd, 0, sizeof(new_passwd));
printf("Please input the new password for ownership:\n"); printf("Please input the new password for ownership:\n");
while ((ch = getchar()) != '\n' && ch != EOF); while ((ch = getchar()) != '\n' && ch != EOF);
passwd_p = get_line(new_passwd, MAX_PASSWORD_SIZE, stdin); passwd_p = get_line(new_passwd, MAX_PASSWORD_SIZE, stdin);
@ -997,9 +997,43 @@ opal_take_ownership(struct dev *iter)
} }
spdk_opal_close(iter->opal_dev); spdk_opal_close(iter->opal_dev);
} else { } else {
printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\n", 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); iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func);
printf("%04x:%02x:%02x.%02x: Opal Not Supported\n\n\n", }
}
static void
opal_revert_tper(struct dev *iter)
{
char passwd[MAX_PASSWORD_SIZE] = {0};
char *passwd_p;
int ret;
int ch;
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 be noted this operation will erase ALL DATA on this drive\n");
printf("Please input password for revert TPer:\n");
while ((ch = getchar()) != '\n' && ch != EOF);
passwd_p = get_line(passwd, MAX_PASSWORD_SIZE, stdin);
if (passwd_p) {
ret = spdk_opal_cmd(iter->opal_dev, OPAL_CMD_REVERT_TPER, passwd_p);
if (ret) {
printf("Revert TPer failure: %d\n", ret);
return;
}
printf("...\n...\nRevert TPer Success\n");
} else {
printf("Input password invalid. Revert TPer 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); iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func);
} }
} }
@ -1036,6 +1070,9 @@ test_opal(void)
case 2: case 2:
opal_take_ownership(ctrlr); opal_take_ownership(ctrlr);
break; break;
case 3:
opal_revert_tper(ctrlr);
break;
default: default:
printf("Invalid option\n"); printf("Invalid option\n");

View File

@ -1224,6 +1224,76 @@ spdk_opal_scan(struct spdk_opal_dev *dev)
return ret; return ret;
} }
static int
opal_revert_tper(struct spdk_opal_dev *dev, void *data)
{
int err = 0;
opal_clear_cmd(dev);
opal_set_comid(dev, dev->comid);
opal_add_token_u8(&err, dev, SPDK_OPAL_CALL);
opal_add_token_bytestring(&err, dev, spdk_opal_uid[UID_ADMINSP],
OPAL_UID_LENGTH);
opal_add_token_bytestring(&err, dev, spdk_opal_method[REVERT_METHOD],
OPAL_UID_LENGTH);
opal_add_token_u8(&err, dev, SPDK_OPAL_STARTLIST);
opal_add_token_u8(&err, dev, SPDK_OPAL_ENDLIST);
if (err) {
SPDK_ERRLOG("Error building REVERT TPER command.\n");
return err;
}
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status);
}
static int
spdk_opal_revert_tper(struct spdk_opal_dev *dev, const char *passwd)
{
int ret;
struct spdk_opal_key *opal_key;
opal_key = calloc(1, sizeof(struct spdk_opal_key));
if (!opal_key) {
SPDK_ERRLOG("Memory allocation failed for spdk_opal_key\n");
return -ENOMEM;
}
opal_key->key_len = strlen(passwd);
memcpy(opal_key->key, passwd, opal_key->key_len);
dev->dev_key = opal_key;
pthread_mutex_lock(&dev->mutex_lock);
opal_setup_dev(dev, NULL);
ret = opal_discovery0(dev, NULL);
if (ret) {
SPDK_ERRLOG("Error on discovery 0 with error %d: %s\n", ret,
opal_error_to_human(ret));
goto end;
}
ret = opal_start_adminsp_session(dev, opal_key);
if (ret) {
opal_end_session_error(dev);
SPDK_ERRLOG("Error on starting admin SP session with error %d: %s\n", ret,
opal_error_to_human(ret));
goto end;
}
ret = opal_revert_tper(dev, NULL);
if (ret) {
opal_end_session_error(dev);
SPDK_ERRLOG("Error on reverting TPer with error %d: %s\n", ret,
opal_error_to_human(ret));
goto end;
}
end:
pthread_mutex_unlock(&dev->mutex_lock);
free(opal_key);
dev->dev_key = NULL;
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)
{ {
@ -1253,9 +1323,10 @@ spdk_opal_cmd(struct spdk_opal_dev *dev, unsigned int cmd, void *arg)
return spdk_opal_scan(dev); return spdk_opal_scan(dev);
case OPAL_CMD_TAKE_OWNERSHIP: case OPAL_CMD_TAKE_OWNERSHIP:
return spdk_opal_take_ownership(dev, arg); return spdk_opal_take_ownership(dev, arg);
case OPAL_CMD_REVERT_TPER:
return spdk_opal_revert_tper(dev, arg);
case OPAL_CMD_LOCK_UNLOCK: case OPAL_CMD_LOCK_UNLOCK:
case OPAL_CMD_ACTIVATE_LSP: case OPAL_CMD_ACTIVATE_LSP:
case OPAL_CMD_REVERT_TPER:
case OPAL_CMD_SETUP_LOCKING_RANGE: case OPAL_CMD_SETUP_LOCKING_RANGE:
default: default: