Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: Memory spike reduction for sh cmds at scale #16672

Merged
merged 1 commit into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions lib/vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,17 @@ int vty_out(struct vty *vty, const char *format, ...)
case VTY_SHELL_SERV:
case VTY_FILE:
default:
vty->vty_buf_size_accumulated += strlen(filtered);
/* print without crlf replacement */
buffer_put(vty->obuf, (uint8_t *)filtered, strlen(filtered));
/* For every chunk of memory, we invoke vtysh_flush where we
* put the data of collective vty->obuf Linked List items on the
* socket and free the vty->obuf data.
*/
if (vty->vty_buf_size_accumulated >= VTY_MAX_INTERMEDIATE_FLUSH) {
vty->vty_buf_size_accumulated = 0;
vtysh_flush(vty);
}
break;
}

Expand Down Expand Up @@ -2118,6 +2127,8 @@ static void vtysh_accept(struct event *thread)
int client_len;
struct sockaddr_un client;
struct vty *vty;
int ret = 0;
uint32_t sndbufsize = VTY_SEND_BUF_MAX;

vty_event_serv(VTYSH_SERV, vtyserv);

Expand All @@ -2141,6 +2152,20 @@ static void vtysh_accept(struct event *thread)
close(sock);
return;
}

/*
* Increasing the SEND socket buffer size so that the socket can hold
* before sending it to VTY shell.
*/
ret = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&sndbufsize,
sizeof(sndbufsize));
if (ret < 0) {
flog_err(EC_LIB_SOCKET,
"Cannot set socket %d send buffer size, %s", sock,
safe_strerror(errno));
close(sock);
return;
}
set_cloexec(sock);

#ifdef VTYSH_DEBUG
Expand Down Expand Up @@ -2227,6 +2252,7 @@ static int vtysh_flush(struct vty *vty)
vty_close(vty);
return -1;
case BUFFER_EMPTY:
vty->vty_buf_size_accumulated = 0;
break;
}
return 0;
Expand Down
7 changes: 7 additions & 0 deletions lib/vty.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ struct vty {
uintptr_t mgmt_req_pending_data;
bool mgmt_locked_candidate_ds;
bool mgmt_locked_running_ds;
uint64_t vty_buf_size_accumulated;
};

static inline void vty_push_context(struct vty *vty, int node, uint64_t id)
Expand Down Expand Up @@ -338,6 +339,12 @@ struct vty_arg {
/* Vty read buffer size. */
#define VTY_READ_BUFSIZ 512

/* Vty max send buffer size */
#define VTY_SEND_BUF_MAX 16777216

/* Vty flush intermediate size */
#define VTY_MAX_INTERMEDIATE_FLUSH 131072

/* Directory separator. */
#ifndef DIRECTORY_SEP
#define DIRECTORY_SEP '/'
Expand Down
17 changes: 17 additions & 0 deletions vtysh/vtysh.c
Original file line number Diff line number Diff line change
Expand Up @@ -4639,6 +4639,7 @@ static int vtysh_connect(struct vtysh_client *vclient)
struct sockaddr_un addr;
struct stat s_stat;
const char *path;
uint32_t rcvbufsize = VTYSH_RCV_BUF_MAX;

if (!vclient->path[0])
snprintf(vclient->path, sizeof(vclient->path), "%s/%s.vty",
Expand Down Expand Up @@ -4688,6 +4689,22 @@ static int vtysh_connect(struct vtysh_client *vclient)
close(sock);
return -1;
}

/*
* Increasing the RECEIVE socket buffer size so that the socket can hold
* after receving from other process.
*/
ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&rcvbufsize,
sizeof(rcvbufsize));
if (ret < 0) {
#ifdef DEBUG
fprintf(stderr, "Cannot set socket %d rcv buffer size, %s\n",
sock, safe_strerror(errno));
#endif /* DEBUG */
close(sock);
return -1;
}

vclient->fd = sock;

return 0;
Expand Down
2 changes: 2 additions & 0 deletions vtysh/vtysh.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ extern struct event_loop *master;
#define VTYSH_PIM6D 0x100000
#define VTYSH_MGMTD 0x200000

#define VTYSH_RCV_BUF_MAX 16777216

#define VTYSH_WAS_ACTIVE (-2)

/* commands in REALLYALL are crucial to correct vtysh operation */
Expand Down
Loading