svn commit: r330733 - in stable/11: cddl/usr.sbin/zfsd etc/mtree lib/libdevdctl sys/geom/eli sys/geom/part tests/sys/geom/class tests/sys/geom/class/eli tests/sys/geom/class/part

Alan Somers asomers at FreeBSD.org
Sat Mar 10 03:34:29 UTC 2018


Author: asomers
Date: Sat Mar 10 03:34:27 2018
New Revision: 330733
URL: https://svnweb.freebsd.org/changeset/base/330733

Log:
  MFC r329273, r329275, r329277, r329284, r329344
  
  r329273:
  geli: append "/eli" to the underlying provider's physical path
  
  If the underlying provider's physical path is null, then the geli device's
  physical path will be, too. Otherwise, it will append "/eli".  This will make
  geli work better with zfsd(8).
  
  PR:		224962
  Differential Revision:	https://reviews.freebsd.org/D13979
  
  r329275:
  gpart: append partition name to the underlying provider's physical path
  
  If the underlying provider's physical path is null, then the gpart device's
  physical path will be, too. Otherwise, it will append the partition name,
  such as "/p1" or "/s1/a". This will make gpart work better with zfsd(8).
  
  PR:		224965
  Differential Revision:	https://reviews.freebsd.org/D14010
  
  r329277:
  Add mtree entry for 329275
  
  X-MFC-With:	329275
  Sponsored by:	Spectra Logic Corp
  
  r329284:
  zfsd: Allow zfsd to work on any type of GEOM provider
  
  cddl/usr.sbin/zfsd/zfsd_event.cc
  	Remove the check for da and ada devices.  This way zfsd can work on md,
  	geli, glabel, gstripe, etc devices.  geli in particular is useful
  	combined with ZFS.  gnop is also useful for simulating drive pulls in
  	the ZFSD test suite.
  
  	Also, eliminate the DevfsEvent class entirely.  Move its
  	responsibilities into GeomEvent.  We can get everything we need to know
  	just from listening to GEOM events.
  
  lib/libdevdctl/event.cc
  	Fix GeomEvent::DevName for CREATE events.  Oddly, the relevant field is
  	named "cdev" for CREATE events but "devname" for disk events.
  
  Relnotes:	Yes (probably worth mentioning the geli part)
  Sponsored by:	Spectra Logic Corp
  
  r329344:
  Optimize zfsd for the happy case
  
  If there are no damaged pools, then ignore all GEOM events.  We only use
  them to fix damaged pools.  However, still pay attention to ZFS events.
  
  X-MFC-With:	329284
  Sponsored by:	Spectra Logic Corp

Added:
  stable/11/tests/sys/geom/class/eli/misc_test.sh
     - copied unchanged from r329273, head/tests/sys/geom/class/eli/misc_test.sh
  stable/11/tests/sys/geom/class/part/
     - copied from r329275, head/tests/sys/geom/class/part/
Modified:
  stable/11/cddl/usr.sbin/zfsd/case_file.cc
  stable/11/cddl/usr.sbin/zfsd/case_file.h
  stable/11/cddl/usr.sbin/zfsd/zfsd.cc
  stable/11/cddl/usr.sbin/zfsd/zfsd_event.cc
  stable/11/cddl/usr.sbin/zfsd/zfsd_event.h
  stable/11/etc/mtree/BSD.tests.dist
  stable/11/lib/libdevdctl/event.cc
  stable/11/sys/geom/eli/g_eli.c
  stable/11/sys/geom/part/g_part.c
  stable/11/tests/sys/geom/class/Makefile
  stable/11/tests/sys/geom/class/eli/Makefile
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/cddl/usr.sbin/zfsd/case_file.cc
==============================================================================
--- stable/11/cddl/usr.sbin/zfsd/case_file.cc	Sat Mar 10 03:24:59 2018	(r330732)
+++ stable/11/cddl/usr.sbin/zfsd/case_file.cc	Sat Mar 10 03:34:27 2018	(r330733)
@@ -186,6 +186,12 @@ CaseFile::DeSerialize()
 	free(caseFiles);
 }
 
