execd: add support for SNN and KNN queue scripts

This change makes sure execd calls KNN style scripts before SNN,
allowing confd to post teardown jobs that are guaranteed to run
before any jobs to create new resources run.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2024-06-25 19:08:22 +02:00
parent 56a5388242
commit 0edc2d5b70
+57 -16
View File
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: ISC */ /* SPDX-License-Identifier: ISC */
#include <ctype.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <getopt.h> #include <getopt.h>
@@ -31,7 +32,7 @@ static int logmask = LOG_UPTO(LOG_NOTICE);
static char buffer[BUFSIZ]; static char buffer[BUFSIZ];
static char *done; static char *done;
static void run_job(char *path, char *file) static void run_job(const char *path, char *file, int archive)
{ {
char cmd[strlen(path) + strlen(file) + 2]; char cmd[strlen(path) + strlen(file) + 2];
int rc; int rc;
@@ -57,32 +58,67 @@ static void run_job(char *path, char *file)
} }
dbg("job %s in %s done", file, path); dbg("job %s in %s done", file, path);
if (done) if (done && archive)
movefile(cmd, done); movefile(cmd, done);
else else
erase(cmd); erase(cmd);
} }
static void run_queue(char *path) /*
* Allow SNN and KNN style jobs, for inotyify_cb() we also allow
* a type '*' just to figure out if a job should be archived in
* the done directory.
*/
static int check(const char *name, int type, int *archive)
{ {
struct dirent *d; if (!name || strlen(name) < 3)
DIR *dir; return -1;
dir = opendir(path); if (isdigit(name[1]) && isdigit(name[2])) {
if (!dir) { if (type == '*')
err("opendir"); type = name[0];
switch (type) {
case 'K':
*archive = 0;
return 0;
case 'S':
*archive = 1;
return 0;
default:
break;
}
}
return 1;
}
static void run_dir(const char *path, int type)
{
struct dirent **namelist;
int archive = 0;
int n, i;
n = scandir(path, &namelist, NULL, alphasort);
if (n < 0) {
err("scandir %s", path);
return; return;
} }
while ((d = readdir(dir))) { for (i = 0; i < n; i++) {
dbg("Running queue %s entry %s", path, d->d_name); if (!check(namelist[i]->d_name, type, &archive))
if (d->d_name[0] == '.') run_job(path, namelist[i]->d_name, archive);
continue;
run_job(path, d->d_name); free(namelist[i]);
} }
closedir(dir); free(namelist);
}
static void run_queue(char *path)
{
run_dir(path, 'K');
run_dir(path, 'S');
} }
static void signal_cb(uev_t *w, void *arg, int _) static void signal_cb(uev_t *w, void *arg, int _)
@@ -113,10 +149,15 @@ static void inotify_cb(uev_t *w, void *arg, int _)
for (char *p = buffer; p < buffer + bytes;) { for (char *p = buffer; p < buffer + bytes;) {
struct inotify_event *event = (struct inotify_event *)p; struct inotify_event *event = (struct inotify_event *)p;
char *name = event->name;
int archive;
if (event->mask & (IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVED_TO)) { if (event->mask & (IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVED_TO)) {
dbg("Got inotify event %s 0x%04x", event->name, event->mask); dbg("Got inotify event %s 0x%04x", name, event->mask);
run_job(arg, event->name); if (check(name, '*', &archive))
continue;
run_job(arg, name, archive);
} }
p += sizeof(struct inotify_event) + event->len; p += sizeof(struct inotify_event) + event->len;