Fix bug of `sysctl` in tools/compat/sysctl.c.

The ff msg shouldn't to free while `ff_ipc_send` success but `ff_ipc_recv` failed (such as F-Stack app are breaking by gdb).
This commit is contained in:
fengbojiang 2020-11-21 21:27:55 +08:00
parent a4f09e1c9b
commit 62653ab1a5
3 changed files with 21 additions and 14 deletions

View File

@ -443,6 +443,8 @@ ff_msg_init(struct rte_mempool *mp,
msg->msg_type = FF_UNKNOWN; msg->msg_type = FF_UNKNOWN;
msg->buf_addr = (char *)msg + sizeof(struct ff_msg); msg->buf_addr = (char *)msg + sizeof(struct ff_msg);
msg->buf_len = mp->elt_size - sizeof(struct ff_msg); msg->buf_len = mp->elt_size - sizeof(struct ff_msg);
msg->original_buf = NULL;
msg->original_buf_len = 0;
} }
static int static int

View File

@ -137,6 +137,8 @@ struct ff_msg {
size_t buf_len; size_t buf_len;
/* Address of segment buffer. */ /* Address of segment buffer. */
char *buf_addr; char *buf_addr;
char *original_buf;
size_t original_buf_len;
union { union {
struct ff_sysctl_args sysctl; struct ff_sysctl_args sysctl;

View File

@ -30,13 +30,23 @@
#include "ff_ipc.h" #include "ff_ipc.h"
#define FREE_FF_MSG(m) do { \
if (m->original_buf) { \
rte_free(m->buf_addr); \
m->buf_addr = m->original_buf; \
m->buf_len = m->original_buf_len; \
m->original_buf = NULL; \
} \
ff_ipc_msg_free(m); \
} while (0);
int int
sysctl(int *name, unsigned namelen, void *old, sysctl(int *name, unsigned namelen, void *old,
size_t *oldlenp, const void *new, size_t newlen) size_t *oldlenp, const void *new, size_t newlen)
{ {
struct ff_msg *msg, *retmsg = NULL; struct ff_msg *msg, *retmsg = NULL;
char *extra_buf = NULL, *original_buf = NULL; char *extra_buf = NULL;
size_t total_len, original_buf_len; size_t total_len;
if (old != NULL && oldlenp == NULL) { if (old != NULL && oldlenp == NULL) {
errno = EINVAL; errno = EINVAL;
@ -62,8 +72,8 @@ sysctl(int *name, unsigned namelen, void *old,
ff_ipc_msg_free(msg); ff_ipc_msg_free(msg);
return -1; return -1;
} }
original_buf = msg->buf_addr; msg->original_buf = msg->buf_addr;
original_buf_len = msg->buf_len; msg->original_buf_len = msg->buf_len;
msg->buf_addr = extra_buf; msg->buf_addr = extra_buf;
msg->buf_len = total_len; msg->buf_len = total_len;
} }
@ -113,12 +123,12 @@ sysctl(int *name, unsigned namelen, void *old,
do { do {
if (retmsg != NULL) { if (retmsg != NULL) {
ff_ipc_msg_free(retmsg); FREE_FF_MSG(retmsg)
} }
ret = ff_ipc_recv(&retmsg, msg->msg_type); ret = ff_ipc_recv(&retmsg, msg->msg_type);
if (ret < 0) { if (ret < 0) {
errno = EPIPE; errno = EPIPE;
goto error; return -1;
} }
} while (msg != retmsg); } while (msg != retmsg);
@ -137,14 +147,7 @@ sysctl(int *name, unsigned namelen, void *old,
} }
error: error:
if (original_buf) { FREE_FF_MSG(msg)
msg->buf_addr = original_buf;
msg->buf_len = original_buf_len;
}
ff_ipc_msg_free(msg);
if (extra_buf) {
rte_free(extra_buf);
}
return ret; return ret;
} }