Example #1
0
static struct file_opening *
file_opening_alloc(struct inode *inode,
	struct peer *peer, struct host *spool_host, int flag)
{
	struct file_opening *fo;

	GFARM_MALLOC(fo);
	if (fo == NULL)
		return (NULL);
	fo->inode = inode;
	fo->flag = flag;
	fo->opener = peer;

	if (inode_is_file(inode)) {
		if (spool_host == NULL) {
			fo->u.f.spool_opener = NULL;
			fo->u.f.spool_host = NULL;
		} else {
			fo->u.f.spool_opener = peer;
			fo->u.f.spool_host = spool_host;
		}
	} else { /* for directory */
		fo->u.d.offset = 0;
		fo->u.d.key = NULL;
	}

	return (fo);
}
Example #2
0
static gfarm_error_t
gfs_dir_alloc(struct gfm_connection *gfm_server, gfarm_int32_t fd,
	GFS_Dir *dirp)
{
	struct gfs_dir_internal *dir;
	static struct gfs_dir_ops ops = {
		gfs_closedir_internal,
		gfs_readdir_internal,
		gfs_seekdir_unimpl,
		gfs_telldir_unimpl
	};

	GFARM_MALLOC(dir);
	if (dir == NULL)
		return (GFARM_ERR_NO_MEMORY);

	dir->super.ops = &ops;
	dir->gfm_server = gfm_server;
	dir->fd = fd;
	dir->n = 0;
	dir->index = 0;

	*dirp = &dir->super;
	return (GFARM_ERR_NO_ERROR);
}
Example #3
0
int
job_table_add(struct gfarm_job_info *info,
	      struct job_table_entry **listp)
{
	int id;

	if (job_table_free >= job_table_size) {
		for (job_table_free = JOB_ID_MIN;
		     job_table_free < job_table_size; job_table_free++)
			if (job_table[job_table_free] == NULL)
				break;
		if (job_table_free >= job_table_size)
			return (-1);
	}

	id = job_table_free;
	GFARM_MALLOC(job_table[id]);
	if (job_table[id] == NULL)
		return (-1);
	job_table[id]->id = id;
	job_table[id]->info = info;
	job_table[id]->next = *listp;
	*listp = job_table[id];

	for (++job_table_free;
	     job_table_free < job_table_size; ++job_table_free)
		if (job_table[job_table_free] == NULL)
			break;
	return (id);
}
Example #4
0
struct gfarm_iobuffer *
gfarm_iobuffer_alloc(int bufsize)
{
	struct gfarm_iobuffer *b;

	GFARM_MALLOC(b);
	if (b == NULL)
		return (NULL);
	GFARM_MALLOC_ARRAY(b->buffer, bufsize);
	if (b->buffer == NULL) {
		free(b);
		return (NULL);
	}
	b->bufsize = bufsize;
	b->head = b->tail = 0;

	b->read_func = NULL;
	b->read_cookie = NULL;
	b->read_fd = -1;

	b->write_func = NULL;
	b->write_cookie = NULL;
	b->write_fd = -1;

	b->write_close_func = gfarm_iobuffer_write_close_nop;

	b->read_eof = 0;
	b->write_eof = 0;
	b->error = 0;

	return (b);
}
Example #5
0
/* FIXME: should support return values other than gfarm_error_t too */
void
gfm_async_server_reply_to_gfsd_schedule(struct host *host,
	struct peer *peer, gfp_xdr_xid_t xid,
	gfarm_error_t errcode, int flags, const char *diag)
{
	gfarm_error_t e;
	struct gfm_async_server_reply_to_gfsd_entry *qe;

	GFARM_MALLOC(qe);
	if (qe == NULL) {
		gflog_error(GFARM_MSG_1004031,
		    "%s: %s: no memory for queue entry",
		    host_name(host), diag);
	} else {
		netsendq_entry_init(&qe->qentry,
		    &gfm_async_server_reply_to_gfsd_queue);
		qe->qentry.abhost = host_to_abstract_host(host);
		qe->peer = peer;
		qe->xid = xid;
		qe->errcode = errcode;
		qe->diag = diag;
		e = netsendq_add_entry(host_sendq(host), &qe->qentry, flags);
		if (e != GFARM_ERR_NO_ERROR) {
			gflog_info(GFARM_MSG_1004032,
			    "%s: %s queueing: %s",
			    host_name(host), diag, gfarm_error_string(e));
			if ((flags & NETSENDQ_ADD_FLAG_DETACH_ERROR_HANDLING)
			    == 0)
				free(qe);
		}
	}
}
Example #6
0
File: job.c Project: ddk50/gfarm_v2
int
job_table_add(struct gfarm_job_info *info,
	      struct job_table_entry **listp)
{
	int id;

	if (job_table_free >= job_table_size) {
		for (job_table_free = JOB_ID_MIN;
		     job_table_free < job_table_size; job_table_free++)
			if (job_table[job_table_free] == NULL)
				break;
		if (job_table_free >= job_table_size)
			return (-1);
	}

	id = job_table_free;
	GFARM_MALLOC(job_table[id]);
	if (job_table[id] == NULL) {
		gflog_debug(GFARM_MSG_1001682,
			"allocation of job_table failed");
		return (-1);
	}
	job_table[id]->id = id;
	job_table[id]->info = info;
	job_table[id]->next = *listp;
	*listp = job_table[id];

