Skip to content

Commit 8ef4376

Browse files
committed
confd: replace initctl shell-outs with direct finit_ C API
Add a finit_enable/disable/reload() family in core.c that directly manipulates Finit's service state without fork+exec overhead: finit_enable(svc) -- create symlink in /etc/finit.d/enabled/ finit_disable(svc) -- remove symlink from /etc/finit.d/enabled/ finit_delete(svc) -- remove both symlink and service entirely finit_reload(svc) -- utimensat() on .conf to schedule reload Printf-style variants (finit_enablef/disablef/reloadf) handle template instance names such as container@foo and hostapd@wlan0. All systemf("initctl ... enable/disable/touch ...") call sites across containers, dhcp-server, firewall, hardware, ntp, routing, services, syslog, and system are converted to the new API. As a related cleanup in services.c, drop the remaining srx_enabled() calls in favour of reading the already-fetched config tree directly via lydx_is_enabled(lydx_get_xpathf(config, ...)), eliminating the last sysrepo round-trips from that module. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
1 parent dff40a7 commit 8ef4376

13 files changed

Lines changed: 180 additions & 48 deletions

File tree

src/confd/src/containers.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,9 @@ static int add(const char *name, struct lyd_node *cif)
322322
fchmod(fileno(fp), 0700);
323323
fclose(fp);
324324

325-
systemf("initctl -bnq touch container@%s.conf", name);
326-
systemf("initctl -bnq %s container@%s.conf", lydx_is_enabled(cif, "enabled")
327-
? "enable" : "disable", name);
325+
finit_reloadf("container@%s", name);
326+
lydx_is_enabled(cif, "enabled") ? finit_enablef("container@%s", name)
327+
: finit_disablef("container@%s", name);
328328

329329
return 0;
330330
}
@@ -341,7 +341,7 @@ static int del(const char *name)
341341
FILE *pp;
342342

343343
erasef("%s/%s.sh", _PATH_CONT, name);
344-
systemf("initctl -bnq disable container@%s.conf", name);
344+
finit_disablef("container@%s", name);
345345

346346
/* Schedule a cleanup job for this container as soon as it has stopped */
347347
snprintf(prune_dir, sizeof(prune_dir), "%s/%s", _PATH_CLEAN, name);

src/confd/src/core.c

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,120 @@
99

1010
struct confd confd;
1111

12+
/*
13+
* Touch a Finit service .conf file to schedule a synchronized reload.
14+
* Equivalent to 'initctl touch <svc>' but without the fork+exec overhead.
15+
* The service name should be given without the .conf suffix.
16+
*/
17+
int finit_reload(const char *svc)
18+
{
19+
char path[256];
20+
21+
/* Prefer the enabled/ symlink -- that's what Finit watches */
22+
snprintf(path, sizeof(path), FINIT_RCSD "/enabled/%s.conf", svc);
23+
if (!utimensat(AT_FDCWD, path, NULL, AT_SYMLINK_NOFOLLOW))
24+
return 0;
25+
26+
snprintf(path, sizeof(path), FINIT_RCSD "/available/%s.conf", svc);
27+
if (!utimensat(AT_FDCWD, path, NULL, AT_SYMLINK_NOFOLLOW))
28+
return 0;
29+
30+
ERRNO("failed marking %s for reload", svc);
31+
return -1;
32+
}
33+
34+
int finit_reloadf(const char *fmt, ...)
35+
{
36+
char svc[64];
37+
va_list ap;
38+
39+
va_start(ap, fmt);
40+
vsnprintf(svc, sizeof(svc), fmt, ap);
41+
va_end(ap);
42+
43+
return finit_reload(svc);
44+
}
45+
46+
int finit_enable(const char *svc)
47+
{
48+
char src[256], dst[256];
49+
50+
snprintf(src, sizeof(src), FINIT_RCSD "/available/%s.conf", svc);
51+
snprintf(dst, sizeof(dst), FINIT_RCSD "/enabled/%s.conf", svc);
52+
if (symlink(src, dst) && errno != EEXIST) {
53+
ERRNO("failed enabling %s", svc);
54+
return -1;
55+
}
56+
return 0;
57+
}
58+
59+
int finit_disable(const char *svc)
60+
{
61+
char path[256];
62+
63+
snprintf(path, sizeof(path), FINIT_RCSD "/enabled/%s.conf", svc);
64+
if (remove(path) && errno != ENOENT) {
65+
ERRNO("failed disabling %s", svc);
66+
return -1;
67+
}
68+
return 0;
69+
}
70+
71+
int finit_delete(const char *svc)
72+
{
73+
char path[256];
74+
75+
snprintf(path, sizeof(path), FINIT_RCSD "/enabled/%s.conf", svc);
76+
if (remove(path) && errno != ENOENT) {
77+
ERRNO("failed removing enabled symlink for %s", svc);
78+
return -1;
79+
}
80+
81+
snprintf(path, sizeof(path), FINIT_RCSD "/available/%s.conf", svc);
82+
if (remove(path) && errno != ENOENT) {
83+
ERRNO("failed removing available conf for %s", svc);
84+
return -1;
85+
}
86+
87+
return 0;
88+
}
89+
90+
int finit_deletef(const char *fmt, ...)
91+
{
92+
char svc[64];
93+
va_list ap;
94+
95+
va_start(ap, fmt);
96+
vsnprintf(svc, sizeof(svc), fmt, ap);
97+
va_end(ap);
98+
99+
return finit_delete(svc);
100+
}
101+
102+
int finit_enablef(const char *fmt, ...)
103+
{
104+
char svc[64];
105+
va_list ap;
106+
107+
va_start(ap, fmt);
108+
vsnprintf(svc, sizeof(svc), fmt, ap);
109+
va_end(ap);
110+
111+
return finit_enable(svc);
112+
}
113+
114+
int finit_disablef(const char *fmt, ...)
115+
{
116+
char svc[64];
117+
va_list ap;
118+
119+
va_start(ap, fmt);
120+
vsnprintf(svc, sizeof(svc), fmt, ap);
121+
va_end(ap);
122+
123+
return finit_disable(svc);
124+
}
125+
12126

