net/mlx5: replace IPC socket with EAL API
Socket API is used for IPC in order for secondary process to acquire Verb command file descriptor. The FD is used to remap UAR address. The multi-process APIs (rte_mp) in EAL are newly introduced. mlx5_socket.c is replaced with mlx5_mp.c, which uses the new APIs. As it is PMD global infrastructure, only one IPC channel is established. All the IPC message types may have port_id in the message if there is need to reference a specific device. Signed-off-by: Yongseok Koh <yskoh@mellanox.com> Acked-by: Shahaf Shuler <shahafs@mellanox.com>
This commit is contained in:
parent
3ebe658059
commit
9a8ab29b84
@ -34,7 +34,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_dv.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_tcf.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_verbs.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_socket.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_mp.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_nl.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_devx_cmds.c
|
||||
|
||||
|
@ -41,7 +41,7 @@ if build
|
||||
'mlx5_rxmode.c',
|
||||
'mlx5_rxq.c',
|
||||
'mlx5_rxtx.c',
|
||||
'mlx5_socket.c',
|
||||
'mlx5_mp.c',
|
||||
'mlx5_stats.c',
|
||||
'mlx5_trigger.c',
|
||||
'mlx5_txq.c',
|
||||
|
@ -325,6 +325,7 @@ mlx5_prepare_shared_data(void)
|
||||
rte_mem_event_callback_register("MLX5_MEM_EVENT_CB",
|
||||
mlx5_mr_mem_event_cb,
|
||||
NULL);
|
||||
mlx5_mp_init();
|
||||
}
|
||||
}
|
||||
rte_spinlock_unlock(&mlx5_shared_data_lock);
|
||||
@ -454,8 +455,6 @@ mlx5_dev_close(struct rte_eth_dev *dev)
|
||||
rte_free(priv->rss_conf.rss_key);
|
||||
if (priv->reta_idx != NULL)
|
||||
rte_free(priv->reta_idx);
|
||||
if (priv->primary_socket)
|
||||
mlx5_socket_uninit(dev);
|
||||
if (priv->config.vf)
|
||||
mlx5_nl_mac_addr_flush(dev);
|
||||
if (priv->nl_socket_route >= 0)
|
||||
@ -970,7 +969,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
|
||||
if (err)
|
||||
return NULL;
|
||||
/* Receive command fd from primary process */
|
||||
err = mlx5_socket_connect(eth_dev);
|
||||
err = mlx5_mp_req_verbs_cmd_fd(eth_dev);
|
||||
if (err < 0)
|
||||
return NULL;
|
||||
/* Remap UAR for Tx queues. */
|
||||
|
@ -56,6 +56,24 @@ enum {
|
||||
PCI_DEVICE_ID_MELLANOX_CONNECTX6VF = 0x101c,
|
||||
};
|
||||
|
||||
/* Request types for IPC. */
|
||||
enum mlx5_mp_req_type {
|
||||
MLX5_MP_REQ_VERBS_CMD_FD = 1,
|
||||
};
|
||||
|
||||
/* Pameters for IPC. */
|
||||
struct mlx5_mp_param {
|
||||
enum mlx5_mp_req_type type;
|
||||
int port_id;
|
||||
int result;
|
||||
};
|
||||
|
||||
/** Request timeout for IPC. */
|
||||
#define MLX5_MP_REQ_TIMEOUT_SEC 5
|
||||
|
||||
/** Key string for IPC. */
|
||||
#define MLX5_MP_NAME "net_mlx5_mp"
|
||||
|
||||
/** Switch information returned by mlx5_nl_switch_info(). */
|
||||
struct mlx5_switch_info {
|
||||
uint32_t master:1; /**< Master device. */
|
||||
@ -272,9 +290,7 @@ struct mlx5_priv {
|
||||
uint32_t link_speed_capa; /* Link speed capabilities. */
|
||||
struct mlx5_xstats_ctrl xstats_ctrl; /* Extended stats control. */
|
||||
struct mlx5_stats_ctrl stats_ctrl; /* Stats control. */
|
||||
int primary_socket; /* Unix socket for primary process. */
|
||||
void *uar_base; /* Reserved address space for UAR mapping */
|
||||
struct rte_intr_handle intr_handle_socket; /* Interrupt handler. */
|
||||
struct mlx5_dev_config config; /* Device configuration. */
|
||||
struct mlx5_verbs_alloc_ctx verbs_alloc_ctx;
|
||||
/* Context for Verbs allocator. */
|
||||
@ -432,12 +448,9 @@ int mlx5_ctrl_flow(struct rte_eth_dev *dev,
|
||||
int mlx5_flow_create_drop_queue(struct rte_eth_dev *dev);
|
||||
void mlx5_flow_delete_drop_queue(struct rte_eth_dev *dev);
|
||||
|
||||
/* mlx5_socket.c */
|
||||
|
||||
int mlx5_socket_init(struct rte_eth_dev *priv);
|
||||
void mlx5_socket_uninit(struct rte_eth_dev *priv);
|
||||
void mlx5_socket_handle(struct rte_eth_dev *priv);
|
||||
int mlx5_socket_connect(struct rte_eth_dev *priv);
|
||||
/* mlx5_mp.c */
|
||||
int mlx5_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev);
|
||||
void mlx5_mp_init(void);
|
||||
|
||||
/* mlx5_nl.c */
|
||||
|
||||
|
@ -1095,20 +1095,6 @@ mlx5_dev_interrupt_handler(void *cb_arg)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle interrupts from the socket.
|
||||
*
|
||||
* @param cb_arg
|
||||
* Callback argument.
|
||||
*/
|
||||
static void
|
||||
mlx5_dev_handler_socket(void *cb_arg)
|
||||
{
|
||||
struct rte_eth_dev *dev = cb_arg;
|
||||
|
||||
mlx5_socket_handle(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall shared asynchronous device events handler.
|
||||
* This function is implemeted to support event sharing
|
||||
@ -1208,14 +1194,7 @@ exit:
|
||||
void
|
||||
mlx5_dev_interrupt_handler_uninstall(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct mlx5_priv *priv = dev->data->dev_private;
|
||||
|
||||
mlx5_dev_shared_handler_uninstall(dev);
|
||||
if (priv->primary_socket)
|
||||
rte_intr_callback_unregister(&priv->intr_handle_socket,
|
||||
mlx5_dev_handler_socket, dev);
|
||||
priv->intr_handle_socket.fd = 0;
|
||||
priv->intr_handle_socket.type = RTE_INTR_HANDLE_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1227,20 +1206,7 @@ mlx5_dev_interrupt_handler_uninstall(struct rte_eth_dev *dev)
|
||||
void
|
||||
mlx5_dev_interrupt_handler_install(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct mlx5_priv *priv = dev->data->dev_private;
|
||||
int ret;
|
||||
|
||||
mlx5_dev_shared_handler_install(dev);
|
||||
ret = mlx5_socket_init(dev);
|
||||
if (ret)
|
||||
DRV_LOG(ERR, "port %u cannot initialise socket: %s",
|
||||
dev->data->port_id, strerror(rte_errno));
|
||||
else if (priv->primary_socket) {
|
||||
priv->intr_handle_socket.fd = priv->primary_socket;
|
||||
priv->intr_handle_socket.type = RTE_INTR_HANDLE_EXT;
|
||||
rte_intr_callback_register(&priv->intr_handle_socket,
|
||||
mlx5_dev_handler_socket, dev);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
139
drivers/net/mlx5/mlx5_mp.c
Normal file
139
drivers/net/mlx5/mlx5_mp.c
Normal file
@ -0,0 +1,139 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright 2019 6WIND S.A.
|
||||
* Copyright 2019 Mellanox Technologies, Ltd
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <rte_eal.h>
|
||||
#include <rte_ethdev_driver.h>
|
||||
#include <rte_string_fns.h>
|
||||
|
||||
#include "mlx5.h"
|
||||
#include "mlx5_utils.h"
|
||||
|
||||
/**
|
||||
* Initialize IPC message.
|
||||
*
|
||||
* @param[in] dev
|
||||
* Pointer to Ethernet structure.
|
||||
* @param[out] msg
|
||||
* Pointer to message to fill in.
|
||||
* @param[in] type
|
||||
* Message type.
|
||||
*/
|
||||
static inline void
|
||||
mp_init_msg(struct rte_eth_dev *dev, struct rte_mp_msg *msg,
|
||||
enum mlx5_mp_req_type type)
|
||||
{
|
||||
struct mlx5_mp_param *param = (struct mlx5_mp_param *)msg->param;
|
||||
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
strlcpy(msg->name, MLX5_MP_NAME, sizeof(msg->name));
|
||||
msg->len_param = sizeof(*param);
|
||||
param->type = type;
|
||||
param->port_id = dev->data->port_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* IPC message handler of primary process.
|
||||
*
|
||||
* @param[in] dev
|
||||
* Pointer to Ethernet structure.
|
||||
* @param[in] peer
|
||||
* Pointer to the peer socket path.
|
||||
*
|
||||
* @return
|
||||
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
||||
*/
|
||||
static int
|
||||
mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
|
||||
{
|
||||
struct rte_mp_msg mp_res;
|
||||
struct mlx5_mp_param *res = (struct mlx5_mp_param *)mp_res.param;
|
||||
const struct mlx5_mp_param *param =
|
||||
(const struct mlx5_mp_param *)mp_msg->param;
|
||||
struct rte_eth_dev *dev;
|
||||
struct mlx5_priv *priv;
|
||||
int ret;
|
||||
|
||||
assert(rte_eal_process_type() == RTE_PROC_PRIMARY);
|
||||
if (!rte_eth_dev_is_valid_port(param->port_id)) {
|
||||
rte_errno = ENODEV;
|
||||
DRV_LOG(ERR, "port %u invalid port ID", param->port_id);
|
||||
return -rte_errno;
|
||||
}
|
||||
dev = &rte_eth_devices[param->port_id];
|
||||
priv = dev->data->dev_private;
|
||||
switch (param->type) {
|
||||
case MLX5_MP_REQ_VERBS_CMD_FD:
|
||||
mp_init_msg(dev, &mp_res, param->type);
|
||||
mp_res.num_fds = 1;
|
||||
mp_res.fds[0] = priv->sh->ctx->cmd_fd;
|
||||
res->result = 0;
|
||||
ret = rte_mp_reply(&mp_res, peer);
|
||||
break;
|
||||
default:
|
||||
rte_errno = EINVAL;
|
||||
DRV_LOG(ERR, "port %u invalid mp request type",
|
||||
dev->data->port_id);
|
||||
return -rte_errno;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request Verbs command file descriptor for mmap to the primary process.
|
||||
*
|
||||
* @param[in] dev
|
||||
* Pointer to Ethernet structure.
|
||||
*
|
||||
* @return
|
||||
* fd on success, a negative errno value otherwise and rte_errno is set.
|
||||
*/
|
||||
int
|
||||
mlx5_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct rte_mp_msg mp_req;
|
||||
struct rte_mp_msg *mp_res;
|
||||
struct rte_mp_reply mp_rep;
|
||||
struct mlx5_mp_param *res;
|
||||
struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
|
||||
int ret;
|
||||
|
||||
assert(rte_eal_process_type() == RTE_PROC_SECONDARY);
|
||||
mp_init_msg(dev, &mp_req, MLX5_MP_REQ_VERBS_CMD_FD);
|
||||
ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
|
||||
if (ret) {
|
||||
DRV_LOG(ERR, "port %u request to primary process failed",
|
||||
dev->data->port_id);
|
||||
return -rte_errno;
|
||||
}
|
||||
assert(mp_rep.nb_received == 1);
|
||||
mp_res = &mp_rep.msgs[0];
|
||||
res = (struct mlx5_mp_param *)mp_res->param;
|
||||
if (res->result) {
|
||||
rte_errno = -res->result;
|
||||
DRV_LOG(ERR,
|
||||
"port %u failed to get command FD from primary process",
|
||||
dev->data->port_id);
|
||||
ret = -rte_errno;
|
||||
goto exit;
|
||||
}
|
||||
assert(mp_res->num_fds == 1);
|
||||
ret = mp_res->fds[0];
|
||||
DRV_LOG(DEBUG, "port %u command FD from primary is %d",
|
||||
dev->data->port_id, ret);
|
||||
exit:
|
||||
free(mp_rep.msgs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
mlx5_mp_init(void)
|
||||
{
|
||||
if (rte_eal_process_type() == RTE_PROC_PRIMARY)
|
||||
rte_mp_action_register(MLX5_MP_NAME, mp_primary_handle);
|
||||
}
|
@ -1,306 +0,0 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright 2016 6WIND S.A.
|
||||
* Copyright 2016 Mellanox Technologies, Ltd
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "mlx5.h"
|
||||
#include "mlx5_utils.h"
|
||||
|
||||
/**
|
||||
* Initialise the socket to communicate with the secondary process
|
||||
*
|
||||
* @param[in] dev
|
||||
* Pointer to Ethernet device.
|
||||
*
|
||||
* @return
|
||||
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
||||
*/
|
||||
int
|
||||
mlx5_socket_init(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct mlx5_priv *priv = dev->data->dev_private;
|
||||
struct sockaddr_un sun = {
|
||||
.sun_family = AF_UNIX,
|
||||
};
|
||||
int ret;
|
||||
int flags;
|
||||
|
||||
/*
|
||||
* Close the last socket that was used to communicate
|
||||
* with the secondary process
|
||||
*/
|
||||
if (priv->primary_socket)
|
||||
mlx5_socket_uninit(dev);
|
||||
/*
|
||||
* Initialise the socket to communicate with the secondary
|
||||
* process.
|
||||
*/
|
||||
ret = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (ret < 0) {
|
||||
rte_errno = errno;
|
||||
DRV_LOG(WARNING, "port %u secondary process not supported: %s",
|
||||
dev->data->port_id, strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
priv->primary_socket = ret;
|
||||
flags = fcntl(priv->primary_socket, F_GETFL, 0);
|
||||
if (flags == -1) {
|
||||
rte_errno = errno;
|
||||
goto error;
|
||||
}
|
||||
ret = fcntl(priv->primary_socket, F_SETFL, flags | O_NONBLOCK);
|
||||
if (ret < 0) {
|
||||
rte_errno = errno;
|
||||
goto error;
|
||||
}
|
||||
snprintf(sun.sun_path, sizeof(sun.sun_path), "/var/tmp/%s_%d",
|
||||
MLX5_DRIVER_NAME, priv->primary_socket);
|
||||
remove(sun.sun_path);
|
||||
ret = bind(priv->primary_socket, (const struct sockaddr *)&sun,
|
||||
sizeof(sun));
|
||||
if (ret < 0) {
|
||||
rte_errno = errno;
|
||||
DRV_LOG(WARNING,
|
||||
"port %u cannot bind socket, secondary process not"
|
||||
" supported: %s",
|
||||
dev->data->port_id, strerror(errno));
|
||||
goto close;
|
||||
}
|
||||
ret = listen(priv->primary_socket, 0);
|
||||
if (ret < 0) {
|
||||
rte_errno = errno;
|
||||
DRV_LOG(WARNING, "port %u secondary process not supported: %s",
|
||||
dev->data->port_id, strerror(errno));
|
||||
goto close;
|
||||
}
|
||||
return 0;
|
||||
close:
|
||||
remove(sun.sun_path);
|
||||
error:
|
||||
claim_zero(close(priv->primary_socket));
|
||||
priv->primary_socket = 0;
|
||||
return -rte_errno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-Initialise the socket to communicate with the secondary process
|
||||
*
|
||||
* @param[in] dev
|
||||
*/
|
||||
void
|
||||
mlx5_socket_uninit(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct mlx5_priv *priv = dev->data->dev_private;
|
||||
|
||||
MKSTR(path, "/var/tmp/%s_%d", MLX5_DRIVER_NAME, priv->primary_socket);
|
||||
claim_zero(close(priv->primary_socket));
|
||||
priv->primary_socket = 0;
|
||||
claim_zero(remove(path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle socket interrupts.
|
||||
*
|
||||
* @param dev
|
||||
* Pointer to Ethernet device.
|
||||
*/
|
||||
void
|
||||
mlx5_socket_handle(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct mlx5_priv *priv = dev->data->dev_private;
|
||||
int conn_sock;
|
||||
int ret = 0;
|
||||
struct cmsghdr *cmsg = NULL;
|
||||
struct ucred *cred = NULL;
|
||||
char buf[CMSG_SPACE(sizeof(struct ucred))] = { 0 };
|
||||
char vbuf[1024] = { 0 };
|
||||
struct iovec io = {
|
||||
.iov_base = vbuf,
|
||||
.iov_len = sizeof(*vbuf),
|
||||
};
|
||||
struct msghdr msg = {
|
||||
.msg_iov = &io,
|
||||
.msg_iovlen = 1,
|
||||
.msg_control = buf,
|
||||
.msg_controllen = sizeof(buf),
|
||||
};
|
||||
int *fd;
|
||||
|
||||
/* Accept the connection from the client. */
|
||||
conn_sock = accept(priv->primary_socket, NULL, NULL);
|
||||
if (conn_sock < 0) {
|
||||
DRV_LOG(WARNING, "port %u connection failed: %s",
|
||||
dev->data->port_id, strerror(errno));
|
||||
return;
|
||||
}
|
||||
ret = setsockopt(conn_sock, SOL_SOCKET, SO_PASSCRED, &(int){1},
|
||||
sizeof(int));
|
||||
if (ret < 0) {
|
||||
ret = errno;
|
||||
DRV_LOG(WARNING, "port %u cannot change socket options: %s",
|
||||
dev->data->port_id, strerror(rte_errno));
|
||||
goto error;
|
||||
}
|
||||
ret = recvmsg(conn_sock, &msg, MSG_WAITALL);
|
||||
if (ret < 0) {
|
||||
ret = errno;
|
||||
DRV_LOG(WARNING, "port %u received an empty message: %s",
|
||||
dev->data->port_id, strerror(rte_errno));
|
||||
goto error;
|
||||
}
|
||||
/* Expect to receive credentials only. */
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
if (cmsg == NULL) {
|
||||
DRV_LOG(WARNING, "port %u no message", dev->data->port_id);
|
||||
goto error;
|
||||
}
|
||||
if ((cmsg->cmsg_type == SCM_CREDENTIALS) &&
|
||||
(cmsg->cmsg_len >= sizeof(*cred))) {
|
||||
cred = (struct ucred *)CMSG_DATA(cmsg);
|
||||
assert(cred != NULL);
|
||||
}
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg);
|
||||
if (cmsg != NULL) {
|
||||
DRV_LOG(WARNING, "port %u message wrongly formatted",
|
||||
dev->data->port_id);
|
||||
goto error;
|
||||
}
|
||||
/* Make sure all the ancillary data was received and valid. */
|
||||
if ((cred == NULL) || (cred->uid != getuid()) ||
|
||||
(cred->gid != getgid())) {
|
||||
DRV_LOG(WARNING, "port %u wrong credentials",
|
||||
dev->data->port_id);
|
||||
goto error;
|
||||
}
|
||||
/* Set-up the ancillary data. */
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
assert(cmsg != NULL);
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(priv->sh->ctx->cmd_fd));
|
||||
fd = (int *)CMSG_DATA(cmsg);
|
||||
*fd = priv->sh->ctx->cmd_fd;
|
||||
ret = sendmsg(conn_sock, &msg, 0);
|
||||
if (ret < 0)
|
||||
DRV_LOG(WARNING, "port %u cannot send response",
|
||||
dev->data->port_id);
|
||||
error:
|
||||
close(conn_sock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the primary process.
|
||||
*
|
||||
* @param[in] dev
|
||||
* Pointer to Ethernet structure.
|
||||
*
|
||||
* @return
|
||||
* fd on success, negative errno value otherwise and rte_errno is set.
|
||||
*/
|
||||
int
|
||||
mlx5_socket_connect(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct mlx5_priv *priv = dev->data->dev_private;
|
||||
struct sockaddr_un sun = {
|
||||
.sun_family = AF_UNIX,
|
||||
};
|
||||
int socket_fd = -1;
|
||||
int *fd = NULL;
|
||||
int ret;
|
||||
struct ucred *cred;
|
||||
char buf[CMSG_SPACE(sizeof(*cred))] = { 0 };
|
||||
char vbuf[1024] = { 0 };
|
||||
struct iovec io = {
|
||||
.iov_base = vbuf,
|
||||
.iov_len = sizeof(*vbuf),
|
||||
};
|
||||
struct msghdr msg = {
|
||||
.msg_control = buf,
|
||||
.msg_controllen = sizeof(buf),
|
||||
.msg_iov = &io,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
ret = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (ret < 0) {
|
||||
rte_errno = errno;
|
||||
DRV_LOG(WARNING, "port %u cannot connect to primary",
|
||||
dev->data->port_id);
|
||||
goto error;
|
||||
}
|
||||
socket_fd = ret;
|
||||
snprintf(sun.sun_path, sizeof(sun.sun_path), "/var/tmp/%s_%d",
|
||||
MLX5_DRIVER_NAME, priv->primary_socket);
|
||||
ret = connect(socket_fd, (const struct sockaddr *)&sun, sizeof(sun));
|
||||
if (ret < 0) {
|
||||
rte_errno = errno;
|
||||
DRV_LOG(WARNING, "port %u cannot connect to primary",
|
||||
dev->data->port_id);
|
||||
goto error;
|
||||
}
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
if (cmsg == NULL) {
|
||||
rte_errno = EINVAL;
|
||||
DRV_LOG(DEBUG, "port %u cannot get first message",
|
||||
dev->data->port_id);
|
||||
goto error;
|
||||
}
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_CREDENTIALS;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(*cred));
|
||||
cred = (struct ucred *)CMSG_DATA(cmsg);
|
||||
if (cred == NULL) {
|
||||
rte_errno = EINVAL;
|
||||
DRV_LOG(DEBUG, "port %u no credentials received",
|
||||
dev->data->port_id);
|
||||
goto error;
|
||||
}
|
||||
cred->pid = getpid();
|
||||
cred->uid = getuid();
|
||||
cred->gid = getgid();
|
||||
ret = sendmsg(socket_fd, &msg, MSG_DONTWAIT);
|
||||
if (ret < 0) {
|
||||
rte_errno = errno;
|
||||
DRV_LOG(WARNING,
|
||||
"port %u cannot send credentials to primary: %s",
|
||||
dev->data->port_id, strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
ret = recvmsg(socket_fd, &msg, MSG_WAITALL);
|
||||
if (ret <= 0) {
|
||||
rte_errno = errno;
|
||||
DRV_LOG(WARNING, "port %u no message from primary: %s",
|
||||
dev->data->port_id, strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
if (cmsg == NULL) {
|
||||
rte_errno = EINVAL;
|
||||
DRV_LOG(WARNING, "port %u no file descriptor received",
|
||||
dev->data->port_id);
|
||||
goto error;
|
||||
}
|
||||
fd = (int *)CMSG_DATA(cmsg);
|
||||
if (*fd < 0) {
|
||||
DRV_LOG(WARNING, "port %u no file descriptor received: %s",
|
||||
dev->data->port_id, strerror(errno));
|
||||
rte_errno = *fd;
|
||||
goto error;
|
||||
}
|
||||
ret = *fd;
|
||||
close(socket_fd);
|
||||
return ret;
|
||||
error:
|
||||
if (socket_fd != -1)
|
||||
close(socket_fd);
|
||||
return -rte_errno;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user