	for (++job_table_free;
	     job_table_free < job_table_size; ++job_table_free)
		if (job_table[job_table_free] == NULL)
			break;
	return (id);
}
Example #7
0
/*
 * Create an object of 'struct gfs_client_relay_closure'.
 */
static struct gfs_client_relay_closure *
gfs_client_relay_closure_alloc(struct abstract_host *abhost,
	gfarm_int64_t private_peer_id, size_t size, void *data, void *closure,
	gfarm_int32_t (*result_callback)(gfarm_error_t, void *, size_t,
	    void *),
	void (*disconnect_callback)(gfarm_error_t, void *))
{
	struct gfs_client_relay_closure *wclosure;

	GFARM_MALLOC(wclosure);
	if (wclosure == NULL)
		return (NULL);
	wclosure->data = malloc(size);
	if (wclosure->data == NULL) {
		free(wclosure);
		return (NULL);
	}

	wclosure->abhost              = abhost;
	wclosure->private_peer_id     = private_peer_id;
	wclosure->size                = size;
	if (data != NULL)
		memcpy(wclosure->data, data, size);
	wclosure->closure             = closure;
	wclosure->result_callback     = result_callback;
	wclosure->disconnect_callback = disconnect_callback;

	return (wclosure);
}
Example #8
0
/* this function never fails, but aborts. */
struct peer_watcher *
peer_watcher_alloc(int thrpool_size, int thrqueue_length, 
	void *(*handler)(void *),
	const char *diag)
{
	gfarm_error_t e;
	struct peer_watcher *pw;

	GFARM_MALLOC(pw);
	if (pw == NULL)
		gflog_fatal(GFARM_MSG_1002763, "peer_watcher %s: no memory",
		    diag);

	e = watcher_alloc(peer_watcher_nfd_hint_default, &pw->w);
	if (e != GFARM_ERR_NO_ERROR)
		gflog_fatal(GFARM_MSG_1002764, "watcher(%d) %s: no memory",
		    peer_watcher_nfd_hint_default, diag);

	pw->thrpool = thrpool_new(thrpool_size, thrqueue_length, diag);
	if (pw->thrpool == NULL)
		gflog_fatal(GFARM_MSG_1002765, "thrpool(%d, %d) %s: no memory",
		    thrpool_size, thrqueue_length, diag);

	pw->handler = handler;

	return (pw);
}
Example #9
0
gfarm_error_t
request_long_format(struct gfarm_host_info *host_info,
	struct gfarm_paraccess *pa)
{
	gfarm_error_t e;
	struct sockaddr addr;
	struct long_format_parameter *param;
	struct gfarm_host_info *info;

	GFARM_MALLOC(param);
	if (param == NULL) {
		e = GFARM_ERR_NO_MEMORY;
		fprintf(stderr, "%s: %s\n", program_name,
		    gfarm_error_string(e));
		return (e);
	}
	info = &param->info;

	/* dup `*host_info' -> `*info' */
	info->hostname = strdup(host_info->hostname);
	info->port = host_info->port;
	info->nhostaliases = host_info->nhostaliases;
	if (host_info->nhostaliases == 0) {
		info->hostaliases = NULL;
	} else {
		info->hostaliases = gfarm_strarray_dup(host_info->hostaliases);
		if (info->hostaliases == NULL)
			info->nhostaliases = 0;
	}
	info->architecture = strdup(host_info->architecture);
	info->ncpu = host_info->ncpu;
	info->flags = host_info->flags;
	if (info->hostname == NULL || info->architecture == NULL) {
		gfarm_host_info_free(info);
		free(param);
		e = GFARM_ERR_NO_MEMORY;
		fprintf(stderr, "%s: %s\n", program_name,
		    gfarm_error_string(e));
		return (e);
	}

	param->if_hostname = NULL;
	e = (*opt_resolv_addr)(info->hostname, info->port, info,
	    &addr, &param->if_hostname);
	if (e != GFARM_ERR_NO_ERROR) {
		output_process(param, info->hostname, NULL, NULL, NULL, e);
		return (e);
	}

