void gfarm_errlist_hashtab_initialize(void) { int i, created; struct gfarm_hash_entry *p; gfarm_errlist_hashtab = gfarm_hash_table_alloc(ERRLIST_HASHTAB_SIZE, gfarm_hash_default, gfarm_hash_key_equal_default); if (gfarm_errlist_hashtab == NULL) { fprintf(stderr, "gfarm_errlist_hashtab_initialize(): " "no memory\n"); exit(1); } for (i = 1; IN_ERRNO(i); i++) { if (STRERROR(i) == NULL) continue; p = gfarm_hash_enter(gfarm_errlist_hashtab, STRERROR(i), strlen(STRERROR(i)) + 1, sizeof(int), &created); if (p == NULL) { fprintf(stderr, "gfarm_errlist_hashtab_initialize(): " "no memory for errno %d\n", i); exit(1); } if (created) *(int *)gfarm_hash_entry_data(p) = i; } }
static gfarm_error_t gfs_stat_cache_enter_internal(const char *path, const struct gfs_stat *st, const struct timeval *nowp) { gfarm_error_t e; struct gfarm_hash_entry *entry; struct stat_cache_data *data; int created; if (stat_cache == NULL) { if ((e = gfs_stat_cache_init()) != GFARM_ERR_NO_ERROR) return (e); } gfs_stat_cache_expire_internal(nowp); if (stat_cache_count >= gfarm_attr_cache_limit) { /* remove the head of the list (i.e. oldest entry) */ data = stat_cache_list_head.next; data->prev->next = data->next; data->next->prev = data->prev; gfs_stat_free(&data->st); entry = data->entry; gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry), gfarm_hash_entry_key_length(entry)); --stat_cache_count; } entry = gfarm_hash_enter(stat_cache, path, strlen(path) + 1, sizeof(*data), &created); if (entry == NULL) return (GFARM_ERR_NO_MEMORY); data = gfarm_hash_entry_data(entry); if (created) { ++stat_cache_count; data->entry = entry; } else { /* remove from the list, to move this to the end of the list */ data->prev->next = data->next; data->next->prev = data->prev; gfs_stat_free(&data->st); } e = gfs_stat_copy(&data->st, st); if (e != GFARM_ERR_NO_ERROR) { gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry), gfarm_hash_entry_key_length(entry)); --stat_cache_count; return (e); } data->expiration = *nowp; gfarm_timeval_add(&data->expiration, &stat_cache_lifespan); /* add to the end of the cache list, i.e. assumes monotonic time */ data->next = &stat_cache_list_head; data->prev = stat_cache_list_head.prev; stat_cache_list_head.prev->next = data; stat_cache_list_head.prev = data; return (GFARM_ERR_NO_ERROR); }
/* Create a set of architectures that the program is registered for */ static char * program_arch_set(char *program, struct gfarm_hash_table **arch_setp) { char *e, *gfarm_file; struct gfarm_path_info pi; struct gfarm_file_section_info *sections; struct gfarm_hash_table *arch_set; int i, nsections, created; e = gfarm_url_make_path(program, &gfarm_file); if (e != NULL) return (e); e = gfarm_path_info_get(gfarm_file, &pi); if (e != NULL) { if (e == GFARM_ERR_NO_SUCH_OBJECT) e = "such program isn't registered"; free(gfarm_file); return (e); } if (!GFARM_S_IS_PROGRAM(pi.status.st_mode)) { gfarm_path_info_free(&pi); free(gfarm_file); return ("specified command is not an executable"); } e = gfarm_file_section_info_get_all_by_file(gfarm_file, &nsections, §ions); gfarm_path_info_free(&pi); free(gfarm_file); if (e != NULL) return ("no binary is registered as the specified command"); arch_set = gfarm_hash_table_alloc(ARCH_SET_HASHTAB_SIZE, gfarm_hash_default, gfarm_hash_key_equal_default); if (arch_set == NULL) { gfarm_file_section_info_free_all(nsections, sections); return (GFARM_ERR_NO_MEMORY); } /* register architectures of the program to `arch_set' */ for (i = 0; i < nsections; i++) { if (gfarm_hash_enter(arch_set, sections[i].section, strlen(sections[i].section) + 1, sizeof(int), &created) == NULL) { free_arch_set(arch_set); gfarm_file_section_info_free_all(nsections, sections); return (GFARM_ERR_NO_MEMORY); } } gfarm_file_section_info_free_all(nsections, sections); *arch_setp = arch_set; return (NULL); }
static char * cache_path_info_put(const char *pathname, struct gfarm_path_info *info) { struct gfarm_hash_entry *he; int pathlen; int created; struct path_info_cache *pic; if (!cache_path_info_init()) return (GFARM_PATH_INFO_CACHE_CANCEL); if (current_cache_num >= hash_size) cache_path_info_free(); /* clear all cache */ pathlen = strlen(pathname); /* set cache */ he = gfarm_hash_enter(cache_table, pathname, pathlen, sizeof(struct path_info_cache), &created); if (he == NULL) { _debug("! cache_path_info_put: no memory\n"); return (GFARM_ERR_NO_MEMORY); } pic = gfarm_hash_entry_data(he); _debug("! put path_info cache: %s\n", pathname); if (created) /* new cache */ current_cache_num++; else if (pic->noent == CACHE_SET) /* have path_info */ gfarm_path_info_free(&pic->info); if (info == NULL) { /* set NOENT */ pic->noent = CACHE_NOENT; _debug("! -> set NOENT: %s\n", pathname); } else { #ifdef DEBUG if (pic->noent == CACHE_NOENT) { _debug("! -> update cache from NOENT: %s\n", pathname); } #endif (void)gfarm_path_info_dup(info, &pic->info); pic->noent = CACHE_SET; } /* current time */ gettimeofday(&pic->time, NULL); return (NULL); }
static gfarm_error_t create_hash_table_from_string_list(int array_length, char **array, int hashsize, struct gfarm_hash_table **hashp) { struct gfarm_hash_table *hash; int i; hash = gfarm_hash_table_alloc(hashsize, gfarm_hash_casefold, gfarm_hash_key_equal_casefold); if (hash == NULL) return (GFARM_ERR_NO_MEMORY); for (i = 0; i < array_length; ++i) gfarm_hash_enter(hash, array[i], strlen(array[i])+1, 0, NULL); *hashp = hash; return (GFARM_ERR_NO_ERROR); }
gfarm_error_t gfp_conn_hash_enter(struct gfarm_hash_table **hashtabp, int hashtabsize, size_t entrysize, const char *hostname, int port, const char *username, struct gfarm_hash_entry **entry_ret, int *created_ret) { gfarm_error_t e; struct gfp_conn_hash_id id, *idp; struct gfarm_hash_entry *entry; int created; if (*hashtabp == NULL && (e = gfp_conn_hash_table_init(hashtabp, hashtabsize)) != GFARM_ERR_NO_ERROR) return (e); id.hostname = (char *)hostname; /* UNCONST */ id.port = port; id.username = (char *)username; /* UNCONST */ entry = gfarm_hash_enter(*hashtabp, &id, sizeof(id), entrysize, &created); if (entry == NULL) return (GFARM_ERR_NO_MEMORY); if (created) { idp = gfarm_hash_entry_key(entry); idp->hostname = strdup(hostname); idp->username = strdup(username); if (idp->hostname == NULL || idp->username == NULL) { if (idp->hostname != NULL) free(idp->hostname); if (idp->username != NULL) free(idp->username); idp->hostname = (char *)hostname; /* UNCONST */ idp->username = (char *)username; /* UNCONST */ gfarm_hash_purge(*hashtabp, &id, sizeof(id)); return (GFARM_ERR_NO_MEMORY); } } *entry_ret = entry; *created_ret = created; return (GFARM_ERR_NO_ERROR); }
static char * alloc_hosts_state(int *n_all_hostsp, struct gfarm_host_info **all_hostsp, struct gfarm_hash_table **hosts_statep) { char *e; int i, created, n_all_hosts; struct gfarm_host_info *all_hosts; struct gfarm_hash_table *hosts_state; struct gfarm_hash_entry *entry; struct search_idle_host_state *h; e = gfarm_host_info_get_all(&n_all_hosts, &all_hosts); if (e != NULL) return (e); if (n_all_hosts == 0) { gfarm_host_info_free_all(n_all_hosts, all_hosts); return (GFARM_ERR_NO_HOST); } hosts_state = gfarm_hash_table_alloc(HOSTS_HASHTAB_SIZE, gfarm_hash_casefold, gfarm_hash_key_equal_casefold); if (hosts_state == NULL) { gfarm_host_info_free_all(n_all_hosts, all_hosts); return (GFARM_ERR_NO_MEMORY); } for (i = 0; i < n_all_hosts; i++) { entry = gfarm_hash_enter(hosts_state, all_hosts[i].hostname, strlen(all_hosts[i].hostname) + 1, sizeof(struct search_idle_host_state), &created); if (entry == NULL) { free_hosts_state(n_all_hosts, all_hosts, hosts_state); return (GFARM_ERR_NO_MEMORY); } /* `created' must be always true. */ h = gfarm_hash_entry_data(entry); h->host_info = &all_hosts[i]; h->flags = 0; } *n_all_hostsp = n_all_hosts; *all_hostsp = all_hosts; *hosts_statep = hosts_state; return (NULL); }
/* * if (op != GFARM_INODE_CREATE), (is_dir) may be -1, * and that means "don't care". */ char * lookup_node(struct node *parent, const char *name, int len, int is_dir, enum gfarm_node_lookup_op op, struct node **np) { struct gfarm_hash_entry *entry; int created, already_purged; struct node *n; if ((parent->flags & NODE_FLAG_IS_DIR) == 0) return (GFARM_ERR_NOT_A_DIRECTORY); if (len == 0) { /* We don't handle GFARM_INODE_MARK for this case */ if (op == GFARM_INODE_REMOVE) return (GFARM_ERR_INVALID_ARGUMENT); *np = parent; return (NULL); } else if (len == 1 && name[0] == '.') { /* We don't handle GFARM_INODE_MARK for this case */ if (op == GFARM_INODE_REMOVE) return (GFARM_ERR_INVALID_ARGUMENT); *np = parent; return (NULL); } else if (len == 2 && name[0] == '.' && name[1] == '.') { /* We don't handle GFARM_INODE_MARK for this case */ if (op == GFARM_INODE_REMOVE) return (GFARM_ERR_DIRECTORY_NOT_EMPTY); *np = parent->parent; return (NULL); } if (len > GFS_MAXNAMLEN) len = GFS_MAXNAMLEN; if (op == GFARM_INODE_MARK) { entry = gfarm_hash_lookup(parent->u.d.children, name, len); /* We should not honor the PURGED flag here */ if (entry != NULL) { n = gfarm_hash_entry_data(entry); if ((n->flags & NODE_FLAG_IS_DIR) == is_dir) { /* abandon the PURGED flag at the mark phase */ n->flags &= ~NODE_FLAG_PURGED; n->flags |= NODE_FLAG_MARKED; *np = n; return (NULL); } if (opendir_count > 0) { if (is_dir) { change_file_node_to_dir(n); } else { recursive_delayed_purge_nodes(n); change_dir_node_to_file(n); } /* abandon the PURGED flag at the mark phase */ n->flags &= ~NODE_FLAG_PURGED; n->flags |= NODE_FLAG_MARKED; *np = n; return (NULL); } recursive_free_nodes(n); gfarm_hash_purge(parent->u.d.children, name, len); } /* do create */ } else if (op != GFARM_INODE_CREATE) { entry = gfarm_hash_lookup(parent->u.d.children, name, len); if (entry == NULL) return (GFARM_ERR_NO_SUCH_OBJECT); n = gfarm_hash_entry_data(entry); already_purged = (n->flags & NODE_FLAG_PURGED) != 0; if (already_purged || op == GFARM_INODE_REMOVE) { if (opendir_count > 0) { recursive_delayed_purge_nodes(n); } else { recursive_free_nodes(n); gfarm_hash_purge(parent->u.d.children, name, len); } if (already_purged) return (GFARM_ERR_NO_SUCH_OBJECT); *np = NULL; return (NULL); } *np = n; return (NULL); } entry = gfarm_hash_enter(parent->u.d.children, name, len, #if 0 is_dir ? DIR_NODE_SIZE : FILE_NODE_SIZE, #else /* * always allocate DIR_NODE_SIZE * to make it possible to change a file to a dir */ DIR_NODE_SIZE, #endif &created); if (entry == NULL) return (GFARM_ERR_NO_MEMORY); n = gfarm_hash_entry_data(entry); if (!created) { n->flags &= ~NODE_FLAG_PURGED; /* assert(op == GFARM_INODE_CREATE); */ *np = n; return (NULL); } if (is_dir) init_dir_node(n, name, len); else init_file_node(n, name, len); n->parent = parent; if (op == GFARM_INODE_MARK) n->flags |= NODE_FLAG_MARKED; *np = n; return (NULL); }
static gfarm_error_t create_filelist(char *file, struct gfs_stat *st, void *arg) { struct flist *a = arg; int i, j, ncopy, src_ncopy = 0, dst_ncopy = 0; char **copy; gfarm_error_t e; if (!GFARM_S_ISREG(st->st_mode)) { if (opt_verbose) printf("%s: not a regular file, skipped\n", file); return (GFARM_ERR_NO_ERROR); } e = gfs_replica_list_by_name(file, &ncopy, ©); if (e != GFARM_ERR_NO_ERROR) return (e); /* if there is no available file replica, display error message */ if (ncopy == 0 && st->st_size > 0) { fprintf(stderr, "%s: no available file repilca\n", file); e = GFARM_ERR_NO_ERROR; goto free_copy; } for (i = 0; i < ncopy; ++i) { if ((a->src_hosthash == NULL || gfarm_hash_lookup( a->src_hosthash, copy[i], strlen(copy[i]) + 1)) && gfarm_host_is_in_domain(copy[i], a->src_domain)) { ++src_ncopy; } if ((a->dst_hosthash == NULL || gfarm_hash_lookup( a->dst_hosthash, copy[i], strlen(copy[i]) + 1)) && gfarm_host_is_in_domain(copy[i], a->dst_domain)) { ++dst_ncopy; } } /* * if there is no replica in a set of source nodes or there * are already specified number of replicas in a set of * destination nodes, do not add. */ if (src_ncopy == 0 || dst_ncopy == opt_nrep) { e = GFARM_ERR_NO_ERROR; goto free_copy; } /* add source nodes to srchash to count the number of source nodes */ for (i = 0; i < ncopy; ++i) { char *s = copy[i]; if ((a->src_hosthash == NULL || gfarm_hash_lookup( a->src_hosthash, s, strlen(s) + 1)) && gfarm_host_is_in_domain(s, a->src_domain)) gfarm_hash_enter(a->srchash, s, strlen(s)+1, 0, NULL); } /* add a file info to slist */ for (j = 0; j < opt_nrep - dst_ncopy; ++j) { e = gfarm_list_add_file_info(file, st->st_size, ncopy, copy, 0, &a->slist); if (e != GFARM_ERR_NO_ERROR) goto free_copy; } /* add a file info to dlist if too many file replicas exist */ if (dst_ncopy > opt_nrep) { e = gfarm_list_add_file_info(file, st->st_size, ncopy, copy, dst_ncopy - opt_nrep, &a->dlist); } free_copy: gfarm_strings_free_deeply(ncopy, copy); return (e); }