This commit introduces the -t switch for originator table output. It makes use of the new last-seen field in batman-adv, the user can specify a timeout interval in seconds (with 3 digits precision before and after a possible dot) if he/she considers a node as dead after this time. (of course this is just influencing the displaying and not actually declearing a node as dead for routing decisions)
Signed-off-by: Linus Lüssing linus.luessing@web.de --- batctl/debug.c | 35 ++++++++++++++++++++++++++++++++--- batctl/functions.c | 14 +++++++++++++- batctl/functions.h | 3 ++- batctl/sys.c | 8 ++++---- 4 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/batctl/debug.c b/batctl/debug.c index c57355a..04d2ebc 100644 --- a/batctl/debug.c +++ b/batctl/debug.c @@ -40,6 +40,7 @@ void originators_usage(void) printf(" \t -h print this help\n"); printf(" \t -n don't replace mac addresses with bat-host names\n"); printf(" \t -w watch mode - refresh the originator table continuously\n"); + printf(" \t -t timeout interval - don't print originators not seen for xxx.xxx seconds \n"); }
void trans_local_usage(void) @@ -74,8 +75,13 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( int optchar, read_opt = USE_BAT_HOSTS; char full_path[MAX_PATH+1]; char *debugfs_mnt; + int orig_timeout_secs; + int orig_timeout_msecs; + char msecs_buff[4]; + memset(msecs_buff, '0', sizeof(msecs_buff)); + msecs_buff[3] = '\0';
- while ((optchar = getopt(argc, argv, "hnw")) != -1) { + while ((optchar = getopt(argc, argv, "hnwt:")) != -1) { switch (optchar) { case 'h': table_usage(); @@ -86,6 +92,29 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( case 'w': read_opt |= CLR_CONT_READ; break; + case 't': + if (table_usage != originators_usage) { + table_usage(); + return EXIT_FAILURE; + } + + read_opt |= NO_OLD_ORIGS; + if (sscanf(optarg, "%3d.%3s", &orig_timeout_secs, + msecs_buff) == 2) { + if (strlen(msecs_buff) < 3) + msecs_buff[strlen(msecs_buff)] = '0'; + sscanf(msecs_buff, "%d", &orig_timeout_msecs); + orig_timeout_msecs += 1000 * orig_timeout_secs; + } + else if (sscanf(optarg, "%3d", &orig_timeout_secs) == 1) { ; } + else { + printf("Error - provided argument of -t is not a number\n"); + return EXIT_FAILURE; + } + break; + case '?': + if (optopt == 't' && table_usage == originators_usage) + return EXIT_FAILURE; default: table_usage(); return EXIT_FAILURE; @@ -99,7 +128,7 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( }
debugfs_make_path(DEBUG_BATIF_PATH "/", full_path, sizeof(full_path)); - return read_file(full_path, file_path, read_opt); + return read_file(full_path, file_path, read_opt, orig_timeout_msecs); }
static void log_usage(void) @@ -137,7 +166,7 @@ int log_print(int argc, char **argv) }
debugfs_make_path(DEBUG_BATIF_PATH "/", full_path, sizeof(full_path)); - res = read_file(full_path, DEBUG_LOG, read_opt); + res = read_file(full_path, DEBUG_LOG, read_opt, 0);
if ((res != EXIT_SUCCESS) && (errno == ENOENT)) printf("To read the debug log you need to compile the module with debugging enabled (see the README)\n"); diff --git a/batctl/functions.c b/batctl/functions.c index 9b697b3..272e08b 100644 --- a/batctl/functions.c +++ b/batctl/functions.c @@ -117,11 +117,13 @@ static int check_sys_dir(char *dir) return EXIT_FAILURE; }
-int read_file(char *dir, char *fname, int read_opt) +int read_file(char *dir, char *fname, int read_opt, int orig_timeout) { struct ether_addr *mac_addr; struct bat_host *bat_host; int res = EXIT_FAILURE; + int last_seen_secs; + int last_seen_msecs; char full_path[500], *buff_ptr, *space_ptr, extra_char; size_t len = 0; ssize_t read; @@ -157,6 +159,16 @@ read: if (read_opt & USE_READ_BUFF) break;
+ /* skip timed out originators */ + if (read_opt & NO_OLD_ORIGS) { + if (sscanf(line_ptr, "%*s %3d.%3d", + &last_seen_secs, &last_seen_msecs) == 2) { + last_seen_msecs += 1000 * last_seen_secs; + if (last_seen_msecs > orig_timeout) + continue; + } + } + if (!(read_opt & USE_BAT_HOSTS)) { printf("%s", line_ptr); continue; diff --git a/batctl/functions.h b/batctl/functions.h index 885df34..10903e0 100644 --- a/batctl/functions.h +++ b/batctl/functions.h @@ -33,7 +33,7 @@ double end_timer(void); char *ether_ntoa_long(const struct ether_addr *addr); char *get_name_by_macaddr(struct ether_addr *mac_addr, int read_opt); char *get_name_by_macstr(char *mac_str, int read_opt); -int read_file(char *dir, char *path, int read_opt); +int read_file(char *dir, char *path, int read_opt, int orig_timeout); int write_file(char *dir, char *fname, char *arg1, char *arg2);
extern char *line_ptr; @@ -46,4 +46,5 @@ enum { LOG_MODE = 0x08, USE_READ_BUFF = 0x10, SILENCE_ERRORS = 0x20, + NO_OLD_ORIGS = 0x40, }; diff --git a/batctl/sys.c b/batctl/sys.c index 321dfc9..7135841 100644 --- a/batctl/sys.c +++ b/batctl/sys.c @@ -79,7 +79,7 @@ static int print_interfaces(void)
while ((iface_dir = readdir(iface_base_dir)) != NULL) { snprintf(path_buff, PATH_BUFF_LEN, SYS_MESH_IFACE_FMT, iface_dir->d_name); - res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS); + res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0); if (res != EXIT_SUCCESS) continue;
@@ -93,7 +93,7 @@ static int print_interfaces(void) line_ptr = NULL;
snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_STATUS_FMT, iface_dir->d_name); - res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS); + res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0); if (res != EXIT_SUCCESS) { printf("<error reading status>\n"); continue; @@ -196,7 +196,7 @@ int handle_loglevel(int argc, char **argv) goto out; }
- res = read_file(SYS_BATIF_PATH, SYS_LOG_LEVEL, SINGLE_READ | USE_READ_BUFF); + res = read_file(SYS_BATIF_PATH, SYS_LOG_LEVEL, SINGLE_READ | USE_READ_BUFF, 0);
if (res != EXIT_SUCCESS) goto out; @@ -271,7 +271,7 @@ int handle_sys_setting(int argc, char **argv, }
if (argc == 1) - return read_file(SYS_BATIF_PATH, file_path, SINGLE_READ); + return read_file(SYS_BATIF_PATH, file_path, SINGLE_READ, 0);
if (!sysfs_param) goto write_file;
If you are running a very mobile mesh network with a fast originator interval, then the last-seen interval might not update fast enough depending on the actual scenario, because the default polling interval of batctl is 1 second. With this patch, an optional interval in seconds and a precision of 3 digits before and after an optional dot can be added, making the batctl-watch-mode updates faster.
Signed-off-by: Linus Lüssing linus.luessing@web.de --- batctl/debug.c | 79 ++++++++++++++++++++++++++++++++++++--------------- batctl/functions.c | 7 ++-- batctl/functions.h | 3 +- batctl/sys.c | 8 ++-- 4 files changed, 66 insertions(+), 31 deletions(-)
diff --git a/batctl/debug.c b/batctl/debug.c index 04d2ebc..7f0e8f3 100644 --- a/batctl/debug.c +++ b/batctl/debug.c @@ -39,7 +39,7 @@ void originators_usage(void) printf("options:\n"); printf(" \t -h print this help\n"); printf(" \t -n don't replace mac addresses with bat-host names\n"); - printf(" \t -w watch mode - refresh the originator table continuously\n"); + printf(" \t -w [interval] watch mode - refresh the originator table continuously\n"); printf(" \t -t timeout interval - don't print originators not seen for xxx.xxx seconds \n"); }
@@ -49,7 +49,7 @@ void trans_local_usage(void) printf("options:\n"); printf(" \t -h print this help\n"); printf(" \t -n don't replace mac addresses with bat-host names\n"); - printf(" \t -w watch mode - refresh the local translation table continuously\n"); + printf(" \t -w [interval] watch mode - refresh the local translation table continuously\n"); }
void trans_global_usage(void) @@ -58,7 +58,7 @@ void trans_global_usage(void) printf("options:\n"); printf(" \t -h print this help\n"); printf(" \t -n don't replace mac addresses with bat-host names\n"); - printf(" \t -w watch mode - refresh the global translation table continuously\n"); + printf(" \t -w [interval] watch mode - refresh the global translation table continuously\n"); }
void gateways_usage(void) @@ -67,7 +67,32 @@ void gateways_usage(void) printf("options:\n"); printf(" \t -h print this help\n"); printf(" \t -n don't replace mac addresses with bat-host names\n"); - printf(" \t -w watch mode - refresh the gateway server list continuously\n"); + printf(" \t -w [interval] watch mode - refresh the gateway server list continuously\n"); +} + +/* secstring is a string containing a time in seconds with an optional decimal + * dot. secstring has a maxmimum precision of "xxx.xxx". + * A return of -1 means an error in conversion. */ +int secstr_to_msecs(char *secstring) { + int seconds; + int mseconds; + char msecs_buff[4]; + msecs_buff[3] = '\0'; + memset(msecs_buff, '0', sizeof(msecs_buff)-1); + + if (sscanf(secstring, "%3d.%3s", &seconds, + msecs_buff) == 2) { + if (strlen(msecs_buff) < 3) + msecs_buff[strlen(msecs_buff)] = '0'; + sscanf(msecs_buff, "%d", &mseconds); + mseconds += 1000 * seconds; + } + else if (sscanf(secstring, "%3d", &seconds) == 1) + return (1000 * seconds); + else + return -1; + + return mseconds; }
int handle_debug_table(int argc, char **argv, char *file_path, void table_usage(void)) @@ -75,13 +100,11 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( int optchar, read_opt = USE_BAT_HOSTS; char full_path[MAX_PATH+1]; char *debugfs_mnt; - int orig_timeout_secs; - int orig_timeout_msecs; - char msecs_buff[4]; - memset(msecs_buff, '0', sizeof(msecs_buff)); - msecs_buff[3] = '\0'; + int orig_timeout = 0; + int watch_interval = 1000; + opterr = 0;
- while ((optchar = getopt(argc, argv, "hnwt:")) != -1) { + while ((optchar = getopt(argc, argv, "hnw:t:")) != -1) { switch (optchar) { case 'h': table_usage(); @@ -91,6 +114,16 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( break; case 'w': read_opt |= CLR_CONT_READ; + if (optarg[0] == '-') { + optind--; + break; + } + + watch_interval = secstr_to_msecs(optarg); + if (watch_interval < 0) { + printf("Error - provided argument of -w is not a number\n"); + return EXIT_FAILURE; + } break; case 't': if (table_usage != originators_usage) { @@ -99,22 +132,22 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( }
read_opt |= NO_OLD_ORIGS; - if (sscanf(optarg, "%3d.%3s", &orig_timeout_secs, - msecs_buff) == 2) { - if (strlen(msecs_buff) < 3) - msecs_buff[strlen(msecs_buff)] = '0'; - sscanf(msecs_buff, "%d", &orig_timeout_msecs); - orig_timeout_msecs += 1000 * orig_timeout_secs; - } - else if (sscanf(optarg, "%3d", &orig_timeout_secs) == 1) { ; } - else { + orig_timeout = secstr_to_msecs(optarg); + if (orig_timeout < 0) { printf("Error - provided argument of -t is not a number\n"); return EXIT_FAILURE; } break; case '?': - if (optopt == 't' && table_usage == originators_usage) - return EXIT_FAILURE; + if (optopt == 't') + printf("Error - argument -t needs a number\n"); + + if (optopt == 'w') { + read_opt |= CLR_CONT_READ; + break; + } + + return EXIT_FAILURE; default: table_usage(); return EXIT_FAILURE; @@ -128,7 +161,7 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( }
debugfs_make_path(DEBUG_BATIF_PATH "/", full_path, sizeof(full_path)); - return read_file(full_path, file_path, read_opt, orig_timeout_msecs); + return read_file(full_path, file_path, read_opt, orig_timeout, watch_interval); }
static void log_usage(void) @@ -166,7 +199,7 @@ int log_print(int argc, char **argv) }
debugfs_make_path(DEBUG_BATIF_PATH "/", full_path, sizeof(full_path)); - res = read_file(full_path, DEBUG_LOG, read_opt, 0); + res = read_file(full_path, DEBUG_LOG, read_opt, 0, 0);
if ((res != EXIT_SUCCESS) && (errno == ENOENT)) printf("To read the debug log you need to compile the module with debugging enabled (see the README)\n"); diff --git a/batctl/functions.c b/batctl/functions.c index 272e08b..573ecb6 100644 --- a/batctl/functions.c +++ b/batctl/functions.c @@ -117,7 +117,8 @@ static int check_sys_dir(char *dir) return EXIT_FAILURE; }
-int read_file(char *dir, char *fname, int read_opt, int orig_timeout) +int read_file(char *dir, char *fname, int read_opt, + int orig_timeout, int watch_interval) { struct ether_addr *mac_addr; struct bat_host *bat_host; @@ -223,14 +224,14 @@ written: }
if (read_opt & CONT_READ) { - sleep(1); + usleep(1000 * watch_interval); goto read; }
if (read_opt & CLR_CONT_READ) { if (fp) fclose(fp); - sleep(1); + usleep(1000 * watch_interval); goto open; }
diff --git a/batctl/functions.h b/batctl/functions.h index 10903e0..0a8666a 100644 --- a/batctl/functions.h +++ b/batctl/functions.h @@ -33,7 +33,8 @@ double end_timer(void); char *ether_ntoa_long(const struct ether_addr *addr); char *get_name_by_macaddr(struct ether_addr *mac_addr, int read_opt); char *get_name_by_macstr(char *mac_str, int read_opt); -int read_file(char *dir, char *path, int read_opt, int orig_timeout); +int read_file(char *dir, char *path, int read_opt, + int orig_timeout, int watch_interval); int write_file(char *dir, char *fname, char *arg1, char *arg2);
extern char *line_ptr; diff --git a/batctl/sys.c b/batctl/sys.c index 7135841..4c07866 100644 --- a/batctl/sys.c +++ b/batctl/sys.c @@ -79,7 +79,7 @@ static int print_interfaces(void)
while ((iface_dir = readdir(iface_base_dir)) != NULL) { snprintf(path_buff, PATH_BUFF_LEN, SYS_MESH_IFACE_FMT, iface_dir->d_name); - res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0); + res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0, 0); if (res != EXIT_SUCCESS) continue;
@@ -93,7 +93,7 @@ static int print_interfaces(void) line_ptr = NULL;
snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_STATUS_FMT, iface_dir->d_name); - res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0); + res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0, 0); if (res != EXIT_SUCCESS) { printf("<error reading status>\n"); continue; @@ -196,7 +196,7 @@ int handle_loglevel(int argc, char **argv) goto out; }
- res = read_file(SYS_BATIF_PATH, SYS_LOG_LEVEL, SINGLE_READ | USE_READ_BUFF, 0); + res = read_file(SYS_BATIF_PATH, SYS_LOG_LEVEL, SINGLE_READ | USE_READ_BUFF, 0, 0);
if (res != EXIT_SUCCESS) goto out; @@ -271,7 +271,7 @@ int handle_sys_setting(int argc, char **argv, }
if (argc == 1) - return read_file(SYS_BATIF_PATH, file_path, SINGLE_READ, 0); + return read_file(SYS_BATIF_PATH, file_path, SINGLE_READ, 0, 0);
if (!sysfs_param) goto write_file;
On Wednesday 30 June 2010 20:03:13 Linus Lüssing wrote:
- char msecs_buff[4];
- memset(msecs_buff, '0', sizeof(msecs_buff));
- msecs_buff[3] = '\0';
Shouldn't a simple memset(msecs_buff, 0, sizeof(msecs_buff)); be enough ?
if (sscanf(optarg, "%3d.%3s", &orig_timeout_secs,
else if (sscanf(optarg, "%3d", &orig_timeout_secs) == 1) { ; }
else {
I don't quite understand the sense of the "else if" here. You could also write: else if (sscanf(optarg, "%3d", &orig_timeout_secs) != 1) and write no else block but I don't see why 1 second should be accepted and nothing else ?
Regards, Marek
On Wed, Jun 30, 2010 at 09:35:49PM +0200, Marek Lindner wrote:
On Wednesday 30 June 2010 20:03:13 Linus Lüssing wrote:
- char msecs_buff[4];
- memset(msecs_buff, '0', sizeof(msecs_buff));
- msecs_buff[3] = '\0';
Shouldn't a simple memset(msecs_buff, 0, sizeof(msecs_buff)); be enough ?
The intention of the msecs_buff was, to do some zeroed alignment which is not possible with sscanf automatically (so without it, a -t 0.99 were converted to 99ms instead of 990). The last one is is for just marking the end of the string (note, '0' != '\0' ;) ).
if (sscanf(optarg, "%3d.%3s", &orig_timeout_secs,
else if (sscanf(optarg, "%3d", &orig_timeout_secs) == 1) { ; }
else {
I don't quite understand the sense of the "else if" here. You could also write: else if (sscanf(optarg, "%3d", &orig_timeout_secs) != 1)
Yep, you're right, I guess I was thinking too 'imperative' here :D.
and write no else block but I don't see why 1 second should be accepted and nothing else ?
Nope, sscanf returns the number of succesfully scanned values, so the 1 is not actually 1sec. But you're right, it can't read more than 1 with only one %d in it anyway, so checking sscanf() < 1 would be fine too.
Anyway, I guess you're right, that integer arithmetics was pretty much like using a slegdehammer to crack a nut in this case :).
See new patches for a less 'creative' approach :P.
Regards, Marek
Cheers, Linus
Okay, we are not pulling the originator table output that often, so doing explicit integer operations instead of dealing with floats does not really make a difference in speed, even on systems without a floating point unit. Also rounding problems are not an issue as the numbers we are calculating with are not that weird.
So in this series, actually using floats, which makes these patches a lot more readable and smaller.
Cheers, Linus
This commit introduces the -t switch for originator table output. It makes use of the new last-seen field in batman-adv, the user can specify a timeout interval in seconds (with 3 digits precision before and after a possible dot) if he/she considers a node as dead after this time. (of course this is just influencing the displaying and not actually declearing a node as dead for routing decisions)
Signed-off-by: Linus Lüssing linus.luessing@web.de --- batctl/debug.c | 23 ++++++++++++++++++++--- batctl/functions.c | 9 ++++++++- batctl/functions.d | 40 ++++++++++++++++++++++++++++++++++++++++ batctl/functions.h | 3 ++- batctl/sys.c | 8 ++++---- 5 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 batctl/functions.d
diff --git a/batctl/debug.c b/batctl/debug.c index c57355a..cd97b8d 100644 --- a/batctl/debug.c +++ b/batctl/debug.c @@ -40,6 +40,7 @@ void originators_usage(void) printf(" \t -h print this help\n"); printf(" \t -n don't replace mac addresses with bat-host names\n"); printf(" \t -w watch mode - refresh the originator table continuously\n"); + printf(" \t -t timeout interval - don't print originators not seen for xxx.xxx seconds \n"); }
void trans_local_usage(void) @@ -74,8 +75,9 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( int optchar, read_opt = USE_BAT_HOSTS; char full_path[MAX_PATH+1]; char *debugfs_mnt; + float orig_timeout;
- while ((optchar = getopt(argc, argv, "hnw")) != -1) { + while ((optchar = getopt(argc, argv, "hnwt:")) != -1) { switch (optchar) { case 'h': table_usage(); @@ -86,6 +88,21 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( case 'w': read_opt |= CLR_CONT_READ; break; + case 't': + if (table_usage != originators_usage) { + table_usage(); + return EXIT_FAILURE; + } + + read_opt |= NO_OLD_ORIGS; + if (!sscanf(optarg, "%f", &orig_timeout)) { + printf("Error - provided argument of -t is not a number\n"); + return EXIT_FAILURE; + } + break; + case '?': + if (optopt == 't' && table_usage == originators_usage) + return EXIT_FAILURE; default: table_usage(); return EXIT_FAILURE; @@ -99,7 +116,7 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( }
debugfs_make_path(DEBUG_BATIF_PATH "/", full_path, sizeof(full_path)); - return read_file(full_path, file_path, read_opt); + return read_file(full_path, file_path, read_opt, orig_timeout); }
static void log_usage(void) @@ -137,7 +154,7 @@ int log_print(int argc, char **argv) }
debugfs_make_path(DEBUG_BATIF_PATH "/", full_path, sizeof(full_path)); - res = read_file(full_path, DEBUG_LOG, read_opt); + res = read_file(full_path, DEBUG_LOG, read_opt, 0);
if ((res != EXIT_SUCCESS) && (errno == ENOENT)) printf("To read the debug log you need to compile the module with debugging enabled (see the README)\n"); diff --git a/batctl/functions.c b/batctl/functions.c index 9b697b3..0aeb99a 100644 --- a/batctl/functions.c +++ b/batctl/functions.c @@ -117,11 +117,12 @@ static int check_sys_dir(char *dir) return EXIT_FAILURE; }
-int read_file(char *dir, char *fname, int read_opt) +int read_file(char *dir, char *fname, int read_opt, float orig_timeout) { struct ether_addr *mac_addr; struct bat_host *bat_host; int res = EXIT_FAILURE; + float last_seen; char full_path[500], *buff_ptr, *space_ptr, extra_char; size_t len = 0; ssize_t read; @@ -157,6 +158,12 @@ read: if (read_opt & USE_READ_BUFF) break;
+ /* skip timed out originators */ + if (read_opt & NO_OLD_ORIGS) + if (sscanf(line_ptr, "%*s %f", &last_seen) + && (last_seen > orig_timeout)) + continue; + if (!(read_opt & USE_BAT_HOSTS)) { printf("%s", line_ptr); continue; diff --git a/batctl/functions.d b/batctl/functions.d new file mode 100644 index 0000000..9a28b76 --- /dev/null +++ b/batctl/functions.d @@ -0,0 +1,40 @@ +functions.o: functions.c /usr/include/netinet/ether.h \ + /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \ + /usr/include/gnu/stubs-32.h /usr/include/netinet/if_ether.h \ + /usr/include/sys/types.h /usr/include/bits/types.h \ + /usr/include/bits/typesizes.h /usr/include/time.h \ + /usr/lib/gcc/i486-linux-gnu/4.3.2/include/stddef.h \ + /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/bits/time.h \ + /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \ + /usr/include/linux/if_ether.h /usr/include/linux/types.h \ + /usr/include/linux/posix_types.h /usr/include/linux/stddef.h \ + /usr/lib/gcc/i486-linux-gnu/4.3.2/include-fixed/asm/posix_types.h \ + /usr/include/asm/posix_types.h /usr/include/asm/posix_types_32.h \ + /usr/include/asm/types.h /usr/include/asm-generic/int-ll64.h \ + /usr/include/net/ethernet.h /usr/include/net/if_arp.h \ + /usr/include/sys/socket.h /usr/include/sys/uio.h \ + /usr/include/bits/uio.h /usr/include/bits/socket.h \ + /usr/lib/gcc/i486-linux-gnu/4.3.2/include-fixed/limits.h \ + /usr/lib/gcc/i486-linux-gnu/4.3.2/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/bits/xopen_lim.h \ + /usr/include/bits/stdio_lim.h /usr/include/bits/sockaddr.h \ + /usr/include/asm/socket.h /usr/include/asm/sockios.h \ + /usr/include/sys/stat.h /usr/include/bits/stat.h /usr/include/unistd.h \ + /usr/include/bits/posix_opt.h /usr/include/bits/environments.h \ + /usr/include/bits/confname.h /usr/include/getopt.h \ + /usr/include/stdlib.h /usr/include/bits/waitflags.h \ + /usr/include/bits/waitstatus.h /usr/include/xlocale.h \ + /usr/include/alloca.h /usr/include/stdio.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/i486-linux-gnu/4.3.2/include/stdarg.h \ + /usr/include/bits/sys_errlist.h /usr/include/string.h \ + /usr/include/errno.h /usr/include/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/bits/fcntl.h /usr/include/sys/time.h \ + main.h functions.h bat-hosts.h diff --git a/batctl/functions.h b/batctl/functions.h index 885df34..3fb8f35 100644 --- a/batctl/functions.h +++ b/batctl/functions.h @@ -33,7 +33,7 @@ double end_timer(void); char *ether_ntoa_long(const struct ether_addr *addr); char *get_name_by_macaddr(struct ether_addr *mac_addr, int read_opt); char *get_name_by_macstr(char *mac_str, int read_opt); -int read_file(char *dir, char *path, int read_opt); +int read_file(char *dir, char *path, int read_opt, float orig_timeout); int write_file(char *dir, char *fname, char *arg1, char *arg2);
extern char *line_ptr; @@ -46,4 +46,5 @@ enum { LOG_MODE = 0x08, USE_READ_BUFF = 0x10, SILENCE_ERRORS = 0x20, + NO_OLD_ORIGS = 0x40, }; diff --git a/batctl/sys.c b/batctl/sys.c index 321dfc9..7135841 100644 --- a/batctl/sys.c +++ b/batctl/sys.c @@ -79,7 +79,7 @@ static int print_interfaces(void)
while ((iface_dir = readdir(iface_base_dir)) != NULL) { snprintf(path_buff, PATH_BUFF_LEN, SYS_MESH_IFACE_FMT, iface_dir->d_name); - res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS); + res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0); if (res != EXIT_SUCCESS) continue;
@@ -93,7 +93,7 @@ static int print_interfaces(void) line_ptr = NULL;
snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_STATUS_FMT, iface_dir->d_name); - res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS); + res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0); if (res != EXIT_SUCCESS) { printf("<error reading status>\n"); continue; @@ -196,7 +196,7 @@ int handle_loglevel(int argc, char **argv) goto out; }
- res = read_file(SYS_BATIF_PATH, SYS_LOG_LEVEL, SINGLE_READ | USE_READ_BUFF); + res = read_file(SYS_BATIF_PATH, SYS_LOG_LEVEL, SINGLE_READ | USE_READ_BUFF, 0);
if (res != EXIT_SUCCESS) goto out; @@ -271,7 +271,7 @@ int handle_sys_setting(int argc, char **argv, }
if (argc == 1) - return read_file(SYS_BATIF_PATH, file_path, SINGLE_READ); + return read_file(SYS_BATIF_PATH, file_path, SINGLE_READ, 0);
if (!sysfs_param) goto write_file;
On Thursday 01 July 2010 00:29:22 Linus Lüssing wrote:
batctl/debug.c | 23 ++++++++++++++++++++--- batctl/functions.c | 9 ++++++++- batctl/functions.d | 40 ++++++++++++++++++++++++++++++++++++++++ batctl/functions.h | 3 ++- batctl/sys.c | 8 ++++---- 5 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 batctl/functions.d
The float variant looks much better! Would you mind sending this patch again without functions.d ? How about mentioning this feature in the man page ?
Cheers, Marek
If you are running a very mobile mesh network with a fast originator interval, then the last-seen interval might not update fast enough depending on the actual scenario, because the default polling interval of batctl is 1 second. With this patch, an optional interval in seconds and a precision of 3 digits before and after an optional dot can be added, making the batctl-watch-mode updates faster.
Signed-off-by: Linus Lüssing linus.luessing@web.de --- batctl/debug.c | 38 +++++++++++++++++++++++++++++--------- batctl/functions.c | 7 ++++--- batctl/functions.h | 3 ++- batctl/sys.c | 8 ++++---- 4 files changed, 39 insertions(+), 17 deletions(-)
diff --git a/batctl/debug.c b/batctl/debug.c index cd97b8d..6e11b06 100644 --- a/batctl/debug.c +++ b/batctl/debug.c @@ -39,7 +39,7 @@ void originators_usage(void) printf("options:\n"); printf(" \t -h print this help\n"); printf(" \t -n don't replace mac addresses with bat-host names\n"); - printf(" \t -w watch mode - refresh the originator table continuously\n"); + printf(" \t -w [interval] watch mode - refresh the originator table continuously\n"); printf(" \t -t timeout interval - don't print originators not seen for xxx.xxx seconds \n"); }
@@ -49,7 +49,7 @@ void trans_local_usage(void) printf("options:\n"); printf(" \t -h print this help\n"); printf(" \t -n don't replace mac addresses with bat-host names\n"); - printf(" \t -w watch mode - refresh the local translation table continuously\n"); + printf(" \t -w [interval] watch mode - refresh the local translation table continuously\n"); }
void trans_global_usage(void) @@ -58,7 +58,7 @@ void trans_global_usage(void) printf("options:\n"); printf(" \t -h print this help\n"); printf(" \t -n don't replace mac addresses with bat-host names\n"); - printf(" \t -w watch mode - refresh the global translation table continuously\n"); + printf(" \t -w [interval] watch mode - refresh the global translation table continuously\n"); }
void gateways_usage(void) @@ -67,7 +67,7 @@ void gateways_usage(void) printf("options:\n"); printf(" \t -h print this help\n"); printf(" \t -n don't replace mac addresses with bat-host names\n"); - printf(" \t -w watch mode - refresh the gateway server list continuously\n"); + printf(" \t -w [interval] watch mode - refresh the gateway server list continuously\n"); }
int handle_debug_table(int argc, char **argv, char *file_path, void table_usage(void)) @@ -76,8 +76,10 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( char full_path[MAX_PATH+1]; char *debugfs_mnt; float orig_timeout; + float watch_interval = 1; + opterr = 0;
- while ((optchar = getopt(argc, argv, "hnwt:")) != -1) { + while ((optchar = getopt(argc, argv, "hnw:t:")) != -1) { switch (optchar) { case 'h': table_usage(); @@ -87,6 +89,15 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( break; case 'w': read_opt |= CLR_CONT_READ; + if (optarg[0] == '-') { + optind--; + break; + } + + if (!sscanf(optarg, "%f", &watch_interval)) { + printf("Error - provided argument of -w is not a number\n"); + return EXIT_FAILURE; + } break; case 't': if (table_usage != originators_usage) { @@ -101,8 +112,17 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( } break; case '?': - if (optopt == 't' && table_usage == originators_usage) - return EXIT_FAILURE; + if (optopt == 't') + printf("Error - argument -t needs a number\n"); + + else if (optopt == 'w') { + read_opt |= CLR_CONT_READ; + break; + } + else + printf("Error - unrecognised option %c\n", optopt); + + return EXIT_FAILURE; default: table_usage(); return EXIT_FAILURE; @@ -116,7 +136,7 @@ int handle_debug_table(int argc, char **argv, char *file_path, void table_usage( }
debugfs_make_path(DEBUG_BATIF_PATH "/", full_path, sizeof(full_path)); - return read_file(full_path, file_path, read_opt, orig_timeout); + return read_file(full_path, file_path, read_opt, orig_timeout, watch_interval); }
static void log_usage(void) @@ -154,7 +174,7 @@ int log_print(int argc, char **argv) }
debugfs_make_path(DEBUG_BATIF_PATH "/", full_path, sizeof(full_path)); - res = read_file(full_path, DEBUG_LOG, read_opt, 0); + res = read_file(full_path, DEBUG_LOG, read_opt, 0, 0);
if ((res != EXIT_SUCCESS) && (errno == ENOENT)) printf("To read the debug log you need to compile the module with debugging enabled (see the README)\n"); diff --git a/batctl/functions.c b/batctl/functions.c index 0aeb99a..497e166 100644 --- a/batctl/functions.c +++ b/batctl/functions.c @@ -117,7 +117,8 @@ static int check_sys_dir(char *dir) return EXIT_FAILURE; }
-int read_file(char *dir, char *fname, int read_opt, float orig_timeout) +int read_file(char *dir, char *fname, int read_opt, + float orig_timeout, float watch_interval) { struct ether_addr *mac_addr; struct bat_host *bat_host; @@ -218,14 +219,14 @@ written: }
if (read_opt & CONT_READ) { - sleep(1); + usleep(1000000 * watch_interval); goto read; }
if (read_opt & CLR_CONT_READ) { if (fp) fclose(fp); - sleep(1); + usleep(1000000 * watch_interval); goto open; }
diff --git a/batctl/functions.h b/batctl/functions.h index 3fb8f35..6aa9487 100644 --- a/batctl/functions.h +++ b/batctl/functions.h @@ -33,7 +33,8 @@ double end_timer(void); char *ether_ntoa_long(const struct ether_addr *addr); char *get_name_by_macaddr(struct ether_addr *mac_addr, int read_opt); char *get_name_by_macstr(char *mac_str, int read_opt); -int read_file(char *dir, char *path, int read_opt, float orig_timeout); +int read_file(char *dir, char *path, int read_opt, + float orig_timeout, float watch_interval); int write_file(char *dir, char *fname, char *arg1, char *arg2);
extern char *line_ptr; diff --git a/batctl/sys.c b/batctl/sys.c index 7135841..4c07866 100644 --- a/batctl/sys.c +++ b/batctl/sys.c @@ -79,7 +79,7 @@ static int print_interfaces(void)
while ((iface_dir = readdir(iface_base_dir)) != NULL) { snprintf(path_buff, PATH_BUFF_LEN, SYS_MESH_IFACE_FMT, iface_dir->d_name); - res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0); + res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0, 0); if (res != EXIT_SUCCESS) continue;
@@ -93,7 +93,7 @@ static int print_interfaces(void) line_ptr = NULL;
snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_STATUS_FMT, iface_dir->d_name); - res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0); + res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS, 0, 0); if (res != EXIT_SUCCESS) { printf("<error reading status>\n"); continue; @@ -196,7 +196,7 @@ int handle_loglevel(int argc, char **argv) goto out; }
- res = read_file(SYS_BATIF_PATH, SYS_LOG_LEVEL, SINGLE_READ | USE_READ_BUFF, 0); + res = read_file(SYS_BATIF_PATH, SYS_LOG_LEVEL, SINGLE_READ | USE_READ_BUFF, 0, 0);
if (res != EXIT_SUCCESS) goto out; @@ -271,7 +271,7 @@ int handle_sys_setting(int argc, char **argv, }
if (argc == 1) - return read_file(SYS_BATIF_PATH, file_path, SINGLE_READ, 0); + return read_file(SYS_BATIF_PATH, file_path, SINGLE_READ, 0, 0);
if (!sysfs_param) goto write_file;
b.a.t.m.a.n@lists.open-mesh.org