Module Name:    src
Committed By:   thorpej
Date:           Sat Mar 30 06:29:01 UTC 2024

Modified Files:
        src/distrib/sets/lists/base: mi
Added Files:
        src/share/examples/devpubd/hooks: 99-ucom-symlinks Makefile

Log Message:
Add an example devpubd hook that makes stable path names, using symlinks,
for USB serial interfaces, regardless of where the interface is connected
or the order of enumeration.  This requires the USB device to have a
"serialnumber" to function.  Examples:

- uftdi serial adapter with two ports:

        /dev/tty-uftdi-FT64S4YP-1 -> /dev/ttyU0
        /dev/tty-uftdi-FT64S4YP-2 -> /dev/ttyU1

- uslsa serial adapter:

        /dev/tty-uslsa-01E7ABCC -> /dev/ttyU4

This allows something like the following in /etc/remote:

sun3:dv=/dev/tty-uftdi-FT64S4YP-1:br#9600:pa=none:dc:

That path will always be stable regardless of which /dev/ttyU* node is
actually assigned when the serial adapter is plugged in.


To generate a diff of this commit:
cvs rdiff -u -r1.1335 -r1.1336 src/distrib/sets/lists/base/mi
cvs rdiff -u -r0 -r1.1 src/share/examples/devpubd/hooks/99-ucom-symlinks \
    src/share/examples/devpubd/hooks/Makefile

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/base/mi
diff -u src/distrib/sets/lists/base/mi:1.1335 src/distrib/sets/lists/base/mi:1.1336
--- src/distrib/sets/lists/base/mi:1.1335	Sat Mar 30 06:11:59 2024
+++ src/distrib/sets/lists/base/mi	Sat Mar 30 06:29:01 2024
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1335 2024/03/30 06:11:59 thorpej Exp $
+# $NetBSD: mi,v 1.1336 2024/03/30 06:29:01 thorpej Exp $
 #
 # Note:	Don't delete entries from here - mark them as "obsolete" instead,
 #	unless otherwise stated below.
@@ -2487,6 +2487,7 @@
 ./usr/share/examples/certctl/certs.conf		base-sysutil-examples
 ./usr/share/examples/devpubd			base-sys-examples
 ./usr/share/examples/devpubd/hooks		base-sys-examples
+./usr/share/examples/devpubd/hooks/99-ucom-symlinks	base-sys-examples
 ./usr/share/examples/dhcp			base-dhcpd-examples
 ./usr/share/examples/dhcpcd			base-dhcpcd-examples
 ./usr/share/examples/dhcpcd/hooks		base-dhcpcd-examples

Added files:

