Skip to content

Commit

Permalink
Merge pull request #2507 from pqarmitage/updates
Browse files Browse the repository at this point in the history
vrrp: handle checking ip utility version properly with BusyBox
  • Loading branch information
pqarmitage authored Nov 10, 2024
2 parents 130368b + 99d2ea9 commit 889eb4c
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 30 deletions.
17 changes: 17 additions & 0 deletions doc/man/man5/keepalived.conf.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -964,8 +964,25 @@ possibly following any cleanup actions needed.
# if more than one keepalived instance is running on a system.
# In order to alleviate this, enabling data_use_instance includes the
# instance name and network namespace in the file name of the .data files.
# This also applies to SIGUSR2 for outputting stats.
\fBdata_use_instance \fR[<BOOL>]

# If the files produced by SIGUSR1 and SIGUSR2 are on slow storage, then writing to
# them may cause keepalived processes to block. This option allows specifying the
# location to which the files should be written, and should ideally be a tmpfs rather
# than a real disc, and definitely not network attached storage or other storage that
# can block for more than a few microseconds.
# If path ends in a / it is considered to be a directory and the normal filenames
# in that directory will be used, otherwise it will be used as the full path name
# of the file to be written. Note that \fBdata_use_instance\fR may also modify the
# file name.
# For the state files, these are template names and "_checker" will be added
# for the checker process, "_bfd" will be added for the BFD process and
# "_parent" will be added for the parent process.
\fBstate_file_location \fRpath
\fBstats_file_location \fRpath
\fBjson_file_location \fRpath

