svn commit: r299371 - in head: sbin/camcontrol sys/cam sys/cam/scsi

Edward Tomasz Napierala trasz at FreeBSD.org
Tue May 10 15:46:35 UTC 2016


Author: trasz
Date: Tue May 10 15:46:33 2016
New Revision: 299371
URL: https://svnweb.freebsd.org/changeset/base/299371

Log:
  Add "camcontrol reprobe" subcommand, and implement it for da(4).
  This makes it possible to manually force updating capacity data
  after the disk got resized. Without it it might be neccessary to
  reboot before FreeBSD notices updated disk size under eg VMWare.
  
  Discussed with:	imp@
  MFC after:	1 month
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D6108

Modified:
  head/sbin/camcontrol/camcontrol.8
  head/sbin/camcontrol/camcontrol.c
  head/sys/cam/cam_ccb.h
  head/sys/cam/cam_xpt.c
  head/sys/cam/scsi/scsi_da.c

Modified: head/sbin/camcontrol/camcontrol.8
==============================================================================
--- head/sbin/camcontrol/camcontrol.8	Tue May 10 15:45:59 2016	(r299370)
+++ head/sbin/camcontrol/camcontrol.8	Tue May 10 15:46:33 2016	(r299371)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 6, 2015
+.Dd April 26, 2016
 .Dt CAMCONTROL 8
 .Os
 .Sh NAME
@@ -98,6 +98,9 @@
 .Op device id
 .Op generic args
 .Nm
+.Ic reprobe
+.Op device id
+.Nm
 .Ic rescan
 .Aq all | bus Ns Op :target:lun
 .Nm
@@ -518,6 +521,12 @@ are not specified).
 Print out the last logical block or the size of the device only, and omit
 the blocksize.
 .El
+.Pp
+Note that this command only displays the information, it does not update
+the kernel data structures.
+Use the
+.Nm 
+reprobe subcommand to do that.
 .It Ic start
 Send the SCSI Start/Stop Unit (0x1B) command to the given device with the
 start bit set.
@@ -539,6 +548,12 @@ The user
 may specify a scan of all busses, a single bus, or a lun.
 Scanning all luns
 on a target is not supported.
