From 89c95d6baa127ddabf391d4c80a1239d3f8e8d77 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 3 Mar 2026 18:51:26 +0100 Subject: [PATCH] confd: relocate generation of mdns service records to C Simplify and consolidate generation of mdns service records from an external script to C. This reduces fork + exec and saves two seconds of boot time on single core Cortex-A7 systems. Signed-off-by: Joachim Wiberg --- src/confd/bin/Makefile.am | 2 +- src/confd/bin/gen-service | 46 ----------------------- src/confd/src/services.c | 77 +++++++++++++++++++++++++++++++++++---- 3 files changed, 70 insertions(+), 55 deletions(-) delete mode 100755 src/confd/bin/gen-service diff --git a/src/confd/bin/Makefile.am b/src/confd/bin/Makefile.am index 49bed009..69b28e5a 100644 --- a/src/confd/bin/Makefile.am +++ b/src/confd/bin/Makefile.am @@ -1,4 +1,4 @@ -pkglibexec_SCRIPTS = bootstrap error load gen-service gen-hostname \ +pkglibexec_SCRIPTS = bootstrap error load gen-hostname \ gen-interfaces gen-motd gen-hardware gen-version \ mstpd-wait-online wait-interface sbin_SCRIPTS = dagger migrate firewall diff --git a/src/confd/bin/gen-service b/src/confd/bin/gen-service deleted file mode 100755 index 6c233a08..00000000 --- a/src/confd/bin/gen-service +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# Very basic avahi .service generator, works for tcp (http) services -. /etc/os-release - -cmd=$1 -host=$2 -name=$3 -type=$4 -port=$5 -desc=$6 -shift 6 -file="/etc/avahi/services/$name.service" - -case $cmd in - delete) - rm -f "$file" - exit 0 - ;; - update) - if [ ! -f "$file" ]; then - exit 0 - fi - ;; - *) - ;; -esac - -cat <"$file" - - - - $desc - - $type - $port - vv=1 - vendor=$(jq -r .vendor /run/system.json) - product=$(jq -r '."product-name"' /run/system.json) - serial=$(jq -r '."serial-number"' /run/system.json) - deviceid=$(jq -r '."mac-address"' /run/system.json) - vn=$VENDOR_NAME - on=$NAME - ov=$VERSION_ID$(for txt in "$@"; do printf "\n %s" "$txt"; done) - - -EOF diff --git a/src/confd/src/services.c b/src/confd/src/services.c index 2ad72dfe..835983bf 100644 --- a/src/confd/src/services.c +++ b/src/confd/src/services.c @@ -19,9 +19,13 @@ #define GENERATE_ENUM(ENUM) ENUM, #define GENERATE_STRING(STRING) #STRING, +#define AVAHI_SVC_PATH "/etc/avahi/services" + #define LLDP_CONFIG "/etc/lldpd.d/confd.conf" #define LLDP_CONFIG_NEXT LLDP_CONFIG"+" +enum mdns_cmd { MDNS_ADD, MDNS_DELETE, MDNS_UPDATE }; + #define FOREACH_SVC(SVC) \ SVC(none) \ SVC(ssh) \ @@ -68,6 +72,13 @@ struct mdns_svc { { ssh, "ssh", "_ssh._tcp", 22, "Secure shell command line interface (CLI)", NULL }, }; +static const char *jgets(json_t *obj, const char *key) +{ + json_t *val = json_object_get(obj, key); + + return val ? json_string_value(val) : NULL; +} + /* * On hostname changes we need to update the mDNS records, in particular * the ones advertising an adminurl (standarized by Apple), because they @@ -77,27 +88,77 @@ struct mdns_svc { * adminurl to include 'admin@%s.local' to pre-populate the default * username in the login dialog. */ -static int mdns_records(const char *cmd, svc type) +static int mdns_records(int cmd, svc type) { char hostname[MAXHOSTNAMELEN + 1]; + const char *vendor, *product, *serial, *mac; + const char *vn, *on, *ov; if (gethostname(hostname, sizeof(hostname))) { ERRNO("failed getting system hostname"); return SR_ERR_SYS; } + vendor = jgets(confd.root, "vendor"); + product = jgets(confd.root, "product-name"); + serial = jgets(confd.root, "serial-number"); + mac = jgets(confd.root, "mac-address"); + + vn = fgetkey("/etc/os-release", "VENDOR_NAME"); + on = fgetkey("/etc/os-release", "NAME"); + ov = fgetkey("/etc/os-release", "VERSION_ID"); + for (size_t i = 0; i < NELEMS(services); i++) { struct mdns_svc *srv = &services[i]; - char buf[256] = ""; + FILE *fp; if (type != all && srv->svc != type) continue; - if (srv->text) - snprintf(buf, sizeof(buf), srv->text, hostname); + if (cmd == MDNS_DELETE) { + erasef(AVAHI_SVC_PATH "/%s.service", srv->name); + continue; + } - systemf("/usr/libexec/confd/gen-service %s %s %s %s %d \"%s\" %s", cmd, - hostname, srv->name, srv->type, srv->port, srv->desc, buf); + if (cmd == MDNS_UPDATE && !fexistf(AVAHI_SVC_PATH "/%s.service", srv->name)) + continue; + + fp = fopenf("w", AVAHI_SVC_PATH "/%s.service", srv->name); + if (!fp) { + ERRNO("failed creating %s.service", srv->name); + continue; + } + + fprintf(fp, + "\n" + "\n" + "\n" + " %s\n" + " \n" + " %s\n" + " %d\n" + " vv=1\n" + " vendor=%s\n" + " product=%s\n" + " serial=%s\n" + " deviceid=%s\n" + " vn=%s\n" + " on=%s\n" + " ov=%s\n", + srv->desc, srv->type, srv->port, + vendor ?: "", product ?: "", serial ?: "", mac ?: "", + vn ?: "", on ?: "", ov ?: ""); + + if (srv->text) { + fprintf(fp, " "); + fprintf(fp, srv->text, hostname); + fprintf(fp, "\n"); + } + + fprintf(fp, + " \n" + "\n"); + fclose(fp); } return SR_ERR_OK; @@ -182,7 +243,7 @@ static void svc_enadis(int ena, svc type, const char *svc) } if (type != none) - mdns_records(ena ? "add" : "delete", type); + mdns_records(ena ? MDNS_ADD : MDNS_DELETE, type); systemf("initctl -nbq touch avahi"); systemf("initctl -nbq touch nginx"); @@ -291,7 +352,7 @@ static int mdns_change(sr_session_ctx_t *session, struct lyd_node *config, struc mdns_conf(srv); /* Generate/update basic mDNS service records */ - mdns_records("update", all); + mdns_records(MDNS_UPDATE, all); } svc_enadis(ena, none, "avahi");