Line data Source code
1 : /* 2 : * vr_uvhost_client.c - client handling in user space vhost server that 3 : * peers with the vhost client inside qemu (version 2.1 and later). 4 : * 5 : * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. 6 : * Copyright Contributors to the OpenSDN project 7 : */ 8 : 9 : #include "vr_dpdk.h" 10 : #include "vr_uvhost_client.h" 11 : #include "vr_uvhost_util.h" 12 : #include "vr_uvhost_msg.h" 13 : 14 : static vr_uvh_client_t vr_uvh_clients[VR_UVH_MAX_CLIENTS]; 15 : 16 : /* 17 : * vr_uvhost_client_init - initialize the client array. 18 : */ 19 : void 20 53 : vr_uvhost_client_init(void) 21 : { 22 : int i; 23 : 24 230868 : for (i = 0; i < VR_UVH_MAX_CLIENTS; i++) { 25 230815 : vr_uvh_clients[i].vruc_fd = -1; 26 : } 27 : 28 53 : return; 29 : } 30 : 31 : /* 32 : * vr_uvhost_new_client - initializes state for a new user space vhost client 33 : * FD is a file descriptor for the client socket. path is the UNIX domain 34 : * socket path. cidx is the index of the client. 35 : * 36 : * Returns a pointer to the client state on success, NULL otherwise. 37 : */ 38 : vr_uvh_client_t * 39 332 : vr_uvhost_new_client(int fd, char *path, int cidx) 40 : { 41 332 : if (cidx >= VR_UVH_MAX_CLIENTS) { 42 0 : return NULL; 43 : } 44 : 45 332 : if (vr_uvh_clients[cidx].vruc_fd != -1) { 46 97 : return NULL; 47 : } 48 : 49 235 : vr_uvh_clients[cidx].vruc_fd = fd; 50 235 : strncpy(vr_uvh_clients[cidx].vruc_path, path, VR_UNIX_PATH_MAX - 1); 51 235 : vr_uvh_clients[cidx].vruc_flags = 0; 52 : 53 235 : return &vr_uvh_clients[cidx]; 54 : } 55 : 56 : /* 57 : * vr_uvhost_del_client - removes a vhost client. 58 : * 59 : * Returns nothing. 60 : */ 61 : void 62 166 : vr_uvhost_del_client(vr_uvh_client_t *vru_cl) 63 : { 64 : /* Remove both the socket we listen for and the socket we have accepted */ 65 166 : vr_uvhost_del_fds_by_arg(vru_cl); 66 : 67 : /* If a VIF is added but not connected, vru_cl->vruc_fd is not added to 68 : * the fd list even though it is created. This can happen when VM is 69 : * stopped. In this case, vr_uvhost_del_fds_by_arg() would not close 70 : * the fd. So, add the fcntl() call below to check if vruc_fd is closed 71 : * or not. 72 : * */ 73 166 : if(fcntl(vru_cl->vruc_fd, F_GETFL) != -1 ){ 74 166 : vr_uvhost_log("Closing socket fd: %d \n", vru_cl->vruc_fd); 75 166 : close(vru_cl->vruc_fd); 76 : } 77 : 78 166 : vru_cl->vruc_fd = -1; 79 166 : if (vru_cl->vruc_vhostuser_mode == VRNU_VIF_MODE_CLIENT) 80 0 : unlink(vru_cl->vruc_path); 81 166 : vru_cl->vruc_flags = 0; 82 : 83 166 : return; 84 : } 85 : 86 : /* 87 : * vr_uvhost_cl_set_fd - set the FD for a user space vhost client 88 : */ 89 : void 90 0 : vr_uvhost_cl_set_fd(vr_uvh_client_t *vru_cl, int fd) 91 : { 92 0 : vru_cl->vruc_fd = fd; 93 : 94 0 : return; 95 : } 96 : 97 : /* 98 : * vr_uvhost_get_client - Returns the client at the specified index, NULL if 99 : * it cannot be found. 100 : */ 101 : vr_uvh_client_t * 102 166 : vr_uvhost_get_client(unsigned int cidx) 103 : { 104 166 : if (cidx >= VR_UVH_MAX_CLIENTS) { 105 0 : return NULL; 106 : } 107 : 108 166 : return &vr_uvh_clients[cidx]; 109 : }