# json_version 2 puts the VRRP data in a named array and adds
# track_process details. Default is version 1.
\fBjson_version \fR{1|2}
Expand Down
8 changes: 4 additions & 4 deletions doc/man/man8/keepalived.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -372,20 +372,20 @@ will shut down.
.TP
.B USR1\fP or \fBSIGFUNC=DATA
Write configuration data to
.B @KA_TMP_DIR@/keepalived.data
.B @KA_TMP_DIR@/keepalived.data or file configured by state_dump_file
.TP
.B USR2\fP or \fBSIGFUNC=STATS
Write statistics info to
.B @KA_TMP_DIR@/keepalived.stats
.B @KA_TMP_DIR@/keepalived.stats or file configured by stats_dump_file
.TP
.B SIGFUNC=STATS_CLEAR
Write statistics info to
.B @KA_TMP_DIR@/keepalived.stats
.B @KA_TMP_DIR@/keepalived.stats or file configured by stats_dump_file
and clear the statistics counters
.TP
.B SIGFUNC=JSON
Write configuration data in JSON format to
.B @KA_TMP_DIR@/keepalived.json
.B @KA_TMP_DIR@/keepalived.json or file configured by json_dump_file
.TP
.B SIGFUNC=TDATA
This causes
Expand Down
2 changes: 1 addition & 1 deletion keepalived/bfd/bfd_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ bfd_print_data(void)
{
FILE *fp;

fp = open_dump_file("keepalived_bfd.data");
fp = open_dump_file("_bfd");

if (!fp)
return;
Expand Down
2 changes: 1 addition & 1 deletion keepalived/check/check_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ check_print_data(void)
{
FILE *fp;

fp = open_dump_file("keepalived_check.data");
fp = open_dump_file("_check");

if (!fp)
return;
Expand Down
76 changes: 57 additions & 19 deletions keepalived/core/global_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,46 +516,78 @@ free_global_data(data_t **datap)
FREE_CONST_PTR(data->iproute_usr_dir);
FREE_CONST_PTR(data->iproute_etc_dir);
#endif
FREE_CONST_PTR(data->state_dump_file);
FREE_CONST_PTR(data->stats_dump_file);
FREE_CONST_PTR(data->json_dump_file);

FREE(data);

*datap = NULL;
}

FILE * __attribute__((malloc))
open_dump_file(const char *file_name)
open_dump_file(const char *default_file_name)
{
FILE *fp;
const char *full_file_name;
char *tmp_file_name;
const char *file_name;
char *full_file_name;
const char *dot;
int len;
size_t len;
const char *dir;
size_t dir_len;

/*
* If no leading /, use tmp_dir
* If trailing /, add "keepalived%s.data", default_file_name
*/

if (global_data->state_dump_file &&
global_data->state_dump_file[0] == '/') {
dir = global_data->state_dump_file;
dir_len = strlen(dir);
if (dir[dir_len - 1] != '/')
dir_len = strrchr(dir, '/') - dir;
} else {
dir = tmp_dir;
dir_len = strlen(tmp_dir);
}

if (global_data->data_use_instance &&
(global_data->instance_name || global_data->network_namespace)) {
len = strlen(tmp_dir) + 1 + strlen(file_name) + 1;
if (global_data->state_dump_file &&
global_data->state_dump_file[strlen(global_data->state_dump_file) - 1] != '/') {
if (!(file_name = strrchr(global_data->state_dump_file, '/')))
file_name = global_data->state_dump_file;
else
file_name++; /* Skip to last '/' */
} else
file_name = "keepalived.data";

if (!(dot = strrchr(file_name, '.')))
dot = file_name + strlen(file_name);

len = dir_len + 1 + strlen(file_name) + 1 + strlen(default_file_name);
if (global_data->data_use_instance) {
if (global_data->instance_name)
len += strlen(global_data->instance_name) + 1;
if (global_data->network_namespace)
len += strlen(global_data->network_namespace) + 1;
}

tmp_file_name = MALLOC(len);
full_file_name = MALLOC(len);

dot = strrchr(file_name, '.');
sprintf(tmp_file_name, "%s/%.*s.%s%s%s%s", tmp_dir,
(int)(dot - file_name), file_name,
global_data->network_namespace ? global_data->network_namespace : "",
global_data->instance_name && global_data->network_namespace ? "_" : "",
global_data->instance_name ? global_data->instance_name : "",
dot);
full_file_name = tmp_file_name;
} else
full_file_name = make_tmp_filename(file_name);
snprintf(full_file_name, len, "%.*s/%.*s%s%s%s%s%s%s", (int)dir_len, dir,
(int)(dot - file_name), file_name,
default_file_name,
global_data->data_use_instance && (global_data->instance_name || global_data->network_namespace) ? "." : "",
global_data->data_use_instance && global_data->network_namespace ? global_data->network_namespace : "",
global_data->data_use_instance && global_data->instance_name && global_data->network_namespace ? "_" : "",
global_data->data_use_instance && global_data->instance_name ? global_data->instance_name : "",
dot);

fp = fopen_safe(full_file_name, "w");

if (!fp)
log_message(LOG_INFO, "Can't open dump file %s (%d: %s)",
file_name, errno, strerror(errno));
full_file_name, errno, strerror(errno));

FREE_CONST(full_file_name);

Expand Down Expand Up @@ -941,4 +973,10 @@ dump_global_data(FILE *fp, data_t * data)
conf_write(fp, " iproute usr directory %s", global_data->iproute_usr_dir ? global_data->iproute_usr_dir : "(none)");
conf_write(fp, " iproute etc directory %s", global_data->iproute_etc_dir ? global_data->iproute_etc_dir : "(none)");
#endif
if (global_data->state_dump_file)
conf_write(fp, " state dump file %s", global_data->state_dump_file);
if (global_data->stats_dump_file)
conf_write(fp, " stats dump file %s", global_data->stats_dump_file);
if (global_data->json_dump_file)
conf_write(fp, " json dump file %s", global_data->json_dump_file);
}
39 changes: 39 additions & 0 deletions keepalived/core/global_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -2469,6 +2469,42 @@ iproute_etc_handler(const vector_t *strvec)
}
#endif

