Date: Tue, 14 Jun 2011 16:29:44 +0000 (UTC) From: "Justin T. Gibbs" <gibbs@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r223085 - in head/sys: kern sys Message-ID: <201106141629.p5EGTiOp042709@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106141629.p5EGTiOp042709>