13127
static int startup_save(sr_session_ctx_t *session, uint32_t sub_id, const char *model,
14128
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
@@ -433,7 +547,7 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
433547
client = srx_enabled(session, "/ietf-system:system/ntp/enabled");
434548
server = lydx_get_xpathf(config, "/ietf-ntp:ntp") != NULL;
435549

436-
systemf("initctl -nbq %s chronyd", client || server ? "enable" : "disable");
550+
(client || server) ? finit_enable("chronyd") : finit_disable("chronyd");
437551
}
438552

439553
if (cfg)

src/confd/src/core.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
#define CONFD_CORE_H_
55

66
#include <errno.h>
7+
#include <fcntl.h>
8+
#include <stdarg.h>
79
#include <stdio.h>
810
#include <syslog.h>
911
#include <stdlib.h>
1012
#include <string.h>
1113
#include <time.h>
14+
#include <sys/stat.h>
1215
#include <sys/time.h>
1316
#include <sys/param.h>
1417
#include <unistd.h>
@@ -31,6 +34,8 @@
3134

3235
#include "dagger.h"
3336

37+
#define FINIT_RCSD "/etc/finit.d"
38+
3439
#define SSH_HOSTKEYS "/etc/ssh/hostkeys"
3540
#define SSH_HOSTKEYS_NEXT SSH_HOSTKEYS"+"
3641
#define SSL_CERT_DIR "/etc/ssl/certs"
@@ -188,6 +193,16 @@ static inline int register_rpc(sr_session_ctx_t *session, const char *xpath,
188193
}
189194

190195

