1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 #include "filebench.h"
28 #include "multi_client_sync.h"
29 #include <netdb.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <errno.h>
33
34 #define MCS_NAMELENGTH 128
35 #define MCS_MSGLENGTH (MCS_NAMELENGTH * 8)
36
37 static int mc_sync_sock_id;
38 static char this_client_name[MCS_NAMELENGTH];
39
40 /*
41 * Open a socket to the master synchronization host
42 */
43 int
mc_sync_open_sock(char * master_name,int master_port,char * my_name)44 mc_sync_open_sock(char *master_name, int master_port, char *my_name)
45 {
46 struct sockaddr_in client_in;
47 struct sockaddr_in master_in;
48 struct hostent master_info;
49 int error_num;
50 char buffer[MCS_MSGLENGTH];
51
52 (void) strncpy(this_client_name, my_name, MCS_NAMELENGTH);
53 if ((mc_sync_sock_id = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
54 filebench_log(LOG_ERROR, "could not create a client socket");
55 return (FILEBENCH_ERROR);
56 }
57
58 client_in.sin_family = AF_INET;
59 client_in.sin_port = INADDR_ANY;
60 client_in.sin_addr.s_addr = INADDR_ANY;
61
62 if (bind(mc_sync_sock_id, (struct sockaddr *)&client_in,
63 sizeof (client_in)) == -1) {
64 filebench_log(LOG_ERROR, "could not bind to client socket");
65 return (FILEBENCH_ERROR);
66 }
67
68 if (gethostbyname_r(master_name, &master_info, buffer, MCS_MSGLENGTH,
69 &error_num) == NULL) {
70 filebench_log(LOG_ERROR, "could not locate sync master");
71 return (FILEBENCH_ERROR);
72 }
73
74 master_in.sin_family = AF_INET;
75 master_in.sin_port = htons((uint16_t)master_port);
76 (void) memcpy(&master_in.sin_addr.s_addr, *master_info.h_addr_list,
77 sizeof (master_in.sin_addr.s_addr));
78
79 if (connect(mc_sync_sock_id, (struct sockaddr *)&master_in,
80 sizeof (master_in)) == -1) {
81 filebench_log(LOG_ERROR,
82 "connection refused to sync master, error %d", errno);
83 return (FILEBENCH_ERROR);
84 }
85
86 return (FILEBENCH_OK);
87 }
88
89 /*
90 * Send a synchronization message and wait for a reply
91 */
92 int
mc_sync_synchronize(int sync_point)93 mc_sync_synchronize(int sync_point)
94 {
95 char msg[MCS_MSGLENGTH];
96 int amnt;
97
98 (void) snprintf(msg, MCS_MSGLENGTH,
99 "cmd=SYNC,id=xyzzy,name=%s,sample=%d\n",
100 this_client_name, sync_point);
101 (void) send(mc_sync_sock_id, msg, strlen(msg), 0);
102
103 amnt = 0;
104 msg[0] = 0;
105
106 while (strchr(msg, '\n') == NULL)
107 amnt += recv(mc_sync_sock_id, msg, sizeof (msg), 0);
108
109 filebench_log(LOG_INFO, "sync point %d succeeded!\n", sync_point);
110 return (FILEBENCH_OK);
111 }
112