mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2025-10-22 23:13:04 +02:00
gpiod-sysfs-proxy: new recipe
Many users are reluctant to use libgpiod instead of the deprecated /sys/class/gpio interface. The gpiod-sysfs-proxy project aims at making the transition easier by implementing a compatibility layer in user-space using FUSE and python3-gpiod. This way we can eat the cookie by disabling the sysfs ABI and have the users have it too by sticking to their existing scripts. The project itself is a very simple setuptools-based python package but the recipe is quite complex due to comprehensive distro integration. By default we use /run/gpio as mountpoint. For full backward compatibility with the kernel interface, the user must explicitly add the 'sys-class-mount' switch to PACKAGECONFIG. We do this because, depending on whether CONFIG_GPIO_SYSFS Kconfig option is enabled, /sys/class/gpio will either be non-empty or not exist at all. In the latter case, we need to somehow create the /sys/class/gpio and, since user-space is not allowed to mkdir() inside sysfs, we use overlayfs for that. As this is rather non-standard, we want the user to be aware of this. We support both systemd and sys V init managers. We also provide a ptest package which uses an external gpio-sysfs-compat-tests script. Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Signed-off-by: Khem Raj <raj.khem@gmail.com>
This commit is contained in:
parent
06eacb769a
commit
ae88d2ff59
|
@ -16,3 +16,7 @@ LAYERVERSION_filesystems-layer = "1"
|
|||
LAYERDEPENDS_filesystems-layer = "core openembedded-layer networking-layer"
|
||||
|
||||
LAYERSERIES_COMPAT_filesystems-layer = "styhead walnascar"
|
||||
|
||||
BBFILES_DYNAMIC += " \
|
||||
meta-python:${LAYERDIR}/dynamic-layers/meta-python/recipes-*/*/*.bb \
|
||||
"
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: gpiod-sysfs-proxy
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 1
|
||||
# Short-Description: User-space, libgpiod-based compatibility layer for linux GPIO sysfs interface.
|
||||
### END INIT INFO
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
# Debian init.d script for gpiod-sysfs-proxy
|
||||
# Copyright (c) 2024 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
||||
|
||||
# set -e
|
||||
|
||||
# Source function library.
|
||||
. /etc/init.d/functions
|
||||
|
||||
PROG="/usr/bin/gpiod-sysfs-proxy"
|
||||
NAME="gpiod-sysfs-proxy"
|
||||
DESC="/sys/class/gpio compatibility layer"
|
||||
MOUNTPOINT="@mountpoint@"
|
||||
|
||||
test -x $PROG || exit 0
|
||||
|
||||
do_start()
|
||||
{
|
||||
echo -n "Starting $DESC: "
|
||||
|
||||
if [ "$MOUNTPOINT" = "/sys/class/gpio" ] && [ ! -e /sys/class/gpio ]; then
|
||||
mkdir -p /run/gpio/sys /run/gpio/class/gpio /run/gpio/work
|
||||
mount -t sysfs sysfs /run/gpio/sys -o nosuid,nodev,noexec
|
||||
# Bail out if overlayfs is not available
|
||||
set -e
|
||||
mount -t overlay overlay /sys/class \
|
||||
-o upperdir=/run/gpio/class,lowerdir=/run/gpio/sys/class,workdir=/run/gpio/work,nosuid,nodev,noexec,relatime,ro
|
||||
set +e
|
||||
else
|
||||
mkdir -p $MOUNTPOINT
|
||||
fi
|
||||
|
||||
$PROG $MOUNTPOINT -o nonempty -o allow_other -o default_permissions -o entry_timeout=0 -f | logger -i $NAME &
|
||||
echo "done"
|
||||
}
|
||||
|
||||
do_stop()
|
||||
{
|
||||
echo -n "Stopping $DESC: "
|
||||
|
||||
umount $MOUNTPOINT
|
||||
|
||||
mountpoint -q /sys/class
|
||||
if [ "$?" = "0" ]; then
|
||||
umount /sys/class
|
||||
umount /run/gpio/sys
|
||||
rm -rf /run/gpio
|
||||
fi
|
||||
echo "done"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
do_start
|
||||
;;
|
||||
stop)
|
||||
do_stop
|
||||
;;
|
||||
status)
|
||||
status $PROG
|
||||
exit $?
|
||||
;;
|
||||
restart)
|
||||
do_stop
|
||||
sleep 1
|
||||
do_start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: /etc/init.d/$NAME {start|stop|status|restart}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,15 @@
|
|||
# SPDX-License-Identifier: CC0-1.0
|
||||
# SPDX-FileCopyrightText: 2024 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
||||
|
||||
[Unit]
|
||||
Description=User-space, libgpiod-based compatibility layer for linux GPIO sysfs interface
|
||||
|
||||
[Service]
|
||||
RuntimeDirectory=gpio
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/gpiod-sysfs-proxy @mountpoint@ -f -o nonempty -o allow_other -o default_permissions -o entry_timeout=0
|
||||
ExecStop=/bin/umount @mountpoint@
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,13 @@
|
|||
# SPDX-License-Identifier: CC0-1.0
|
||||
# SPDX-FileCopyrightText: 2024 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
||||
|
||||
[Unit]
|
||||
Description=Remount of sysfs for gpiod-sysfs-proxy
|
||||
ConditionPathExists=!/sys/class/gpio
|
||||
|
||||
[Mount]
|
||||
DirectoryMode=0700
|
||||
What=sysfs
|
||||
Where=/run/gpio/sys
|
||||
Type=sysfs
|
||||
Options=nosuid,nodev,noexec
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/sh
|
||||
|
||||
ptestdir=$(dirname "$(readlink -f "$0")")
|
||||
testbin="gpio-sysfs-compat-tests"
|
||||
|
||||
modprobe gpio-sim
|
||||
modprobe configfs
|
||||
|
||||
mountpoint -q /sys/kernel/config
|
||||
if [ "$?" -ne "0" ]; then
|
||||
mount -t configfs configfs /sys/kernel/config
|
||||
fi
|
||||
|
||||
cd $ptestdir/tests
|
||||
|
||||
./$testbin -v --gpio-class @mountpoint@ --chown-user gpio-test > ./$testbin.out 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "FAIL: $testbin"
|
||||
else
|
||||
echo "PASS: $testbin"
|
||||
fi
|
|
@ -0,0 +1,16 @@
|
|||
# SPDX-License-Identifier: CC0-1.0
|
||||
# SPDX-FileCopyrightText: 2024 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
||||
|
||||
[Unit]
|
||||
Description=Overlay on top of /sys/class adding the gpio class directory
|
||||
Before=gpiod-sysfs-proxy.service
|
||||
After=run-gpio-sys.mount
|
||||
ConditionPathExists=!/sys/class/gpio
|
||||
|
||||
[Mount]
|
||||
RuntimeDirectory=gpio/class/gpio
|
||||
DirectoryMode=0755
|
||||
What=overlay
|
||||
Where=/sys/class
|
||||
Type=overlay
|
||||
Options=upperdir=/run/gpio/class,lowerdir=/run/gpio/sys/class,workdir=/run/gpio/work,ro,nosuid,nodev,noexec,relatime
|
|
@ -0,0 +1,85 @@
|
|||
SUMMARY = "User-space, libgpiod-based compatibility layer for linux GPIO sysfs interface."
|
||||
|
||||
LICENSE = "MIT"
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=0dcf8b702b5c96178978c7223f64a73b"
|
||||
|
||||
inherit systemd update-rc.d ptest pypi python_pep517 python_setuptools_build_meta useradd
|
||||
|
||||
PYPI_PACKAGE = "gpiod_sysfs_proxy"
|
||||
|
||||
SRC_URI += " \
|
||||
file://gpiod-sysfs-proxy.service.in \
|
||||
file://run-gpio-sys.mount \
|
||||
file://sys-class.mount \
|
||||
file://gpiod-sysfs-proxy.init.in \
|
||||
file://run-ptest.in \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "c7830cb6a2c01914df2bc0549aef2dcfcb955520d400f65b3b50fb7a6f77f1b4"
|
||||
|
||||
# For full backward compatibility with the kernel sysfs interface, this option
|
||||
# must be selected. However, we don't make it the default as - with kernel sysfs
|
||||
# disabled - it plays a silly game with /sys/class, where it mounts a read-only
|
||||
# overlay containing the missing /sys/class/gpio directory. This is a rather
|
||||
# non-standard behavior so make sure the user actually wants it.
|
||||
PACKAGECONFIG[sys-class-mount] = ""
|
||||
|
||||
export MOUNTPOINT="${@bb.utils.contains('PACKAGECONFIG', 'sys-class-mount', '\/sys\/class\/gpio', '\/run\/gpio', d)}"
|
||||
|
||||
do_install:append() {
|
||||
if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
|
||||
install -d ${D}${systemd_system_unitdir}
|
||||
install -m 0644 ${UNPACKDIR}/gpiod-sysfs-proxy.service.in ${D}${systemd_system_unitdir}/gpiod-sysfs-proxy.service
|
||||
|
||||
if ${@bb.utils.contains('PACKAGECONFIG', 'sys-class-mount', 'true', 'false', d)}; then
|
||||
install -d ${D}${systemd_system_unitdir}/sysinit.target.wants/
|
||||
|
||||
install -m 0644 ${UNPACKDIR}/run-gpio-sys.mount ${D}${systemd_system_unitdir}/run-gpio-sys.mount
|
||||
install -m 0644 ${UNPACKDIR}/sys-class.mount ${D}${systemd_system_unitdir}/sys-class.mount
|
||||
|
||||
ln -sf ../run-gpio-sys.mount ${D}${systemd_system_unitdir}/sysinit.target.wants/run-gpio-sys.mount
|
||||
ln -sf ../sys-class.mount ${D}${systemd_system_unitdir}/sysinit.target.wants/sys-class.mount
|
||||
fi
|
||||
|
||||
sed -i "s/@mountpoint@/$MOUNTPOINT/g" ${D}${systemd_system_unitdir}/gpiod-sysfs-proxy.service
|
||||
elif ${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', 'true', 'false', d)}; then
|
||||
install -d ${D}${sysconfdir}/init.d
|
||||
install -m 0755 ${UNPACKDIR}/gpiod-sysfs-proxy.init.in ${D}${sysconfdir}/init.d/gpiod-sysfs-proxy
|
||||
sed -i "s/@mountpoint@/$MOUNTPOINT/g" ${D}${sysconfdir}/init.d/gpiod-sysfs-proxy
|
||||
fi
|
||||
}
|
||||
|
||||
SYSTEMD_SERVICE:${PN} = "gpiod-sysfs-proxy.service"
|
||||
SYSTEMD_AUTO_ENABLE = "enable"
|
||||
|
||||
INITSCRIPT_NAME = "gpiod-sysfs-proxy"
|
||||
INITSCRIPT_PARAMS = "start 20 2 3 4 5 . stop 20 0 1 6 ."
|
||||
|
||||
FILES:${PN} += "/usr/lib/systemd/system"
|
||||
|
||||
RDEPENDS:${PN} += " \
|
||||
python3-fuse \
|
||||
python3-gpiod \
|
||||
python3-pyudev \
|
||||
"
|
||||
|
||||
python __anonymous() {
|
||||
if d.getVar("PTEST_ENABLED") == "1":
|
||||
d.appendVar("SRC_URI", "git://github.com/brgl/gpio-sysfs-compat-tests;protocol=https;branch=main;destsuffix=tests;name=tests")
|
||||
d.setVar("SRCREV_tests", "a3c9daa4650dd1e8d7fd8972db68d9c2c204263d")
|
||||
}
|
||||
|
||||
do_install_ptest() {
|
||||
install -d ${D}${PTEST_PATH}/tests/
|
||||
install -m 0755 ${UNPACKDIR}/run-ptest.in ${D}${PTEST_PATH}/run-ptest
|
||||
sed -i "s/@mountpoint@/$MOUNTPOINT/g" ${D}${PTEST_PATH}/run-ptest
|
||||
install -m 0755 ${UNPACKDIR}/tests/gpio-sysfs-compat-tests ${D}${PTEST_PATH}/tests/gpio-sysfs-compat-tests
|
||||
}
|
||||
|
||||
# Test user is created for verifying chown() and chmod() operations.
|
||||
USERADD_PACKAGES = "${PN}-ptest"
|
||||
GROUPADD_PARAM:${PN}-ptest = "--system gpio-test"
|
||||
USERADD_PARAM:${PN}-ptest = "--system -M -s /bin/nologin -g gpio-test gpio-test"
|
||||
|
||||
RDEPENDS:${PN}-ptest += "kmod"
|
||||
RRECOMMENDS:${PN}-ptest += "kernel-module-gpio-sim kernel-module-configfs"
|
Loading…
Reference in New Issue
Block a user