+bool
+CaseFile::Empty()
+{
+	return (s_activeCases.empty());
+}
+
 void
 CaseFile::LogAll()
 {

Modified: stable/11/cddl/usr.sbin/zfsd/case_file.h
==============================================================================
--- stable/11/cddl/usr.sbin/zfsd/case_file.h	Sat Mar 10 03:24:59 2018	(r330732)
+++ stable/11/cddl/usr.sbin/zfsd/case_file.h	Sat Mar 10 03:34:27 2018	(r330733)
@@ -135,6 +135,11 @@ class CaseFile (public)
 	static void      DeSerialize();
 
 	/**
+	 * \brief returns true if there are no CaseFiles
+	 */
+	static bool	Empty();
+
+	/**
 	 * \brief Emit syslog data on all active CaseFile%%s in the system.
 	 */
 	static void      LogAll();

Modified: stable/11/cddl/usr.sbin/zfsd/zfsd.cc
==============================================================================
--- stable/11/cddl/usr.sbin/zfsd/zfsd.cc	Sat Mar 10 03:24:59 2018	(r330732)
+++ stable/11/cddl/usr.sbin/zfsd/zfsd.cc	Sat Mar 10 03:34:27 2018	(r330733)
@@ -98,7 +98,6 @@ int		     ZfsDaemon::s_signalPipeFD[2];
 bool		     ZfsDaemon::s_systemRescanRequested(false);
 EventFactory::Record ZfsDaemon::s_registryEntries[] =
 {
-	{ Event::NOTIFY, "DEVFS", &DevfsEvent::Builder },
 	{ Event::NOTIFY, "GEOM",  &GeomEvent::Builder },
 	{ Event::NOTIFY, "ZFS",   &ZfsEvent::Builder }
 };

Modified: stable/11/cddl/usr.sbin/zfsd/zfsd_event.cc
==============================================================================
--- stable/11/cddl/usr.sbin/zfsd/zfsd_event.cc	Sat Mar 10 03:24:59 2018	(r330732)
+++ stable/11/cddl/usr.sbin/zfsd/zfsd_event.cc	Sat Mar 10 03:34:27 2018	(r330733)
@@ -76,113 +76,42 @@ using std::stringstream;
 
 /*=========================== Class Implementations ==========================*/
 
-/*-------------------------------- DevfsEvent --------------------------------*/
+/*-------------------------------- GeomEvent --------------------------------*/
 
-//- DevfsEvent Static Public Methods -------------------------------------------
+//- GeomEvent Static Public Methods -------------------------------------------
 Event *
-DevfsEvent::Builder(Event::Type type,
-		    NVPairMap &nvPairs,
-		    const string &eventString)
+GeomEvent::Builder(Event::Type type,
+		   NVPairMap &nvPairs,
+		   const string &eventString)
 {
-	return (new DevfsEvent(type, nvPairs, eventString));
+	return (new GeomEvent(type, nvPairs, eventString));
 }
 
-//- DevfsEvent Static Protected Methods ----------------------------------------
-nvlist_t *
-DevfsEvent::ReadLabel(int devFd, bool &inUse, bool &degraded)
-{
-	pool_state_t poolState;
-	char        *poolName;
-	boolean_t    b_inuse;
-	int          nlabels;
-
-	inUse    = false;
-	degraded = false;
-	poolName = NULL;
-	if (zpool_in_use(g_zfsHandle, devFd, &poolState,
-			 &poolName, &b_inuse) == 0) {
-		nvlist_t *devLabel = NULL;
-
-		inUse = b_inuse == B_TRUE;
-		if (poolName != NULL)
-			free(poolName);
-
-		nlabels = zpool_read_all_labels(devFd, &devLabel);
-		/*
-		 * If we find a disk with fewer than the maximum number of
-		 * labels, it might be the whole disk of a partitioned disk
-		 * where ZFS resides on a partition.  In that case, we should do
-		 * nothing and wait for the partition to appear.  Or, the disk
-		 * might be damaged.  In that case, zfsd should do nothing and
-		 * wait for the sysadmin to decide.
-		 */
-		if (nlabels != VDEV_LABELS || devLabel == NULL) {
-			nvlist_free(devLabel);
-			return (NULL);
-		}
-
-		try {
-			Vdev vdev(devLabel);
-			degraded = vdev.State() != VDEV_STATE_HEALTHY;
-			return (devLabel);
-		} catch (ZfsdException &exp) {
-			string devName = fdevname(devFd);
-			string devPath = _PATH_DEV + devName;
-			string context("DevfsEvent::ReadLabel: "
-				     + devPath + ": ");
-
-			exp.GetString().insert(0, context);
-			exp.Log();
-			nvlist_free(devLabel);
-		}
-	}
-	return (NULL);
-}
-
-bool
-DevfsEvent::OnlineByLabel(const string &devPath, const string& physPath,
-			      nvlist_t *devConfig)
-{
-	try {
-		/*
-		 * A device with ZFS label information has been
-		 * inserted.  If it matches a device for which we
-		 * have a case, see if we can solve that case.
-		 */
-		syslog(LOG_INFO, "Interrogating VDEV label for %s\n",
-		       devPath.c_str());
-		Vdev vdev(devConfig);
-		CaseFile *caseFile(CaseFile::Find(vdev.PoolGUID(),
-						  vdev.GUID()));
-		if (caseFile != NULL)
-			return (caseFile->ReEvaluate(devPath, physPath, &vdev));
-
-	} catch (ZfsdException &exp) {
-		string context("DevfsEvent::OnlineByLabel: " + devPath + ": ");
-
-		exp.GetString().insert(0, context);
-		exp.Log();
-	}
-	return (false);
-}
-
-//- DevfsEvent Virtual Public Methods ------------------------------------------
+//- GeomEvent Virtual Public Methods ------------------------------------------
 Event *
-DevfsEvent::DeepCopy() const
+GeomEvent::DeepCopy() const
 {
-	return (new DevfsEvent(*this));
+	return (new GeomEvent(*this));
 }
-
+ 
 bool
-DevfsEvent::Process() const
+GeomEvent::Process() const
 {
 	/*
-	 * We are only concerned with newly discovered
-	 * devices that can be ZFS vdevs.
+	 * We only use GEOM events to repair damaged pools.  So return early if
+	 * there are no damaged pools
 	 */
-	if (Value("type") != "CREATE" || !IsDiskDev())
+	if (CaseFile::Empty())
 		return (false);
 
+	/*
+	 * We are only concerned with arrivals and physical path changes,
+	 * because those can be used to satisfy online and autoreplace
+	 * operations
+	 */
+	if (Value("type") != "GEOM::physpath" && Value("type") != "CREATE")
+		return (false);
+
 	/* Log the event since it is of interest. */
 	Log(LOG_INFO);
 
@@ -199,7 +128,7 @@ DevfsEvent::Process() const
 	nvlist_t *devLabel(ReadLabel(devFd, inUse, degraded));
 
 	string physPath;
-	bool havePhysPath(PhysicalPath(physPath));
+        bool havePhysPath(PhysicalPath(physPath));
 
 	string devName;
 	DevName(devName);
@@ -211,8 +140,8 @@ DevfsEvent::Process() const
 		syslog(LOG_INFO, "%s is marked degraded.  Ignoring "
 		       "as a replace by physical path candidate.\n",
 		       devName.c_str());
-	} else if (havePhysPath && IsWholeDev()) {
-		/*
+	} else if (havePhysPath) {
+		/* 
 		 * TODO: attempt to resolve events using every casefile
 		 * that matches this physpath
 		 */
@@ -227,93 +156,97 @@ DevfsEvent::Process() const
 			caseFile->ReEvaluate(devPath, physPath, /*vdev*/NULL);
 		}
 	}
