6aaad0193d2b6d272bcfb31afb20bf421a278ad0
[fio.git] / client.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <limits.h>
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <sys/poll.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <sys/wait.h>
11 #include <sys/mman.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #include <netdb.h>
15
16 #include "fio.h"
17 #include "server.h"
18 #include "crc/crc32.h"
19
20 int fio_client_fd = -1;
21
22 int fio_client_connect(const char *host)
23 {
24         struct sockaddr_in addr;
25         int fd;
26
27         memset(&addr, 0, sizeof(addr));
28         addr.sin_family = AF_INET;
29         addr.sin_port = htons(fio_net_port);
30
31         if (inet_aton(host, &addr.sin_addr) != 1) {
32                 struct hostent *hent;
33
34                 hent = gethostbyname(host);
35                 if (!hent) {
36                         log_err("fio: gethostbyname: %s\n", strerror(errno));
37                         return 1;
38                 }
39
40                 memcpy(&addr.sin_addr, hent->h_addr, 4);
41         }
42
43         fd = socket(AF_INET, SOCK_STREAM, 0);
44         if (fd < 0) {
45                 log_err("fio: socket: %s\n", strerror(errno));
46                 return 1;
47         }
48
49         if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
50                 log_err("fio: connect: %s\n", strerror(errno));
51                 return 1;
52         }
53
54         fio_client_fd = fd;
55         return 0;
56 }
57
58 static int send_file_buf(char *buf, off_t size)
59 {
60         struct fio_net_cmd *cmd;
61         int ret;
62
63         cmd = malloc(sizeof(*cmd) + size);
64
65         fio_init_net_cmd(cmd);
66         cmd->opcode     = cpu_to_le16(FIO_NET_CMD_JOB_END);
67         cmd->pdu_len    = cpu_to_le32(size);
68
69         memcpy(&cmd->payload, buf, size);
70
71         fio_net_cmd_crc(cmd);
72
73         ret = fio_send_data(fio_client_fd, cmd, sizeof(*cmd) + size);
74         free(cmd);
75         return ret;
76 }
77
78 /*
79  * Send file contents to server backend. We could use sendfile(), but to remain
80  * more portable lets just read/write the darn thing.
81  */
82 int fio_client_send_ini(const char *filename)
83 {
84         struct stat sb;
85         char *p, *buf;
86         off_t len;
87         int fd, ret;
88
89         fd = open(filename, O_RDONLY);
90         if (fd < 0) {
91                 log_err("fio: job file open: %s\n", strerror(errno));
92                 return 1;
93         }
94
95         if (fstat(fd, &sb) < 0) {
96                 log_err("fio: job file stat: %s\n", strerror(errno));
97                 return 1;
98         }
99
100         buf = malloc(sb.st_size);
101
102         len = sb.st_size;
103         p = buf;
104         do {
105                 ret = read(fd, p, len);
106                 if (ret > 0) {
107                         len -= ret;
108                         if (!len)
109                                 break;
110                         p += ret;
111                         continue;
112                 } else if (!ret)
113                         break;
114                 else if (errno == EAGAIN || errno == EINTR)
115                         continue;
116         } while (1);
117
118         ret = send_file_buf(buf, sb.st_size);
119         free(buf);
120         return ret;
121 }
122
123 int fio_handle_clients(void)
124 {
125         struct fio_net_cmd *cmd;
126
127         while (!exit_backend) {
128                 cmd = fio_net_cmd_read(fio_client_fd);
129
130                 if (cmd->opcode == FIO_NET_CMD_ACK) {
131                         free(cmd);
132                         continue;
133                 }
134                 if (cmd->opcode != FIO_NET_CMD_TEXT) {
135                         printf("non text: %d\n", cmd->opcode);
136                         free(cmd);
137                         continue;
138                 }
139                 printf("%s", cmd->payload);
140                 fflush(stdout);
141                 free(cmd);
142         }
143
144         return 0;
145 }