196+
/* core.c */
197+
int finit_enable(const char *svc);
198+
int finit_disable(const char *svc);
199+
int finit_delete(const char *svc);
200+
int finit_reload(const char *svc);
201+
int finit_enablef(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
202+
int finit_disablef(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
203+
int finit_deletef(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
204+
int finit_reloadf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
205+
191206
/* interfaces.c */
192207
int interfaces_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
193208
int interfaces_cand_init(struct confd *confd);

src/confd/src/dhcp-client.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static void add(const char *ifname, struct lyd_node *cfg)
9999
const char *metric = lydx_get_cattr(cfg, "route-preference");
100100
const char *client_id = lydx_get_cattr(cfg, "client-id");
101101
char *cid = NULL, *options = NULL;
102-
const char *action = "disable";
102+
int ena = 0;
103103
const char *vendor_class;
104104
char vendor[128] = { 0 };
105105
char do_arp[20] = { 0 };
@@ -153,9 +153,10 @@ static void add(const char *ifname, struct lyd_node *cfg)
153153
options ? "-o " : "", options,
154154
ifname, cid ?: "", vendor, ifname);
155155
fclose(fp);
156-
action = "enable";
156+
ena = 1;
157157
err:
158-
systemf("initctl -bfqn %s dhcp-client-%s", action, ifname);
158+
ena ? finit_enablef("dhcp-client-%s", ifname)
159+
: finit_disablef("dhcp-client-%s", ifname);
159160
if (options)
160161
free(options);
161162
if (cid)
@@ -164,7 +165,7 @@ static void add(const char *ifname, struct lyd_node *cfg)
164165

165166
static void del(const char *ifname)
166167
{
167-
systemf("initctl -bfq delete dhcp-client-%s", ifname);
168+
finit_deletef("dhcp-client-%s", ifname);
168169
}
169170

170171
int dhcp_client_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff,

src/confd/src/dhcp-server.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ int dhcp_server_change(sr_session_ctx_t *session, struct lyd_node *config, struc
377377

378378
err_done:
379379
if (added || deleted)
380-
system("initctl -nbq touch dnsmasq");
380+
finit_reload("dnsmasq");
381381

382382
return err;
383383
}

src/confd/src/dhcpv6-client.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static void add_v6(const char *ifname, struct lyd_node *cfg)
8080
const char *metric = lydx_get_cattr(cfg, "route-preference");
8181
const char *duid = lydx_get_cattr(cfg, "duid");
8282
char *client_duid = NULL, *options = NULL;
83-
const char *action = "disable";
83+
int ena = 0;
8484
const char *addr_mode = "-N try"; /* Default: stateful mode */
8585
char prefix_del[16] = { 0 };
8686
bool request_pd = false;
@@ -127,9 +127,10 @@ static void add_v6(const char *ifname, struct lyd_node *cfg)
127127
options ?: "", client_duid ?: "",
128128
ifname, ifname);
129129
fclose(fp);
130-
action = "enable";
130+
ena = 1;
131131
err:
132-
systemf("initctl -bfqn %s dhcpv6-client-%s", action, ifname);
132+
ena ? finit_enablef("dhcpv6-client-%s", ifname)
133+
: finit_disablef("dhcpv6-client-%s", ifname);
133134
if (options)
134135
free(options);
135136
if (client_duid)
@@ -138,7 +139,7 @@ static void add_v6(const char *ifname, struct lyd_node *cfg)
138139

139140
static void del_v6(const char *ifname)
140141
{
141-
systemf("initctl -bfq delete dhcpv6-client-%s", ifname);
142+
finit_deletef("dhcpv6-client-%s", ifname);
142143
}
143144

144145
int dhcpv6_client_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff,

src/confd/src/firewall.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ int firewall_change(sr_session_ctx_t *session, struct lyd_node *config, struct l
510510
case SR_EV_DONE:
511511
if (!fisdir(FIREWALLD_DIR_NEXT)) {
512512
/* Firewall is disabled */
513-
systemf("initctl -nbq disable firewalld");
513+
finit_disable("firewalld");
514514
return SR_ERR_OK;
515515
}
516516

@@ -521,8 +521,8 @@ int firewall_change(sr_session_ctx_t *session, struct lyd_node *config, struct l
521521
return SR_ERR_SYS;
522522
}
523523

524-
systemf("initctl -nbq touch firewalld");
525-
systemf("initctl -nbq enable firewalld");
524+
finit_reload("firewalld");
525+
finit_enable("firewalld");
526526
return SR_ERR_OK;
527527

528528
default:

src/confd/src/hardware.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -685,14 +685,14 @@ int hardware_change(sr_session_ctx_t *session, struct lyd_node *config, struct l
685685
ap_interfaces++;
686686

687687
if (running)
688-
systemf("initctl -bfq touch hostapd@%s", name);
688+
finit_reloadf("hostapd@%s", name);
689689
else
690-
systemf("initctl -bfq enable hostapd@%s", name);
690+
finit_enablef("hostapd@%s", name);
691691
}
692692
}
693693
}
694694
if (!ap_interfaces) {
695-
systemf("initctl -bfq disable hostapd@%s", name);
695+
finit_disablef("hostapd@%s", name);
696696
erasef(HOSTAPD_CONF, name);
697697
erasef(HOSTAPD_CONF_NEXT, name);
698698
}
@@ -784,10 +784,10 @@ int hardware_change(sr_session_ctx_t *session, struct lyd_node *config, struct l
784784
if (fexist(GPSD_CONF_NEXT)) {
785785
unlink(GPSD_CONF);
786786
rename(GPSD_CONF_NEXT, GPSD_CONF);
787-
systemf("initctl -nbq enable gpsd");
787+
finit_enable("gpsd");
788788
} else {
789789
unlink(GPSD_CONF);
790-
systemf("initctl -nbq disable gpsd");
790+
finit_disable("gpsd");
791791
}
792792
break;
793793
}

src/confd/src/ntp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static int change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd
4848
if (systemf("chronyc reload sources >/dev/null 2>&1"))
4949
ERRNO("Failed reloading chronyd sources");
5050

51-
systemf("initctl -nbq touch chronyd");
51+
finit_reload("chronyd");
5252
return SR_ERR_OK;
5353

5454
default:

src/confd/src/routing.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -605,17 +605,17 @@ int routing_change(sr_session_ctx_t *session, struct lyd_node *config, struct ly
605605

606606
/* Enable/disable FRR daemons as standalone finit services.
607607
* Harmless no-op when using watchfrr (services not installed). */
608-
systemf("initctl -nbq %s ospfd", ospfd_enabled ? "enable" : "disable");
608+
ospfd_enabled ? finit_enable("ospfd") : finit_disable("ospfd");
609609
if (ospfd_enabled)
610-
systemf("initctl -nbq touch ospfd");
611-
systemf("initctl -nbq %s ripd", ripd_enabled ? "enable" : "disable");
612-
systemf("initctl -nbq %s bfdd", bfdd_enabled ? "enable" : "disable");
610+
finit_reload("ospfd");
611+
ripd_enabled ? finit_enable("ripd") : finit_disable("ripd");
612+
bfdd_enabled ? finit_enable("bfdd") : finit_disable("bfdd");
613613

614614
/*
615615
* Signal netd to reload - it assembles /etc/frr/frr.conf and
616616
* Finit propagates the restart to the frr sysv service
617617
*/
618-
if (systemf("initctl -bfq touch netd"))
618+
if (finit_reload("netd"))
619619
ERROR("Failed to signal netd for reload");
620620

621621
return rc;

0 commit comments

Comments
 (0)