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); }
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); }
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); }
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); }
/* 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); } } }
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); }
/* * 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); }
/* 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); }
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 = ¶m->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, ¶m->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)); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
/* * 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); }
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)); }
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); }
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; }
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)); }
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); }
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; } }
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, §ions); 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); }