Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sed: improved contextual error messages #2740

Merged
merged 1 commit into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 */