Skip to content

Commit

Permalink
tipc: phase out most of the struct print_buf usage
Browse files Browse the repository at this point in the history
The tipc_printf is renamed to tipc_snprintf, as the new name
describes more what the function actually does.  It is also
changed to take a buffer and length parameter and return
number of characters written to the buffer.  All callers of
this function that used to pass a print_buf are updated.

Final removal of the struct print_buf itself will be done
synchronously with the pending removal of the deprecated
logging code that also was using it.

Functions that build up a response message with a list of
ports, nametable contents etc. are changed to return the number
of characters written to the output buffer. This information
was previously hidden in a field of the print_buf struct, and
the number of chars written was fetched with a call to
tipc_printbuf_validate.  This function is removed since it
is no longer referenced nor needed.

A generic max size ULTRA_STRING_MAX_LEN is defined, named
in keeping with the existing TIPC_TLV_ULTRA_STRING, and the
various definitions in port, link and nametable code that
largely duplicated this information are removed.  This means
that amount of link statistics that can be returned is now
increased from 2k to 32k.

The buffer overflow check is now done just before the reply
message is passed over netlink or TIPC to a remote node and
the message indicating a truncated buffer is changed to a less
dramatic one (less CAPS), placed at the end of the message.

Signed-off-by: Erik Hugne <erik.hugne@ericsson.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
  • Loading branch information
Erik Hugne authored and Paul Gortmaker committed Jul 13, 2012
1 parent e2dbd60 commit dc1aed3
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 222 deletions.
63 changes: 29 additions & 34 deletions net/tipc/bcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -701,48 +701,43 @@ void tipc_bcbearer_sort(void)

int tipc_bclink_stats(char *buf, const u32 buf_size)
{
struct print_buf pb;
int ret;
struct tipc_stats *s;

if (!bcl)
return 0;

tipc_printbuf_init(&pb, buf, buf_size);

spin_lock_bh(&bc_lock);

tipc_printf(&pb, "Link <%s>\n"
" Window:%u packets\n",
bcl->name, bcl->queue_limit[0]);
tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n",
bcl->stats.recv_info,
bcl->stats.recv_fragments,
bcl->stats.recv_fragmented,
bcl->stats.recv_bundles,
bcl->stats.recv_bundled);
tipc_printf(&pb, " TX packets:%u fragments:%u/%u bundles:%u/%u\n",
bcl->stats.sent_info,
bcl->stats.sent_fragments,
bcl->stats.sent_fragmented,
bcl->stats.sent_bundles,
bcl->stats.sent_bundled);
tipc_printf(&pb, " RX naks:%u defs:%u dups:%u\n",
bcl->stats.recv_nacks,
bcl->stats.deferred_recv,
bcl->stats.duplicates);
tipc_printf(&pb, " TX naks:%u acks:%u dups:%u\n",
bcl->stats.sent_nacks,
bcl->stats.sent_acks,
bcl->stats.retransmitted);
tipc_printf(&pb, " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n",
bcl->stats.bearer_congs,
bcl->stats.link_congs,
bcl->stats.max_queue_sz,
bcl->stats.queue_sz_counts
? (bcl->stats.accu_queue_sz / bcl->stats.queue_sz_counts)
: 0);
s = &bcl->stats;

ret = tipc_snprintf(buf, buf_size, "Link <%s>\n"
" Window:%u packets\n",
bcl->name, bcl->queue_limit[0]);
ret += tipc_snprintf(buf + ret, buf_size - ret,
" RX packets:%u fragments:%u/%u bundles:%u/%u\n",
s->recv_info, s->recv_fragments,
s->recv_fragmented, s->recv_bundles,
s->recv_bundled);
ret += tipc_snprintf(buf + ret, buf_size - ret,
" TX packets:%u fragments:%u/%u bundles:%u/%u\n",
s->sent_info, s->sent_fragments,
s->sent_fragmented, s->sent_bundles,
s->sent_bundled);
ret += tipc_snprintf(buf + ret, buf_size - ret,
" RX naks:%u defs:%u dups:%u\n",
s->recv_nacks, s->deferred_recv, s->duplicates);
ret += tipc_snprintf(buf + ret, buf_size - ret,
" TX naks:%u acks:%u dups:%u\n",
s->sent_nacks, s->sent_acks, s->retransmitted);
ret += tipc_snprintf(buf + ret, buf_size - ret,
" Congestion bearer:%u link:%u Send queue max:%u avg:%u\n",
s->bearer_congs, s->link_congs, s->max_queue_sz,
s->queue_sz_counts ?
(s->accu_queue_sz / s->queue_sz_counts) : 0);

