diff --git a/daemon/remote.c b/daemon/remote.c index e889ca4dd..df222c520 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1186,6 +1186,34 @@ do_flush_name(SSL* ssl, struct worker* worker, char* arg) send_ok(ssl); } +/** do the status command */ +static void +do_status(SSL* ssl, struct worker* worker) +{ + int i; + time_t uptime; + if(!ssl_printf(ssl, "version: %s\n", PACKAGE_VERSION)) + return; + if(!ssl_printf(ssl, "verbosity: %d\n", verbosity)) + return; + if(!ssl_printf(ssl, "threads: %d\n", worker->daemon->num)) + return; + if(!ssl_printf(ssl, "modules: %d [", worker->daemon->mods.num)) + return; + for(i=0; idaemon->mods.num; i++) { + if(!ssl_printf(ssl, " %s", worker->daemon->mods.mod[i]->name)) + return; + } + if(!ssl_printf(ssl, " ]\n")) + return; + uptime = (time_t)time(NULL) - (time_t)worker->daemon->time_boot.tv_sec; + if(!ssl_printf(ssl, "uptime: %u seconds\n", (unsigned)uptime)) + return; + if(!ssl_printf(ssl, "unbound (pid %d) is running...\n", + (int)getpid())) + return; +} + /** tell other processes to execute the command */ void distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd) @@ -1221,6 +1249,9 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd, } else if(strncmp(p, "stats", 5) == 0) { do_stats(ssl, rc); return; + } else if(strncmp(p, "status", 6) == 0) { + do_status(ssl, worker); + return; } else if(strncmp(p, "dump_cache", 10) == 0) { (void)dump_cache(ssl, worker); return; diff --git a/doc/Changelog b/doc/Changelog index 3b05bde5c..103aadb4c 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,5 +1,6 @@ 17 December 2008: Wouter - follows ldns makedist.sh. -rc option. autom4te dir removed. + - unbound-control status command. 16 December 2008: Wouter - follow makedist improvements from ldns, for maintainers prereleases. diff --git a/doc/unbound-control.8.in b/doc/unbound-control.8.in index 999453477..068abfb4a 100644 --- a/doc/unbound-control.8.in +++ b/doc/unbound-control.8.in @@ -61,6 +61,10 @@ Print statistics. Resets the internal counters to zero, this can be controlled using the \fBstatistics\-cumulative\fR config statement. Statistics are printed with one [name]: [value] per line. .TP +.B status +Display server status. Exit code 3 if not running (the connection to the +port is refused), 1 on error, 0 if running. +.TP .B local_zone \fIname\fR \fItype Add new local zone with name and type. Like \fBlocal\-zone\fR config statement. If the zone already exists, the type is changed to the given argument. diff --git a/services/localzone.h b/services/localzone.h index 742405c74..1652a95af 100644 --- a/services/localzone.h +++ b/services/localzone.h @@ -72,7 +72,6 @@ enum localzone_type { /** * Authoritative local zones storage, shared. - * This tree is fixed at startup, so, readonly, no locks or mutexes necessary. */ struct local_zones { /** lock on the localzone tree */ diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index 728667e3f..3d81fe398 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -62,6 +62,7 @@ usage() printf(" stop stops the server\n"); printf(" reload reloads the server\n"); printf(" stats print statistics\n"); + printf(" status display status of server\n"); printf(" verbosity [number] change logging detail\n"); printf(" local_zone [name] [type] add new local zone\n"); printf(" local_zone_remove [name] remove local zone and its contents\n"); @@ -124,7 +125,7 @@ setup_ctx(struct config_file* cfg) /** contact the server with TCP connect */ static int -contact_server(const char* svr, struct config_file* cfg) +contact_server(const char* svr, struct config_file* cfg, int statuscmd) { struct sockaddr_storage addr; socklen_t addrlen; @@ -163,8 +164,16 @@ contact_server(const char* svr, struct config_file* cfg) log_addr(0, "address", &addr, addrlen); #ifndef USE_WINSOCK log_err("connect: %s", strerror(errno)); + if(errno == ECONNREFUSED && statuscmd) { + printf("unbound is stopped\n"); + exit(3); + } #else log_err("connect: %s", wsa_strerror(WSAGetLastError())); + if(WSAGetLastError() == WSAECONNREFUSED && statuscmd) { + printf("unbound is stopped\n"); + exit(3); + } #endif exit(1); } @@ -278,7 +287,7 @@ go(const char* cfgfile, char* svr, int argc, char* argv[]) ctx = setup_ctx(cfg); /* contact server */ - fd = contact_server(svr, cfg); + fd = contact_server(svr, cfg, argc>0&&strcmp(argv[0],"status")==0); ssl = setup_ssl(ctx, fd); /* send command */