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
  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
  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 }