void gfarm_barrier_destroy(pthread_barrier_t *barrier, const char *where, const char *what) { #ifdef HAVE_PTHREAD_BARRIER_WAIT int err = pthread_barrier_destroy(barrier); if (err != 0) gflog_fatal(GFARM_MSG_1003255, "%s: %s barrier destroy: %s", where, what, strerror(err)); #else int err; err = pthread_cond_destroy(&barrier->all_entered); if (err != 0) gflog_fatal(GFARM_MSG_1003256, "%s: %s barrier destroy: cond_destroy all_entered: %s", where, what, strerror(err)); err = pthread_mutex_destroy(&barrier->mutex); if (err != 0) gflog_fatal(GFARM_MSG_1003257, "%s: %s barrier destroy: mutex_destroy: %s", where, what, strerror(err)); #endif }
void gfarm_auth_sharedsecret_response_data(char *shared_key, char *challenge, char *response) { EVP_MD_CTX mdctx; unsigned int md_len; static pthread_mutex_t openssl_mutex = PTHREAD_MUTEX_INITIALIZER; int rv; /* * according to "valgrind --tool=helgrind", * these OpenSSL functions are not multithread safe, * at least about openssl-0.9.8e-12.el5_4.1.x86_64 on CentOS 5.4 */ if ((rv = pthread_mutex_lock(&openssl_mutex)) != 0) gflog_fatal(GFARM_MSG_UNFIXED, "gfarm_auth_sharedsecret_response_data: " "openssl mutex lock: %s", strerror(rv)); EVP_DigestInit(&mdctx, EVP_md5()); EVP_DigestUpdate(&mdctx, challenge, GFARM_AUTH_CHALLENGE_LEN); EVP_DigestUpdate(&mdctx, shared_key, GFARM_AUTH_SHARED_KEY_LEN); EVP_DigestFinal(&mdctx, (unsigned char *)response, &md_len); if ((rv = pthread_mutex_unlock(&openssl_mutex)) != 0) gflog_fatal(GFARM_MSG_UNFIXED, "gfarm_auth_sharedsecret_response_data: " "openssl mutex unlock: %s", strerror(rv)); if (md_len != GFARM_AUTH_RESPONSE_LEN) { fprintf(stderr, "gfarm_auth_sharedsecret_response_data:" "md5 digest length should be %d, but %d\n", GFARM_AUTH_RESPONSE_LEN, md_len); abort(); } }
void gfarm_barrier_init(pthread_barrier_t *barrier, unsigned int count, const char *where, const char *what) { #ifdef HAVE_PTHREAD_BARRIER_WAIT int err = pthread_barrier_init(barrier, NULL, count); if (err != 0) gflog_fatal(GFARM_MSG_1003252, "%s: %s barrier init: %s", where, what, strerror(err)); #else int err; err = pthread_mutex_init(&barrier->mutex, NULL); if (err != 0) gflog_fatal(GFARM_MSG_1003253, "%s: %s barrier init: mutex_init: %s", where, what, strerror(err)); err = pthread_cond_init(&barrier->all_entered, NULL); if (err != 0) gflog_fatal(GFARM_MSG_1003254, "%s: %s barrier init: cond_init all_entered: %s", where, what, strerror(err)); barrier->n_members = barrier->n_pending = count; barrier->cycle = 0; #endif }
/* 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); }
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); }
char * gfj_server_hostinfo(struct xxx_connection *client) { /* XXX - NOT IMPLEMENTED */ gflog_fatal("host_info", "not implemented"); return (gfj_server_put_reply(client, "host_info", GFJ_ERROR_NOERROR, "")); }
char * gfj_server_register_node(struct xxx_connection *client) { /* XXX - NOT IMPLEMENTED */ gflog_fatal("register_node", "not implemented"); return (gfj_server_put_reply(client, "register_node", GFJ_ERROR_NOERROR, "")); }
gfarm_error_t gfj_server_register_node(struct peer *peer, int from_client, int skip) { /* XXX - NOT IMPLEMENTED */ gflog_fatal("register_node: not implemented"); return (gfj_server_put_reply(peer, "register_node", GFARM_ERR_NO_ERROR, "")); }
static gfarm_error_t gfarm_authorize_panic(struct gfp_xdr *conn, int switch_to, char *service_tag, char *hostname, gfarm_error_t (*auth_uid_to_global_user)(void *, enum gfarm_auth_method, const char *, char **), void *closure, enum gfarm_auth_id_type *peer_typep, char **global_usernamep) { gflog_fatal(GFARM_MSG_1000021, "gfarm_authorize: authorization assertion failed"); return (GFARM_ERR_PROTOCOL); }
gfarm_error_t gfj_server_register_node(struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep, int from_client, int skip) { static const char diag[] = "GFJ_PROTO_REGISTER_NODE"; /* XXX - NOT IMPLEMENTED */ gflog_fatal(GFARM_MSG_1000295, "%s: not implemented", diag); return (gfj_server_put_reply(peer, xid, sizep, diag, GFARM_ERR_NO_ERROR, "")); }
void gflog_fatal_errno(const char *format, ...) { char buffer[2048]; va_list ap; va_start(ap, format); vsnprintf(buffer, sizeof buffer, format, ap); va_end(ap); gflog_fatal("%s: %s", buffer, strerror(errno)); }
void gfp_connection_unlock(struct gfp_cached_connection *connection) { #ifdef __KERNEL__ int err; err = GFSP_CONN_UNLOCK(connection); if (err != 0) { gflog_fatal(GFARM_MSG_1003721, "owner=%d count=%d", connection->conn_lock.r_owner, connection->conn_lock.r_locked); } #endif /* __KERNEL__ */ }
/* convert from uncached connection to cached */ static inline gfarm_error_t gfp_uncached_connection_into_cache(struct gfp_conn_cache *cache, struct gfp_cached_connection *connection, void (*func)(struct gfarm_lru_cache *, struct gfarm_lru_entry *)) { gfarm_error_t e; struct gfarm_hash_entry *entry; int created; static const char diag[] = "gfp_uncached_connection_enter_cache"; if (GFP_IS_CACHED_CONNECTION(connection)) { gflog_fatal(GFARM_MSG_1000057, "gfp_uncached_connection_enter_cache(%s): " "programming error", cache->type_name); } gfarm_mutex_lock(&cache->mutex, diag, diag_what); e = gfp_conn_hash_id_enter_noalloc(&cache->hashtab, cache->table_size, sizeof(connection), &connection->id, &entry, &created); if (e != GFARM_ERR_NO_ERROR) { gfarm_mutex_unlock(&cache->mutex, diag, diag_what); gflog_debug(GFARM_MSG_1001088, "insertion to connection hash (%s)(%d) failed: %s", gfp_cached_connection_hostname(connection), gfp_cached_connection_port(connection), gfarm_error_string(e)); return (e); } if (!created) { gfarm_mutex_unlock(&cache->mutex, diag, diag_what); gflog_debug(GFARM_MSG_1001089, "insertion to connection hash (%s)(%d) failed: %s", gfp_cached_connection_hostname(connection), gfp_cached_connection_port(connection), gfarm_error_string(GFARM_ERR_ALREADY_EXISTS)); return (GFARM_ERR_ALREADY_EXISTS); } func(&cache->lru_list, &connection->lru_entry); *(struct gfp_cached_connection **)gfarm_hash_entry_data(entry) = connection; connection->hash_entry = entry; gfarm_mutex_unlock(&cache->mutex, diag, diag_what); return (GFARM_ERR_NO_ERROR); }
gfarm_error_t gfj_server_hostinfo(struct peer *peer, int from_client, int skip) { gfarm_error_t e = GFARM_ERR_NO_ERROR; if (!from_client) e = GFARM_ERR_OPERATION_NOT_PERMITTED; /* XXX - NOT IMPLEMENTED */ gflog_fatal("host_info: not implemented"); return (gfj_server_put_reply(peer, "host_info", GFARM_ERR_NO_ERROR, "")); }
gfarm_error_t process_alloc(struct user *user, gfarm_int32_t keytype, size_t keylen, char *sharedkey, struct process **processp, gfarm_pid_t *pidp) { struct process *process; struct file_opening **filetab; int fd; gfarm_int32_t pid32; if (process_id_table == NULL) { process_id_table = gfarm_id_table_alloc(&process_id_table_ops); if (process_id_table == NULL) gflog_fatal("allocating pid table: no memory"); } if (keytype != GFM_PROTO_PROCESS_KEY_TYPE_SHAREDSECRET || keylen != GFM_PROTO_PROCESS_KEY_LEN_SHAREDSECRET) return (GFARM_ERR_INVALID_ARGUMENT); GFARM_MALLOC_ARRAY(filetab, FILETAB_INITIAL); if (filetab == NULL) return (GFARM_ERR_NO_MEMORY); process = gfarm_id_alloc(process_id_table, &pid32); if (process == NULL) { free(filetab); return (GFARM_ERR_NO_MEMORY); } process->siblings.next = process->siblings.prev = &process->siblings; process->children.next = process->children.prev = &process->children; process->parent = NULL; memcpy(process->sharedkey, sharedkey, keylen); process->pid = pid32; process->user = user; process->refcount = 0; process->nfiles = FILETAB_INITIAL; process->filetab = filetab; for (fd = 0; fd < FILETAB_INITIAL; fd++) filetab[fd] = NULL; *processp = process; *pidp = pid32; return (GFARM_ERR_NO_ERROR); }
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); }
/* * the following function is for client, * server/daemon process shouldn't call it. * Because this function may read incorrect setting from user specified * $USER or $HOME. */ gfarm_error_t gfarm_initialize(int *argcp, char ***argvp) { gfarm_error_t e; enum gfarm_auth_method auth_method; #ifdef HAVE_GSI int saved_auth_verb; #endif e = gfarm_set_local_user_for_this_local_account(); if (e != GFARM_ERR_NO_ERROR) return (e); e = gfarm_config_read(); if (e != GFARM_ERR_NO_ERROR) return (e); #ifdef HAVE_GSI /* * Suppress verbose error messages. The message will be * displayed later in gfarm_auth_request_gsi(). */ saved_auth_verb = gflog_auth_set_verbose(0); (void)gfarm_gsi_client_initialize(); (void)gflog_auth_set_verbose(saved_auth_verb); #endif /* * In sharedsecret authentication, a global user name is * required to be set to access a metadata server. */ e = gfarm_set_global_user_for_sharedsecret(); if (e != GFARM_ERR_NO_ERROR) return (e); /* * XXX FIXME this shouldn't be necessary here * to support multiple metadata server */ e = gfm_client_connection_acquire(gfarm_metadb_server_name, gfarm_metadb_server_port, &gfarm_metadb_server); if (e != GFARM_ERR_NO_ERROR) { fprintf(stderr, "connecting gfmd: %s\n", gfarm_error_string(e)); exit(1); } gfarm_metadb_set_server(gfarm_metadb_server); /* metadb access is required to obtain a global user name by GSI */ auth_method = gfm_client_connection_auth_method(gfarm_metadb_server); if (GFARM_IS_AUTH_GSI(auth_method)) { e = gfarm_set_global_user_by_gsi(); if (e != GFARM_ERR_NO_ERROR) return (e); } if (argvp != NULL) { #if 0 /* not yet in gfarm v2 */ if (getenv("DISPLAY") != NULL) gfarm_debug_initialize((*argvp)[0]); e = gfarm_parse_argv(argcp, argvp); if (e != GFARM_ERR_NO_ERROR) return (e); #endif /* not yet in gfarm v2 */ } gfarm_auth_random(gfarm_client_pid_key, gfarm_client_pid_key_len); e = gfm_client_process_alloc(gfarm_metadb_server, gfarm_client_pid_key_type, gfarm_client_pid_key, gfarm_client_pid_key_len, &gfarm_client_pid); if (e != GFARM_ERR_NO_ERROR) gflog_fatal("failed to allocate gfarm PID: %s", gfarm_error_string(e)); #if 0 /* not yet in gfarm v2 */ gfarm_initialized = 1; #endif /* not yet in gfarm v2 */ return (GFARM_ERR_NO_ERROR); }
int gfarm_barrier_wait(pthread_barrier_t *barrier, const char *where, const char *what) { #ifdef HAVE_PTHREAD_BARRIER_WAIT int err = pthread_barrier_wait(barrier); if (err == PTHREAD_BARRIER_SERIAL_THREAD) return (1); /* this is the serial thread */ if (err != 0) gflog_fatal(GFARM_MSG_1003258, "%s: %s barrier wait: %s", where, what, strerror(err)); return (0); #else int err, cycle, retval; err = pthread_mutex_lock(&barrier->mutex); if (err != 0) gflog_fatal(GFARM_MSG_1003259, "%s: %s barrier wait: mutex_lock: %s", where, what, strerror(err)); cycle = barrier->cycle; if (--barrier->n_pending > 0) { /* XXX need to disable cancelstate */ do { err = pthread_cond_wait(&barrier->all_entered, &barrier->mutex); if (err != 0) gflog_fatal(GFARM_MSG_1003260, "%s: %s barrier wait: " " cond_wait all_entered: %s", where, what, strerror(err)); } while (barrier->cycle == cycle); /* XXX need to re-enable cancelstate */ retval = 0; } else { /* now all entered */ barrier->cycle = !barrier->cycle; barrier->n_pending = barrier->n_members; /* * pthread_cond_signal() and pthraed_cond_broadcast() may * return EAGAIN on MacOS X 10.7 (Lion), * if retry count exceeds 8192 times. * http://www.opensource.apple.com/source/Libc/Libc-763.11/pthreads/pthread_cond.c */ while ((err = pthread_cond_broadcast(&barrier->all_entered)) == EAGAIN) ; if (err != 0) gflog_fatal(GFARM_MSG_1003261, "%s: %s barrier wait: " "cond_broadcast all_entered: %s", where, what, strerror(err)); retval = 1; /* this is the serial thread */ } err = pthread_mutex_unlock(&barrier->mutex); if (err != 0) gflog_fatal(GFARM_MSG_1003262, "%s: %s barrier wait: mutex_unlock: %s", where, what, strerror(err)); return (retval); #endif }
int main(int argc, char **argv) { extern char *optarg; extern int optind; char *e, *config_file = NULL, *port_number = NULL; int syslog_facility = GFARM_DEFAULT_FACILITY; int ch, sock, table_size; if (argc >= 1) program_name = basename(argv[0]); gflog_set_identifier(program_name); while ((ch = getopt(argc, argv, "df:p:s:")) != -1) { switch (ch) { case 'd': debug_mode = 1; break; case 'f': config_file = optarg; break; case 'p': port_number = optarg; break; case 's': syslog_facility = gflog_syslog_name_to_facility(optarg); if (syslog_facility == -1) gflog_fatal(optarg, "unknown syslog facility"); break; case '?': default: usage(); } } argc -= optind; argv += optind; if (config_file != NULL) gfarm_config_set_filename(config_file); e = gfarm_server_initialize(); if (e != NULL) { fprintf(stderr, "gfarm_server_initialize: %s\n", e); exit(1); } if (port_number != NULL) gfarm_metadb_server_port = strtol(port_number, NULL, 0); sock = open_accepting_socket(gfarm_metadb_server_port); if (!debug_mode) { gflog_syslog_open(LOG_PID, syslog_facility); gfarm_daemon(0, 0); } table_size = GFMD_CONNECTION_LIMIT; gfarm_unlimit_nofiles(&table_size); if (table_size > GFMD_CONNECTION_LIMIT) table_size = GFMD_CONNECTION_LIMIT; file_table_init(table_size); job_table_init(table_size); /* * We don't want SIGPIPE, but want EPIPE on write(2)/close(2). */ signal(SIGPIPE, SIG_IGN); main_loop(sock); /*NOTREACHED*/ return (0); /* to shut up warning */ }