Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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);
}
Beispiel #8
0
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);
}
Beispiel #9
0
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));
}
Beispiel #10
0
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);
}
Beispiel #11
0
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);
}
Beispiel #12
0
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);
}
Beispiel #13
0
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);
}
Beispiel #14
0
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);
}
Beispiel #15
0
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);
}
Beispiel #16
0
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);
}
Beispiel #17
0
/*
 * '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);
}
Beispiel #18
0
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);
}
Beispiel #19
0
/* 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);
}
Beispiel #20
0
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))
Beispiel #21
0
/* 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);
}
Beispiel #22
0
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);
}
Beispiel #23
0
/*
 * 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);
}
Beispiel #24
0
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);
}
Beispiel #25
0
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);
		}
	}
}