spin_unlock_bh(&bc_lock);
return tipc_printbuf_validate(&pb);
return ret;
}

int tipc_bclink_reset_stats(void)
Expand Down
10 changes: 6 additions & 4 deletions net/tipc/bearer.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,23 @@ int tipc_register_media(struct tipc_media *m_ptr)
/**
* tipc_media_addr_printf - record media address in print buffer
*/
void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a)
{
char addr_str[MAX_ADDR_STR];
struct tipc_media *m_ptr;
int ret;

m_ptr = media_find_id(a->media_id);

if (m_ptr && !m_ptr->addr2str(a, addr_str, sizeof(addr_str)))
tipc_printf(pb, "%s(%s)", m_ptr->name, addr_str);
ret = tipc_snprintf(buf, len, "%s(%s)", m_ptr->name, addr_str);
else {
u32 i;

tipc_printf(pb, "UNKNOWN(%u)", a->media_id);
ret = tipc_snprintf(buf, len, "UNKNOWN(%u)", a->media_id);
for (i = 0; i < sizeof(a->value); i++)
tipc_printf(pb, "-%02x", a->value[i]);
ret += tipc_snprintf(buf - ret, len + ret,
"-%02x", a->value[i]);
}
}

Expand Down
2 changes: 1 addition & 1 deletion net/tipc/bearer.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ void tipc_eth_media_stop(void);

int tipc_media_set_priority(const char *name, u32 new_value);
int tipc_media_set_window(const char *name, u32 new_value);
void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a);
void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a);
struct sk_buff *tipc_media_get_names(void);

struct sk_buff *tipc_bearer_get_names(void);
Expand Down
27 changes: 18 additions & 9 deletions net/tipc/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#include "name_table.h"
#include "config.h"

#define REPLY_TRUNCATED "<truncated>\n"

static u32 config_port_ref;

static DEFINE_SPINLOCK(config_lock);
Expand Down Expand Up @@ -104,13 +106,12 @@ struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string)
return buf;
}

#define MAX_STATS_INFO 2000

static struct sk_buff *tipc_show_stats(void)
{
struct sk_buff *buf;
struct tlv_desc *rep_tlv;
struct print_buf pb;
char *pb;
int pb_len;
int str_len;
u32 value;

Expand All @@ -121,17 +122,16 @@ static struct sk_buff *tipc_show_stats(void)
if (value != 0)
return tipc_cfg_reply_error_string("unsupported argument");

buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_STATS_INFO));
buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
if (buf == NULL)
return NULL;

rep_tlv = (struct tlv_desc *)buf->data;
tipc_printbuf_init(&pb, (char *)TLV_DATA(rep_tlv), MAX_STATS_INFO);

tipc_printf(&pb, "TIPC version " TIPC_MOD_VER "\n");
pb = TLV_DATA(rep_tlv);
pb_len = ULTRA_STRING_MAX_LEN;

/* Use additional tipc_printf()'s to return more info ... */
str_len = tipc_printbuf_validate(&pb);
str_len = tipc_snprintf(pb, pb_len, "TIPC version " TIPC_MOD_VER "\n");
str_len += 1; /* for "\0" */
skb_put(buf, TLV_SPACE(str_len));
TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);

Expand Down Expand Up @@ -408,6 +408,15 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
break;
}

WARN_ON(rep_tlv_buf->len > TLV_SPACE(ULTRA_STRING_MAX_LEN));

/* Append an error message if we cannot return all requested data */
if (rep_tlv_buf->len == TLV_SPACE(ULTRA_STRING_MAX_LEN)) {
if (*(rep_tlv_buf->data + ULTRA_STRING_MAX_LEN) != '\0')
sprintf(rep_tlv_buf->data + rep_tlv_buf->len -
sizeof(REPLY_TRUNCATED) - 1, REPLY_TRUNCATED);
}

/* Return reply buffer */
exit:
spin_unlock_bh(&config_lock);
Expand Down
4 changes: 3 additions & 1 deletion net/tipc/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@

