Exemple #1
0
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;
	}
}
Exemple #2
0
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);
		
}
Exemple #3
0
/* 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, &sections);
	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);
}
Exemple #4
0
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);
}
Exemple #5
0
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);
}
Exemple #6
0
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);
}
Exemple #7
0
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);			
}
Exemple #8
0
/*
 * 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);
}
Exemple #9
0
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, &copy);
	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);
}