svn commit: r223085 - in head/sys: kern sys

Justin T. Gibbs gibbs at FreeBSD.org
Tue Jun 14 16:29:44 UTC 2011


Author: gibbs
Date: Tue Jun 14 16:29:43 2011
New Revision: 223085
URL: http://svn.freebsd.org/changeset/base/223085

Log:
  sys/sys/conf.h:
  sys/kern/kern_conf.c:
  	Add make_dev_physpath_alias().  This interface takes
  	the parent cdev of the alias, an old alias cdev (if any)
  	to replace with the newly created alias, and the physical
  	path string.  The alias is visiable as a symlink to the
  	parent, with the same name as the parent, rooted at
  	physpath in devfs.
  
  	Note: make_dev_physpath_alias() has hard coded knowledge of the
  	      Solaris style prefix convention for physical path data,
  	      "id1,".  In the future, I expect the convention to change
  	      to allow "physical path quality" to be reported in the
  	      prefix.  For example, a physical path based on NewBus
  	      topology would be of "lower quality" than a physical path
  	      reported by a device enclosure.
  
  Sponsored by:	Spectra Logic Corporation

Modified:
  head/sys/kern/kern_conf.c
  head/sys/sys/conf.h

Modified: head/sys/kern/kern_conf.c
==============================================================================
--- head/sys/kern/kern_conf.c	Tue Jun 14 16:05:00 2011	(r223084)
+++ head/sys/kern/kern_conf.c	Tue Jun 14 16:29:43 2011	(r223085)
@@ -963,6 +963,68 @@ make_dev_alias_p(int flags, struct cdev 
 	return (res);
 }
 
+int
+make_dev_physpath_alias(int flags, struct cdev **cdev, struct cdev *pdev, 
+    struct cdev *old_alias, const char *physpath)
+{
+	char *devfspath;
+	int physpath_len;
+	int max_parentpath_len;
+	int parentpath_len;
+	int devfspathbuf_len;
+	int mflags;
+	int ret;
+
+	*cdev = NULL;
+	devfspath = NULL;
+	physpath_len = strlen(physpath);
+	ret = EINVAL;
+	if (physpath_len == 0)
+		goto out;
+
+	if (strncmp("id1,", physpath, 4) == 0) {
+		physpath += 4;
+		physpath_len -= 4;
+		if (physpath_len == 0)
+			goto out;
+	}
+
+	max_parentpath_len = SPECNAMELEN - physpath_len - /*/*/1;
+	parentpath_len = strlen(pdev->si_name);
+	if (max_parentpath_len < parentpath_len) {
+		printf("make_dev_physpath_alias: WARNING - Unable to alias %s "
+		    "to %s/%s - path too long\n",
+		    pdev->si_name, physpath, pdev->si_name);
+		ret = ENAMETOOLONG;
+		goto out;
+	}
+
+	mflags = (flags & MAKEDEV_NOWAIT) ? M_NOWAIT : M_WAITOK;
+	devfspathbuf_len = physpath_len + /*/*/1 + parentpath_len + /*NUL*/1;
+	devfspath = malloc(devfspathbuf_len, M_DEVBUF, mflags);
+	if (devfspath == NULL) {
+		ret = ENOMEM;
+		goto out;
+	}
+
+	sprintf(devfspath, "%s/%s", physpath, pdev->si_name);
+	if (old_alias != NULL
+	 && strcmp(old_alias->si_name, devfspath) == 0) {
+		/* Retain the existing alias. */
+		*cdev = old_alias;
+		old_alias = NULL;
+		ret = 0;
+	} else {
+		ret = make_dev_alias_p(flags, cdev, pdev, devfspath);
+	}
+out:
+	if (old_alias != NULL)	
+		destroy_dev(old_alias);
+	if (devfspath != NULL)
+		free(devfspath, M_DEVBUF);
+	return (ret);
+}
+
 static void
 destroy_devl(struct cdev *dev)
 {

Modified: head/sys/sys/conf.h
==============================================================================
--- head/sys/sys/conf.h	Tue Jun 14 16:05:00 2011	(r223084)
+++ head/sys/sys/conf.h	Tue Jun 14 16:29:43 2011	(r223085)
@@ -280,6 +280,9 @@ struct cdev *make_dev_alias(struct cdev 
 		__printflike(2, 3);
 int	make_dev_alias_p(int _flags, struct cdev **_cdev, struct cdev *_pdev,
 		const char *_fmt, ...) __printflike(4, 5);
+int	make_dev_physpath_alias(int _flags, struct cdev **_cdev,
+	        struct cdev *_pdev, struct cdev *_old_alias,
+                const char *_physpath);
 void	dev_lock(void);
 void	dev_unlock(void);
 void	setconf(void);


More information about the svn-src-head mailing list