	return (gfarm_paraccess_request(pa, param, info->hostname, info->port,
	    &addr));
}
Example #10
0
static struct file_info *
file_info_alloc(void)
{
	struct file_info *i;

	GFARM_MALLOC(i);
	if (i == NULL)
		return (NULL);

	i->pathname = NULL;
	i->copy = NULL;
	return (i);
}
Example #11
0
struct gfarm_event *
gfarm_timer_event_alloc(
	void (*callback)(void *, const struct timeval *), void *closure)
{
	struct gfarm_event *ev;

	GFARM_MALLOC(ev);
	if (ev == NULL)
		return (NULL);
	ev->next = ev->prev = NULL; /* to be sure */
	ev->type = GFARM_TIMER_EVENT;
	ev->filter = GFARM_EVENT_TIMEOUT;
	ev->closure = closure;
	ev->u.timeout.callback = callback;
	return (ev);
}
Example #12
0
static gfarm_error_t
gfs_dirplus_alloc(struct gfm_connection *gfm_server, gfarm_int32_t fd,
	GFS_DirPlus *dirp)
{
	GFS_DirPlus dir;

	GFARM_MALLOC(dir);
	if (dir == NULL)
		return (GFARM_ERR_NO_MEMORY);

	dir->gfm_server = gfm_server;
	dir->fd = fd;
	dir->n = dir->index = 0;

	*dirp = dir;
	return (GFARM_ERR_NO_ERROR);
}
Example #13
0
struct gfarm_eventqueue *
gfarm_eventqueue_alloc(void)
{
	struct gfarm_eventqueue *q;

	GFARM_MALLOC(q);
	if (q == NULL)
		return (NULL);

	/* make the queue empty */
	q->header.next = q->header.prev = &q->header;

	q->fd_set_size = q->fd_set_bytes = 0;
	q->read_fd_set = q->write_fd_set =
	    q->exception_fd_set = NULL;
	return (q);
}
Example #14
0
struct gfarm_event *
gfarm_fd_event_alloc(int filter, int fd,
	void (*callback)(int, int, void *, const struct timeval *),
	void *closure)
{
	struct gfarm_event *ev;

	GFARM_MALLOC(ev);
	if (ev == NULL)
		return (NULL);
	ev->next = ev->prev = NULL; /* to be sure */
	ev->type = GFARM_FD_EVENT;
	ev->filter = filter;
	ev->closure = closure;
	ev->u.fd.callback = callback;
	ev->u.fd.fd = fd;
	return (ev);
}
Example #15
0
gfarm_error_t
gfp_xdr_set_secsession(struct gfp_xdr *conn,
	gfarmSecSession *secsession, gss_cred_id_t cred_to_be_freed)
{
	struct io_gfsl *io;

	GFARM_MALLOC(io);
	if (io == NULL)
		return (GFARM_ERR_NO_MEMORY);
	io->session = secsession;
	io->cred_to_be_freed = cred_to_be_freed;
	io->exported_credential = NULL;
	io->buffer = NULL;
	io->p = io->residual = 0;
	gfp_xdr_set(conn, &gfp_xdr_secsession_iobuffer_ops,
	    io, secsession->fd);
	return (GFARM_ERR_NO_ERROR);
}
Example #16
0
gfarm_error_t
gfs_opendir_caching_internal(const char *path, GFS_Dir *dirp)
{
	gfarm_error_t e;
	GFS_DirPlus dp;
	struct gfs_dir_caching *dir;
	char *p;
	static struct gfs_dir_ops ops = {
		gfs_closedir_caching_internal,
		gfs_readdir_caching_internal,
		gfs_seekdir_unimpl,
		gfs_telldir_unimpl
	};

	if ((e = gfs_opendirplus(path, &dp)) != GFARM_ERR_NO_ERROR)
		return (e);

	GFARM_MALLOC(dir);
	if (*gfarm_path_dir_skip(path) != '\0') {
		GFARM_MALLOC_ARRAY(p, strlen(path) + 1 + 1);
		if (p != NULL)
			sprintf(p, "%s/", path);
	} else {
		GFARM_MALLOC_ARRAY(p, strlen(path) + 1);
		if (p != NULL)
			strcpy(p, path);
	}

	if (dir == NULL || p == NULL) {
		gfs_closedirplus(dp);
		if (dir != NULL)
			free(dir);
		if (p != NULL)
			free(p);
		return (GFARM_ERR_NO_MEMORY);
	}

	dir->super.ops = &ops;
	dir->dp = dp;
	dir->path = p;
	*dirp = &dir->super;
	return (GFARM_ERR_NO_ERROR);
}
Example #17
0
gfarm_error_t
gfp_uncached_connection_new(const char *hostname, int port,
	const char *username, struct gfp_cached_connection **connectionp)
{
	struct gfp_cached_connection *connection;
	struct gfp_conn_hash_id *idp;

	GFARM_MALLOC(connection);
	if (connection == NULL) {
		gflog_debug(GFARM_MSG_1001087,
			"allocation of 'connection' failed: %s",
			gfarm_error_string(GFARM_ERR_NO_MEMORY));
		return (GFARM_ERR_NO_MEMORY);
	}

	connection->hash_entry = NULL; /* this is an uncached connection */
	idp = &connection->id;
	idp->hostname = strdup(hostname);
	idp->username = strdup(username);
	if (idp->hostname == NULL || idp->username == NULL) {
		gflog_debug(GFARM_MSG_1002565,
		    "gfp_cached_connection_acquire (%s)(%d)"
		    " failed: %s",
		    hostname, port,
		    gfarm_error_string(GFARM_ERR_NO_MEMORY));
		free(idp->hostname);
		free(idp->username);
		free(connection);
		return (GFARM_ERR_NO_MEMORY);
	}
	idp->port = port;

	gfarm_lru_init_uncached_entry(&connection->lru_entry);

	connection->connection_data = NULL;
	connection->dispose_connection_data = NULL;
	GFSP_CONN_INIT(connection)
	*connectionp = connection;
	return (GFARM_ERR_NO_ERROR);
}
Example #18
0
gfarm_error_t
gfp_xdr_set_secsession(struct gfp_xdr *conn,
	gfarmSecSession *secsession, gss_cred_id_t cred_to_be_freed)
{
	struct io_gfsl *io;

	GFARM_MALLOC(io);
	if (io == NULL) {
		gflog_debug(GFARM_MSG_1001480,
			"allocation of 'io_gfsl' failed: %s",
			gfarm_error_string(GFARM_ERR_NO_MEMORY));
		return (GFARM_ERR_NO_MEMORY);
	}
	io->session = secsession;
	io->cred_to_be_freed = cred_to_be_freed;
	io->exported_credential = NULL;
	io->buffer = NULL;
	io->p = io->residual = 0;
	gfp_xdr_set(conn, &gfp_xdr_secsession_iobuffer_ops,
	    io, secsession->fd);
	return (GFARM_ERR_NO_ERROR);
}
Example #19
0
gfarm_error_t
gfarm_paraccess_alloc(
	int concurrency, int try_auth,
	struct gfarm_paraccess **pap)
{
	int syserr;
	struct gfarm_paraccess *pa;
	int i;

