ref: 894718e16f690d6ae1d1f1061a8ad703947ea5d9
parent: 5ddcb59618def30c1e17a651b29c9722dca82df2
author: halfwit <michaelmisch1985@gmail.com>
date: Thu Oct 19 18:35:27 PDT 2023
monitor also can be a simple binary, make a lib function to free a svc
--- a/libservice/mkfile
+++ b/libservice/mkfile
@@ -6,6 +6,7 @@
svcdial.$O\
svcquery.$O\
svctimefmt.$O\
+ svcfree.$O\
HFILES=\
service.h
--- a/libservice/service.h
+++ b/libservice/service.h
@@ -30,3 +30,4 @@
int svctimefmt(Fmt *f);
int svcdial(char *netroot, char *authdom);
Service* svcquery(int fd, char *query, char **argv, int argc);
+void svcfree(Service *);
--- /dev/null
+++ b/libservice/svcfree.c
@@ -1,0 +1,14 @@
+#include <u.h>
+#include <libc.h>
+#include "service.h"
+
+void
+svcfree(Service *s)
+{
+ Service *sn;
+
+ for(; s; s = sn){
+ sn = s->next;
+ free(s);
+ }
+}
--- a/mkfile
+++ b/mkfile
@@ -5,7 +5,8 @@
drop\
publish\
query\
- svcfs
+ svcfs\
+ monitor
LIB=libservice/libservice.a$O
--- a/monitor
+++ /dev/null
@@ -1,51 +1,0 @@
-#!/bin/rc
-
-$argv0 = $0
-
-fn usage {
- echo 'Usage: '$argv0' [-o] [-s svcfs]' >[1=2]
- exits 'usage'
-}
-
-svcfs=()
-order=1
-while(~ $1 -*){
- switch($1){
- case -o; order=2
- case *
- ~ $#* 1 && usage
- switch($1){
- case -s; svcfs=(-s $2)
- case *; usage
- }
- shift
- }
- shift
-}
-
-! ~ $#* 0 && usage
-
-# TODO: Authdom goes in first line of tuple, consider that as well
-fn update {
- for(f in `{svc/query $svcfs . status ok grep service}){
- name=`{echo f | sed 's/.*service=//;s/ address=.*//'}
- address=`{echo f | sed 's/.*address=tcp!//;s/ .*//'}
- entry=$name^'/'^$address
- ~ $order 2 && entry=$address^'.'^$name
- test -f '/srv/'^$entry || srv $address $entry
- }
- for(f in `{svc/query $svcfs . status down | grep services}){
- name=`{echo f | sed 's/.*service=//;s/ address=.*//'}
- address=`{echo f | sed 's/.*address=tcp!//;s/ .*//'}
- entry='/srv/'^$name^'.'^$address
- ~ $order 2 && entry='/srv/'^$address^'.'^$name
- test -f $entry && rm $entry
- }
-}
-
-fn watch {
- while(1){
- update
- sleep 30 # Not the best way to watch for a service coming up. At worst it can take a full minute
- }
-}
--- /dev/null
+++ b/monitor.c
@@ -1,0 +1,130 @@
+#include <u.h>
+#include <libc.h>
+#include "libservice/service.h"
+
+void monitor(char *,int, int, int);
+void publish(Service *, char *);
+
+static void
+usage(void)
+{
+ fprint(2, "usage: %s [-o] [-r timeout] [-a authdom] [-s svcfs]\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ char *svcfs;
+ char *authdom;
+ int style, fd, pollrate;
+
+ svcfs = nil;
+ authdom = nil;
+ style = 1;
+ pollrate = 30;
+
+ ARGBEGIN{
+ case 's':
+ svcfs = EARGF(usage());
+ break;
+ case 'a':
+ authdom = EARGF(usage());
+ break;
+ case 'o':
+ style++;
+ break;
+ case 'r':
+ pollrate = atoi(EARGF(usage()));
+ break;
+ default:
+ usage();
+ }ARGEND
+ argv0 = "monitor";
+
+ if(argc > 0)
+ usage();
+ if((fd = svcdial(svcfs, authdom)) < 0){
+ fprint(2, "Unable to dial svcfs: %r\n");
+ exits("error");
+ }
+
+ if(authdom != nil){
+ monitor(authdom, fd, style, pollrate);
+ exits(0);
+ }
+ monitor("9front", fd, style, pollrate);
+ exits(0);
+
+}
+
+char *
+clean(char *addr)
+{
+ char *c;
+ if(strncmp(addr, "tcp!", 4) == 0)
+ addr += 4;
+ c = strchr(addr, '!');
+ if(c != nil)
+ *c='\0';
+ return addr ;
+}
+
+void
+monitor(char *authdom, int fd, int style, int rate)
+{
+ Service *svc, *s;
+ char srv[MAXADDR];
+ int i;
+
+ for(;;){
+ for(i=0; i < rate; i++)
+ sleep(1000);
+ svc = svcquery(fd, ".", nil, 0);
+ for(s = svc; s; s = s->next){
+ switch(style){
+ case 1:
+ sprint(srv, "/srv/%s.%s.%s", s->name, clean(s->address), authdom);
+ break;
+ case 2:
+ sprint(srv, "/srv/%s.%s.%s", authdom, clean(s->address), s->name);
+ break;
+ }
+ switch(s->status){
+ case Sok:
+ publish(s, srv);
+ break;
+ case Sdown:
+ remove(srv);
+ break;
+ case Sreg:
+ // No-op
+ break;
+ }
+ }
+ svcfree(svc);
+ }
+}
+
+void
+publish(Service *s, char *srv)
+{
+ char buf[128];
+ int f, fd;
+ char *dest;
+
+ /* TODO: stat first and bail before we double dial/create */
+
+ /* Dial */
+ dest = netmkaddr(s->address, 0, "9fs");
+ fd = dial(dest, 0, 0, 0);
+ if(fd < 0)
+ return;
+ f = create(srv, OWRITE, 0666);
+ if(f < 0)
+ return;
+ /* Publish fd from dial */
+ sprint(buf, "%d", fd);
+ write(f, buf, strlen(buf));
+ close(f);
+}
--- a/query.c
+++ b/query.c
@@ -33,11 +33,7 @@
if(s->next != nil)
print("\n");
}
- for(s = svcs; s;){
- svcs = s->next;
- free(s);
- s = svcs;
- }
+ svcfree(svcs);
}
void