Skip to content

Commit

Permalink
nvme: Use nvme cli internal names for capabilities
Browse files Browse the repository at this point in the history
These dynamic/generated names don't really work as can probably be
noticed by adding the `fna` and `sanicap` synthetic capabilities. They
don't work because nvme gives different output for enabled/disable,
supported/unsupported, all/single capabilities. So we end up with
enabled/disabled is detected by presence vs absence and we have to look
up two "different" capabilities to determine the status of an _actual_
capability.

So instead of doing that dynamic name we just use the internal nvme
identifiers seen in `nvme-print-stdout.c` at this point in time. We will
not change them later if nvme changes them internally. This way we end
up being more likely to be future proof. It would be much easier for
nvme-cli to tweak the string returned in the human readable output than
it would be for the linux kernel to change meaning of bits returned in
the ioctl call.
  • Loading branch information
mmlb committed Apr 16, 2024
1 parent 20297be commit 744f2ea
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 193 deletions.
18 changes: 8 additions & 10 deletions fixtures/dell/r6515.go
Original file line number Diff line number Diff line change
Expand Up @@ -1782,18 +1782,16 @@ var (
}

nvmeDriveCapabilities = []*common.Capability{
{Name: "ammasocsind", Description: "Additional media modification after sanitize operation completes successfully is not defined"},
{Name: "nasbiscs", Description: "No-Deallocate After Sanitize bit in Sanitize command Supported"},
{Name: "osons", Description: "Overwrite Sanitize Operation Not Supported"},
{Name: "besons", Description: "Block Erase Sanitize Operation Not Supported"},
{Name: "cesons", Description: "Crypto Erase Sanitize Operation Not Supported"},
{Name: "cesapose", Description: "Crypto Erase Supported as part of Secure Erase", Enabled: true},
{Name: "ceatsn", Description: "Crypto Erase Applies to Single Namespace(s)"},
{Name: "fatsn", Description: "Format Applies to Single Namespace(s)"},
{Name: "fmns", Description: "Format Applies to All/Single Namespace(s) (t:All, f:Single)"},
{Name: "cens", Description: "Crypto Erase Applies to All/Single Namespace(s) (t:All, f:Single)"},
{Name: "cese", Description: "Crypto Erase Supported as part of Secure Erase", Enabled: true},
{Name: "cer", Description: "Crypto Erase Sanitize Operation Supported"},
{Name: "ber", Description: "Block Erase Sanitize Operation Supported"},
{Name: "owr", Description: "Overwrite Sanitize Operation Supported"},
{Name: "ndi", Description: "No-Deallocate After Sanitize bit in Sanitize command Supported"},
}

