Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174391083
D59535.id187925.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D59535.id187925.diff
View Options
diff --git a/sbin/camcontrol/Makefile b/sbin/camcontrol/Makefile
--- a/sbin/camcontrol/Makefile
+++ b/sbin/camcontrol/Makefile
@@ -18,7 +18,7 @@
SRCS+= identify_ext.c
SRCS+= nc_util.c
.PATH: ${SRCTOP}/sys/dev/nvme
-SRCS+= nvme_util.c nvres.c
+SRCS+= nvme_util.c nvres.c nvformat.c
# This is verboten
.if ${MACHINE_CPUARCH} == "arm"
WARNS?= 3
diff --git a/sbin/camcontrol/camcontrol.h b/sbin/camcontrol/camcontrol.h
--- a/sbin/camcontrol/camcontrol.h
+++ b/sbin/camcontrol/camcontrol.h
@@ -80,6 +80,9 @@
int nvmepersist(struct cam_device *device, int argc, char **argv,
char *combinedopt, int retry_count, int timeout,
int verbosemode, int err_recover);
+int nvmeformat(struct cam_device *device, int argc, char **argv,
+ char *combinedopt, int retry_count, int timeout,
+ int verbosemode, int err_recover);
int camxferrate(struct cam_device *device);
int fwdownload(struct cam_device *device, int argc, char **argv,
char *combinedopt, int printerrors, int task_attr,
diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8
--- a/sbin/camcontrol/camcontrol.8
+++ b/sbin/camcontrol/camcontrol.8
@@ -369,6 +369,16 @@
.Op generic args
.Ao Fl r Oo Ns Fl f Ar format | Fl m | Fl U Oc | Fl s Ao Fl f Ar format Fl T Ar time | Fl U Ac Ac
.Nm
+.Ic nvformat
+.Op device id
+.Op generic args
+.Op Fl e Ar ses
+.Op Fl G
+.Op Fl f Ar lbaf
+.Op Fl l Ar pil
+.Op Fl m Ar mset
+.Op Fl p Ar pi
+.Nm
.Ic devtype
.Op device id
.Nm
@@ -1230,6 +1240,12 @@
Issue the
.Tn SCSI
FORMAT UNIT command to the named device.
+This only works on
+.Tn SCSI
+devices.
+See the nvformat subcommand to format
+.Tn NVMe
+devices.
.Pp
.Em WARNING! WARNING! WARNING!
.Pp
@@ -2696,6 +2712,65 @@
Set the timestamp to the host system's time in UTC.
.El
.El
+.It Ic nvformat
+Format an NVMe device.
+Most devices format very quickly, but for drives that take longer, you can
+see format progress in the NVMe namespace identify if the drive supports
+it.
+.Bl -tag -width 8n
+.It Fl e Ar ses
+Specify the NVMe Secure Erase Setting.
+.Bl -tag -width 8n
+.It none
+This is the default.
+It indicates that no specific erase option is requested.
+.It user
+This requests that all user data be erased.
+The controller can use any method to erase the user data.
+.It crypto
+This requests that the controller erase the data cryptographically by
+deleting the encryption key.
+.It num
+Specify a numeric (decimal or hexadecimal) value
+.El
+.It Fl G
+Some NVMe controllers only allow formatting all namespaces attached to the
+controller.
+By default,
+.Nm
+will format the NVMe namespace addressed by the command.
+If you get an error message saying that the controller doesn't support
+per-NS format, you can try this option.
+.It Fl f Ar lbaf
+Use the specified LBA format number.
+You can use this option to change the sector size of the drive.
+To see a list of allowed LBA formats (combination of sector size and
+metadata size), and the current LBA format, look at
+the NVMe Namespace Identify data.
+You can see it with:
+.Pp
+.Dl camcontrol identify ndaX -N
+.It Fl l Ar pil
+Specify the protection information location.
+If set to 1, and protection information is enabled (see the
+.Fl p
+option), protection information is transferred as the first 8 bytes of
+metadata.
+If set to 0 (the default) and protection information is enabled, protection
+information is transferred as the last 8 bytes of metadata.
+.It Fl m Ar mset
+If set to 1, metadata is transferred as part of an extended LBA.
+If set to 0 (the default), metadata is transferred as part of a separate
+buffer.
+.It Fl p Ar pi
+This specifies whether protection information is enabled, and if so, the
+type of protection information.
+The default is 0, no protection information enabled.
+You may specify Type 1, 2 or 3 protection with a numeric argument of 1, 2
+or 3 respectively.
+Other types are allowed up to 7, but the only values currently defined in
+the NVMe 1.4 specification are 0-3.
+.El
.It Ic devtype
Print out the device type for specified device.
.Bl -tag -width 10n
diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c
--- a/sbin/camcontrol/camcontrol.c
+++ b/sbin/camcontrol/camcontrol.c
@@ -112,7 +112,8 @@
CAM_CMD_DEVTYPE,
CAM_CMD_AMA,
CAM_CMD_DEPOP,
- CAM_CMD_REQSENSE
+ CAM_CMD_REQSENSE,
+ CAM_CMD_NVFORMAT
} cam_cmd;
typedef enum {
@@ -234,6 +235,7 @@
{"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
{"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
{"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
+ {"nvformat", CAM_CMD_NVFORMAT, CAM_ARG_NONE, "e:Gf:l:m:p:"},
{"depop", CAM_CMD_DEPOP, CAM_ARG_NONE, "ac:de:ls"},
{"sense", CAM_CMD_REQSENSE, CAM_ARG_NONE, "Dx"},
{"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
@@ -10158,6 +10160,8 @@
" [-S power_src] [-T timer]\n"
" camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
" <-s <-f format -T time | -U >>\n"
+" camcontrol nvformat [dev_id][generic args][-e <user|crypto|num>]\n"
+" [-G][-f format][-l pil][-m mset][-p pi]\n"
" camcontrol devtype [dev_id]\n"
" camcontrol depop [dev_id] [-d | -l | -r] [-e element] [-c capacity]\n"
" camcontrol mmcsdcmd [dev_id] [[-c mmc_opcode] [-a mmc_arg]\n"
@@ -10213,6 +10217,7 @@
"zone manage Zoned Block (Shingled) devices\n"
"epc send ATA Extended Power Conditions commands\n"
"timestamp report or set the device's timestamp\n"
+"nvformat send NVMe format command\n"
"devtype report the type of device\n"
"depop manage drive storage elements\n"
"mmcsdcmd send the given MMC command, needs -c and -a as well\n"
@@ -10429,6 +10434,13 @@
"-f format the format of the time string passed into strptime(3)\n"
"-T time the time value passed into strptime(3)\n"
"-U set the timestamp of the device to UTC time\n"
+"nvformat arguments:\n"
+"-e ses secure erase setting: user, crypto\n"
+"-G global format, formats all Namespaces\n"
+"-f num specify format number, see Namespace Identify\n"
+"-l pil Protection Information Location, 1 = start, 0 = end\n"
+"-m mset metadata setting, 0 = separate buffer, 1 ext. LBA\n"
+"-p pi Protection Information type\n"
"depop arguments:\n"
"-d remove an element from service\n"
"-l list status of all elements of drive\n"
@@ -10877,6 +10889,12 @@
task_attr, retry_count, timeout,
arglist & CAM_ARG_VERBOSE);
break;
+ case CAM_CMD_NVFORMAT:
+ error = nvmeformat(cam_dev, argc, argv, combinedopt,
+ retry_count, timeout,
+ arglist & CAM_ARG_VERBOSE,
+ arglist & CAM_ARG_ERR_RECOVER);
+ break;
case CAM_CMD_DEPOP:
error = depop(cam_dev, argc, argv, combinedopt,
task_attr, retry_count, timeout,
diff --git a/sbin/camcontrol/nvformat.c b/sbin/camcontrol/nvformat.c
new file mode 100644
--- /dev/null
+++ b/sbin/camcontrol/nvformat.c
@@ -0,0 +1,278 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (C) 2018-2019 Alexander Motin <mav@FreeBSD.org>
+ * Copyright (C) 2021 Spectra Logic Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * NVMe format support for camcontrol(8).
+ */
+
+#include <sys/ioctl.h>
+#include <sys/stdint.h>
+#include <sys/types.h>
+#include <sys/endian.h>
+#include <sys/sbuf.h>
+#include <sys/queue.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <string.h>
+#include <strings.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <limits.h>
+#include <err.h>
+
+#include <cam/cam.h>
+#include <cam/cam_debug.h>
+#include <cam/cam_ccb.h>
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_pass.h>
+#include <dev/nvme/nvme.h>
+#include <camlib.h>
+#include "camcontrol.h"
+
+static struct scsi_nv nvme_ses_settings[] = {
+ { "none", NVME_FORMAT_SES_NONE },
+ { "user", NVME_FORMAT_SES_USER },
+ { "crypto", NVME_FORMAT_SES_CRYPTO },
+};
+
+int
+nvmeformat(struct cam_device *device, int argc, char **argv, char *combinedopt,
+ int retry_count, int timeout, int verbosemode, int err_recover)
+{
+ union ccb *ccb = NULL;
+ struct nvme_controller_data cdata;
+ struct nvme_namespace_data nsdata;
+ char *end;
+ int global_op = 0;
+ int lbaf = -1, mset = -1, pi = -1, pil = -1, ses = -1;
+ int error = 0;
+ int c;
+
+ ccb = cam_getccb(device);
+ if (ccb == NULL) {
+ warnx("%s: error allocating CCB", __func__);
+ error = 1;
+ goto bailout;
+ }
+
+ CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->nvmeio);
+
+ while ((c = getopt(argc, argv, combinedopt)) != -1) {
+ switch (c) {
+ case 'e': {
+ scsi_nv_status status;
+ int table_entry = 0;
+
+ status = scsi_get_nv(nvme_ses_settings,
+ sizeof(nvme_ses_settings) /
+ sizeof(nvme_ses_settings[0]), optarg,
+ &table_entry, SCSI_NV_FLAG_IG_CASE);
+ if (status == SCSI_NV_FOUND)
+ ses = nvme_ses_settings[table_entry].value;
+ else if (status == SCSI_NV_AMBIGUOUS) {
+ warnx("%s: ambiguous Secure Erase Setting %s",
+ __func__, optarg);
+ error = 1;
+ goto bailout;
+ } else {
+ ses = strtol(optarg, &end, 0);
+ if ((*end != '\0')
+ || ((ses < 0) || (ses > 0x7))) {
+ warnx("%s: invalid Secure Erase "
+ "setting %s", __func__, optarg);
+ error = 1;
+ goto bailout;
+ }
+ }
+ break;
+ }
+ case 'G':
+ global_op = 1;
+ break;
+ case 'f':
+ lbaf = strtol(optarg, &end, 0);
+ if (*end != '\0') {
+ warnx("%s: invalid format argument %s",
+ __func__, optarg);
+ error = 1;
+ goto bailout;
+ }
+ break;
+ case 'l':
+ pil = strtol(optarg, &end, 0);
+ if ((*end != '\0') || ((pil < 0) || (pil > 1))) {
+ warnx("%s: invalid location argument %s",
+ __func__, optarg);
+ error = 1;
+ goto bailout;
+ }
+ break;
+ case 'm':
+ mset = strtol(optarg, &end, 0);
+ if ((*end != '\0') || ((mset < 0) || (mset > 1))) {
+ warnx("%s: invalid metadata setting %s",
+ __func__, optarg);
+ error = 1;
+ goto bailout;
+ }
+ break;
+ case 'p':
+ pi = strtol(optarg, &end, 0);
+ if ((*end != '\0') || ((pi < 0) || (pi > 0x7))) {
+ warnx("%s: invalid Protection Information "
+ "type %s", __func__, optarg);
+ error = 1;
+ goto bailout;
+ }
+ break;
+ }
+ }
+
+ bzero(&cdata, sizeof(cdata));
+ error = nvme_get_data(device, CDAI_TYPE_NVME_CNTRL, &cdata,
+ sizeof(cdata));
+ if (error != 0)
+ goto bailout;
+
+ if (((cdata.oacs >> NVME_CTRLR_DATA_OACS_FORMAT_SHIFT) &
+ NVME_CTRLR_DATA_OACS_FORMAT_MASK) == 0) {
+ warnx("%s: controller doesn't support format", __func__);
+ error = 1;
+ goto bailout;
+ }
+
+ if ((((cdata.fna >> NVME_CTRLR_DATA_FNA_CRYPTO_ERASE_SHIFT) &
+ NVME_CTRLR_DATA_FNA_CRYPTO_ERASE_MASK) == 0) && (ses == 2)){
+ warnx("%s: controller doesn't support crypto erase", __func__);
+ error = 1;
+ goto bailout;
+ }
+
+ if (global_op == 0) {
+
+ if ((cdata.fna >> NVME_CTRLR_DATA_FNA_FORMAT_ALL_SHIFT) &
+ NVME_CTRLR_DATA_FNA_FORMAT_ALL_MASK) {
+ warnx("%s: controller does not support per-NS format, "
+ "use -G", __func__);
+ error = 1;
+ goto bailout;
+ }
+ if ((cdata.fna >> NVME_CTRLR_DATA_FNA_ERASE_ALL_SHIFT) &
+ NVME_CTRLR_DATA_FNA_ERASE_ALL_MASK) {
+ warnx("%s: controller does not support per-NS erase, "
+ "use -G", __func__);
+ error = 1;
+ goto bailout;
+ }
+
+ bzero(&nsdata, sizeof(nsdata));
+ error = nvme_get_data(device, CDAI_TYPE_NVME_NS, &nsdata,
+ sizeof(nsdata));
+ if (error != 0)
+ goto bailout;
+
+ if (lbaf < 0)
+ lbaf = (nsdata.flbas >> NVME_NS_DATA_FLBAS_FORMAT_SHIFT)
+ & NVME_NS_DATA_FLBAS_FORMAT_MASK;
+
+ if (lbaf > nsdata.nlbaf) {
+ warnx("%s: LBA format %d is out of range", __func__,
+ lbaf);
+ error = 1;
+ goto bailout;
+ }
+ if (mset < 0) {
+ mset = (nsdata.flbas >>
+ NVME_NS_DATA_FLBAS_EXTENDED_SHIFT)
+ & NVME_NS_DATA_FLBAS_EXTENDED_MASK;
+ }
+ if (pi < 0) {
+ pi = (nsdata.dps >> NVME_NS_DATA_DPS_MD_START_SHIFT)
+ & NVME_NS_DATA_DPS_MD_START_MASK;
+ }
+ if (pil < 0) {
+ pil = (nsdata.dps >> NVME_NS_DATA_DPS_PIT_SHIFT) &
+ NVME_NS_DATA_DPS_PIT_MASK;
+ }
+ if (ses < 0)
+ ses = 0;
+ } else {
+ if (ses < 0)
+ ses = 0;
+ if (lbaf < 0)
+ lbaf = 0;
+ if (mset < 0)
+ mset = 0;
+ if (pi < 0)
+ pi = 0;
+ if (pil < 0)
+ pil = 0;
+ }
+
+ nvme_format(/*nvmeio*/ &ccb->nvmeio,
+ /*retries*/ retry_count,
+ /*cbfcnp*/ NULL,
+ /*nsid*/ global_op ? NVME_GLOBAL_NAMESPACE_TAG :
+ device->target_lun,
+ /*ses*/ ses,
+ /*pil*/ pil,
+ /*pi*/ pi,
+ /*mset*/ mset,
+ /*lbaf*/ lbaf,
+ /*
+ * A cryptographic erase just changes the media
+ * encryption key, so it should be quick. A user data
+ * erase or a plain format can take a long time.
+ */
+ /*timeout*/ timeout ? timeout :
+ (ses == NVME_FORMAT_SES_CRYPTO ?
+ (30 * 1000) : (30 * 60 * 1000)));
+
+ if (err_recover != 0)
+ ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
+
+ if (cam_send_ccb(device, ccb) < 0) {
+ warn("error sending NVMe Format command");
+ error = 1;
+ goto bailout;
+ }
+
+ if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+ if (verbosemode != 0) {
+ cam_error_print(device, ccb, CAM_ESF_ALL,
+ CAM_EPF_ALL, stderr);
+ }
+ error = 1;
+ goto bailout;
+ }
+
+bailout:
+ return (error);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 3, 9:09 PM (21 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40153548
Default Alt Text
D59535.id187925.diff (14 KB)
Attached To
Mode
D59535: camcontrol: Support NVMe namespace formatting via the format subcommand
Attached
Detach File
Event Timeline
Log In to Comment