char * gfm_server_put_reply(struct xxx_connection *client, char *diag, int ecode, char *format, ...) { va_list ap; char *e; va_start(ap, format); e = xxx_proto_send(client, "i", (gfarm_int32_t)ecode); if (e != NULL) { gflog_warning(diag, e); return (e); } if (ecode == GFJ_ERROR_NOERROR) { e = xxx_proto_vsend(client, &format, &ap); if (e != NULL) { gflog_warning(diag, e); return (e); } } va_end(ap); if (ecode == 0 && *format != '\0') gflog_fatal(diag, "invalid format character to put reply"); return (NULL); }
static gfarm_error_t gfs_readdir_caching_internal(GFS_Dir super, struct gfs_dirent **entryp) { struct gfs_dir_caching *dir = (struct gfs_dir_caching *)super; struct gfs_dirent *ep; struct gfs_stat *stp; char *path; gfarm_error_t e = gfs_readdirplus(dir->dp, &ep, &stp); if (e != GFARM_ERR_NO_ERROR) return (e); if (ep != NULL) { /* i.e. not EOF */ GFARM_MALLOC_ARRAY(path, strlen(dir->path) + strlen(ep->d_name) + 1); if (path == NULL) { /* * It's ok to fail in entering the cache, * since it's merely cache. */ gflog_warning(GFARM_MSG_UNUSED, "dircache: failed to cache %s%s due to no memory", dir->path, ep->d_name); } else { struct timeval now; gettimeofday(&now, NULL); sprintf(path, "%s%s", dir->path, ep->d_name); #ifdef DIRCACHE_DEBUG gflog_debug(GFARM_MSG_1000094, "%ld.%06ld: gfs_readdir_caching()->" "\"%s\" (%d)", (long)now.tv_sec, (long)now.tv_usec, path, stat_cache_count); #endif /* * It's ok to fail in entering the cache, * since it's merely cache. */ if ((e = gfs_stat_cache_enter_internal(path, stp, &now)) != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_UNUSED, "dircache: failed to cache %s: %s", path, gfarm_error_string(e)); } free(path); } } *entryp = ep; return (GFARM_ERR_NO_ERROR); }
int open_accepting_socket(int port) { char *e; struct sockaddr_in self_addr; socklen_t self_addr_size; int sock, sockopt; memset(&self_addr, 0, sizeof(self_addr)); self_addr.sin_family = AF_INET; self_addr.sin_addr.s_addr = INADDR_ANY; self_addr.sin_port = htons(port); self_addr_size = sizeof(self_addr); sock = socket(PF_INET, SOCK_STREAM, 0); if (sock < 0) gflog_fatal_errno("accepting socket"); sockopt = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)) == -1) gflog_warning_errno("SO_REUSEADDR"); if (bind(sock, (struct sockaddr *)&self_addr, self_addr_size) < 0) gflog_fatal_errno("bind accepting socket"); e = gfarm_sockopt_apply_listener(sock); if (e != NULL) gflog_warning("setsockopt", e); if (listen(sock, LISTEN_BACKLOG) < 0) gflog_fatal_errno("listen"); return (sock); }
void service(int client_socket) { struct xxx_connection *client; char *e; int eof; gfarm_int32_t request; char buffer[GFARM_INT32STRLEN]; client = file_table[client_socket].conn; e = xxx_proto_recv(client, 0, &eof, "i", &request); if (eof) { file_table_close(client_socket); return; } if (e != NULL) { gflog_warning("request number", e); return; } switch (request) { case GFJ_PROTO_LOCK_REGISTER: e = gfj_server_lock_register(client); break; case GFJ_PROTO_UNLOCK_REGISTER: e = gfj_server_unlock_register(client); break; case GFJ_PROTO_REGISTER: e = gfj_server_register(client_socket); break; case GFJ_PROTO_UNREGISTER: e = gfj_server_unregister(client_socket); break; case GFJ_PROTO_REGISTER_NODE: e = gfj_server_register_node(client); break; case GFJ_PROTO_LIST: e = gfj_server_list(client); break; case GFJ_PROTO_INFO: e = gfj_server_info(client); break; case GFJ_PROTO_HOSTINFO: e = gfj_server_hostinfo(client); break; default: sprintf(buffer, "%d", request); gflog_warning("unknown request", buffer); } if (e == NULL) e = xxx_proto_flush(client); if (e != NULL) file_table_close(client_socket); }
gfarm_error_t gfm_client_rpc_with_failover( gfarm_error_t (*rpc_op)(struct gfm_connection **, void *), gfarm_error_t (*post_failover_op)(struct gfm_connection *, void *), void (*exit_op)(struct gfm_connection *, gfarm_error_t, void *), int (*must_be_warned_op)(gfarm_error_t, void *), void *closure) { gfarm_error_t e; struct gfm_connection *gfm_server; int nretry = 1, post_nretry = 1; retry: gfm_server = NULL; e = rpc_op(&gfm_server, closure); if (nretry > 0 && gfm_client_connection_should_failover( gfm_server, e)) { if ((e = failover(gfm_server)) != GFARM_ERR_NO_ERROR) { gflog_debug(GFARM_MSG_1003865, "failover: %s", gfarm_error_string(e)); } else if (post_failover_op && (e = post_failover_op(gfm_server, closure)) != GFARM_ERR_NO_ERROR) { gflog_debug(GFARM_MSG_1003866, "post_failover_op: %s", gfarm_error_string(e)); if (gfm_client_is_connection_error(e) && post_nretry > 0) { /* * following cases: * - acquired conneciton in failover() is * created before failover(). * - connection error occurred after failover(). */ post_nretry--; goto retry; } } else { nretry--; goto retry; } } else if (e != GFARM_ERR_NO_ERROR) { gflog_debug(GFARM_MSG_1003867, "gfm_client_rpc_with_failover: rpc_op: %s", gfarm_error_string(e)); if (nretry == 0 && must_be_warned_op && must_be_warned_op(e, closure)) gflog_warning(GFARM_MSG_1003868, "error ocurred at retry for the operation after " "connection to metadb server was failed over, " "so the operation possibly succeeded in the server." " error='%s'", gfarm_error_string(e)); } if (exit_op) exit_op(gfm_server, e, closure); return (e); }
static gfarm_error_t gfm_readlink_request(struct gfm_connection *gfm_server, void *closure) { gfarm_error_t e = gfm_client_readlink_request(gfm_server); if (e != GFARM_ERR_NO_ERROR) gflog_warning(GFARM_MSG_1000135, "readlink request; %s", gfarm_error_string(e)); return (e); }
static gfarm_error_t gfm_getdirentsplus_request(struct gfm_connection *gfm_server, void *closure) { gfarm_error_t e = gfm_client_getdirentsplus_request( gfm_server, DIRENTSPLUS_BUFCOUNT); if (e != GFARM_ERR_NO_ERROR) gflog_warning(GFARM_MSG_1000090, "getdirentsplus request: %s", gfarm_error_string(e)); return (e); }
static gfarm_error_t gfm_chown_request(struct gfm_connection *gfm_server, void *closure) { struct gfm_chown_closure *c = closure; gfarm_error_t e = gfm_client_fchown_request(gfm_server, c->username, c->groupname); if (e != GFARM_ERR_NO_ERROR) gflog_warning(GFARM_MSG_1000116, "fchown_fd request; %s", gfarm_error_string(e)); return (e); }
void gflog_warning_errno(const char *format, ...) { char buffer[2048]; va_list ap; va_start(ap, format); vsnprintf(buffer, sizeof buffer, format, ap); va_end(ap); gflog_warning("%s: %s", buffer, strerror(errno)); }
static gfarm_error_t gfm_getdirents_request(struct gfm_connection *gfm_server, void *closure) { struct gfs_dir_internal *dir = closure; gfarm_error_t e = gfm_client_getdirents_request(dir->gfm_server, DIRENTS_BUFCOUNT); if (e != GFARM_ERR_NO_ERROR) gflog_warning(GFARM_MSG_1000088, "getdirents request: %s", gfarm_error_string(e)); return (e); }
static gfarm_error_t gfm_getdirentsplus_result(struct gfm_connection *gfm_server, void *closure) { GFS_DirPlus dir = closure; gfarm_error_t e = gfm_client_getdirentsplus_result(gfm_server, &dir->n, dir->buffer, dir->stbuf); if (e != GFARM_ERR_NO_ERROR) gflog_warning(GFARM_MSG_1000091, "getdirentsplus result: %s", gfarm_error_string(e)); return (e); }
static gfarm_error_t gfm_getdirents_result(struct gfm_connection *gfm_server, void *closure) { struct gfs_dir_internal *dir = closure; gfarm_error_t e = gfm_client_getdirents_result(gfm_server, &dir->n, dir->buffer); if (e != GFARM_ERR_NO_ERROR) gflog_warning(GFARM_MSG_1000089, "getdirents result: %s", gfarm_error_string(e)); return (e); }
static gfarm_error_t gfm_replica_list_by_name_request(struct gfm_connection *gfm_server, struct gfp_xdr_context *ctx, void *closure) { gfarm_error_t e = gfm_client_replica_list_by_name_request( gfm_server, ctx); if (e != GFARM_ERR_NO_ERROR) gflog_warning(GFARM_MSG_1000151, "replica_list_by_name request: %s", gfarm_error_string(e)); return (e); }
static gfarm_error_t gfm_replica_remove_by_file_request(struct gfm_connection *gfm_server, struct gfp_xdr_context *ctx, void *closure) { struct gfm_replica_remove_by_file_closure *c = closure; gfarm_error_t e = gfm_client_replica_remove_by_file_request(gfm_server, ctx, c->host); if (e != GFARM_ERR_NO_ERROR) gflog_warning(GFARM_MSG_1000153, "replica_remove_by_file request: %s", gfarm_error_string(e)); return (e); }
static gfarm_error_t gfm_replicate_file_from_to_request(struct gfm_connection *gfm_server, struct gfp_xdr_context *ctx, void *closure) { struct gfm_replicate_file_from_to_closure *c = closure; gfarm_error_t e = gfm_client_replicate_file_from_to_request( gfm_server, ctx, c->srchost, c->dsthost, c->flags); if (e != GFARM_ERR_NO_ERROR) gflog_warning(GFARM_MSG_1001386, "replicate_file_from_to request: %s", gfarm_error_string(e)); return (e); }
char * gfm_server_get_request(struct xxx_connection *client, char *diag, char *format, ...) { va_list ap; char *e; int eof; va_start(ap, format); e = xxx_proto_vrecv(client, 0, &eof, &format, &ap); va_end(ap); if (e != NULL) { gflog_warning(diag, e); return (e); } if (eof) { gflog_warning(diag, "missing RPC argument"); return (GFARM_ERR_PROTOCOL); } if (*format != '\0') gflog_fatal(diag, "invalid format character to get request"); return (NULL); }
/* * 'result_callback' handler for gfs_client_relay(). */ static gfarm_int32_t gfs_client_relay_result(void *p, void *arg, size_t size) { gfarm_error_t e, e2; struct peer *peer = p; struct gfp_xdr *conn = peer_get_conn(peer); struct gfs_client_relay_closure *wclosure = arg; void *data = NULL; size_t data_size; int eof; static const char diag[] = "gfs_client_relay_result"; do { data = malloc(size); if (data == NULL) { e = GFARM_ERR_NO_MEMORY; (void) gfp_xdr_purge(conn, 0, size); break; } data_size = size; e = gfp_xdr_recv(conn, 1, &eof, "r", data_size, &data_size, data); if (e != GFARM_ERR_NO_ERROR) { (void) gfp_xdr_purge(conn, 0, size); break; } else if (eof) { e = GFARM_ERR_UNEXPECTED_EOF; } else if (data_size != 0) { e = GFARM_ERR_PROTOCOL; gflog_warning(GFARM_MSG_1004036, "%s: <%s> protocol redidual %u", peer_get_hostname(peer), diag, (int)data_size); } } while (0); e2 = wclosure->result_callback(e, wclosure->closure, size, data); if (e == GFARM_ERR_NO_ERROR) e = e2; free(data); gfs_client_relay_closure_free(wclosure); return (e); }
static void * gfm_async_server_reply_to_gfsd(void *arg) { gfarm_error_t e; struct gfm_async_server_reply_to_gfsd_entry *qe = arg; struct host *host = abstract_host_to_host(qe->qentry.abhost); struct netsendq *qhost = abstract_host_get_sendq(qe->qentry.abhost); const char *diag = qe->diag; e = gfm_async_server_put_reply(host, qe->peer, qe->xid, diag, qe->errcode, ""); netsendq_entry_was_sent(qhost, &qe->qentry); netsendq_remove_entry(qhost, &qe->qentry, e); if (e != GFARM_ERR_NO_ERROR) gflog_warning(GFARM_MSG_1004030, "%s: %s reply: %s", host_name(host), diag, gfarm_error_string(e)); return (NULL); }
/* this returns uncached result, but enter the result to the cache */ gfarm_error_t gfs_stat_caching(const char *path, struct gfs_stat *st) { gfarm_error_t e; struct timeval now; e = gfs_stat(path, st); if (e != GFARM_ERR_NO_ERROR) return (e); gettimeofday(&now, NULL); if ((e = gfs_stat_cache_enter_internal(path, st, &now)) != GFARM_ERR_NO_ERROR) { /* * It's ok to fail in entering the cache, * since it's merely cache. */ gflog_warning(GFARM_MSG_UNUSED, "gfs_stat_caching: failed to cache %s: %s", path, gfarm_error_string(e)); } return (GFARM_ERR_NO_ERROR); }
gfarm_error_t gfs_stat(const char *path, struct gfs_stat *s) { gfarm_error_t e; gfarm_timerval_t t1, t2; GFARM_TIMEVAL_FIX_INITIALIZE_WARNING(t1); gfs_profile(gfarm_gettimerval(&t1)); if ((e = gfm_client_compound_begin_request(gfarm_metadb_server)) != GFARM_ERR_NO_ERROR) gflog_warning("compound_begin request: %s", gfarm_error_string(e)); else if ((e = gfm_tmp_open_request(gfarm_metadb_server, path, GFARM_FILE_LOOKUP)) != GFARM_ERR_NO_ERROR) gflog_warning("tmp_open(%s) request: %s", path, gfarm_error_string(e)); else if ((e = gfm_client_fstat_request(gfarm_metadb_server)) != GFARM_ERR_NO_ERROR) gflog_warning("fstat request: %s", gfarm_error_string(e)); else if ((e = gfm_client_compound_end_request(gfarm_metadb_server)) != GFARM_ERR_NO_ERROR) gflog_warning("compound_end request: %s", gfarm_error_string(e)); else if ((e = gfm_client_compound_begin_result(gfarm_metadb_server)) != GFARM_ERR_NO_ERROR) gflog_warning("compound_begin result: %s", gfarm_error_string(e)); else if ((e = gfm_tmp_open_result(gfarm_metadb_server, path, NULL)) != GFARM_ERR_NO_ERROR) #if 0 gflog_warning("tmp_open(%s) result: %s", path, gfarm_error_string(e)); #else ; #endif else if ((e = gfm_client_fstat_result(gfarm_metadb_server, s))
/* XXX FIXME */ static gfarm_error_t gfs_replicate_from_to_internal(GFS_File gf, char *srchost, int srcport, char *dsthost, int dstport) { gfarm_error_t e; struct gfm_connection *gfm_server = gfs_pio_metadb(gf); struct gfs_connection *gfs_server; int nretry = 1, gfsd_retried = 0, failover_retried = 0; retry: gfm_server = gfs_pio_metadb(gf); if ((e = gfs_client_connection_and_process_acquire( &gfm_server, dsthost, dstport, &gfs_server, NULL)) != GFARM_ERR_NO_ERROR) { gflog_debug(GFARM_MSG_1001388, "acquirement of client connection failed: %s", gfarm_error_string(e)); return (e); } e = gfs_client_replica_add_from(gfs_server, srchost, srcport, gfs_pio_fileno(gf)); gfs_client_connection_free(gfs_server); if (e != GFARM_ERR_NO_ERROR) { gflog_debug(GFARM_MSG_1003878, "gfs_client_replica_add_from: %s", gfarm_error_string(e)); if (nretry-- > 0) { if (gfs_client_is_connection_error(e)) { gfsd_retried = 1; goto retry; } if (gfs_pio_should_failover(gf, e)) { if ((e = gfs_pio_failover(gf)) != GFARM_ERR_NO_ERROR) { gflog_debug(GFARM_MSG_1003879, "gfs_pio_failover: %s", gfarm_error_string(e)); } else { failover_retried = 1; goto retry; } } } } if ((e == GFARM_ERR_ALREADY_EXISTS || e == GFARM_ERR_FILE_BUSY) && (gfsd_retried || failover_retried)) { gflog_warning(GFARM_MSG_1003453, "error ocurred at retry for the operation after " "connection to %s, " "so the operation possibly succeeded in the server." " error='%s'", gfsd_retried && failover_retried ? "gfsd was disconnected and connection to " "gfmd was failed over" : gfsd_retried ? "gfsd was disconnected" : "gfmd was failed over" , gfarm_error_string(e)); } return (e); }
static gfarm_error_t gfm_server_switch_back_channel_common( struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep, int from_client, int version, const char *diag, struct relayed_request *relay) { gfarm_error_t e = GFARM_ERR_NO_ERROR, e2; struct host *host; gfp_xdr_async_peer_t async = NULL; struct local_peer *local_peer = NULL; int is_direct_connection; int i = 0; #ifdef __GNUC__ /* workaround gcc warning: might be used uninitialized */ host = NULL; #endif is_direct_connection = (peer_get_parent(peer) == NULL); giant_lock(); if (from_client) { gflog_debug(GFARM_MSG_1001995, "Operation not permitted: from_client"); e = GFARM_ERR_OPERATION_NOT_PERMITTED; } else if ((host = peer_get_host(peer)) == NULL) { gflog_debug(GFARM_MSG_1001996, "Operation not permitted: peer_get_host() failed"); e = GFARM_ERR_OPERATION_NOT_PERMITTED; } else if (is_direct_connection && (e = gfp_xdr_async_peer_new(&async)) != GFARM_ERR_NO_ERROR) { gflog_error(GFARM_MSG_1002288, "%s: gfp_xdr_async_peer_new(): %s", diag, gfarm_error_string(e)); } giant_unlock(); e2 = gfm_server_relay_put_reply(peer, xid, sizep, relay, diag, &e, "i", &i/*XXX FIXME*/); if (e2 != GFARM_ERR_NO_ERROR) return (e2); if (debug_mode) gflog_debug(GFARM_MSG_1000404, "gfp_xdr_flush"); e2 = gfp_xdr_flush(peer_get_conn(peer)); if (e2 != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_1000405, "%s: protocol flush: %s", diag, gfarm_error_string(e2)); return (e2); } else if (e != GFARM_ERR_NO_ERROR) return (e2); if (is_direct_connection) { local_peer = peer_to_local_peer(peer); local_peer_set_async(local_peer, async); /* XXXRELAY */ local_peer_set_readable_watcher(local_peer, back_channel_recv_watcher); } if (host_is_up(host)) /* throw away old connetion */ { gflog_warning(GFARM_MSG_1002440, "back_channel(%s): switching to new connection", host_name(host)); host_disconnect_request(host, NULL); } giant_lock(); peer_set_peer_type(peer, peer_type_back_channel); abstract_host_set_peer(host_to_abstract_host(host), peer, version); giant_unlock(); if (is_direct_connection) { local_peer_watch_readable(local_peer); gfarm_thr_statewait_signal( local_peer_get_statewait(local_peer), e2, diag); } callout_setfunc(host_status_callout(host), NULL /* or, use back_channel_send_manager thread pool? */, gfs_client_status_callout, host); gfs_client_status_schedule(host, 1); gflog_info(GFARM_MSG_1004035, "back_channel(%s): started", host_name(host)); return (e2); }
/* * Back channel protocol switch for slave gfmd. It forwards a GFS protocol * request from gfsd it a master gmfd and relays its reply in the opposite * direction. */ static gfarm_error_t async_back_channel_protocol_switch_slave(struct abstract_host *h, struct peer *peer, int request, gfp_xdr_xid_t xid, size_t size, int *unknown_request) { gfarm_error_t e = GFARM_ERR_NO_ERROR; struct host *host = abstract_host_to_host(h); struct gfp_xdr *conn = peer_get_conn(peer); struct protocol_switch_slave_closure *closure = NULL; size_t data_size; int eof; static const char diag[] = "async_back_channel_protocol_switch_slave"; if (debug_mode) gflog_info(GFARM_MSG_1004033, "%s: <%s> back_channel start receiving request(%d)", peer_get_hostname(peer), diag, (int)request); do { /* * We dispose 'closure' in * async_back_channel_protocol_switch_slave_result(). */ closure = protocol_switch_slave_closure_alloc(h, peer_get_private_peer_id(peer), xid, size, NULL); if (closure == NULL) { e = GFARM_ERR_NO_MEMORY; (void) gfp_xdr_purge(conn, 0, size); break; } data_size = size; e = gfp_xdr_recv(conn, 1, &eof, "r", data_size, &data_size, closure->data); if (e != GFARM_ERR_NO_ERROR) { (void) gfp_xdr_purge(conn, 0, size); break; } else if (eof) { e = GFARM_ERR_UNEXPECTED_EOF; break; } else if (data_size != 0) { e = GFARM_ERR_PROTOCOL; gflog_warning(GFARM_MSG_1004034, "%s: <%s> protocol redidual %u", peer_get_hostname(peer), diag, (int)data_size); } e = gfmdc_slave_client_remote_gfs_rpc(peer, closure, async_back_channel_protocol_switch_slave_result, async_back_channel_protocol_switch_slave_disconnect, request, size, closure->data); } while (0); if (e != GFARM_ERR_NO_ERROR) { if (!eof) { (void) gfm_async_server_put_reply(host, peer, xid, diag, e, ""); } if (closure != NULL) protocol_switch_slave_closure_free(closure); } return (e); }
gfarm_error_t gfs_link(const char *src, const char *dst) { gfarm_error_t e, e_save; int retry = 0; struct gfm_connection *sgfmd, *dgfmd; const char *spath, *dpath, *dbase; for (;;) { e_save = GFARM_ERR_NO_ERROR; spath = src; dpath = dst; if ((e = gfarm_url_parse_metadb(&spath, &sgfmd)) != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_1000118, "url_parse_metadb(%s): %s", src, gfarm_error_string(e)); return (e); } else if ((e = gfarm_url_parse_metadb(&dpath, &dgfmd)) != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_1000119, "url_parse_metadb(%s): %s", dst, gfarm_error_string(e)); gfm_client_connection_free(sgfmd); return (e); } else if (sgfmd != dgfmd) { gfm_client_connection_free(dgfmd); gfm_client_connection_free(sgfmd); return (GFARM_ERR_CROSS_DEVICE_LINK); } if ((e = gfm_tmp_open_request(sgfmd, spath, GFARM_FILE_LOOKUP)) != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_1000120, "tmp_open(%s) request: %s", src, gfarm_error_string(e)); } else if ((e = gfm_client_save_fd_request(sgfmd)) != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_1000121, "save_fd request: %s", gfarm_error_string(e)); } else if ((e = gfm_lookup_dir_request(dgfmd, dpath, &dbase)) != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_1000122, "lookup_dir(%s) request: %s", dst, gfarm_error_string(e)); } else if (dbase[0] == '/' && dbase[1] == '\0') { /* "/" is special */ e_save = GFARM_ERR_OPERATION_NOT_PERMITTED; } else if ((e = gfm_client_flink_request(dgfmd, dbase)) != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_1000123, "flink request: %s", gfarm_error_string(e)); } if (e != GFARM_ERR_NO_ERROR) break; if ((e = gfm_client_compound_end_request(sgfmd)) != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_1000124, "compound_end request: %s", gfarm_error_string(e)); } else if ((e = gfm_tmp_open_result(sgfmd, spath, NULL)) != GFARM_ERR_NO_ERROR) { if (gfm_client_is_connection_error(e) && ++retry <= 1){ gfm_client_connection_free(dgfmd); gfm_client_connection_free(sgfmd); continue; } #if 0 /* DEBUG */ gflog_debug(GFARM_MSG_1000125, "tmp_open(%s) result: %s", src, gfarm_error_string(e)); #endif } else if ((e = gfm_client_save_fd_result(sgfmd)) != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_1000126, "save_fd result: %s", gfarm_error_string(e)); } else if ((e = gfm_lookup_dir_result(dgfmd, dpath, &dbase)) != GFARM_ERR_NO_ERROR) { #if 0 /* DEBUG */ gflog_debug(GFARM_MSG_1000127, "lookup_dir(%s) result: %s", dst, gfarm_error_string(e)); #endif } else if (dbase[0] == '/' && dbase[1] == '\0') { /* "/" is special */ e_save = GFARM_ERR_OPERATION_NOT_PERMITTED; } else if ((e = gfm_client_flink_result(dgfmd)) != GFARM_ERR_NO_ERROR) { #if 0 /* DEBUG */ gflog_debug(GFARM_MSG_1000128, "flink result: %s", gfarm_error_string(e)); #endif } if (e != GFARM_ERR_NO_ERROR) break; if ((e = gfm_client_compound_end_result(sgfmd)) != GFARM_ERR_NO_ERROR) { gflog_warning(GFARM_MSG_1000129, "compound_end result: %s", gfarm_error_string(e)); } break; } gfm_client_connection_free(dgfmd); gfm_client_connection_free(sgfmd); /* NOTE: the opened descriptor is automatically closed by gfmd */ return (e_save != GFARM_ERR_NO_ERROR ? e_save : e); }
void main_loop(int accepting_socket) { char *e, *username, *hostname; int max_fd, nfound, client_socket, fd; struct xxx_connection *client_conn; struct sockaddr_in client_addr; socklen_t client_addr_size; fd_set readable; /* * To deal with race condition which may be caused by RST, * listening socket must be O_NONBLOCK, if the socket will be * used as a file descriptor for select(2) . * See section 15.6 of "UNIX NETWORK PROGRAMMING, Volume1, * Second Edition" by W. Richard Stevens, for detail. * We do report such case by gflog_warning_errno("accept"); */ if (fcntl(accepting_socket, F_SETFL, fcntl(accepting_socket, F_GETFL, NULL) | O_NONBLOCK) == -1) gflog_warning_errno("accepting_socket O_NONBLOCK"); for (;;) { FD_ZERO(&readable); FD_SET(accepting_socket, &readable); file_table_fd_set(&readable); max_fd = file_table_max >= accepting_socket ? file_table_max : accepting_socket; nfound = select(max_fd + 1, &readable, NULL, NULL, 0); if (nfound <= 0) continue; if (FD_ISSET(accepting_socket, &readable)) { client_addr_size = sizeof(client_addr); client_socket = accept(accepting_socket, (struct sockaddr *)&client_addr, &client_addr_size); if (client_socket < 0) { if (errno != EINTR) gflog_warning_errno("accept"); } else if ((e = xxx_fd_connection_new(client_socket, &client_conn)) != NULL) { gflog_warning("fd_connection_new", e); close(client_socket); } else if ((e = gfarm_authorize(client_conn, 0, &username, &hostname)) != NULL) { gflog_warning("authorize", e); xxx_connection_free(client_conn); } else if ((errno = file_table_add(client_conn, username, hostname)) != 0) { gflog_warning_errno("file_table_add"); xxx_connection_free(client_conn); free(username); free(hostname); } } for (fd = 0; fd <= file_table_max; fd++) { if (file_table[fd].conn != NULL && FD_ISSET(fd, &readable)) service(fd); } } }