+.It Ic reprobe
+Tell the kernel to refresh the information about the device and
+notify the upper layer,
+.Xr GEOM 4 .
+This includes sending the SCSI READ CAPACITY command and updating
+the disk size visible to the rest of the system.
 .It Ic reset
 Tell the kernel to reset all busses in the system (with the
 .Ar all

Modified: head/sbin/camcontrol/camcontrol.c
==============================================================================
--- head/sbin/camcontrol/camcontrol.c	Tue May 10 15:45:59 2016	(r299370)
+++ head/sbin/camcontrol/camcontrol.c	Tue May 10 15:46:33 2016	(r299371)
@@ -100,7 +100,8 @@ typedef enum {
 	CAM_CMD_APM		= 0x00000021,
 	CAM_CMD_AAM		= 0x00000022,
 	CAM_CMD_ATTRIB		= 0x00000023,
-	CAM_CMD_OPCODES		= 0x00000024
+	CAM_CMD_OPCODES		= 0x00000024,
+	CAM_CMD_REPROBE		= 0x00000025
 } cam_cmdmask;
 
 typedef enum {
@@ -190,6 +191,7 @@ static struct camcontrol_opts option_tab
 	{"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL},
 	{"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"},
 	{"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"},
+	{"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL},
 #endif /* MINIMALISTIC */
 	{"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL},
 	{"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL},
@@ -328,6 +330,7 @@ static int scsiprintopcodes(struct cam_d
 static int scsiopcodes(struct cam_device *device, int argc, char **argv,
 		       char *combinedopt, int retry_count, int timeout,
 		       int verbose);
+static int scsireprobe(struct cam_device *device);
 
 #endif /* MINIMALISTIC */
 #ifndef min
@@ -8660,6 +8663,42 @@ bailout:
 
 #endif /* MINIMALISTIC */
 
+static int
+scsireprobe(struct cam_device *device)
+{
+	union ccb *ccb;
+	int retval = 0;
+
+	ccb = cam_getccb(device);
+
+	if (ccb == NULL) {
+		warnx("%s: error allocating ccb", __func__);
+		return (1);
+	}
+
+	bzero(&(&ccb->ccb_h)[1],
+	      sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
+
+	ccb->ccb_h.func_code = XPT_REPROBE_LUN;
+
+	if (cam_send_ccb(device, ccb) < 0) {
+		warn("error sending XPT_REPROBE_LUN CCB");
+		retval = 1;
+		goto bailout;
+	}
+
+	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+		cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
+		retval = 1;
+		goto bailout;
+	}
+
+bailout:
+	cam_freeccb(ccb);
+
+	return (retval);
+}
+
 void
 usage(int printlong)
 {
@@ -8679,6 +8718,7 @@ usage(int printlong)
 "        camcontrol stop       [dev_id][generic args]\n"
 "        camcontrol load       [dev_id][generic args]\n"
 "        camcontrol eject      [dev_id][generic args]\n"
+"        camcontrol reprobe    [dev_id][generic args]\n"
 #endif /* MINIMALISTIC */
 "        camcontrol rescan     <all | bus[:target:lun]>\n"
 "        camcontrol reset      <all | bus[:target:lun]>\n"
@@ -8751,6 +8791,7 @@ usage(int printlong)
 "stop        send a Stop Unit command to the device\n"
 "load        send a Start Unit command to the device with the load bit set\n"
 "eject       send a Stop Unit command to the device with the eject bit set\n"
+"reprobe     update capacity information of the given device\n"
 "rescan      rescan all busses, the given bus, or bus:target:lun\n"
 "reset       reset all busses, the given bus, or bus:target:lun\n"
 "defects     read the defect list of the specified device\n"
@@ -9296,6 +9337,10 @@ main(int argc, char **argv)
 			error = scsiopcodes(cam_dev, argc, argv, combinedopt,
 			    retry_count, timeout, arglist & CAM_ARG_VERBOSE);
 			break;
+		case CAM_CMD_REPROBE:
+			error = scsireprobe(cam_dev);
+			break;
+
 #endif /* MINIMALISTIC */
 		case CAM_CMD_USAGE:
 			usage(1);

Modified: head/sys/cam/cam_ccb.h
==============================================================================
--- head/sys/cam/cam_ccb.h	Tue May 10 15:45:59 2016	(r299370)
+++ head/sys/cam/cam_ccb.h	Tue May 10 15:46:33 2016	(r299371)
@@ -231,6 +231,8 @@ typedef enum {
 				/* Notify Host Target driver of event */
 	XPT_NOTIFY_ACKNOWLEDGE	= 0x37 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
 				/* Acknowledgement of event */
+	XPT_REPROBE_LUN		= 0x38 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
+				/* Query device capacity and notify GEOM */
 
 /* Vendor Unique codes: 0x80->0x8F */
 	XPT_VUNIQUE		= 0x80

Modified: head/sys/cam/cam_xpt.c
==============================================================================
--- head/sys/cam/cam_xpt.c	Tue May 10 15:45:59 2016	(r299370)
+++ head/sys/cam/cam_xpt.c	Tue May 10 15:46:33 2016	(r299371)
@@ -2994,6 +2994,11 @@ call_sim:
 			xpt_freeze_devq(path, 1);
 		start_ccb->ccb_h.status = CAM_REQ_CMP;
 		break;
+	case XPT_REPROBE_LUN:
+		xpt_async(AC_INQ_CHANGED, path, NULL);
+		start_ccb->ccb_h.status = CAM_REQ_CMP;
+		xpt_done(start_ccb);
+		break;
 	default:
 	case XPT_SDEV_TYPE:
 	case XPT_TERM_IO:

Modified: head/sys/cam/scsi/scsi_da.c
==============================================================================
--- head/sys/cam/scsi/scsi_da.c	Tue May 10 15:45:59 2016	(r299370)
+++ head/sys/cam/scsi/scsi_da.c	Tue May 10 15:46:33 2016	(r299371)
@@ -1769,6 +1769,11 @@ daasync(void *callback_arg, u_int32_t co
 			ccbh->ccb_state |= DA_CCB_RETRY_UA;
 		break;
 	}
+	case AC_INQ_CHANGED:
+		softc = (struct da_softc *)periph->softc;
+		softc->flags &= ~DA_FLAG_PROBED;
+		dareprobe(periph);
+		break;
 	default:
 		break;
 	}
@@ -2329,8 +2334,8 @@ daregister(struct cam_periph *periph, vo
 	 * would be to not attach the device on failure.
 	 */
 	xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE |
-	    AC_ADVINFO_CHANGED | AC_SCSI_AEN | AC_UNIT_ATTENTION,
-	    daasync, periph, periph->path);
+	    AC_ADVINFO_CHANGED | AC_SCSI_AEN | AC_UNIT_ATTENTION |
+	    AC_INQ_CHANGED, daasync, periph, periph->path);
 
 	/*
 	 * Emit an attribute changed notification just in case 


More information about the svn-src-all mailing list