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); }
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); } }
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 */ }