int
main(int argc, char **argv)
{
  char *port_number = NULL;
  int ch, sock, server_port = DEFAULT_SERVER_PORT;
  int debug_mode = 0;
  pthread_t signal_handler;

  while ((ch = getopt(argc, argv, "dp:")) != -1) {
    switch (ch) {
      case 'd':
        debug_mode = 1;
        break;
      case 'p':
        port_number = optarg;
        break;
      case '?':
      default:
        usage();
    }
  }
  argc -= optind;
  argv += optind;

  if (port_number != NULL)
    server_port = strtol(port_number, NULL, 0);

  /* server_portでlistenし,socket descriptorをsockに代入 */
  sock = open_accepting_socket(server_port);

  if (!debug_mode) {
    logutil_syslog_open(program_name, LOG_PID, LOG_LOCAL0);
    daemon(0, 0);
  }

  // シグナルマスクの作成
  sigemptyset(&signal_set);
  sigaddset(&signal_set, SIGINT);
  sigaddset(&signal_set, SIGTERM);
  pthread_sigmask(SIG_BLOCK, &signal_set, NULL);

  // シグナルハンドラスレッドの起動
  pthread_create(&signal_handler, NULL, (void *)handle_signal, NULL);

  /*
   * 無限ループでsockをacceptし,acceptしたらそのクライアント用
   * のスレッドを作成しプロトコル処理を続ける.
   */
  main_loop(sock);

  /*NOTREACHED*/
  return (0);
}
Exemple #2
0
void
session(struct xxx_connection *from_client, struct xxx_connection *to_client,
	int algorithm_version, int ndivisions, int interleave_factor,
	int send_stripe_sync,
	int n, gfarm_stringlist *files, gfarm_stringlist *sections)
{
	char *e, *pathname;
	gfarm_int32_t r;
	int i, listening_sock, *socks, ifd;
	long file_read_size;
	struct xxx_connection **conns;
	struct gfs_client_rep_rate_info **rinfos = NULL;
	file_offset_t file_size;
	struct stat st;

	struct sockaddr_in listen_addr, client_addr;
	socklen_t listen_addr_len, client_addr_len;

	if (rate_limit != 0) {
		rinfos = malloc(sizeof(*rinfos) * ndivisions);
		if (rinfos == NULL) {
			fprintf(stderr,
			    "%s: no memory for %d rate limits "
			    "on gfrebe_server %s\n",
			    program_name, ndivisions, my_name);
			fatal();
		}
		for (i = 0; i < ndivisions; i++) {
			rinfos[i] =
			    gfs_client_rep_rate_info_alloc(rate_limit);
			if (rinfos[i] == NULL) {
				fprintf(stderr,
				    "%s: no memory for %d/%d rate limit "
				    "on gfrebe_server %s\n",
				    program_name, i, ndivisions, my_name);
				fatal();
			}
		}
	}

	socks = malloc(sizeof(*socks) * ndivisions);
	conns = malloc(sizeof(*conns) * ndivisions);
	if (socks == NULL || conns == NULL) {
		if (socks != NULL)
			free(socks);
		if (conns != NULL)
			free(conns);
		fprintf(stderr,
		    "%s: no memory for %d connections on gfrebe_server %s\n",
		     program_name, ndivisions, my_name);
		fatal();
	}

	/*
	 * XXX FIXME: this port may be blocked by firewall.
	 * This should be implemented via gfsd connection passing service.
	 */

	listening_sock = open_accepting_socket();
	listen_addr_len = sizeof(listen_addr);
	if (getsockname(listening_sock,
	    (struct sockaddr *)&listen_addr, &listen_addr_len) == -1) {
		fprintf(stderr, "%s: getsockname: %s\n",
		    program_name, strerror(errno));
		fatal();
	}
	e = xxx_proto_send(to_client, "i", htons(listen_addr.sin_port));
	if (e == NULL)
		e = xxx_proto_flush(to_client);
	if (e != NULL) {
		fprintf(stderr,
		    "%s: while sending port number on %s: %s\n",
		     program_name, my_name, e);
		fatal();
	}

	/* XXX FIXME: make connections in parallel */
	for (i = 0; i < ndivisions; i++) {
		client_addr_len = sizeof(client_addr);
		socks[i] = accept(listening_sock,
		   (struct sockaddr *)&client_addr, &client_addr_len);
		if (socks[i] == -1) {
			if (errno == EINTR) {
				--i;
				continue;
			}
			fprintf(stderr,
			    "%s: while accepting sockets on %s: %s\n",
			     program_name, my_name, strerror(errno));
			fatal();
		}
		e = xxx_fd_connection_new(socks[i], &conns[i]);
		if (e != NULL) {
			fprintf(stderr,
			    "%s: while allocating connection %d on %s: %s\n",
			     program_name, i, my_name, e);
			fatal();
		}
		e = gfarm_authorize(conns[i], 1, NULL, NULL, NULL);
		if (e != NULL) {
			fprintf(stderr,
			    "%s: authorization on %s: %s\n",
			     program_name, my_name, e);
			fatal();
		}
		e = xxx_proto_send(conns[i], "i", i);
		if (e == NULL)
			e = xxx_proto_flush(conns[i]);
		if (e != NULL) {
			fprintf(stderr,
			    "%s: sending connection index on %s: %s\n",
			     program_name, my_name, e);
			fatal();
		}
	}
	close(listening_sock);

	e = gfarm_netparam_config_get_long(&gfarm_netparam_file_read_size,
	    NULL, (struct sockaddr *)&client_addr, &file_read_size);
	if (e != NULL) { /* shouldn't happen */
		fprintf(stderr, "%s: get netparam file_read_size on %s: %s\n",
		    program_name, my_name, e);
		fatal();
	}

	e = gfarm_netparam_config_get_long(&gfarm_netparam_rate_limit,
	    NULL, (struct sockaddr *)&client_addr, &rate_limit);
	if (e != NULL) { /* shouldn't happen */
		fprintf(stderr, "%s: get netparam rate_limit on %s: %s\n",
		    program_name, my_name, e);
		fatal();
	}

	for (i = 0; i < n; i++) {
		char *file = gfarm_stringlist_elem(files, i);
		char *section = gfarm_stringlist_elem(sections, i);

		/* NOTE: assumes current directory == spool_root */
		if (*section == '\0') {
			pathname = file;
		} else {
			pathname = malloc(strlen(file) + strlen(section) + 2);
			if (pathname == NULL) {
				fprintf(stderr,
				    "%s: no memory for pathname %s:%s"
				    " to replicate on %s\n",
				     program_name, file, section, my_name);
				fatal();
			}
			sprintf(pathname, "%s:%s", file, section);
		}
		ifd = open(pathname, O_RDONLY);
		if (ifd == -1) {
			r = gfs_errno_to_proto_error(errno);
		} else if (fstat(ifd, &st) == -1) {
			r = gfs_errno_to_proto_error(errno);
		} else {
			r = GFS_ERROR_NOERROR;
			file_size = st.st_size;
		}
		e = xxx_proto_send(conns[0], "i", r);
		if (e != NULL) {
			fprintf(stderr, "%s: send reply on %s\n",
			    program_name, my_name);
			fatal();
		}
		if (r != GFS_ERROR_NOERROR)
			continue;
		e = xxx_proto_send(conns[0], "o", file_size);
		if (e == NULL)
			e = xxx_proto_flush(conns[0]);
		if (e != NULL) {
			fprintf(stderr, "%s: send reply on %s\n",
			    program_name, my_name);
			fatal();
		}
		e = transfer(pathname, ifd, file_size, algorithm_version,
		    ndivisions, interleave_factor, file_read_size,
		    send_stripe_sync, conns, socks, rinfos,
		    &r);
		close(ifd);
		e = xxx_proto_send(conns[0], "i", r);
		if (e != NULL) {
			fprintf(stderr, "%s: send reply on %s\n",
			    program_name, my_name);
			fatal();
		}
		if (*section != '\0')
			free(pathname);
	}
	e = xxx_proto_flush(conns[0]);
	if (e != NULL) {
		fprintf(stderr, "%s: send reply on %s\n",
		    program_name, my_name);
		fatal();
	}

	for (i = 0; i < ndivisions; i++)
		xxx_connection_free(conns[i]);
	free(conns);
	free(socks);

	if (rinfos != NULL) {
		for (i = 0; i < ndivisions; i++)
			gfs_client_rep_rate_info_free(rinfos[i]);
		free(rinfos);
	}
}
Exemple #3
0
int
main(int argc, char **argv)
{
	extern char *optarg;
	extern int optind;
	char *e, *config_file = NULL, *port_number = NULL;
	int syslog_facility = GFARM_DEFAULT_FACILITY;
	int ch, sock, table_size;

	if (argc >= 1)
		program_name = basename(argv[0]);
	gflog_set_identifier(program_name);

	while ((ch = getopt(argc, argv, "df:p:s:")) != -1) {
		switch (ch) {
		case 'd':
			debug_mode = 1;
			break;
		case 'f':
			config_file = optarg;
			break;
		case 'p':
			port_number = optarg;
			break;
		case 's':
			syslog_facility =
			    gflog_syslog_name_to_facility(optarg);
			if (syslog_facility == -1)
				gflog_fatal(optarg, "unknown syslog facility");
			break;
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (config_file != NULL)
		gfarm_config_set_filename(config_file);
	e = gfarm_server_initialize();
	if (e != NULL) {
		fprintf(stderr, "gfarm_server_initialize: %s\n", e);
		exit(1);
	}
	if (port_number != NULL)
		gfarm_metadb_server_port = strtol(port_number, NULL, 0);
	sock = open_accepting_socket(gfarm_metadb_server_port);
	if (!debug_mode) {
		gflog_syslog_open(LOG_PID, syslog_facility);
		gfarm_daemon(0, 0);
	}

	table_size = GFMD_CONNECTION_LIMIT;
	gfarm_unlimit_nofiles(&table_size);
	if (table_size > GFMD_CONNECTION_LIMIT)
		table_size = GFMD_CONNECTION_LIMIT;
	file_table_init(table_size);
	job_table_init(table_size);

	/*
	 * We don't want SIGPIPE, but want EPIPE on write(2)/close(2).
	 */
	signal(SIGPIPE, SIG_IGN);

	main_loop(sock);

	/*NOTREACHED*/
	return (0); /* to shut up warning */
}