rdma-core rsocket сервер-получатель connect fork новый подпроцесс, отправка return 13 разрешение отклонено - PullRequest
0 голосов
/ 10 февраля 2020

Сейчас я тестирую rdma-core с помощью fork.

На сервере я использую rselect и raccept для получения соединения rsocket от клиента. Сервер может успешно получить сообщение от клиента. Но сервер не может отправить клиенту. Возврат -1 и ошибочное разрешение 13 отклонено. Тот же код без rsocket, он пошлет ОК. Для rsocket rdma-core / librdmacm, как поддерживать fork?

int main(int argc,char *argv[])
{
    int ret;
    int server_sockfd, client_sockfd;
    int server_len, client_len;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;
    memset(&server_address,0,sizeof(server_address));
    memset(&client_address,0,sizeof(client_address));
    int result;
    fd_set readfds, testfds;
    int maxfd;
    int on=1;

    server_sockfd = rsocket(AF_INET, SOCK_STREAM, 0);
    setsockopt(server_sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(8888);
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);

    ret = rbind(server_sockfd,(struct sockaddr *)&server_address,sizeof(server_address));
    printf("rbind retunr %d\n", ret);
    ret = rlisten(server_sockfd,5);
    printf("rlisten retunr %d\n", ret);

    //set fd_set
    FD_ZERO(&readfds);
    FD_SET(server_sockfd,&readfds);
    maxfd = server_sockfd + 1;

    while(1)
    {
        char ch;
        int fd,i;
        int nread;
        testfds = readfds;
        result = rselect(FD_SETSIZE, &testfds, NULL, NULL, NULL);
        printf("rselect retunr %d\n", result);
        if(result < 1)
        {
            printf("server5\n");
            exit(1);
        }


        for( fd = 1; fd < maxfd; fd++)
        {
            if(FD_ISSET(fd,&testfds))
            {
                if(fd == server_sockfd)
                {
                    memset(&client_address,0,sizeof(client_address));
                    client_len = sizeof(client_address);
                    client_sockfd = raccept(server_sockfd,(struct sockaddr *)&client_address,&client_len);

                    if(fork()==0)
                    {


                        setsockopt(client_sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
                        rclose(server_sockfd);
                        ret = rrecv(client_sockfd,&ch,1,0);

                        printf("recv from client : %c, ret %d\n",ch, ret);
                        sleep(2);
                        ch++;
                        ret = rsend(client_sockfd,&ch,1,0);
                        printf("rsend to client : %c, ret %d, erro %d\n",ch, ret, errno);
                    }
                }
            }
        }
    }
}

1 Ответ

0 голосов
/ 11 февраля 2020

Как видно из справочной страницы rsocket :

Библиотеку предварительной загрузки можно использовать, задав LD_PRELOAD во время работы. Обратите внимание, что не все приложения будут работать с rsockets. Поддержка ограничена в зависимости от параметров сокетов, используемых приложением. Поддержка fork () ограничена, но доступна. Чтобы использовать rsockets с библиотекой предварительной загрузки для приложений, которые вызывают fork, пользователи должны установить переменную среды RDMAV_FORK_SAFE = 1 как на стороне клиента, так и на стороне соединения. В общем случае fork поддерживается для серверных приложений, которые принимают соединение, а затем отключают процесс для обработки нового соединения.

Насколько я вижу, для использования rsockets с fork необходимо :

  1. Используйте API сокетов как на вашем клиенте, так и на ваших серверах (вместо непосредственного использования вызовов rsocket).
  2. Запустите клиент и ваш сервер с этими переменными среды: RDMAV_FORK_SAFE=1 LD_PRELOAD=/usr/lib/x86_64-linux-gnu/rsocket/librspreload.so (или измените путь в соответствии с тем, где librspreload.so установлен в вашей системе).

Без использования LD_PRELOAD кажется, что fork не поддерживается, то есть дочерний процесс не может использовать rsockets, что родитель создал.

...