static struct sk_buff *tipc_show_stats(void) { struct sk_buff *buf; struct tlv_desc *rep_tlv; struct print_buf pb; int str_len; u32 value; if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); value = ntohl(*(u32 *)TLV_DATA(req_tlv_area)); if (value != 0) return tipc_cfg_reply_error_string("unsupported argument"); buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_STATS_INFO)); 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"); /* Use additional tipc_printf()'s to return more info ... */ str_len = tipc_printbuf_validate(&pb); skb_put(buf, TLV_SPACE(str_len)); TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); return buf; }
struct sk_buff *tipc_log_dump(void) { struct sk_buff *reply; spin_lock_bh(&print_lock); if (!TIPC_LOG->buf) { spin_unlock_bh(&print_lock); reply = tipc_cfg_reply_ultra_string("log not activated\n"); } else if (tipc_printbuf_empty(TIPC_LOG)) { spin_unlock_bh(&print_lock); reply = tipc_cfg_reply_ultra_string("log is empty\n"); } else { struct tlv_desc *rep_tlv; struct print_buf pb; int str_len; str_len = min(TIPC_LOG->size, 32768u); spin_unlock_bh(&print_lock); reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len)); if (reply) { rep_tlv = (struct tlv_desc *)reply->data; tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len); spin_lock_bh(&print_lock); tipc_printbuf_move(&pb, TIPC_LOG); spin_unlock_bh(&print_lock); str_len = strlen(TLV_DATA(rep_tlv)) + 1; skb_put(reply, TLV_SPACE(str_len)); TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); } } return reply; }
void tipc_log_reinit(int log_size) { tipc_log_stop(); if (log_size) { if (log_size < TIPC_PB_MIN_SIZE) log_size = TIPC_PB_MIN_SIZE; spin_lock_bh(&print_lock); tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), log_size); spin_unlock_bh(&print_lock); } }
static void disc_dupl_alert(struct tipc_bearer *b_ptr, u32 node_addr, struct tipc_media_addr *media_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); warn("Duplicate %s using %s seen on <%s>\n", node_addr_str, media_addr_str, b_ptr->name); }
int tipc_bclink_stats(char *buf, const u32 buf_size) { struct print_buf pb; 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); spin_unlock_bh(&bc_lock); return tipc_printbuf_validate(&pb); }
int tipc_bclink_init(void) { bcbearer = kmalloc(sizeof(*bcbearer), GFP_ATOMIC); bclink = kmalloc(sizeof(*bclink), GFP_ATOMIC); if (!bcbearer || !bclink) { nomem: warn("Multicast link creation failed, no memory\n"); kfree(bcbearer); bcbearer = NULL; kfree(bclink); bclink = NULL; return -ENOMEM; } memset(bcbearer, 0, sizeof(struct bcbearer)); INIT_LIST_HEAD(&bcbearer->bearer.cong_links); bcbearer->bearer.media = &bcbearer->media; bcbearer->media.send_msg = tipc_bcbearer_send; sprintf(bcbearer->media.name, "tipc-multicast"); bcl = &bclink->link; memset(bclink, 0, sizeof(struct bclink)); INIT_LIST_HEAD(&bcl->waiting_ports); bcl->next_out_no = 1; spin_lock_init(&bclink->node.lock); bcl->owner = &bclink->node; bcl->max_pkt = MAX_PKT_DEFAULT_MCAST; tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT); bcl->b_ptr = &bcbearer->bearer; bcl->state = WORKING_WORKING; sprintf(bcl->name, tipc_bclink_name); if (BCLINK_LOG_BUF_SIZE) { char *pb = kmalloc(BCLINK_LOG_BUF_SIZE, GFP_ATOMIC); if (!pb) goto nomem; tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE); } return TIPC_OK; }
int tipc_log_resize(int log_size) { int res = 0; spin_lock_bh(&print_lock); kfree(TIPC_LOG->buf); TIPC_LOG->buf = NULL; if (log_size) { if (log_size < TIPC_PB_MIN_SIZE) log_size = TIPC_PB_MIN_SIZE; res = TIPC_LOG->echo; tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), log_size); TIPC_LOG->echo = res; res = !TIPC_LOG->buf; } spin_unlock_bh(&print_lock); return res; }
int tipc_printbuf_validate(struct print_buf *pb) { char *err = "\n\n*** PRINT BUFFER OVERFLOW ***\n\n"; char *cp_buf; struct print_buf cb; if (!pb->buf) return 0; if (pb->buf[pb->size - 1] == 0) { cp_buf = kmalloc(pb->size, GFP_ATOMIC); if (cp_buf) { tipc_printbuf_init(&cb, cp_buf, pb->size); tipc_printbuf_move(&cb, pb); tipc_printbuf_move(pb, &cb); kfree(cp_buf); memcpy(pb->buf, err, strlen(err)); } else { tipc_printbuf_reset(pb); tipc_printf(pb, err); } } return (pb->crs - pb->buf + 1); }
void tipc_printbuf_reset(struct print_buf *pb) { tipc_printbuf_init(pb, pb->buf, pb->size); }