#define TIPC_MOD_VER "2.0.0"

#define ULTRA_STRING_MAX_LEN 32768

struct tipc_msg; /* msg.h */
struct print_buf; /* log.h */

Expand All @@ -82,7 +84,7 @@ extern struct print_buf *const TIPC_NULL;
extern struct print_buf *const TIPC_CONS;
extern struct print_buf *const TIPC_LOG;

void tipc_printf(struct print_buf *, const char *fmt, ...);
int tipc_snprintf(char *buf, int len, const char *fmt, ...);

/*
* TIPC_OUTPUT is the destination print buffer for system messages.
Expand Down
6 changes: 2 additions & 4 deletions net/tipc/discover.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,10 @@ static void disc_dupl_alert(struct tipc_bearer *b_ptr, u32 node_addr,
{
char node_addr_str[16];
char media_addr_str[64];
struct print_buf pb;

tipc_addr_string_fill(node_addr_str, node_addr);
tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str));
tipc_media_addr_printf(&pb, media_addr);
tipc_printbuf_validate(&pb);
tipc_media_addr_printf(media_addr_str, sizeof(media_addr_str),
media_addr);
pr_warn("Duplicate %s using %s seen on <%s>\n", node_addr_str,
media_addr_str, b_ptr->name);
}
Expand Down
130 changes: 66 additions & 64 deletions net/tipc/link.c
Original file line number Diff line number Diff line change
Expand Up @@ -2866,112 +2866,114 @@ static u32 percent(u32 count, u32 total)
*/
static int tipc_link_stats(const char *name, char *buf, const u32 buf_size)
{
struct print_buf pb;
struct tipc_link *l_ptr;
struct tipc_link *l;
struct tipc_stats *s;
struct tipc_node *node;
char *status;
u32 profile_total = 0;
int ret;

if (!strcmp(name, tipc_bclink_name))
return tipc_bclink_stats(buf, buf_size);

tipc_printbuf_init(&pb, buf, buf_size);

read_lock_bh(&tipc_net_lock);
l_ptr = link_find_link(name, &node);
if (!l_ptr) {
l = link_find_link(name, &node);
if (!l) {
read_unlock_bh(&tipc_net_lock);
return 0;
}
tipc_node_lock(node);
s = &l->stats;

if (tipc_link_is_active(l_ptr))
if (tipc_link_is_active(l))
status = "ACTIVE";
else if (tipc_link_is_up(l_ptr))
else if (tipc_link_is_up(l))
status = "STANDBY";
else
status = "DEFUNCT";
tipc_printf(&pb, "Link <%s>\n"
" %s MTU:%u Priority:%u Tolerance:%u ms"
" Window:%u packets\n",
l_ptr->name, status, l_ptr->max_pkt,
l_ptr->priority, l_ptr->tolerance, l_ptr->queue_limit[0]);
tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n",
l_ptr->next_in_no - l_ptr->stats.recv_info,
l_ptr->stats.recv_fragments,
l_ptr->stats.recv_fragmented,
l_ptr->stats.recv_bundles,
l_ptr->stats.recv_bundled);
tipc_printf(&pb, " TX packets:%u fragments:%u/%u bundles:%u/%u\n",
l_ptr->next_out_no - l_ptr->stats.sent_info,
l_ptr->stats.sent_fragments,
l_ptr->stats.sent_fragmented,
l_ptr->stats.sent_bundles,
l_ptr->stats.sent_bundled);
profile_total = l_ptr->stats.msg_length_counts;

ret = tipc_snprintf(buf, buf_size, "Link <%s>\n"
" %s MTU:%u Priority:%u Tolerance:%u ms"
" Window:%u packets\n",
l->name, status, l->max_pkt, l->priority,
l->tolerance, l->queue_limit[0]);

ret += tipc_snprintf(buf + ret, buf_size - ret,
" RX packets:%u fragments:%u/%u bundles:%u/%u\n",
l->next_in_no - s->recv_info, s->recv_fragments,
s->recv_fragmented, s->recv_bundles,
s->recv_bundled);

ret += tipc_snprintf(buf + ret, buf_size - ret,
" TX packets:%u fragments:%u/%u bundles:%u/%u\n",
l->next_out_no - s->sent_info, s->sent_fragments,
s->sent_fragmented, s->sent_bundles,
s->sent_bundled);

profile_total = s->msg_length_counts;
if (!profile_total)
profile_total = 1;
tipc_printf(&pb, " TX profile sample:%u packets average:%u octets\n"
" 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% "
"-16384:%u%% -32768:%u%% -66000:%u%%\n",
l_ptr->stats.msg_length_counts,
l_ptr->stats.msg_lengths_total / profile_total,
percent(l_ptr->stats.msg_length_profile[0], profile_total),
percent(l_ptr->stats.msg_length_profile[1], profile_total),
percent(l_ptr->stats.msg_length_profile[2], profile_total),
percent(l_ptr->stats.msg_length_profile[3], profile_total),
percent(l_ptr->stats.msg_length_profile[4], profile_total),
percent(l_ptr->stats.msg_length_profile[5], profile_total),
percent(l_ptr->stats.msg_length_profile[6], profile_total));
tipc_printf(&pb, " RX states:%u probes:%u naks:%u defs:%u dups:%u\n",
l_ptr->stats.recv_states,
l_ptr->stats.recv_probes,
l_ptr->stats.recv_nacks,
l_ptr->stats.deferred_recv,
l_ptr->stats.duplicates);
tipc_printf(&pb, " TX states:%u probes:%u naks:%u acks:%u dups:%u\n",
l_ptr->stats.sent_states,
l_ptr->stats.sent_probes,
l_ptr->stats.sent_nacks,
l_ptr->stats.sent_acks,
l_ptr->stats.retransmitted);
tipc_printf(&pb, " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n",
l_ptr->stats.bearer_congs,
l_ptr->stats.link_congs,
l_ptr->stats.max_queue_sz,
l_ptr->stats.queue_sz_counts
? (l_ptr->stats.accu_queue_sz / l_ptr->stats.queue_sz_counts)
: 0);

ret += tipc_snprintf(buf + ret, buf_size - ret,
" TX profile sample:%u packets average:%u octets\n"
" 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% "
"-16384:%u%% -32768:%u%% -66000:%u%%\n",
s->msg_length_counts,
s->msg_lengths_total / profile_total,
percent(s->msg_length_profile[0], profile_total),
percent(s->msg_length_profile[1], profile_total),
percent(s->msg_length_profile[2], profile_total),
percent(s->msg_length_profile[3], profile_total),
percent(s->msg_length_profile[4], profile_total),
percent(s->msg_length_profile[5], profile_total),
percent(s->msg_length_profile[6], profile_total));

ret += tipc_snprintf(buf + ret, buf_size - ret,
" RX states:%u probes:%u naks:%u defs:%u"
" dups:%u\n", s->recv_states, s->recv_probes,
s->recv_nacks, s->deferred_recv, s->duplicates);

ret += tipc_snprintf(buf + ret, buf_size - ret,
" TX states:%u probes:%u naks:%u acks:%u"
" dups:%u\n", s->sent_states, s->sent_probes,
s->sent_nacks, s->sent_acks, s->retransmitted);

ret += tipc_snprintf(buf + ret, buf_size - ret,
" Congestion bearer:%u link:%u Send queue"
" max:%u avg:%u\n", s->bearer_congs, s->link_congs,
s->max_queue_sz, s->queue_sz_counts ?
(s->accu_queue_sz / s->queue_sz_counts) : 0);

tipc_node_unlock(node);
read_unlock_bh(&tipc_net_lock);
return tipc_printbuf_validate(&pb);
return ret;
}

#define MAX_LINK_STATS_INFO 2000

struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space)
{
struct sk_buff *buf;
struct tlv_desc *rep_tlv;
int str_len;
int pb_len;
char *pb;

if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);

buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_LINK_STATS_INFO));
buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
if (!buf)
return NULL;

rep_tlv = (struct tlv_desc *)buf->data;

pb = TLV_DATA(rep_tlv);
pb_len = ULTRA_STRING_MAX_LEN;
str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area),
(char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO);
pb, pb_len);
if (!str_len) {
kfree_skb(buf);
return tipc_cfg_reply_error_string("link not found");
}

str_len += 1; /* for "\0" */
skb_put(buf, TLV_SPACE(str_len));
TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);

Expand Down
Loading

0 comments on commit dc1aed3

Please sign in to comment.