	GFARM_MALLOC(pa);
	if (pa == NULL)
		return (GFARM_ERR_NO_MEMORY);

	syserr = gfarm_eventqueue_alloc(concurrency, &pa->q);
	if (syserr !=0) {
		free(pa);
		return (gfarm_errno_to_error(syserr));
	}

	GFARM_MALLOC_ARRAY(pa->access_state, concurrency);
	if (pa->access_state == NULL) {
		gfarm_eventqueue_free(pa->q);
		free(pa);
		return (GFARM_ERR_NO_MEMORY);
        }

	/* construct free slot list */
	i = concurrency - 1;
	pa->access_state[i].next = NULL;
	while (--i >= 0)
		pa->access_state[i].next = &pa->access_state[i + 1];
	pa->free_list = &pa->access_state[0];
	pa->concurrency = pa->nfree = concurrency;

	pa->try_auth = try_auth;
	*pap = pa;
	return (GFARM_ERR_NO_ERROR);
}
Example #20
0
int
proto1_request_multiplexed(struct gfarm_eventqueue *q, int peer_socket,
	void (*continuation)(void *), void *closure,
	struct proto1_state **statepp)
{
	struct proto1_state *state;
	int rv = ENOMEM;

	GFARM_MALLOC(state);
	if (state == NULL)
		return (ENOMEM);
	state->writable = gfarm_fd_event_alloc(GFARM_EVENT_WRITE, peer_socket,
	    proto1_sending, state);
	if (state->writable != NULL) {
		state->readable = gfarm_fd_event_alloc(
		    GFARM_EVENT_READ, peer_socket, proto1_receiving, state);
		if (state->readable != NULL) {
			state->q = q;
			state->sock = peer_socket;
			state->continuation = continuation;
			state->closure = closure;
			state->error = 0;
			rv = gfarm_eventqueue_add_event(q, state->writable,
			    NULL);
			if (rv == 0) {
				*statepp = state;
				return (0); /* go to proto1_sending() */
			}
			gfarm_event_free(state->readable);
		}
		gfarm_event_free(state->writable);
	}
	free(state);
	return (rv);
	
}
Example #21
0
/*
 * Create an object of 'struct protocol_switch_slave_closure'.
 */