//
// // r6515 inventory taken with lshw, merged with data from smartctl
// r6515 inventory taken with lshw, merged with data from smartctl
R6515_inventory_lshw_smartctl = &common.Device{
Common: common.Common{
Oem: false,
Expand Down
169 changes: 42 additions & 127 deletions utils/nvme.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,156 +162,71 @@ func (n *Nvme) DriveCapabilities(ctx context.Context, logicalName string) ([]*co
}

var capabilitiesFound []*common.Capability
capabilitiesFound = append(capabilitiesFound, parseSanicap(caps.SANICAP)...)
capabilitiesFound = append(capabilitiesFound, parseFna(caps.FNA)...)
capabilitiesFound = append(capabilitiesFound, parseSanicap(caps.SANICAP)...)

return capabilitiesFound, err
}

func parseFna(fna uint) []*common.Capability {
caps := make([]*common.Capability, 0, 4)

// nvme: cese
if (fna&0b100)>>2 == 0 {
caps = append(caps, &common.Capability{
Name: "censapose",
Description: "Crypto Erase Not Supported as part of Secure Erase",
Enabled: false,
})
} else {
caps = append(caps, &common.Capability{
Name: "cesapose",
return []*common.Capability{
{
Name: "fmns",
Description: "Format Applies to All/Single Namespace(s) (t:All, f:Single)",
Enabled: (fna&0b1)>>0 != 0,
},
{
Name: "cens",
Description: "Crypto Erase Applies to All/Single Namespace(s) (t:All, f:Single)",
Enabled: (fna&0b10)>>1 != 0,
},
{
Name: "cese",
Description: "Crypto Erase Supported as part of Secure Erase",
Enabled: true,
})
}

// nvme: cens
if (fna&0b10)>>1 == 0 {
caps = append(caps, &common.Capability{
Name: "ceatsn",
Description: "Crypto Erase Applies to Single Namespace(s)",
Enabled: false,
})
} else {
caps = append(caps, &common.Capability{
Name: "ceatan",
Description: "Crypto Erase Applies to All Namespace(s)",
Enabled: true,
})
}

// nvme: fmns
if (fna&0b1)>>0 == 0 {
caps = append(caps, &common.Capability{
Name: "fatsn",
Description: "Format Applies to Single Namespace(s)",
Enabled: false,
})
} else {
caps = append(caps, &common.Capability{
Name: "fatan",
Description: "Format Applies to All Namespace(s)",
Enabled: true,
})
Enabled: (fna&0b100)>>2 != 0,
},
}

return caps
}

func parseSanicap(sanicap uint) []*common.Capability {
caps := make([]*common.Capability, 0, 6)
caps := []*common.Capability{
{
Name: "cer",
Description: "Crypto Erase Sanitize Operation Supported",
Enabled: (sanicap&0b1)>>0 != 0,
},
{
Name: "ber",
Description: "Block Erase Sanitize Operation Supported",
Enabled: (sanicap&0b10)>>1 != 0,
},
{
Name: "owr",
Description: "Overwrite Sanitize Operation Supported",
Enabled: (sanicap&0b100)>>2 != 0,
},
{
Name: "ndi",
Description: "No-Deallocate After Sanitize bit in Sanitize command Supported",
Enabled: (sanicap&(0b1<<29))>>29 != 0,
},
}

// nvme: nodmmas
switch (sanicap & (0b11 << 30)) >> 30 {
case 0b00:
case 0b01, 0b10:
caps = append(caps, &common.Capability{
Name: "ammasocsind",
Description: "Additional media modification after sanitize operation completes successfully is not defined",
Enabled: false,
})
case 0b01:
caps = append(caps, &common.Capability{
Name: "minamasocs",
Description: "Media is not additionally modified after sanitize operation completes successfully",
Enabled: true,
})
case 0b10:
caps = append(caps, &common.Capability{
Name: "miamasocs",
Name: "nodmmas",
Description: "Media is additionally modified after sanitize operation completes successfully",
Enabled: true,
Enabled: (sanicap&(0b11<<30))>>30 == 0b10,
})
case 0b11:
caps = append(caps, &common.Capability{
Name: "",
Description: "Reserved",
Enabled: true,
})
panic("Reserved value set, not sure what to do")
default:
panic("unreachable")
}

// nvme: ndi
if (sanicap&(0b1<<29))>>29 == 0 {
caps = append(caps, &common.Capability{
Name: "nasbiscs",
Description: "No-Deallocate After Sanitize bit in Sanitize command Supported",
Enabled: false,
})
} else {
caps = append(caps, &common.Capability{
Name: "nasbiscns",
Description: "No-Deallocate After Sanitize bit in Sanitize command Not Supported",
Enabled: true,
})
}

// nvme: owr
if (sanicap&0b100)>>2 == 0 {
caps = append(caps, &common.Capability{
Name: "osons",
Description: "Overwrite Sanitize Operation Not Supported",
Enabled: false,
})
} else {
caps = append(caps, &common.Capability{
Name: "osos",
Description: "Overwrite Sanitize Operation Supported",
Enabled: true,
})
}

// nvme: ber
if (sanicap&0b10)>>1 == 0 {
caps = append(caps, &common.Capability{
Name: "besons",
Description: "Block Erase Sanitize Operation Not Supported",
Enabled: false,
})
} else {
caps = append(caps, &common.Capability{
Name: "besos",
Description: "Block Erase Sanitize Operation Supported",
Enabled: true,
})
}

// nvme: cer
if (sanicap&0b1)>>0 == 0 {
caps = append(caps, &common.Capability{
Name: "cesons",
Description: "Crypto Erase Sanitize Operation Not Supported",
Enabled: false,
})
} else {
caps = append(caps, &common.Capability{
Name: "cesos",
Description: "Crypto Erase Sanitize Operation Supported",
Enabled: true,
})
}

return caps
}

Expand Down
77 changes: 21 additions & 56 deletions utils/nvme_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,25 @@ func Test_NvmeComponents(t *testing.T) {
{Common: common.Common{
Serial: "Z9DF70I8FY3L", Vendor: "TOSHIBA", Model: "KXG60ZNV256G TOSHIBA", Description: "KXG60ZNV256G TOSHIBA", Firmware: &common.Firmware{Installed: "AGGA4104"}, ProductName: "NULL",
Metadata: map[string]string{
"Additional media modification after sanitize operation completes successfully is not defined": "false",
"Block Erase Sanitize Operation Not Supported": "false",
"Crypto Erase Applies to Single Namespace(s)": "false",
"Crypto Erase Sanitize Operation Not Supported": "false",
"Crypto Erase Supported as part of Secure Erase": "true",
"Format Applies to Single Namespace(s)": "false",
"No-Deallocate After Sanitize bit in Sanitize command Supported": "false",
"Overwrite Sanitize Operation Not Supported": "false",
"No-Deallocate After Sanitize bit in Sanitize command Supported": "false",
"Format Applies to All/Single Namespace(s) (t:All, f:Single)": "false",
"Block Erase Sanitize Operation Supported": "false",
"Crypto Erase Applies to All/Single Namespace(s) (t:All, f:Single)": "false",
"Crypto Erase Sanitize Operation Supported": "false",
"Crypto Erase Supported as part of Secure Erase": "true",
"Overwrite Sanitize Operation Supported": "false",
},
}},
{Common: common.Common{
Serial: "Z9DF70I9FY3L", Vendor: "TOSHIBA", Model: "KXG60ZNV256G TOSHIBA", Description: "KXG60ZNV256G TOSHIBA", Firmware: &common.Firmware{Installed: "AGGA4104"}, ProductName: "NULL",
Metadata: map[string]string{
"Additional media modification after sanitize operation completes successfully is not defined": "false",
"Block Erase Sanitize Operation Not Supported": "false",
"Crypto Erase Applies to Single Namespace(s)": "false",
"Crypto Erase Sanitize Operation Not Supported": "false",
"Crypto Erase Supported as part of Secure Erase": "true",
"Format Applies to Single Namespace(s)": "false",
"No-Deallocate After Sanitize bit in Sanitize command Supported": "false",
"Overwrite Sanitize Operation Not Supported": "false",
"No-Deallocate After Sanitize bit in Sanitize command Supported": "false",
"Block Erase Sanitize Operation Supported": "false",
"Crypto Erase Applies to All/Single Namespace(s) (t:All, f:Single)": "false",
"Crypto Erase Sanitize Operation Supported": "false",
"Crypto Erase Supported as part of Secure Erase": "true",
"Format Applies to All/Single Namespace(s) (t:All, f:Single)": "false",
"Overwrite Sanitize Operation Supported": "false",
},
}},
}
Expand Down Expand Up @@ -62,44 +60,11 @@ func Test_NvmeDriveCapabilities(t *testing.T) {
}

var fixtureNvmeDeviceCapabilities = []*common.Capability{
{
Name: "ammasocsind",
Description: "Additional media modification after sanitize operation completes successfully is not defined",
Enabled: false,
},
{
Name: "nasbiscs",
Description: "No-Deallocate After Sanitize bit in Sanitize command Supported",
Enabled: false,
},
{
Name: "osons",
Description: "Overwrite Sanitize Operation Not Supported",
Enabled: false,
},
{
Name: "besons",
Description: "Block Erase Sanitize Operation Not Supported",
Enabled: false,
},
{
Name: "cesons",
Description: "Crypto Erase Sanitize Operation Not Supported",
Enabled: false,
},
{
Name: "cesapose",
Description: "Crypto Erase Supported as part of Secure Erase",
Enabled: true,
},
{
Name: "ceatsn",
Description: "Crypto Erase Applies to Single Namespace(s)",
Enabled: false,
},
{
Name: "fatsn",
Description: "Format Applies to Single Namespace(s)",
Enabled: false,
},
{Name: "fmns", Description: "Format Applies to All/Single Namespace(s) (t:All, f:Single)", Enabled: false},
{Name: "cens", Description: "Crypto Erase Applies to All/Single Namespace(s) (t:All, f:Single)", Enabled: false},
{Name: "cese", Description: "Crypto Erase Supported as part of Secure Erase", Enabled: true},
{Name: "cer", Description: "Crypto Erase Sanitize Operation Supported", Enabled: false},
{Name: "ber", Description: "Block Erase Sanitize Operation Supported", Enabled: false},
{Name: "owr", Description: "Overwrite Sanitize Operation Supported", Enabled: false},
{Name: "ndi", Description: "No-Deallocate After Sanitize bit in Sanitize command Supported", Enabled: false},
}

0 comments on commit 744f2ea

Please sign in to comment.