Skip to content

Commit

Permalink
sed: improved contextual error messages
Browse files Browse the repository at this point in the history
Improve quality of error messages but including context and
locking state.

Signed-off-by: Greg Joyce <gjoyce@linux.ibm.com>
  • Loading branch information
gjoyce-ibm committed Mar 10, 2025
1 parent 21516ec commit 350cfc3
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 22 deletions.
8 changes: 4 additions & 4 deletions plugins/sed/sed.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ static int sed_opal_initialize(int argc, char **argv, struct command *cmd,
return err;

err = sedopal_cmd_initialize(dev->direct.fd);
if (err != 0)
if ((err != 0) && (err != -EOPNOTSUPP))
fprintf(stderr, "initialize: SED error - %s\n",
sedopal_error_to_text(err));

Expand All @@ -130,7 +130,7 @@ static int sed_opal_revert(int argc, char **argv, struct command *cmd,
return err;

err = sedopal_cmd_revert(dev->direct.fd);
if (err != 0)
if ((err != 0) && (err != -EOPNOTSUPP))
fprintf(stderr, "revert: SED error - %s\n",
sedopal_error_to_text(err));

Expand All @@ -150,7 +150,7 @@ static int sed_opal_lock(int argc, char **argv, struct command *cmd,
return err;

err = sedopal_cmd_lock(dev->direct.fd);
if (err != 0)
if ((err != 0) && (err != -EOPNOTSUPP))
fprintf(stderr, "lock: SED error - %s\n",
sedopal_error_to_text(err));

Expand All @@ -170,7 +170,7 @@ static int sed_opal_unlock(int argc, char **argv, struct command *cmd,
return err;

err = sedopal_cmd_unlock(dev->direct.fd);
if (err != 0)
if ((err != 0) && (err != -EOPNOTSUPP))
fprintf(stderr, "unlock: SED error - %s\n",
sedopal_error_to_text(err));

Expand Down
122 changes: 104 additions & 18 deletions plugins/sed/sedopal_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ bool sedopal_discovery_verbose;
*/
bool sedopal_discovery_udev;

/*
* level 0 discovery buffer
*/
char level0_discovery_buf[4096];

struct sedopal_feature_parser {
uint32_t features;
void *tper_desc;
Expand Down Expand Up @@ -205,6 +210,15 @@ int sedopal_cmd_initialize(int fd)
struct opal_lr_act lr_act = {};
struct opal_user_lr_setup lr_setup = {};
struct opal_new_pw new_pw = {};
uint8_t locking_state;

locking_state = sedopal_locking_state(fd);

if (locking_state & OPAL_FEATURE_LOCKING_ENABLED) {
fprintf(stderr,
"Error: cannot initialize an initialized drive\n");
return -EOPNOTSUPP;
}

sedopal_ask_key = true;
sedopal_ask_new_key = true;
Expand Down Expand Up @@ -319,6 +333,15 @@ int sedopal_lock_unlock(int fd, int lock_state)
{
int rc;
struct opal_lock_unlock opal_lu = {};
uint8_t locking_state;

locking_state = sedopal_locking_state(fd);

if (!(locking_state & OPAL_FEATURE_LOCKING_ENABLED)) {
fprintf(stderr,
"Error: cannot lock/unlock an uninitialized drive\n");
return -EOPNOTSUPP;
}

rc = sedopal_set_key(&opal_lu.session.opal_key);
if (rc != 0)
Expand Down Expand Up @@ -433,6 +456,21 @@ int sedopal_cmd_revert(int fd)
} else {
#ifdef IOC_OPAL_REVERT_LSP
struct opal_revert_lsp revert_lsp;
uint8_t locking_state;

locking_state = sedopal_locking_state(fd);

if (!(locking_state & OPAL_FEATURE_LOCKING_ENABLED)) {
fprintf(stderr,
"Error: can't revert an uninitialized drive\n");
return -EOPNOTSUPP;
}

if (locking_state & OPAL_FEATURE_LOCKED) {
fprintf(stderr,
"Error: cannot revert drive while locked\n");
return -EOPNOTSUPP;
}

rc = sedopal_set_key(&revert_lsp.key);
if (rc != 0)
Expand Down Expand Up @@ -958,22 +996,18 @@ void sedopal_print_features(struct sedopal_feature_parser *sfp)
}

/*
* Query a drive to determine if it's SED Opal capable and
* it's current locking status.
* Query a drive to retrieve it's level 0 features.
*/
int sedopal_cmd_discover(int fd)
int sedopal_discover_device(int fd, struct level_0_discovery_features **feat,
struct level_0_discovery_features **feat_end)
{
#ifdef IOC_OPAL_DISCOVERY
int rc, feat_length;
int rc;
struct opal_discovery discover;
struct level_0_discovery_header *dh;
struct level_0_discovery_features *feat;
struct level_0_discovery_features *feat_end;
char buf[4096];
struct sedopal_feature_parser sfp = {};

discover.data = (uintptr_t)buf;
discover.size = sizeof(buf);
discover.data = (uintptr_t)level0_discovery_buf;
discover.size = sizeof(level0_discovery_buf);

rc = ioctl(fd, IOC_OPAL_DISCOVERY, &discover);
if (rc < 0) {
Expand All @@ -987,10 +1021,33 @@ int sedopal_cmd_discover(int fd)
*
* TCG Opal Specification v2.0.2 section 3.1.1
*/
dh = (struct level_0_discovery_header *)buf;
feat = (struct level_0_discovery_features *)(dh + 1);
feat_end = (struct level_0_discovery_features *)
(buf + be32toh(dh->parameter_length));
dh = (struct level_0_discovery_header *)level0_discovery_buf;
*feat = (struct level_0_discovery_features *)(dh + 1);
*feat_end = (struct level_0_discovery_features *)
(level0_discovery_buf + be32toh(dh->parameter_length));

return 0
;
#else /* IOC_OPAL_DISCOVERY */
fprintf(stderr, "ERROR : NVMe device discovery is not supported\n");
return -EOPNOTSUPP;
#endif
}

/*
* Query a drive to determine if it's SED Opal capable and
* it's current locking status.
*/
int sedopal_cmd_discover(int fd)
{
int rc, feat_length;
struct level_0_discovery_features *feat;
struct level_0_discovery_features *feat_end;
struct sedopal_feature_parser sfp = {};

rc = sedopal_discover_device(fd, &feat, &feat_end);
if (rc != 0)
return rc;

/*
* iterate through all the features that were returned
Expand All @@ -1016,8 +1073,37 @@ int sedopal_cmd_discover(int fd)


return rc;
#else /* IOC_OPAL_DISCOVERY */
fprintf(stderr, "ERROR : NVMe device discovery is not supported\n");
return -EOPNOTSUPP;
#endif
}

/*
* Query a drive to determine its locking state
*/
int sedopal_locking_state(int fd)
{
int rc, feat_length;
struct level_0_discovery_features *feat;
struct level_0_discovery_features *feat_end;

rc = sedopal_discover_device(fd, &feat, &feat_end);
if (rc != 0)
return rc;

/*
* iterate through all the features that were returned
*/
while (feat < feat_end) {
uint16_t code = be16toh(feat->code);

if (code == OPAL_FEATURE_CODE_LOCKING) {
struct locking_desc *ld = (struct locking_desc *) (feat + 1);

return ld->features;
}

feat_length = feat->length + 4 /* hdr */;
feat = (struct level_0_discovery_features *)
((char *)feat + feat_length);
}

return 0;
}
1 change: 1 addition & 0 deletions plugins/sed/sedopal_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@ int sedopal_cmd_discover(int fd);
int sedopal_open_nvme_device(char *device);
int sedopal_lock_unlock(int fd, int lock_state);
const char *sedopal_error_to_text(int code);
int sedopal_locking_state(int fd);

#endif /* _SED_OPAL_CMD_H */

0 comments on commit 350cfc3

Please sign in to comment.