static struct protocol_switch_slave_closure *
protocol_switch_slave_closure_alloc(struct abstract_host *abhost,
	gfarm_int64_t private_peer_id, gfp_xdr_xid_t xid, size_t size,
	void *data)
{
	static struct protocol_switch_slave_closure *closure;

	GFARM_MALLOC(closure);
	if (closure == NULL)
		return (NULL);
	closure->abhost          = abhost;
	closure->private_peer_id = private_peer_id;
	closure->xid             = xid;
	closure->size            = size;
	closure->data            = malloc(size);
	if (closure->data == NULL) {
		free(closure);
		return (NULL);
	}
	if (data != NULL)
		memcpy(closure->data, data, size);

	return (closure);
}
Example #22
0
gfarm_error_t
gfj_server_register(struct peer *peer, int from_client, int skip)
{
	gfarm_error_t e;
	struct gfp_xdr *client = peer_get_conn(peer);
	char *user = peer_get_username(peer);
	int i, eof;
	gfarm_int32_t flags, total_nodes, argc, error, job_id = 0;
	struct gfarm_job_info *info;

	GFARM_MALLOC(info);
	if (info == NULL)
		return (GFARM_ERR_NO_MEMORY);
	gfarm_job_info_clear(info, 1);
	e = gfj_server_get_request(peer, "register", "iisssi",
				   &flags,
				   &total_nodes,
				   &info->job_type,
				   &info->originate_host,
				   &info->gfarm_url_for_scheduling,
				   &argc);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	/* XXX - currently `flags' is just igored */
	info->total_nodes = total_nodes;
	info->argc = argc;
	GFARM_MALLOC_ARRAY(info->argv, argc + 1);
	GFARM_MALLOC_ARRAY(info->nodes, total_nodes);
	if (info->argv == NULL || info->nodes == NULL) {
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		if (info->argv != NULL)
			free(info->argv);
		if (info->nodes != NULL)
			free(info->nodes);
		free(info);
		return (GFARM_ERR_NO_MEMORY);
	}
	for (i = 0; i < argc; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s", &info->argv[i]);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
	}
	info->argv[i] = NULL;
	info->user = user; /* shared with file_table[].user */
	for (i = 0; i < total_nodes; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s",
				   &info->nodes[i].hostname);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->nodes[i].hostname);
			for (i = 0; i < argc; i++)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
		info->nodes[i].pid = 0;
		info->nodes[i].state = GFJ_NODE_NONE;
	}

	if (skip || !from_client) {
		for (i = 0; i < total_nodes; i++)
			free(info->nodes[i].hostname);
		for (i = 0; i < argc; i++)
			free(info->argv[i]);
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		free(info->argv);
		free(info->nodes);
		if (skip)
			return (GFARM_ERR_NO_ERROR);
		error = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else {
		giant_lock();
		job_id = job_table_add(info, peer_get_jobs_ref(peer));
		giant_unlock();
		if (job_id < JOB_ID_MIN) {
			job_id = 0;
			error = GFARM_ERR_TOO_MANY_JOBS;
		} else {
			error = GFARM_ERR_NO_ERROR;
		}
	}
	return (gfj_server_put_reply(peer, "register",
	    error, "i", job_id));
}
Example #23
0
File: gsi.c Project: ddk50/gfarm_v2
struct gfarmGssInitiateSecurityContextState *
gfarmGssInitiateSecurityContextRequest(struct gfarm_eventqueue *q, int fd,
    const gss_name_t acceptorName, gss_cred_id_t cred, OM_uint32 reqFlag,
    void (*continuation) (void *), void *closure, OM_uint32 *majStatPtr,
    OM_uint32 *minStatPtr)
{
    OM_uint32 majStat;
    OM_uint32 minStat;
    struct gfarmGssInitiateSecurityContextState *state;

    /*
     * Implementation specification:
     * In gfarm, an initiator must reveal own identity to an acceptor.
     */
    if ((reqFlag & GSS_C_ANON_FLAG) == GSS_C_ANON_FLAG) {
	/* It is a bit safer to deny the request than to silently ignore it */
	gflog_auth_error(GFARM_MSG_1000625,
	    "gfarmGssInitiateSecurityContextRequest(): "
	    "GSS_C_ANON_FLAG is not allowed");
	majStat = GSS_S_UNAVAILABLE;
	minStat = GFSL_DEFAULT_MINOR_ERROR;
	goto ReturnStat;
    }

    GFARM_MALLOC(state);
    if (state == NULL) {
	gflog_auth_error(GFARM_MSG_1000626,
	    "gfarmGssInitiateSecurityContextRequest(): "
			 "no memory");
	majStat = GSS_S_FAILURE;
	minStat = GFSL_DEFAULT_MINOR_ERROR;
	goto ReturnStat;
    }

    state->completed = 0;
    state->majStat = GSS_S_COMPLETE;
    state->minStat = GFSL_DEFAULT_MINOR_ERROR;

    state->writable =
	gfarm_fd_event_alloc(GFARM_EVENT_WRITE, fd,
			     gfarmGssInitiateSecurityContextSendToken,
			     state);
    if (state->writable == NULL) {
	gflog_auth_error(GFARM_MSG_1000627,
	    "gfarmGssInitiateSecurityContextRequest(): "
			 "no memory");
	state->majStat = GSS_S_FAILURE;
	goto FreeState;
    }
    /*
     * We cannot use two independent events (i.e. a fd_event with
     * GFARM_EVENT_READ flag and a timer_event) here, because
     * it's possible that both event handlers are called at once.
     */
    state->readable =
	gfarm_fd_event_alloc(GFARM_EVENT_READ|GFARM_EVENT_TIMEOUT, fd,
			     gfarmGssInitiateSecurityContextReceiveToken,
			     state);
    if (state->readable == NULL) {
	gflog_auth_error(GFARM_MSG_1000628,
	    "gfarmGssInitiateSecurityContextRequest(): "
			 "no memory");
	state->majStat = GSS_S_FAILURE;
	goto FreeWritable;
    }

    state->q = q;
    state->fd = fd;
    state->acceptorName = acceptorName;
    state->cred = cred;
    state->reqFlag = reqFlag;
    state->continuation = continuation;
    state->closure = closure;

    state->retFlag = 0;

    /* GSS_C_EMPTY_BUFFER */
    state->inputToken.length = 0; state->inputToken.value = NULL;
    state->itPtr = &state->inputToken;

    /* GSS_C_EMPTY_BUFFER */
    state->outputToken.length = 0; state->outputToken.value = NULL;
    state->otPtr = &state->outputToken;

    state->actualMechType = NULL;

    state->sc = GSS_C_NO_CONTEXT;

    gssInitiateSecurityContextNext(state);
    assert(!state->completed);
    if (!GSS_ERROR(state->majStat)) {
	if (majStatPtr != NULL) {
	    *majStatPtr = GSS_S_COMPLETE;
	}
	if (minStatPtr != NULL) {
	    *minStatPtr = GFSL_DEFAULT_MINOR_ERROR;
	}
	return (state);
    }

    gfarm_event_free(state->readable);

    FreeWritable:
    gfarm_event_free(state->writable);

    FreeState:
    majStat = state->majStat;
    minStat = state->minStat;
    free(state);

    ReturnStat:
    if (majStatPtr != NULL)
	*majStatPtr = majStat;
    if (minStatPtr != NULL)
	*minStatPtr = minStat;

    if (GSS_ERROR(majStat)) {
	gflog_debug(GFARM_MSG_1000801,
		"failed to request initiate security context (%u)(%u)",
		 majStat, minStat);
    }

    return (NULL);
}
Example #24
0
File: gsi.c Project: ddk50/gfarm_v2
gfarmExportedCredential *
gfarmGssExportCredential(gss_cred_id_t cred, OM_uint32 *statPtr)
{
    gfarmExportedCredential *exportedCred = NULL;
    OM_uint32 majStat = 0;
    OM_uint32 minStat = 0;
    gss_buffer_desc buf = GSS_C_EMPTY_BUFFER;
    char *exported, *filename, *env;
    static char exported_name[] = "X509_USER_DELEG_PROXY=";
    static char env_name[] = "X509_USER_PROXY=";
    static char file_prefix[] = "FILE:";

    majStat = gss_export_cred(&minStat, cred, GSS_C_NO_OID, 1, &buf);
    if (GSS_ERROR(majStat))
	goto Done;

    exported = buf.value;
    for (filename = exported; *filename != '\0'; filename++)
	if (!isalnum(*(unsigned char *)filename) && *filename != '_')
	    break;
    if (*filename != '=') { /* not an environment variable */
	majStat = GSS_S_UNAVAILABLE;
	goto Done;
    }
    filename++;
    if (memcmp(exported, exported_name, sizeof(exported_name) - 1) == 0) {
	GFARM_MALLOC_ARRAY(env, sizeof(env_name) + strlen(filename));
	if (env == NULL) {
	    majStat = GSS_S_FAILURE;
	    goto Done;
	}
	memcpy(env, env_name, sizeof(env_name) - 1);
	strcpy(env + sizeof(env_name) - 1, filename);
	filename = env + sizeof(env_name) - 1;
    } else {
	env = strdup(exported);
	if (env == NULL) {
	    majStat = GSS_S_FAILURE;
	    goto Done;
	}
	filename = env + (filename - exported);
    }
    if (memcmp(filename, file_prefix, sizeof(file_prefix) - 1) == 0)
	filename += sizeof(file_prefix) - 1;

    GFARM_MALLOC(exportedCred);
    if (exportedCred == NULL) {
	free(env);
	majStat = GSS_S_FAILURE;
	goto Done;
    }
    exportedCred->env = env;
    exportedCred->filename = access(filename, R_OK) == 0 ? filename : NULL;

    Done:
    gss_release_buffer(&minStat, &buf);
    if (statPtr != NULL)
	*statPtr = majStat;

    if (GSS_ERROR(majStat)) {
	gflog_debug(GFARM_MSG_1000800,
		"failed to export credential (%u)(%u)",
		 majStat, minStat);
    }

    return exportedCred;
}
Example #25
0
File: job.c Project: ddk50/gfarm_v2
gfarm_error_t
gfj_server_register(struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep,
	int from_client, int skip)
{
	gfarm_error_t e;
	struct gfp_xdr *client = peer_get_conn(peer);
	char *user = peer_get_username(peer);
	int i, eof;
	gfarm_int32_t flags, total_nodes, argc, error, job_id = 0;
	struct gfarm_job_info *info;
	static const char diag[] = "GFJ_PROTO_REGISTER";

	GFARM_MALLOC(info);
	if (info == NULL) {
		gflog_debug(GFARM_MSG_1001685,
			"allocation of gfarm_job_info failed");
		return (GFARM_ERR_NO_MEMORY);
	}
	gfarm_job_info_clear(info, 1);
	e = gfj_server_get_request(peer, sizep, diag, "iisssi",
				   &flags,
				   &total_nodes,
				   &info->job_type,
				   &info->originate_host,
				   &info->gfarm_url_for_scheduling,
				   &argc);
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1001686,
			"gfj_server_get_request() failed");
		return (e);
	}

	/* XXX - currently `flags' is just igored */
	info->total_nodes = total_nodes;
	info->argc = argc;
	GFARM_MALLOC_ARRAY(info->argv, argc + 1);
	GFARM_MALLOC_ARRAY(info->nodes, total_nodes);
	if (info->argv == NULL || info->nodes == NULL) {
		gflog_debug(GFARM_MSG_1001687,
			"allocation of 'info->argv' or 'info->nodes' failed ");
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		if (info->argv != NULL)
			free(info->argv);
		if (info->nodes != NULL)
			free(info->nodes);
		free(info);
		return (GFARM_ERR_NO_MEMORY);
	}
	for (i = 0; i < argc; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s", &info->argv[i]);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			gflog_debug(GFARM_MSG_1001688,
				"gfp_xdr_recv(info->argv[i]) failed");
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
	}
	info->argv[i] = NULL;
	info->user = user; /* shared with file_table[].user */
	for (i = 0; i < total_nodes; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s",
				   &info->nodes[i].hostname);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			gflog_debug(GFARM_MSG_1001689,
				"gfp_xdr_recv(hostname) failed");
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->nodes[i].hostname);
			for (i = 0; i < argc; i++)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
		info->nodes[i].pid = 0;
		info->nodes[i].state = GFJ_NODE_NONE;
	}

	if (skip || !from_client) {
		for (i = 0; i < total_nodes; i++)
			free(info->nodes[i].hostname);
		for (i = 0; i < argc; i++)
			free(info->argv[i]);
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		free(info->argv);
		free(info->nodes);
		if (skip)
			return (GFARM_ERR_NO_ERROR);
		error = GFARM_ERR_OPERATION_NOT_PERMITTED;
		gflog_debug(GFARM_MSG_1001690,
			"operation is not permitted for from_client");
	} else {
		giant_lock();
		job_id = job_table_add(info, peer_get_jobs_ref(peer));
		giant_unlock();
		if (job_id < JOB_ID_MIN) {
			job_id = 0;
			error = GFARM_ERR_TOO_MANY_JOBS;
			gflog_debug(GFARM_MSG_1001691,
				"too many jobs");
		} else {
			error = GFARM_ERR_NO_ERROR;
		}
	}
	return (gfj_server_put_reply(peer, xid, sizep, diag,
	    error, "i", job_id));
}
Example #26
0
gfarm_error_t
gfp_cached_connection_acquire(struct gfp_conn_cache *cache,
	const char *canonical_hostname, int port, const char *user,
	struct gfp_cached_connection **connectionp, int *createdp)
{
	gfarm_error_t e;
	struct gfarm_hash_entry *entry;
	struct gfp_cached_connection *connection;
	struct gfp_conn_hash_id *idp, *kidp;
	static const char diag[] = "gfp_cached_connection_acquire";