Index: src/share/examples/devpubd/hooks/99-ucom-symlinks
diff -u /dev/null src/share/examples/devpubd/hooks/99-ucom-symlinks:1.1
--- /dev/null	Sat Mar 30 06:29:01 2024
+++ src/share/examples/devpubd/hooks/99-ucom-symlinks	Sat Mar 30 06:29:01 2024
@@ -0,0 +1,134 @@
+#!/bin/sh -
+#
+# $NetBSD: 99-ucom-symlinks,v 1.1 2024/03/30 06:29:01 thorpej Exp $
+#
+# Attempt to create stable names (using symbolic links) to USB serial
+# devices, regardless of device enumeration order, suitable for use in
+# configuration files.  The format of the stable names is:
+#
+#	/dev/{cdt}ty-$driver-$serialnumber-$portnumber
+# - or -
+#	/dev/{cdt}ty-$driver-$serialnumber
+#
+# depending on whether or not the device is a multi-port adapter.
+#
+# e.g.
+#
+#	/dev/tty-uftdi-FT64S4YP-1 -> /dev/ttyU0
+#
+#	/dev/tty-uslsa-01E7ABCC -> /dev/ttyU4
+#
+# If $driver or $serialnumber cannot be determined, then no symbolic link
+# will be created.
+#
+# Written by Jason R. Thorpe, December 2022.  Public domain.
+#
+
+export LC_ALL=C
+
+event="$1"
+shift
+devices=$@
+
+symlink_name()
+{
+	local parent
+	local portnum
+	local serialnum
+	local driver
+
+	parent=$(drvctl -p $1 device-parent)
+	if [ x"$parent" != x ]; then
+		driver=$(drvctl -p $parent device-driver)
+		serialnum=$(drvctl -p $parent serialnumber)
+	fi
+
+	# If the device is a single-port device, it may have the default
+	# port number locator of '-1'.  In that case, elide the port
+	# number.
+	portnum=$(drvctl -p $1 port)
+	if [ x"$portnum" = x"-1" -o x"$portnum" = x ]; then
+		portnum=""
+	else
+		portnum="-${portnum}"
+	fi
+
+	if [ x"$driver" != x -a x"$serialnum" != x ]; then
+		echo "${driver}-${serialnum}${portnum}"
+	else
+		echo ""
+	fi
+}
+
+remove_ucom_symlink()
+{
+	local name
+	local unit
+
+	name=$(readlink "/dev/${1}")
+
+	if [ x"$name" != x ]; then
+		rm -f "/dev/tty-${name}"
+		rm -f "/dev/dty-${name}"
+		rm -f "/dev/cty-${name}"
+		rm -f "/dev/${1}"
+	fi
+}
+
+add_ucom_symlink()
+{
+	local name
+	local tty_path
+	local dty_path
+	local cty_path
+
+	name=$(symlink_name $1)
+	unit=$(drvctl -p $1 device-unit)
+
+	if [ x"$name" != x -a x"$unit" != x ]; then
+		#
+		# We need to make two sets of symlinks:
+		#
+		# /dev/tty-uslsa-01E7ABCC -> /dev/ttyU4
+		#
+		# /dev/ucom4 -> uslsa-01E7ABCC
+		#
+		# This is needed because when we get the detach event
+		# for e.g. ucom4, the parent device (e.g. uslsa0) may
+		# already be gone, meaning we cannot query it.  So
+		# what we're doing is stashing the information in the
+		# second symlink so we can readlink(1) it later to
+		# recover the stable name.
+		#
+
+		tty_path="/dev/ttyU${unit}"
+		dty_path="/dev/dtyU${unit}"
+		cty_path="/dev/ctyU${unit}"
+
+		ln -sf "${name}" "/dev/${1}"
+		if [ -c ${tty_path} ]; then
+			ln -sf ${tty_path} "/dev/tty-${name}"
+		fi
+		if [ -c ${dty_path} ]; then
+			ln -sf ${dty_path} "/dev/dty-${name}"
+		fi
+		if [ -c ${cty_path} ]; then
+			ln -sf ${cty_path} "/dev/cty-${name}"
+		fi
+	fi
+}
+
+for device in $devices; do
+	case $device in
+	ucom*)
+		case $event in
+		device-attach)
+			remove_ucom_symlink $device
+			add_ucom_symlink $device
+			;;
+		device-detach)
+			remove_ucom_symlink $device
+			;;
+		esac
+	esac
+done
Index: src/share/examples/devpubd/hooks/Makefile
diff -u /dev/null src/share/examples/devpubd/hooks/Makefile:1.1
--- /dev/null	Sat Mar 30 06:29:01 2024
+++ src/share/examples/devpubd/hooks/Makefile	Sat Mar 30 06:29:01 2024
@@ -0,0 +1,12 @@
+#	$NetBSD: Makefile,v 1.1 2024/03/30 06:29:01 thorpej Exp $
+
+NOOBJ=	# defined
+
+.include <bsd.own.mk>
+
+.if ${MKSHARE} != "no"
+FILES=	99-ucom-symlinks
+FILESDIR=/usr/share/examples/devpubd/hooks
+.endif
+
+.include <bsd.prog.mk>

Reply via email to