static void
state_dump_file_handler(const vector_t *strvec)
{
if (vector_size(strvec) != 2 ||
!strvec_slot(strvec, 1)[0]) {
report_config_error(CONFIG_GENERAL_ERROR, "%s requires a non-empty path", strvec_slot(strvec, 0));
return;
}

global_data->state_dump_file = STRDUP(strvec_slot(strvec, 1));
}

static void
stats_dump_file_handler(const vector_t *strvec)
{
if (vector_size(strvec) != 2 ||
!strvec_slot(strvec, 1)[0]) {
report_config_error(CONFIG_GENERAL_ERROR, "%s requires a non-empty path", strvec_slot(strvec, 0));
return;
}

global_data->stats_dump_file = STRDUP(strvec_slot(strvec, 1));
}

static void
json_dump_file_handler(const vector_t *strvec)
{
if (vector_size(strvec) != 2 ||
!strvec_slot(strvec, 1)[0]) {
report_config_error(CONFIG_GENERAL_ERROR, "%s requires a non-empty path", strvec_slot(strvec, 0));
return;
}

global_data->json_dump_file = STRDUP(strvec_slot(strvec, 1));
}

void
init_global_keywords(bool global_active)
{
Expand Down Expand Up @@ -2688,4 +2724,7 @@ init_global_keywords(bool global_active)
install_keyword("iproute_usr_dir", &iproute_usr_handler);
install_keyword("iproute_etc_dir", &iproute_etc_handler);
#endif
install_keyword("state_dump_file", &state_dump_file_handler);
install_keyword("stats_dump_file", &stats_dump_file_handler);
install_keyword("json_dump_file", &json_dump_file_handler);
}
2 changes: 1 addition & 1 deletion keepalived/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ print_parent_data(__attribute__((unused)) thread_ref_t thread)

log_message(LOG_INFO, "Printing parent data for process(%d) on signal", getpid());

fp = open_dump_file("keepalived_parent.data");
fp = open_dump_file("_parent");

if (!fp)
return;
Expand Down
3 changes: 3 additions & 0 deletions keepalived/include/global_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ typedef struct _data {
const char *iproute_usr_dir;
const char *iproute_etc_dir;
#endif
const char *state_dump_file;
const char *stats_dump_file;
const char *json_dump_file;
} data_t;

/* Global vars exported */
Expand Down
2 changes: 1 addition & 1 deletion keepalived/vrrp/vrrp_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ vrrp_print_data(void)
{
FILE *fp;

fp = open_dump_file("keepalived.data");
fp = open_dump_file("");

if (!fp)
return;
Expand Down
17 changes: 14 additions & 3 deletions lib/rttables.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ write_addrproto_config(const char *name, uint32_t val)
bool file_exists = false;
struct stat statbuf;

fp = popen("ip -V", "re");
fp = popen("ip -V 2>&1", "re");
res = fgets(buf, sizeof(buf), fp);
pclose(fp);

Expand All @@ -616,14 +616,25 @@ write_addrproto_config(const char *name, uint32_t val)
* ip utility, iproute2-5.10.0
* or
* ip utility, iproute2-6.7.0, libbpf 1.2.3
*/
* or
* BusyBox v1.36.1 (2024-06-10 07:11:47 UTC) multi-call binary
*
* Busybox does not support the iproute2 configuration files.
*/
if (!strstr(buf, "iproute2"))
return;
if (strstr(buf, "BusyBox"))
return;

if (!(v = strchr(buf, '-')))
return;

v++;
if ((e = strchr(v, ',')))
*e = '\0';
sscanf(v, "%d.%d.%d", &ver_maj, &ver_min, &ver_rel);
if (sscanf(v, "%d.%d.%d", &ver_maj, &ver_min, &ver_rel) != 3)
return;

if (ver_maj >= 7 || (ver_maj == 6 && ver_min >= 12)) {
dir = IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE ".d";
path = IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE ".d/keepalived.conf" ;
Expand Down

0 comments on commit 889eb4c

Please sign in to comment.