	gfarm_mutex_lock(&cache->mutex, diag, diag_what);
	e = gfp_conn_hash_enter_noalloc(&cache->hashtab, cache->table_size,
	    sizeof(connection), canonical_hostname, port, user,
	    &entry, createdp);
	if (e != GFARM_ERR_NO_ERROR) {
		gfarm_mutex_unlock(&cache->mutex, diag, diag_what);
		gflog_debug(GFARM_MSG_1001090,
			"insertion to connection hash (%s)(%d) failed: %s",
			canonical_hostname, port,
			gfarm_error_string(e));
		return (e);
	}
	if (!*createdp) {
		connection = *(struct gfp_cached_connection **)
		    gfarm_hash_entry_data(entry);
		gfarm_lru_cache_addref_entry(&cache->lru_list,
		    &connection->lru_entry);
	} else {
		GFARM_MALLOC(connection);
		if (connection == NULL) {
			gfp_conn_hash_purge(cache->hashtab, entry);
			gfarm_mutex_unlock(&cache->mutex, diag, diag_what);
			gflog_debug(GFARM_MSG_1001091,
				"allocation of 'connection' failed: %s",
				gfarm_error_string(GFARM_ERR_NO_MEMORY));
			return (GFARM_ERR_NO_MEMORY);
		}

		idp = &connection->id;
		idp->hostname = strdup(canonical_hostname);
		idp->port = port;
		idp->username = strdup(user);
		if (idp->hostname == NULL || idp->username == NULL) {
			e = GFARM_ERR_NO_MEMORY;
			gflog_debug(GFARM_MSG_1002566,
			    "gfp_cached_connection_acquire (%s)(%d)"
			    " failed: %s",
			    canonical_hostname, port,
			    gfarm_error_string(e));
			free(idp->hostname);
			free(idp->username);
			free(connection);
			gfp_conn_hash_purge(cache->hashtab, entry);
			gfarm_mutex_unlock(&cache->mutex, diag, diag_what);
			return (e);
		}
		kidp = (struct gfp_conn_hash_id *)gfarm_hash_entry_key(entry);
		kidp->hostname = idp->hostname;
		kidp->username = idp->username;

		gfarm_lru_cache_add_entry(&cache->lru_list,
		    &connection->lru_entry);

		*(struct gfp_cached_connection **)gfarm_hash_entry_data(entry)
		    = connection;
		connection->hash_entry = entry;
		connection->connection_data = NULL;
		connection->dispose_connection_data = NULL;
		GFSP_CONN_INIT(connection)
	}
	gfarm_mutex_unlock(&cache->mutex, diag, diag_what);
	*connectionp = connection;
	return (GFARM_ERR_NO_ERROR);
}
Example #27
0
static void
gfs_client_status_schedule(struct host *host, int first_attempt)
{
	gfarm_error_t e;
	struct gfs_client_status_entry *qe;
	enum { stop_callout, do_next, do_retry } callout_next = do_next;
	const char diag[] = "GFS_PROTO_STATUS";

	GFARM_MALLOC(qe);
	if (qe == NULL) {
		callout_next = do_retry;
		gflog_error(GFARM_MSG_1004026,
		    "%s: %s: no memory for queue entry",
		    host_name(host), diag);
	} else {
		netsendq_entry_init(&qe->qentry, &gfs_proto_status_queue);
		qe->qentry.abhost = host_to_abstract_host(host);
		e = netsendq_add_entry(host_sendq(host), &qe->qentry,
		    NETSENDQ_ADD_FLAG_DETACH_ERROR_HANDLING);
		if (e == GFARM_ERR_NO_ERROR) {
			/* OK */
		} else if (first_attempt && e == GFARM_ERR_DEVICE_BUSY) {
			/*
			 * if this is first attempt just after
			 * the back channel connection is made,
			 * it's possible previous callout remains
			 * with the following scenario:
			 * 1. gfs_client_status_callout() thread begins to run
			 * 2. host_unset_peer() calls callout_stop()
			 * 3. netsendq_host_becomes_down() clears readyq
			 * 4. the gfs_client_status_callout() thread in 1
			 *    adds an entry to workq and readyq
			 */
			gflog_info(GFARM_MSG_1004027,
			    "%s: %s queueing conflict", host_name(host), diag);
		} else {
			/* increment refcount */
			struct peer *peer = host_get_peer(host);

			callout_next = stop_callout;
			gflog_info(GFARM_MSG_1004028,
			    "%s: %s queueing: %s",
			    host_name(host), diag, gfarm_error_string(e));
			/* `qe' is be freed by gfs_client_status_finalize() */
			if (peer == NULL) {
				gflog_info(GFARM_MSG_1004029,
				    "%s: %s: already disconnected",
				    host_name(host), diag);
			} else {
				gfs_client_status_disconnect_or_message(host,
				    peer, diag, "queueing",
				    gfarm_error_string(e));
				 /* decrement refcount */
				host_put_peer(host, peer);
			}
		}
	}
	switch (callout_next) {
	case stop_callout:
		/* do nothing */
		break;
	case do_next:
		callout_schedule(host_status_callout(host),
		    gfarm_metadb_heartbeat_interval * 1000000);
		break;
	case do_retry:
		callout_schedule(host_status_callout(host),
		    gfarm_metadb_heartbeat_interval * 1000000 / 10);
		break;
	}
}
Example #28
0
gfarm_error_t
gfs_pio_set_view_global(GFS_File gf, int flags)
{
	struct gfs_file_global_context *gc;
	gfarm_error_t e;
	char *arch;
	int i, n;
	struct gfarm_file_section_info *infos;
	static char gfarm_url_prefix[] = "gfarm:/";

	e = gfs_pio_set_view_default(gf);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	if (GFS_FILE_IS_PROGRAM(gf)) {
		e = gfarm_host_get_self_architecture(&arch);
		if (e != GFARM_ERR_NO_ERROR)
			return (gf->error = e);
		e = gfs_pio_set_view_section(gf, arch, NULL, flags);
		if (e == GFARM_ERR_NO_SUCH_OBJECT)
			e = gfs_pio_set_view_section(
				gf, "noarch", NULL, flags);
		return (e);
	}

	if ((gf->mode & GFS_FILE_MODE_FILE_WAS_CREATED) != 0)
		return (gfs_pio_set_view_index(gf, 1, 0, NULL, flags));

	if (gf->open_flags & GFARM_FILE_TRUNC) {
		int nsections;
		struct gfarm_file_section_info *sections;

		/* XXX this may not be OK, if a parallel process does this */
		/* remove all sections except section "0" */
		e = gfarm_file_section_info_get_all_by_file(gf->pi.pathname,
		    &nsections, &sections);
		if (e != GFARM_ERR_NO_ERROR)
			return (e);
		for (i = 0; i < nsections; i++) {
			if (strcmp(sections[i].section, "0") == 0)
				continue;
			(void)gfs_unlink_section_internal(gf->pi.pathname,
			    sections[i].section);
		}
		gfarm_file_section_info_free_all(nsections, sections);

		gf->pi.status.st_nsections = 1;
		return (gfs_pio_set_view_index(gf, 1, 0, NULL, flags));
	}

	/* XXX - GFARM_FILE_APPEND is not supported */
	if (gf->open_flags & GFARM_FILE_APPEND) {
		gf->error = GFARM_ERR_OPERATION_NOT_SUPPORTED;
		return (gf->error);
	}

	GFARM_MALLOC(gc);
	if (gc == NULL) {
		gf->error = GFARM_ERR_NO_MEMORY;
		return (gf->error);
	}

	e = gfarm_file_section_info_get_sorted_all_serial_by_file(
		gf->pi.pathname, &n, &infos);
	if (e != GFARM_ERR_NO_ERROR) {
		free(gc);
		gf->error = e;
		return (e);
	}

	if (n != gf->pi.status.st_nsections) {
		gfarm_file_section_info_free_all(n, infos);
		free(gc);
		gf->error = "metainfo inconsitency, fragment number mismatch";
		return (gf->error);
	}

	GFARM_MALLOC_ARRAY(gc->offsets, n + 1);
	GFARM_MALLOC_ARRAY(gc->url,
	    sizeof(gfarm_url_prefix) + strlen(gf->pi.pathname));
	if (gc->offsets == NULL || gc->url == NULL) {
		if (gc->offsets != NULL)
			free(gc->offsets);
		if (gc->url != NULL)
			free(gc->url);
		gfarm_file_section_info_free_all(n, infos);
		free(gc);
		gf->error = GFARM_ERR_NO_MEMORY;
		return (gf->error);
	}

	gc->offsets[0] = 0;
	for (i = 0; i < n; i++)
		gc->offsets[i + 1] = gc->offsets[i] + infos[i].filesize;
	gfarm_file_section_info_free_all(n, infos);

	sprintf(gc->url, "%s%s", gfarm_url_prefix, gf->pi.pathname);

	gf->view_context = gc;
	gf->view_flags = flags;
	gc->fragment_gf = NULL;
	e = gfs_pio_view_global_move_to(gf, 0);
	if (e != GFARM_ERR_NO_ERROR) {
		free(gc->url);
		free(gc->offsets);
		free(gc);
		gf->view_context = NULL;
		gfs_pio_set_view_default(gf);
		gf->error = e;
		return (e);
	}

	gf->ops = &gfs_pio_view_global_ops;
	gf->p = gf->length = 0;
	gf->io_offset = gf->offset = 0;
	gf->error = GFARM_ERR_NO_ERROR;
	return (GFARM_ERR_NO_ERROR);
}