-	if (devLabel != NULL)
-		nvlist_free(devLabel);
 	return (false);
 }
 
-//- DevfsEvent Protected Methods -----------------------------------------------
-DevfsEvent::DevfsEvent(Event::Type type, NVPairMap &nvpairs,
+//- GeomEvent Protected Methods -----------------------------------------------
+GeomEvent::GeomEvent(Event::Type type, NVPairMap &nvpairs,
 			       const string &eventString)
- : DevdCtl::DevfsEvent(type, nvpairs, eventString)
+ : DevdCtl::GeomEvent(type, nvpairs, eventString)
 {
 }
 
-DevfsEvent::DevfsEvent(const DevfsEvent &src)
- : DevdCtl::DevfsEvent::DevfsEvent(src)
+GeomEvent::GeomEvent(const GeomEvent &src)
+ : DevdCtl::GeomEvent::GeomEvent(src)
 {
 }
 
-/*-------------------------------- GeomEvent --------------------------------*/
-
-//- GeomEvent Static Public Methods -------------------------------------------
-Event *
-GeomEvent::Builder(Event::Type type,
-		   NVPairMap &nvPairs,
-		   const string &eventString)
+nvlist_t *
+GeomEvent::ReadLabel(int devFd, bool &inUse, bool &degraded)
 {
-	return (new GeomEvent(type, nvPairs, eventString));
-}
+	pool_state_t poolState;
+	char        *poolName;
+	boolean_t    b_inuse;
+	int          nlabels;
 
-//- GeomEvent Virtual Public Methods ------------------------------------------
-Event *
-GeomEvent::DeepCopy() const
-{
-	return (new GeomEvent(*this));
-}
- 
-bool
-GeomEvent::Process() const
-{
-	/*
-	 * We are only concerned with physical path changes, because those can
-	 * be used to satisfy autoreplace operations
-	 */
-	if (Value("type") != "GEOM::physpath" || !IsDiskDev())
-		return (false);
+	inUse    = false;
+	degraded = false;
+	poolName = NULL;
+	if (zpool_in_use(g_zfsHandle, devFd, &poolState,
+			 &poolName, &b_inuse) == 0) {
+		nvlist_t *devLabel = NULL;
 
-	/* Log the event since it is of interest. */
-	Log(LOG_INFO);
+		inUse = b_inuse == B_TRUE;
+		if (poolName != NULL)
+			free(poolName);
 
-	string devPath;
-	if (!DevPath(devPath))
-		return (false);
+		nlabels = zpool_read_all_labels(devFd, &devLabel);
+		/*
+		 * If we find a disk with fewer than the maximum number of
+		 * labels, it might be the whole disk of a partitioned disk
+		 * where ZFS resides on a partition.  In that case, we should do
+		 * nothing and wait for the partition to appear.  Or, the disk
+		 * might be damaged.  In that case, zfsd should do nothing and
+		 * wait for the sysadmin to decide.
+		 */
+		if (nlabels != VDEV_LABELS || devLabel == NULL) {
+			nvlist_free(devLabel);
+			return (NULL);
+		}
 
-	string physPath;
-        bool havePhysPath(PhysicalPath(physPath));
+		try {
+			Vdev vdev(devLabel);
+			degraded = vdev.State() != VDEV_STATE_HEALTHY;
+			return (devLabel);
+		} catch (ZfsdException &exp) {
+			string devName = fdevname(devFd);
+			string devPath = _PATH_DEV + devName;
+			string context("GeomEvent::ReadLabel: "
+				     + devPath + ": ");
 
-	string devName;
-	DevName(devName);
-
-	if (havePhysPath) {
-		/* 
-		 * TODO: attempt to resolve events using every casefile
-		 * that matches this physpath
-		 */
-		CaseFile *caseFile(CaseFile::Find(physPath));
-		if (caseFile != NULL) {
-			syslog(LOG_INFO,
-			       "Found CaseFile(%s:%s:%s) - ReEvaluating\n",
-			       caseFile->PoolGUIDString().c_str(),
-			       caseFile->VdevGUIDString().c_str(),
-			       zpool_state_to_name(caseFile->VdevState(),
-						   VDEV_AUX_NONE));
-			caseFile->ReEvaluate(devPath, physPath, /*vdev*/NULL);
+			exp.GetString().insert(0, context);
+			exp.Log();
+			nvlist_free(devLabel);
 		}
 	}
-	return (false);
+	return (NULL);
 }
 
-//- GeomEvent Protected Methods -----------------------------------------------
-GeomEvent::GeomEvent(Event::Type type, NVPairMap &nvpairs,
-			       const string &eventString)
- : DevdCtl::GeomEvent(type, nvpairs, eventString)
+bool
+GeomEvent::OnlineByLabel(const string &devPath, const string& physPath,
+			      nvlist_t *devConfig)
 {
-}
+	try {
+		/*
+		 * A device with ZFS label information has been
+		 * inserted.  If it matches a device for which we
+		 * have a case, see if we can solve that case.
+		 */
+		syslog(LOG_INFO, "Interrogating VDEV label for %s\n",
+		       devPath.c_str());
+		Vdev vdev(devConfig);
+		CaseFile *caseFile(CaseFile::Find(vdev.PoolGUID(),
+						  vdev.GUID()));
+		if (caseFile != NULL)
+			return (caseFile->ReEvaluate(devPath, physPath, &vdev));
 
-GeomEvent::GeomEvent(const GeomEvent &src)
- : DevdCtl::GeomEvent::GeomEvent(src)
-{
+	} catch (ZfsdException &exp) {
+		string context("GeomEvent::OnlineByLabel: " + devPath + ": ");
+
+		exp.GetString().insert(0, context);
+		exp.Log();
+	}
+	return (false);
 }
 
 

Modified: stable/11/cddl/usr.sbin/zfsd/zfsd_event.h
==============================================================================
--- stable/11/cddl/usr.sbin/zfsd/zfsd_event.h	Sat Mar 10 03:24:59 2018	(r330732)
+++ stable/11/cddl/usr.sbin/zfsd/zfsd_event.h	Sat Mar 10 03:34:27 2018	(r330733)
@@ -60,63 +60,6 @@ typedef struct zpool_handle zpool_handle_t;
 struct nvlist;
 typedef struct nvlist nvlist_t;
 
-/*============================= Class Definitions ============================*/
-/*-------------------------------- DevfsEvent --------------------------------*/
-class DevfsEvent : public DevdCtl::DevfsEvent
-{
-public:
-	/** Specialized DevdCtlEvent object factory for Devfs events. */
-	static BuildMethod Builder;
-
-	virtual DevdCtl::Event *DeepCopy() const;
-
-	/**
-	 * Interpret and perform any actions necessary to
-	 * consume the event.
-	 * \return True if this event should be queued for later reevaluation
-	 */
-	virtual bool Process()		  const;
-
-protected:
-	/**
-	 * \brief Read and return label information for a device.
-	 *
-	 * \param devFd     The device from which to read ZFS label information.
-	 * \param inUse     The device is part of an active or potentially
-	 *                  active configuration.
-	 * \param degraded  The device label indicates the vdev is not healthy.
-	 *
-	 * \return  If label information is available, an nvlist describing
-	 *          the vdev configuraiton found on the device specified by
-	 *          devFd.  Otherwise NULL.
-	 */
-	static nvlist_t    *ReadLabel(int devFd, bool &inUse, bool &degraded);
-
-	/**
-	 * Attempt to match the ZFS labeled device at devPath with an active
-	 * CaseFile for a missing vdev.  If a CaseFile is found, attempt
-	 * to re-integrate the device with its pool.
-	 *
-	 * \param devPath    The devfs path to the potential leaf vdev.
-	 * \param physPath   The physical path string reported by the device
-	 *                   at devPath.
-	 * \param devConfig  The ZFS label information found on the device
-	 *                   at devPath.
-	 *
-	 * \return  true if the event that caused the online action can
-	 *          be considered consumed.
-	 */
-	static bool	    OnlineByLabel(const string &devPath,
-					  const string& physPath,
-					  nvlist_t *devConfig);
-
-	/** DeepCopy Constructor. */
-	DevfsEvent(const DevfsEvent &src);
-
-	/** Constructor */
-	DevfsEvent(Type, DevdCtl::NVPairMap &, const string &);
-};
-
 /*--------------------------------- ZfsEvent ---------------------------------*/
 class ZfsEvent : public DevdCtl::ZfsEvent
 {
@@ -164,5 +107,38 @@ class GeomEvent : public DevdCtl::GeomEvent (protected
 
 	/** Constructor */
 	GeomEvent(Type, DevdCtl::NVPairMap &, const string &);
+
+	/**
+	 * Attempt to match the ZFS labeled device at devPath with an active
+	 * CaseFile for a missing vdev.  If a CaseFile is found, attempt
+	 * to re-integrate the device with its pool.
+	 *
+	 * \param devPath    The devfs path to the potential leaf vdev.
+	 * \param physPath   The physical path string reported by the device
+	 *                   at devPath.
+	 * \param devConfig  The ZFS label information found on the device
+	 *                   at devPath.
+	 *
+	 * \return  true if the event that caused the online action can
+	 *          be considered consumed.
+	 */
+	static bool	    OnlineByLabel(const string &devPath,
+					  const string& physPath,
+					  nvlist_t *devConfig);
+
+	/**
+	 * \brief Read and return label information for a device.
+	 *
+	 * \param devFd     The device from which to read ZFS label information.
+	 * \param inUse     The device is part of an active or potentially
+	 *                  active configuration.
+	 * \param degraded  The device label indicates the vdev is not healthy.
+	 *
+	 * \return  If label information is available, an nvlist describing
+	 *          the vdev configuraiton found on the device specified by
+	 *          devFd.  Otherwise NULL.
+	 */
+	static nvlist_t    *ReadLabel(int devFd, bool &inUse, bool &degraded);
+
 };
 #endif /*_ZFSD_EVENT_H_ */

Modified: stable/11/etc/mtree/BSD.tests.dist
==============================================================================
--- stable/11/etc/mtree/BSD.tests.dist	Sat Mar 10 03:24:59 2018	(r330732)
+++ stable/11/etc/mtree/BSD.tests.dist	Sat Mar 10 03:34:27 2018	(r330733)
@@ -440,6 +440,8 @@
                 ..
                 nop
                 ..
+                part
+                ..
                 raid3
                 ..
                 shsec

Modified: stable/11/lib/libdevdctl/event.cc
==============================================================================
--- stable/11/lib/libdevdctl/event.cc	Sat Mar 10 03:24:59 2018	(r330732)
+++ stable/11/lib/libdevdctl/event.cc	Sat Mar 10 03:34:27 2018	(r330733)
@@ -542,7 +542,10 @@ GeomEvent::DeepCopy() const
 bool
 GeomEvent::DevName(std::string &name) const
 {
-	name = Value("devname");
+	if (Value("subsystem") == "disk")
+		name = Value("devname");
+	else
+		name = Value("cdev");
 	return (!name.empty());
 }
 

Modified: stable/11/sys/geom/eli/g_eli.c
==============================================================================
--- stable/11/sys/geom/eli/g_eli.c	Sat Mar 10 03:24:59 2018	(r330732)
+++ stable/11/sys/geom/eli/g_eli.c	Sat Mar 10 03:34:27 2018	(r330733)
@@ -210,6 +210,16 @@ g_eli_crypto_rerun(struct cryptop *crp)
 	return (error);
 }
 
+static void
+g_eli_getattr_done(struct bio *bp)
+{
+	if (bp->bio_error == 0 && 
+	    !strcmp(bp->bio_attribute, "GEOM::physpath")) {
+		strlcat(bp->bio_data, "/eli", bp->bio_length);
+	}
+	g_std_done(bp);
+}
+
 /*
  * The function is called afer reading encrypted data from the provider.
  *
@@ -378,7 +388,10 @@ g_eli_start(struct bio *bp)
 	case BIO_FLUSH:
 	case BIO_DELETE:
 	case BIO_ZONE:
-		cbp->bio_done = g_std_done;
+		if (bp->bio_cmd == BIO_GETATTR)
+			cbp->bio_done = g_eli_getattr_done;
+		else
+			cbp->bio_done = g_std_done;
 		cp = LIST_FIRST(&sc->sc_geom->consumer);
 		cbp->bio_to = cp->provider;
 		G_ELI_LOGREQ(2, cbp, "Sending request.");

Modified: stable/11/sys/geom/part/g_part.c
==============================================================================
--- stable/11/sys/geom/part/g_part.c	Sat Mar 10 03:24:59 2018	(r330732)
+++ stable/11/sys/geom/part/g_part.c	Sat Mar 10 03:34:27 2018	(r330733)
@@ -268,6 +268,35 @@ g_part_geometry(struct g_part_table *table, struct g_c
 	}
 }
 
+static void
+g_part_get_physpath_done(struct bio *bp)
+{
+	struct g_geom *gp;
+	struct g_part_entry *entry;
+	struct g_part_table *table;
+	struct g_provider *pp;
+	struct bio *pbp;
+
+	pbp = bp->bio_parent;
+	pp = pbp->bio_to;
+	gp = pp->geom;
+	table = gp->softc;
+	entry = pp->private;
+
+	if (bp->bio_error == 0) {
+		char *end;
+		size_t len, remainder;
+		len = strlcat(bp->bio_data, "/", bp->bio_length);
+		if (len < bp->bio_length) {
+			end = bp->bio_data + len;
+			remainder = bp->bio_length - len;
+			G_PART_NAME(table, entry, end, remainder);
+		}
+	}
+	g_std_done(bp);
+}
+
+
 #define	DPRINTF(...)	if (bootverbose) {	\
 	printf("GEOM_PART: " __VA_ARGS__);	\
 }
@@ -2157,6 +2186,7 @@ g_part_start(struct bio *bp)
 	struct g_part_table *table;
 	struct g_kerneldump *gkd;
 	struct g_provider *pp;
+	void (*done_func)(struct bio *) = g_std_done;
 	char buf[64];
 
 	pp = bp->bio_to;
@@ -2209,6 +2239,10 @@ g_part_start(struct bio *bp)
 		if (g_handleattr_str(bp, "PART::type",
 		    G_PART_TYPE(table, entry, buf, sizeof(buf))))
 			return;
+		if (!strcmp("GEOM::physpath", bp->bio_attribute)) {
+			done_func = g_part_get_physpath_done;
+			break;
+		}
 		if (!strcmp("GEOM::kerneldump", bp->bio_attribute)) {
 			/*
 			 * Check that the partition is suitable for kernel
@@ -2245,7 +2279,7 @@ g_part_start(struct bio *bp)
 		g_io_deliver(bp, ENOMEM);
 		return;
 	}
-	bp2->bio_done = g_std_done;
+	bp2->bio_done = done_func;
 	g_io_request(bp2, cp);
 }
 

Modified: stable/11/tests/sys/geom/class/Makefile
==============================================================================
--- stable/11/tests/sys/geom/class/Makefile	Sat Mar 10 03:24:59 2018	(r330732)
+++ stable/11/tests/sys/geom/class/Makefile	Sat Mar 10 03:34:27 2018	(r330733)
@@ -7,10 +7,9 @@ TESTSDIR=	${TESTSBASE}/sys/geom/class
 TESTS_SUBDIRS+=	concat
 TESTS_SUBDIRS+=	eli
 TESTS_SUBDIRS+=	gate
-# XXX: might not work due to geom(4) changes; more investigation's needed
-#TESTS_SUBDIRS+=	gpt
 TESTS_SUBDIRS+=	mirror
 TESTS_SUBDIRS+=	nop
+TESTS_SUBDIRS+=	part
 TESTS_SUBDIRS+=	raid3
 TESTS_SUBDIRS+=	shsec
 TESTS_SUBDIRS+=	stripe

Modified: stable/11/tests/sys/geom/class/eli/Makefile
==============================================================================
--- stable/11/tests/sys/geom/class/eli/Makefile	Sat Mar 10 03:24:59 2018	(r330732)
+++ stable/11/tests/sys/geom/class/eli/Makefile	Sat Mar 10 03:34:27 2018	(r330733)
@@ -14,6 +14,7 @@ ATF_TESTS_SH+=	detach_test
 ATF_TESTS_SH+=	init_test
 ATF_TESTS_SH+=	integrity_test
 ATF_TESTS_SH+=	kill_test
+ATF_TESTS_SH+=	misc_test
 ATF_TESTS_SH+=	onetime_test
 ATF_TESTS_SH+=	resize_test
 ATF_TESTS_SH+=	setkey_test

Copied: stable/11/tests/sys/geom/class/eli/misc_test.sh (from r329273, head/tests/sys/geom/class/eli/misc_test.sh)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/tests/sys/geom/class/eli/misc_test.sh	Sat Mar 10 03:34:27 2018	(r330733, copy of r329273, head/tests/sys/geom/class/eli/misc_test.sh)
@@ -0,0 +1,177 @@
+# Copyright (c) 2018 Alan Somers
+# All rights reserved.
+#
+# 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.
+#
+# $FreeBSD$
+
+atf_test_case preserve_props cleanup
+preserve_props_head()
+{
+	atf_set "descr" "geli should preserve basic GEOM properties"
+	atf_set "require.user" "root"
+	atf_set "timeout" 15
+}
+preserve_props_body()
+{
+	. $(atf_get_srcdir)/conf.sh
+	md=$(attach_md -s1m)
+	atf_check geli onetime /dev/${md}
+	md_secsize=$(diskinfo ${md} | cut -wf 2)
+	md_stripesize=$(diskinfo ${md} | cut -wf 5)
+	eli_secsize=$(diskinfo ${md}.eli | cut -wf 2)
+	eli_stripesize=$(diskinfo ${md}.eli | cut -wf 5)
+	atf_check_equal "$md_secsize" "$eli_secsize"
+	atf_check_equal "$md_stripesize" "$eli_stripesize"
+}
+preserve_props_cleanup()
+{
+	. $(atf_get_srcdir)/conf.sh
+	geli_test_cleanup
+}
+
+atf_test_case preserve_disk_props cleanup
+preserve_disk_props_head()
+{
+	atf_set "descr" "geli should preserve properties for disks"
+	atf_set "require.user" "root"
+	atf_set "require.config" "disks"
+	atf_set "timeout" 15
+}
+preserve_disk_props_body()
+{
+	. $(atf_get_srcdir)/conf.sh
+	disks=`atf_config_get disks`
+	disk=${disks%% *}
+	if [ -z "$disk" ]; then
+		atf_skip "Must define disks (see tests(7))"
+	fi
+	atf_check geli onetime ${disk}
+
+	disk_ident=$(diskinfo -s ${disk})
+	disk_descr=$(diskinfo -v ${disk} | awk '/Disk descr/ {print $1}')
+	disk_rotrate=$(diskinfo -v ${disk} | awk '/Rotation rate/ {print $1}')
+	disk_zonemode=$(diskinfo -v ${disk} | awk '/Zone Mode/ {print $1}')
+	eli_ident=$(diskinfo -s ${disk}.eli)
+	eli_descr=$(diskinfo -v ${disk}.eli | awk '/Disk descr/ {print $1}')
+	eli_rotrate=$(diskinfo -v ${disk}.eli | awk '/Rotation/ {print $1}')
+	eli_zonemode=$(diskinfo -v ${disk}.eli | awk '/Zone Mode/ {print $1}')
+	atf_check_equal "$disk_ident" "$eli_ident"
+	atf_check_equal "$disk_descr" "$eli_descr"
+	atf_check_equal "$disk_rotrate" "$eli_rotrate"
+	atf_check_equal "$disk_zonemode" "$eli_zonemode"
+}
+preserve_disk_props_cleanup()
+{
+	. $(atf_get_srcdir)/conf.sh
+	disk_cleanup
+	geli_test_cleanup
+}
+
+atf_test_case physpath cleanup
+physpath_head()
+{
+	atf_set "descr" "geli should append /eli to the underlying device's physical path"
+	atf_set "require.user" "root"
+	atf_set "timeout" 15
+}
+physpath_body()
+{
+	. $(atf_get_srcdir)/conf.sh
+	load_gnop
+
+	md=$(attach_md -s1m)
+	# If the underlying device has no physical path, then geli should not
+	# create one.
+	atf_check -o empty -e ignore diskinfo -p $md
+	atf_check -s exit:0 geli onetime $md
+	atf_check -o empty -e ignore diskinfo -p $md.eli
+	atf_check -s exit:0 geli kill $md
+
+	# If the underlying device does have a physical path, then geli should
+	# append "/eli"
+	physpath="some/physical/path"
+	atf_check gnop create -z $physpath ${md}
+	atf_check -s exit:0 geli onetime $md.nop
+	atf_check -o match:"^${physpath}/eli$" diskinfo -p $md.nop.eli
+}
+physpath_cleanup()
+{
+	. $(atf_get_srcdir)/conf.sh
+
+	if [ -f "$TEST_MDS_FILE" ]; then
+		while read md; do
+			[ -c /dev/${md}.nop.eli ] && \
+				geli detach $md.nop.eli 2>/dev/null
+			[ -c /dev/${md}.nop ] && \
+				gnop destroy -f $md.nop 2>/dev/null
+			[ -c /dev/${md}.eli ] && \
+				geli detach $md.eli 2>/dev/null
+			mdconfig -d -u $md 2>/dev/null
+		done < $TEST_MDS_FILE
+	fi
+	true
+}
+
+atf_init_test_cases()
+{
+	atf_add_test_case physpath
+	atf_add_test_case preserve_props
+	atf_add_test_case preserve_disk_props
+}
+
+
+common_cleanup()
+{
+
+	if [ -f "$MD_DEVS" ]; then
+		while read test_md; do
+			gnop destroy -f ${test_md}.nop 2>/dev/null
+			mdconfig -d -u $test_md 2>/dev/null
+		done < $MD_DEVS
+		rm $MD_DEVS
+	fi
+
+	if [ -f "$PLAINFILES" ]; then
+		while read f; do
+			rm -f ${f}
+		done < ${PLAINFILES}
+		rm ${PLAINFILES}
+	fi
+	true
+}
+
+disk_cleanup()
+{
+	disks=`atf_config_get disks`
+	disk=${disks%% *}
+	if [ -n "$disk" ]; then
+		geli kill ${disk} 2>/dev/null
+	fi
+}
+
+load_gnop()
+{
+	if ! kldstat -q -m g_nop; then
+		geom nop load || atf_skip "could not load module for geom nop"
+	fi
+}


More information about the svn-src-all mailing list