Commit 755b4390 authored by Chunyang Hui's avatar Chunyang Hui Committed by Changpeng Liu
Browse files

Opal: Add activate locking SP method



Change-Id: I4189bdefdb5a6651bb73bd32e61c16e899b2ae5a
Signed-off-by: default avatarChunyang Hui <chunyang.hui@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/454211


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent bcfb2b2b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ Added spdk_nvme_ctrlr_get_transport_id() to get the transport ID from a
previously attached controller.

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
from "Manufactured-Inactive" state to "Manufactured" state. Upon successfully invoking
of this method, lock and unlock features will be enabled.

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).
+11 −5
Original line number Diff line number Diff line
@@ -938,7 +938,7 @@ opal_usage(void)
	printf("Opal General Usage:\n");
	printf("\n");
	printf("\t[1: scan device]\n");
	printf("\t[2: take ownership]\n");
	printf("\t[2: init - take ownership and activate locking]\n");
	printf("\t[3: revert tper]\n");
	printf("\t[0: quit]\n");
}
@@ -968,7 +968,7 @@ opal_scan(struct dev *iter)
}

static void
opal_take_ownership(struct dev *iter)
opal_init(struct dev *iter)
{
	char new_passwd[MAX_PASSWORD_SIZE] = {0};
	char *passwd_p;
@@ -991,9 +991,15 @@ opal_take_ownership(struct dev *iter)
					spdk_opal_close(iter->opal_dev);
					return;
				}
				printf("...\n...\nTake Ownership Success\n");

				ret = spdk_opal_cmd_activate_locking_sp(iter->opal_dev, passwd_p);
				if (ret) {
					printf("Locking SP activate failure: %d\n", ret);
					return;
				}
				printf("...\n...\nOpal Init Success\n");
			} else {
				printf("Input password invalid. Take ownership failure\n");
				printf("Input password invalid. Opal Init failure\n");
			}
		}
		spdk_opal_close(iter->opal_dev);
@@ -1070,7 +1076,7 @@ test_opal(void)
			opal_scan(ctrlr);
			break;
		case 2:
			opal_take_ownership(ctrlr);
			opal_init(ctrlr);   /* Take ownership, Activate Locking SP */
			break;
		case 3:
			opal_revert_tper(ctrlr);
+1 −0
Original line number Diff line number Diff line
@@ -164,5 +164,6 @@ bool spdk_opal_supported(struct spdk_opal_dev *dev);
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_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);

#endif
+125 −0
Original line number Diff line number Diff line
@@ -1113,6 +1113,86 @@ opal_generic_pw_cmd(uint8_t *key, size_t key_len, uint8_t *cpin_uid,
	return err;
}

static int
opal_get_locking_sp_lifecycle_cb(struct spdk_opal_dev *dev)
{
	uint8_t lifecycle;
	int error = 0;

	error = opal_parse_and_check_status(dev);
	if (error) {
		return error;
	}

	lifecycle = opal_response_get_u64(&dev->parsed_resp, 4);
	if (lifecycle != OPAL_MANUFACTURED_INACTIVE) { /* status before activate */
		SPDK_ERRLOG("Couldn't determine the status of the Lifecycle state\n");
		return -EINVAL;
	}

	return 0;
}

static int
opal_get_locking_sp_lifecycle(struct spdk_opal_dev *dev)
{
	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_LOCKINGSP],
				  OPAL_UID_LENGTH);
	opal_add_token_bytestring(&err, dev, spdk_opal_method[GET_METHOD], OPAL_UID_LENGTH);

	opal_add_tokens(&err, dev, 12, SPDK_OPAL_STARTLIST,
			SPDK_OPAL_STARTLIST,
			SPDK_OPAL_STARTNAME,
			SPDK_OPAL_STARTCOLUMN,
			SPDK_OPAL_LIFECYCLE,
			SPDK_OPAL_ENDNAME,
			SPDK_OPAL_STARTNAME,
			SPDK_OPAL_ENDCOLUMN,
			SPDK_OPAL_LIFECYCLE,
			SPDK_OPAL_ENDNAME,
			SPDK_OPAL_ENDLIST,
			SPDK_OPAL_ENDLIST);

	if (err) {
		SPDK_ERRLOG("Error Building GET Lifecycle Status command\n");
		return err;
	}

	return opal_finalize_and_send(dev, 1, opal_get_locking_sp_lifecycle_cb);
}

static int
opal_activate(struct spdk_opal_dev *dev)
{
	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_LOCKINGSP],
				  OPAL_UID_LENGTH);
	opal_add_token_bytestring(&err, dev, spdk_opal_method[ACTIVATE_METHOD],
				  OPAL_UID_LENGTH);

	opal_add_tokens(&err, dev, 2, SPDK_OPAL_STARTLIST, SPDK_OPAL_ENDLIST);

	if (err) {
		SPDK_ERRLOG("Error building Activate LockingSP command.\n");
		return err;
	}

	/* TODO: Single User Mode for activatation */

	return opal_finalize_and_send(dev, 1, opal_parse_and_check_status);
}

static int
opal_set_sid_cpin_pin(struct spdk_opal_dev *dev, void *data)
{
@@ -1311,6 +1391,51 @@ end:
	return ret;
}

int
spdk_opal_cmd_activate_locking_sp(struct spdk_opal_dev *dev, const char *passwd)
{
	struct spdk_opal_key opal_key;
	int ret;

	ret = opal_init_key(&opal_key, passwd, OPAL_LOCKING_RANGE_GLOBAL);
	if (ret != 0) {
		return ret;
	}

	pthread_mutex_lock(&dev->mutex_lock);
	ret = opal_start_adminsp_session(dev, &opal_key);
	if (ret) {
		SPDK_ERRLOG("Error on starting admin SP session with error %d: %s\n", ret,
			    opal_error_to_human(ret));
		pthread_mutex_unlock(&dev->mutex_lock);
		return ret;
	}

	ret = opal_get_locking_sp_lifecycle(dev);
	if (ret) {
		SPDK_ERRLOG("Error on getting SP lifecycle with error %d: %s\n", ret,
			    opal_error_to_human(ret));
		goto end;
	}

	ret = opal_activate(dev);
	if (ret) {
		SPDK_ERRLOG("Error on activation with error %d: %s\n", ret,
			    opal_error_to_human(ret));
		goto end;
	}

end:
	ret += opal_end_session(dev);
	if (ret) {
		SPDK_ERRLOG("Error on ending session with error %d: %s\n", ret,
			    opal_error_to_human(ret));
	}

	pthread_mutex_unlock(&dev->mutex_lock);
	return ret;
}

struct spdk_opal_info *
spdk_opal_get_info(struct spdk_opal_dev *dev)
{
+0 −7
Original line number Diff line number Diff line
@@ -259,13 +259,6 @@ struct spdk_opal_key {
	uint8_t key[OPAL_KEY_MAX];
};

struct opal_locking_range_activate_session {
	struct spdk_opal_key key;
	uint32_t sum;		/* single user mode */
	uint8_t lockingrange_num;
	uint8_t lockingrange[OPAL_MAX_LRS];
};

struct opal_locking_range_setup_session {
	uint8_t id;
	uint8_t _padding[7];