svn commit: r271350 - head/sys/dev/nmdm

Peter Grehan grehan at FreeBSD.org
Wed Sep 10 05:44:16 UTC 2014


Author: grehan
Date: Wed Sep 10 05:44:15 2014
New Revision: 271350
URL: http://svnweb.freebsd.org/changeset/base/271350

Log:
  Fix issue with nmdm and leading zeros in device name.
  
  The nmdm code enforces a number between the 'nmdm' and 'A|B' portions
  of the device name. This is then used as a unit number, and sprintf'd
  back into the tty name. If leading zeros were used in the name,
  the created device name is different than the string used for the
  clone-open (e.g. /dev/nmdm0001A will result in /dev/nmdm1A).
  
  Since unit numbers are no longer required with the updated tty
  code, there seems to be no reason to force the string to be a
  number. The fix is to allow an arbitrary string between
  'nmdm' and 'A|B', within the constraints of devfs names. This allows
  all existing user of numeric strings to continue to work, and also
  allows more meaningful names to be used, such as bhyve VM names.
  
  Tested on amd64, i386 and ppc64.
  
  Reported by:	Dave Smith
  PR:		192281
  Reviewed by:	neel, glebius
  Phabric:	D729
  MFC after:	3 days

Modified:
  head/sys/dev/nmdm/nmdm.c

Modified: head/sys/dev/nmdm/nmdm.c
==============================================================================
--- head/sys/dev/nmdm/nmdm.c	Wed Sep 10 03:54:57 2014	(r271349)
+++ head/sys/dev/nmdm/nmdm.c	Wed Sep 10 05:44:15 2014	(r271350)
@@ -157,21 +157,21 @@ nmdm_clone(void *arg, struct ucred *cred
 {
 	struct nmdmsoftc *ns;
 	struct tty *tp;
-	unsigned long unit;
 	char *end;
 	int error;
+	char endc;
 
 	if (*dev != NULL)
 		return;
 	if (strncmp(name, "nmdm", 4) != 0)
 		return;
-
-	/* Device name must be "nmdm%lu%c", where %c is 'A' or 'B'. */
-	name += 4;
-	unit = strtoul(name, &end, 10);
-	if (unit == ULONG_MAX || name == end)
+	if (strlen(name) <= strlen("nmdmX"))
 		return;
-	if ((end[0] != 'A' && end[0] != 'B') || end[1] != '\0')
+
+	/* Device name must be "nmdm%s%c", where %c is 'A' or 'B'. */
+	end = name + strlen(name) - 1;
+	endc = *end;
+	if (endc != 'A' && endc != 'B')
 		return;
 
 	ns = malloc(sizeof(*ns), M_NMDM, M_WAITOK | M_ZERO);
@@ -191,9 +191,11 @@ nmdm_clone(void *arg, struct ucred *cred
 	/* Create device nodes. */
 	tp = ns->ns_part1.np_tty = tty_alloc_mutex(&nmdm_class, &ns->ns_part1,
 	    &ns->ns_mtx);
-	error = tty_makedevf(tp, NULL, end[0] == 'A' ? TTYMK_CLONING : 0,
-	    "nmdm%luA", unit);
+	*end = 'A';
+	error = tty_makedevf(tp, NULL, endc == 'A' ? TTYMK_CLONING : 0,
+	    "%s", name);
 	if (error) {
+		*end = endc;
 		mtx_destroy(&ns->ns_mtx);
 		free(ns, M_NMDM);
 		return;
@@ -201,9 +203,11 @@ nmdm_clone(void *arg, struct ucred *cred
 
 	tp = ns->ns_part2.np_tty = tty_alloc_mutex(&nmdm_class, &ns->ns_part2,
 	    &ns->ns_mtx);
-	error = tty_makedevf(tp, NULL, end[0] == 'B' ? TTYMK_CLONING : 0,
-	    "nmdm%luB", unit);
+	*end = 'B';
+	error = tty_makedevf(tp, NULL, endc == 'B' ? TTYMK_CLONING : 0,
+	    "%s", name);
 	if (error) {
+		*end = endc;
 		mtx_lock(&ns->ns_mtx);
 		/* see nmdm_free() */
 		ns->ns_part1.np_other = NULL;
@@ -212,11 +216,12 @@ nmdm_clone(void *arg, struct ucred *cred
 		return;
 	}
 
-	if (end[0] == 'A')
+	if (endc == 'A')
 		*dev = ns->ns_part1.np_tty->t_dev;
 	else
 		*dev = ns->ns_part2.np_tty->t_dev;
 
+	*end = endc;
 	atomic_add_int(&nmdm_count, 1);
 }
 


More information about the svn-src-all mailing list