computing-offload/qtfs/ipc/uds_connector.c
Yikun Jiang a68570b5d9 Add computing offloading code
1. Add computing offloading code
2. Add script.md
3. Add virsh_demo.xml

Change-Id: Id9ef883e2f0eb727eb5448b9d1c47767f46b1021
Signed-off-by: Yikun Jiang <yikunkero@gmail.com>
2023-10-23 19:29:57 +08:00

161 lines
4.9 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******************************************************************************
* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
* qtfs licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
* PURPOSE.
* See the Mulan PSL v2 for more details.
* Author: Liqiang
* Create: 2023-03-20
* Description:
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <time.h>
#include <dlfcn.h>
#include <sys/types.h>
#include "uds_module.h"
#define LOG_OFF 1
#if LOG_OFF
#define uds_log(info, ...)
#define uds_err(info, ...)
#else
#define uds_log(info, ...) \
do { \
time_t t; \
struct tm p; \
time(&t); \
localtime_r(&t, &p); \
printf("[%d/%02d/%02d %02d:%02d:%02d][LOG:%s:%3d]"info"\n", \
p.tm_year + 1900, p.tm_mon+1, p.tm_mday, \
p.tm_hour, p.tm_min, p.tm_sec, __func__, __LINE__, ##__VA_ARGS__); \
} while (0);
#define uds_err(info, ...) \
do { \
time_t t; \
struct tm p; \
time(&t); \
localtime_r(&t, &p); \
printf("[%d/%02d/%02d %02d:%02d:%02d][LOG:%s:%3d]"info"\n", \
p.tm_year + 1900, p.tm_mon+1, p.tm_mday, \
p.tm_hour, p.tm_min, p.tm_sec, __func__, __LINE__, ##__VA_ARGS__); \
} while (0);
#endif
static unsigned short uds_conn_get_sock_type(int sockfd)
{
unsigned short type;
socklen_t len = 2;
int ret = getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &type, &len);
if (ret < 0) {
uds_err("get sock type failed, fd:%d", sockfd);
return (unsigned short)-1;
}
uds_log("fd:%d type:%d", sockfd, type);
return type;
}
static int uds_conn_whitelist_check(const char *path)
{
return 1;
}
int connect(int fd, const struct sockaddr *addrarg, socklen_t len)
{
int sock_fd;
typeof(connect) *libcconnect = NULL;
int libcret;
const struct sockaddr_un *addr = (const struct sockaddr_un *)addrarg;
if (libcconnect == NULL) {
libcconnect = dlsym(((void *) - 1l), "connect");
if (libcconnect == NULL) {
uds_err("can't find connect by dlsym.");
return -1;
}
}
libcret = (*libcconnect)(fd, addrarg, len);
if (libcret == 0 || addr->sun_family != AF_UNIX) {
// 如果本地connect成功或者非UNIX DOMAIN SOCKET都直接返回即可
return libcret;
}
if (strlen(addr->sun_path) >= (UDS_SUN_PATH_LEN - strlen(UDS_PROXY_SUFFIX))) {
uds_err("sun_path:<%s> len:%d is too large to add suffex:<%s>, so can't connect to uds proxy.",
addr->sun_path, strlen(addr->sun_path), UDS_PROXY_SUFFIX);
return libcret;
}
uds_log("enter uds connect fd:%d sunpath:%s family:%d len:%d ", fd, addr->sun_path, addr->sun_family, len);
// 本地未连接且是uds链接
if (!uds_conn_whitelist_check(addr->sun_path)) {
uds_err("path:%s not in white list", addr->sun_path);
return libcret;
}
// 尝试远端链接
do {
int ret;
struct uds_proxy_remote_conn_req remoteconn;
struct uds_proxy_remote_conn_rsp remotersp;
struct sockaddr_un proxy = {.sun_family = AF_UNIX};
sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock_fd < 0) {
uds_err("create socket failed");
return libcret;
}
strncpy(proxy.sun_path, UDS_BUILD_CONN_ADDR, sizeof(proxy.sun_path));
if ((*libcconnect)(sock_fd, (struct sockaddr *)&proxy, sizeof(struct sockaddr_un)) < 0) {
uds_err("can't connect to uds proxy: %s", UDS_BUILD_CONN_ADDR);
goto err_end;
}
// 这里type需要是第一个入参fd的type
remoteconn.type = uds_conn_get_sock_type(fd);
if (remoteconn.type == (unsigned short)-1) {
remoteconn.type = SOCK_STREAM;
}
memset(remoteconn.sun_path, 0, sizeof(remoteconn.sun_path));
strncpy(remoteconn.sun_path, addr->sun_path, sizeof(remoteconn.sun_path));
ret = send(sock_fd, &remoteconn, sizeof(remoteconn), 0);
if (ret <= 0) {
uds_err("send remote connect request failed, ret:%d errno:%d", ret, errno);
goto err_end;
}
ret = recv(sock_fd, &remotersp, sizeof(remotersp), MSG_WAITALL);
if (ret <= 0) {
uds_err("recv remote connect replay failed, ret:%d errno:%d", ret, errno);
goto err_end;
}
if (remotersp.ret == 0) {
goto err_end;
}
} while(0);
close(sock_fd);
struct sockaddr_un addr_proxy;
int sun_len = strlen(addr->sun_path);
memcpy(&addr_proxy, addr, sizeof(struct sockaddr_un));
memcpy(&addr_proxy.sun_path[sun_len], UDS_PROXY_SUFFIX, strlen(UDS_PROXY_SUFFIX));
addr_proxy.sun_path[sun_len + strlen(UDS_PROXY_SUFFIX)] = '\0';
return (*libcconnect)(fd, (const struct sockaddr *)&addr_proxy, sizeof(struct sockaddr_un));
err_end:
close(sock_fd);
return libcret;
}