예제 #1
0
파일: gfs_statfs.c 프로젝트: eterps/pwrake
gfarm_error_t
gfs_statfs(gfarm_off_t *used, gfarm_off_t *avail, gfarm_off_t *files)
{
	gfarm_error_t e;
	struct gfm_connection *gfm_server;
	int retry = 0;

	for (;;) {
		if ((e = gfm_client_connection_and_process_acquire(
		    gfarm_metadb_server_name, gfarm_metadb_server_port,
		    &gfm_server)) != GFARM_ERR_NO_ERROR)
			return (e);

		e = gfm_client_statfs(gfm_server, used, avail, files);
		if (gfm_client_is_connection_error(e) && ++retry <= 1){
			gfm_client_connection_free(gfm_server);
			continue;
		}

		break;
	}
	gfm_client_connection_free(gfm_server);

	return (e);

}
예제 #2
0
static gfarm_error_t
acquire_valid_connection(struct gfm_connection *gfm_server, const char *host,
	int port, const char *user, struct gfarm_filesystem *fs)
{
	gfarm_error_t e;
	int fc = gfarm_filesystem_failover_count(fs);
	int acquired = 0;

	while (fc > gfm_client_connection_failover_count(gfm_server)) {
		gfm_client_purge_from_cache(gfm_server);
		if (acquired)
			gfm_client_connection_free(gfm_server);

		if ((e = gfm_client_connection_and_process_acquire(
		    host, port, user, &gfm_server)) != GFARM_ERR_NO_ERROR) {
			gflog_debug(GFARM_MSG_1003860,
			    "gfm_client_connection_and_process_acquire: %s",
			    gfarm_error_string(e));
			return (e);
		}
		acquired = 1;
	}
	if (acquired)
		gfm_client_connection_free(gfm_server);
	gfarm_filesystem_set_failover_detected(fs, 0);
	return (GFARM_ERR_NO_ERROR);
}
예제 #3
0
파일: gfs_statfs.c 프로젝트: ddk50/gfarm_v2
static gfarm_error_t
statfs_post_failover(struct gfm_connection *gfm_server, void *closure)
{
	if (gfm_server)
		gfm_client_connection_free(gfm_server);
	return (GFARM_ERR_NO_ERROR);
}
예제 #4
0
파일: gfs_dir.c 프로젝트: eterps/pwrake
static gfarm_error_t
gfs_closedir_internal(GFS_Dir super)
{
	struct gfs_dir_internal *dir = (struct gfs_dir_internal *)super;
	gfarm_error_t e = gfm_close_fd(dir->gfm_server, dir->fd);

	gfm_client_connection_free(dir->gfm_server);
	free(dir);
	return (e);
}
예제 #5
0
파일: gfs_dirplus.c 프로젝트: eterps/pwrake
gfarm_error_t
gfs_closedirplus(GFS_DirPlus dir)
{
	gfarm_error_t e = gfm_close_fd(dir->gfm_server, dir->fd);

	gfm_client_connection_free(dir->gfm_server);
	gfs_dirplus_clear(dir);
	free(dir);
	return (e);
}
예제 #6
0
static gfarm_error_t
gfs_pio_reopen(struct gfarm_filesystem *fs, GFS_File gf)
{
	gfarm_error_t e;
	struct gfm_connection *gfm_server;
	int fd, type;
	gfarm_ino_t ino;
	char *real_url = NULL;

	/* avoid failover in gfm_open_fd_with_ino() */
	gfarm_filesystem_set_failover_detected(fs, 0);

	/* increment ref count of gfm_server */
	if ((e = gfm_open_fd_with_ino(gf->url,
	    gf->open_flags & (~GFARM_FILE_TRUNC),
	    &gfm_server, &fd, &type, &real_url, &ino)) != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1003380,
		    "reopen operation on file descriptor for URL (%s) "
		    "failed: %s",
		    gf->url,
		    gfarm_error_string(e));
		free(real_url);
		return (e);
	} else if (gfm_server != gf->gfm_server ||
	    type != GFS_DT_REG || ino != gf->ino) {
		e = GFARM_ERR_STALE_FILE_HANDLE;
	} else {
		gf->fd = fd;
		/* storage_context is null in scheduling */
		if (get_storage_context(gf->view_context) != NULL)
			e = (*gf->ops->view_reopen)(gf);
	}

	if (e == GFARM_ERR_NO_ERROR) {
		if (real_url != NULL) {
			free(gf->url);
			gf->url = real_url;
		}
	} else {
		if (real_url != NULL) {
			free(real_url);
		}
		(void)gfm_close_fd(gfm_server, fd); /* ignore result */
		gf->fd = GFARM_DESCRIPTOR_INVALID;
		gf->error = e;
		gflog_debug(GFARM_MSG_1003381,
		    "reopen operation on pio for URL (%s) failed: %s",
		    gf->url,
		    gfarm_error_string(e));
	}
	/* decrement ref count of gfm_server. then we'll use gf->gfm_server */
	gfm_client_connection_free(gfm_server);

	return (e);
}
예제 #7
0
static gfarm_error_t
name2_op_success(struct gfm_connection *conn, void *closure)
{
	struct op_closure *c = (struct op_closure *)closure;

	assert(conn);
	assert(closure);
	c->success++;
	gfm_client_connection_free(conn);
	return (GFARM_ERR_NO_ERROR);
}
예제 #8
0
static gfarm_error_t
name_op_success(struct gfm_connection *conn, void *closure, int type,
	const char *path, gfarm_ino_t ino)
{
	struct op_closure *c = (struct op_closure *)closure;

	assert(conn);
	assert(closure);
	assert(path);
	c->success++;
	gfm_client_connection_free(conn);
	return (GFARM_ERR_NO_ERROR);
}
예제 #9
0
파일: gfrep.c 프로젝트: ddk50/gfarm_v2
/*
 * XXX FIXME
 * - should use appropriate metadata server for the file,
 * - maybe(?) should use gfm_client_schedule_file instead.
 */
gfarm_error_t
schedule_host_domain(const char *path, const char *domain,
	int *nhostsp, struct gfarm_host_sched_info **hostsp)
{
	gfarm_error_t e;
	struct gfm_connection *gfm_server;

	if ((e = gfm_client_connection_and_process_acquire_by_path(
	    path, &gfm_server)) != GFARM_ERR_NO_ERROR)
		return (e);
	e = gfm_client_schedule_host_domain(gfm_server, domain,
	    nhostsp, hostsp);
	gfm_client_connection_free(gfm_server);
	return (e);
}
예제 #10
0
static gfarm_error_t
inode_op_success(struct gfm_connection *conn, void *closure, int type,
	const char *path, gfarm_ino_t ino)
{
	struct op_closure *c = (struct op_closure *)closure;

	assert(conn);
	assert(closure);
	assert(path);
	assert(type == GFS_DT_DIR || type == GFS_DT_LNK ||
		type == GFS_DT_REG || type == GFS_DT_UNKNOWN);
	c->success = 1;
	gfm_client_connection_free(conn);
	return (GFARM_ERR_NO_ERROR);
}
예제 #11
0
파일: gfs_dirplus.c 프로젝트: eterps/pwrake
gfarm_error_t
gfs_opendirplus(const char *path, GFS_DirPlus *dirp)
{
	gfarm_error_t e;
	struct gfm_connection *gfm_server;
	int fd, type;

	if ((e = gfm_open_fd(path, GFARM_FILE_RDONLY, &gfm_server, &fd, &type))
	    != GFARM_ERR_NO_ERROR)
		return (e);

	if (type != GFS_DT_DIR)
		e = GFARM_ERR_NOT_A_DIRECTORY;
	else if ((e = gfs_dirplus_alloc(gfm_server, fd, dirp)) ==
	    GFARM_ERR_NO_ERROR)
		return (GFARM_ERR_NO_ERROR);

	(void)gfm_close_fd(gfm_server, fd); /* ignore result */
	gfm_client_connection_free(gfm_server);
	return (e);
}
예제 #12
0
static gfarm_error_t
compound_fd_op_post_failover(struct gfm_connection *gfm_server, void *closure)
{
	gfarm_error_t e;
	int fd, type;
	char *url;
	gfarm_ino_t ino;
	struct compound_fd_op_info *ci = closure;
	void *file = ci->file;
	struct gfs_failover_file_ops *ops = ci->ops;
	const char *url0 = ops->get_url(file);

	/* reopen */
	if ((e = gfm_open_fd_with_ino(url0, GFARM_FILE_RDONLY,
	    &gfm_server, &fd, &type, &url, &ino)) != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1003869,
		    "gfm_open_fd_with_ino(%s) failed: %s",
		    url0, gfarm_error_string(e));
		/*
		 * any error except connection error means that the file
		 * cannot be accessed.
		 */
		return (gfm_client_is_connection_error(e) ? e :
			GFARM_ERR_STALE_FILE_HANDLE);
	}
	free(url);

	if (type != ops->type || ino != ops->get_ino(file))
		e = GFARM_ERR_STALE_FILE_HANDLE;
	else {
		/* set new fd and connection */
		ops->set_fileno(file, fd);
		ops->set_connection(file, gfm_server);
	}

	if (e != GFARM_ERR_NO_ERROR)
		gfm_client_connection_free(gfm_server);

	return (e);
}
예제 #13
0
gfarm_error_t
gfs_statfsnode(char *host, int port,
	gfarm_int32_t *bsize, gfarm_off_t *blocks, gfarm_off_t *bfree,
	gfarm_off_t *bavail, gfarm_off_t *files, gfarm_off_t *ffree,
	gfarm_off_t *favail)
{
	gfarm_error_t e;
	struct gfm_connection *gfm_server;
	struct gfs_connection *gfs_server;
	int retry = 0;

	for (;;) {
		if ((e = gfm_client_connection_and_process_acquire(
		    gfarm_metadb_server_name, gfarm_metadb_server_port,
		    &gfm_server)) != GFARM_ERR_NO_ERROR)
			return (e);

		if ((e = gfs_client_connection_acquire_by_host(gfm_server,
		    host, port, &gfs_server, NULL))!= GFARM_ERR_NO_ERROR)
			goto free_gfm_connection;

		if (gfs_client_pid(gfs_server) == 0)
			e = gfarm_client_process_set(gfs_server, gfm_server);
		if (e == GFARM_ERR_NO_ERROR) {
			/* "/" is actually not used */
			e = gfs_client_statfs(gfs_server, "/", bsize, blocks,
				bfree, bavail, files, ffree, favail);
			if (gfs_client_is_connection_error(e) && ++retry<=1) {
				gfs_client_connection_free(gfs_server);
				continue;
			}
		}
		break;
	}
	gfs_client_connection_free(gfs_server);
 free_gfm_connection:
	gfm_client_connection_free(gfm_server);
	return (e);
}
예제 #14
0
파일: gfusage.c 프로젝트: ddk50/gfarm_v2
int
main(int argc, char **argv)
{
	gfarm_error_t e;
	int c, status = 0;
	int opt_group = 0; /* default: users list */
	char *name = NULL, *realpath = NULL;
	const char *path = ".";

	if (argc > 0)
		program_name = basename(argv[0]);
	e = gfarm_initialize(&argc, &argv);
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: %s\n", program_name,
		    gfarm_error_string(e));
		exit(1);
	}

	while ((c = getopt(argc, argv, "P:gh?")) != -1) {
		switch (c) {
		case 'P':
			path = optarg;
			break;
		case 'g':
			opt_group = 1;
			break;
		case 'h':
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (gfarm_realpath_by_gfarm2fs(path, &realpath) == GFARM_ERR_NO_ERROR)
		path = realpath;
	if ((e = gfm_client_connection_and_process_acquire_by_path(
		     path, &gfm_server)) != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: metadata server for \"%s\": %s\n",
			program_name, path, gfarm_error_string(e));
		status = 1;
		goto terminate;
	}

	if (argc > 0)
		name = argv[0];

	if (name) {
		if (opt_group)
			e = usage_group_one(name);
		else
			e = usage_user_one(name);
	} else {
		if (opt_group)
			e = usage_group_all();
		else
			e = usage_user_all();
	}
	if (e != GFARM_ERR_NO_ERROR)
		status = 1;
	if (e == GFARM_ERR_OPERATION_NOT_PERMITTED)
		fprintf(stderr, "%s: %s\n", program_name,
			gfarm_error_string(e));
	gfm_client_connection_free(gfm_server);
terminate:
	free(realpath);
	e = gfarm_terminate();
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: %s\n", program_name,
		    gfarm_error_string(e));
		status = 1;
	}
	return (status);
}
예제 #15
0
파일: gfgroup.c 프로젝트: ddk50/gfarm_v2
int
main(int argc, char *argv[])
{
	gfarm_error_t e;
	char op = OP_GROUPNAME, *groupname;
	int c;
	const char *path = ".";
	char *realpath = NULL;

	e = gfarm_initialize(&argc, &argv);
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: gfarm_initialize: %s\n",
		    program_name, gfarm_error_string(e));
		exit(1);
	}

	while ((c = getopt(argc, argv, "P:cdlm?")) != -1) {
		switch (c) {
		case 'P':
			path = optarg;
			break;
		case OP_CREATE_GROUP:
		case OP_DELETE_GROUP:
		case OP_MODIFY_GROUP:
		case OP_LIST_LONG:
			op = c;
			break;
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (gfarm_realpath_by_gfarm2fs(path, &realpath) == GFARM_ERR_NO_ERROR)
		path = realpath;
	if ((e = gfm_client_connection_and_process_acquire_by_path(path,
	    &gfm_server)) != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: metadata server for \"%s\": %s\n",
		    program_name, path, gfarm_error_string(e));
		exit(1);
	}
	free(realpath);

	switch (op) {
	case OP_GROUPNAME:
	case OP_LIST_LONG:
		if (argc == 0)
			e = list_all(op);
		else
			e = list(op, argc, argv);
		break;
	case OP_CREATE_GROUP:
	case OP_MODIFY_GROUP:
		if (argc < 1)
			usage();
		groupname = *argv++;
		--argc;
		e = create_group(op, groupname, argc, argv);
		break;
	case OP_DELETE_GROUP:
		if (argc != 1)
			usage();
		e = delete_group(*argv);
		break;
	}
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: %s\n",
		    program_name, gfarm_error_string(e));
		exit(1);
	}

	gfm_client_connection_free(gfm_server);

	e = gfarm_terminate();
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: gfarm_terminate: %s\n",
		    program_name, gfarm_error_string(e));
		exit(1);
	}
	exit(0);
}
예제 #16
0
파일: gfccinfo.c 프로젝트: ddk50/gfarm_v2
int
main(int argc, char **argv)
{
	int argc_save = argc;
	char **argv_save = argv;
	gfarm_error_t e, e_save = GFARM_ERR_NO_ERROR;
	char opt_operation = '\0'; /* default operation */
	int opt_concurrency = DEFAULT_CONCURRENCY;
	int opt_alter_aliases = 0;
	const char *opt_path = ".";
	char *realpath = NULL;
	char *opt_architecture = NULL, *opt_domainname = NULL;
	long opt_ncpu = 0;
	int opt_port = 0, opt_flags = -1;
	int opt_plain_order = 0; /* i.e. do not sort */
	int opt_sort_by_loadavg = 0;
	int i, c, opt_use_metadb = 1;
	char *s;

	if (argc > 0)
		program_name = basename(argv[0]);
	while ((c = getopt(argc, argv, "AD:HLMP:RUa:cdf:ij:lmn:p:ruv?"))
	    != -1) {
		switch (c) {
		case 'A':
			opt_alter_aliases = 1;
			break;
		case 'L':
			opt_sort_by_loadavg = 1;
			break;
		case 'P':
			opt_path = optarg;
			break;
		case 'M':
		case 'H':
		case 'R':
		case 'c':
		case 'd':
		case 'l':
		case 'm':
			if (opt_operation != '\0' && opt_operation != c)
				inconsistent_option(opt_operation, c);
			opt_operation = c;
			break;
		case 'a':
			opt_architecture = optarg;
			s = validate_architecture(opt_architecture);
			if (s != NULL) {
				fprintf(stderr, "%s: "
				    "invalid character '%c' in \"-a %s\"\n",
				    program_name, *s, opt_architecture);
				exit(1);
			}
			break;
		case 'D':
			opt_domainname = optarg;
			s = validate_hostname(opt_domainname);
			if (s != NULL) {
				fprintf(stderr, "%s: "
				    "invalid character '%c' in \"-a %s\"\n",
				    program_name, *s, opt_domainname);
				exit(1);
			}
			break;
		case 'i':
			opt_resolv_addr = resolv_addr_without_address_use;
			break;
		case 'j':
			opt_concurrency = parse_opt_long(optarg,
			    c, "<concurrency>");
			if (opt_concurrency <= 0) {
				fprintf(stderr, "%s: invalid value: -%c %d\n",
				    program_name, c, opt_concurrency);
				usage();
			}
			break;
		case 'f':
			opt_flags = parse_opt_long(optarg, c, "<flags>");
			break;
		case 'n':
			opt_ncpu = parse_opt_long(optarg, c, "<ncpu>");
			break;
		case 'p':
			opt_port = parse_opt_long(optarg, c, "<port>");
			break;
		case 'r':
			output_sort_reverse = 1;
			break;
		case 'U':
			opt_udp_only = 1;
			break;
		case 'u':
			opt_plain_order = 1;
			break;
		case 'v':
			opt_verbose = 1;
			break;
		case '?':
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	switch (opt_operation) {
	case OP_CREATE_ENTRY:
		if (opt_architecture == NULL) {
			fprintf(stderr, "%s: missing -a <architecture>\n",
			    program_name);
			usage();
		}
		if (opt_ncpu == 0)
			opt_ncpu = 1;
		if (opt_flags == -1)
			opt_flags = 0;
		/* opt_alter_aliases is meaningless, but allowed */
		break;
	case OP_REGISTER_DB:
	case OP_DELETE_ENTRY:
		if (opt_architecture != NULL)
			invalid_option('a');
		if (opt_domainname != NULL)
			invalid_option('D');
		/* fall through */
	case OP_NODENAME:
	case OP_LIST_GFSD_INFO:
	case OP_LIST_LONG:
	case OP_DUMP_METADB:
		if (opt_ncpu != 0)
			invalid_option('n');
		if (opt_alter_aliases)
			invalid_option('A');
		break;
	case OP_MODIFY_ENTRY:
		if (opt_domainname != NULL)
			invalid_option('D');
		break;
	default:
		;
	}

	for (i = 0; i < argc; i++) {
		s = validate_hostname(argv[i]);
		if (s != NULL) {
			fprintf(stderr, "%s: "
			    "invalid character '%c' in hostname \"%s\"\n",
			    program_name, *s, argv[i]);
			exit(1);
		}
	}

	e = gfarm_initialize(&argc_save, &argv_save);
	if (opt_operation == OP_LIST_GFSD_INFO && argc > 0 &&
	    opt_resolv_addr == resolv_addr_without_address_use) {
		/*
		 * An implicit feature to access gfsd directly
		 * without having working gfmd.
		 * e.g. gfhost -Hi <hostname>
		 *
		 * XXX	should describe this in the manual?
		 *	or use explicit and different option?
		 */
		opt_use_metadb = 0;
		opt_resolv_addr = resolv_addr_without_metadb;
	} else if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: %s\n", program_name,
		    gfarm_error_string(e));
		exit(1);
	}

	e = gfarm_realpath_by_gfarm2fs(opt_path, &realpath);
	if (e == GFARM_ERR_NO_ERROR)
		opt_path = realpath;
	if (opt_use_metadb &&
	    (e = gfm_client_connection_and_process_acquire_by_path(opt_path,
	    &gfm_server)) != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: metadata server for \"%s\": %s\n",
		    program_name, opt_path, gfarm_error_string(e));
		exit(1);
	}
	free(realpath);

	switch (opt_operation) {
	case OP_CREATE_ENTRY:
		/* if (argc <= 0) */
		/* 	usage(); */
		/* if (opt_port == 0) { */
		/* 	fprintf(stderr, "%s: option -p <port> is " */
		/* 	    "mandatory with -c\n", program_name); */
		/* 	usage(); */
		/* } */
		/* e_save = add_host(argv[0], opt_port, &argv[1], */
		/*     opt_architecture, opt_ncpu, opt_flags); */
		/* if (e_save != GFARM_ERR_NO_ERROR) */
		/* 	fprintf(stderr, "%s: %s: %s\n", program_name, */
		/* 	    argv[0], gfarm_error_string(e_save)); */
		break;
	case OP_MODIFY_ENTRY:
		/* if (argc <= 0) */
		/* 	usage(); */
		/* e_save = gfarm_modify_host(argv[0], opt_port, &argv[1], */
		/*     opt_architecture, opt_ncpu, opt_flags, */
		/*     !opt_alter_aliases); */
		/* if (e_save != GFARM_ERR_NO_ERROR) */
		/* 	fprintf(stderr, "%s: %s: %s\n", program_name, */
		/* 	    argv[0], gfarm_error_string(e_save)); */
		break;
	case OP_DELETE_ENTRY:
		/* if (argc <= 0) */
		/* 	usage(); */
		/* for (i = 0; i < argc; i++) { */
		/* 	e = gfm_client_host_info_remove(gfm_server, */
		/* 	    argv[i]); */
		/* 	if (e != GFARM_ERR_NO_ERROR) { */
		/* 		fprintf(stderr, "%s: %s\n", argv[i], */
		/* 		    gfarm_error_string(e)); */
		/* 		if (e_save == GFARM_ERR_NO_ERROR) */
		/* 			e_save = e; */
		/* 	} */
		/* } */
		break;
	case OP_REGISTER_DB:
		/* if (argc > 0) { */
		/* 	fprintf(stderr, "%s: too many argument: %s\n", */
		/* 	    program_name, argv[0]); */
		/* 	usage(); */
		/* } */
		/* e_save = register_db(); */
		break;
	case OP_LIST_GFSD_INFO:
		e_save = paraccess_list(opt_concurrency, opt_udp_only,
		    opt_architecture, opt_domainname, opt_port,
		    opt_plain_order, opt_sort_by_loadavg,
		    opt_use_metadb, argc, argv,
		    request_clear_gfsd_cacheinfo, callback_gfsd_info);
		break;
	case OP_NODENAME:
		e_save = paraccess_list(opt_concurrency, opt_udp_only,
		    opt_architecture, opt_domainname, opt_port,
		    opt_plain_order, opt_sort_by_loadavg,
		    opt_use_metadb, argc, argv,
		    request_gfsd_cacheinfo, callback_nodename);
		break;
	case OP_LIST_LONG:
		/* e_save = paraccess_list(opt_concurrency, opt_udp_only, */
		/*     opt_architecture, opt_domainname, opt_port, */
		/*     opt_plain_order, opt_sort_by_loadavg, */
		/*     opt_use_metadb, argc, argv, */
		/*     request_long_format, callback_long_format); */
		break;
	case OP_DUMP_METADB:
		/* if (argc == 0) { */
		/* 	e_save = list_all(opt_architecture, opt_domainname, */
		/* 		print_host_info, NULL); */
		/* } else { */
		/* 	e_save = list(argc, argv, print_host_info, NULL); */
		/* } */
		break;
	}

	if (opt_use_metadb)
		gfm_client_connection_free(gfm_server);

	e = gfarm_terminate();
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: %s\n", program_name,
		    gfarm_error_string(e));
		exit(1);
	}
	exit(e_save == GFARM_ERR_NO_ERROR ? 0 : 1);
}
예제 #17
0
파일: gfs_link.c 프로젝트: eterps/pwrake
gfarm_error_t
gfs_link(const char *src, const char *dst)
{
	gfarm_error_t e, e_save;
	int retry = 0;
	struct gfm_connection *sgfmd, *dgfmd;
	const char *spath, *dpath, *dbase;

	for (;;) {
		e_save = GFARM_ERR_NO_ERROR;
		spath = src;
		dpath = dst;

		if ((e = gfarm_url_parse_metadb(&spath, &sgfmd))
		    != GFARM_ERR_NO_ERROR) {
			gflog_warning(GFARM_MSG_1000118,
			    "url_parse_metadb(%s): %s", src,
			    gfarm_error_string(e));
			return (e);
		} else if ((e = gfarm_url_parse_metadb(&dpath, &dgfmd))
		    != GFARM_ERR_NO_ERROR) {
			gflog_warning(GFARM_MSG_1000119,
			    "url_parse_metadb(%s): %s", dst,
			    gfarm_error_string(e));
			gfm_client_connection_free(sgfmd);
			return (e);
		} else if (sgfmd != dgfmd) {
			gfm_client_connection_free(dgfmd);
			gfm_client_connection_free(sgfmd);
			return (GFARM_ERR_CROSS_DEVICE_LINK);
		}


		if ((e = gfm_tmp_open_request(sgfmd, spath, GFARM_FILE_LOOKUP))
		    != GFARM_ERR_NO_ERROR) {
			gflog_warning(GFARM_MSG_1000120,
			    "tmp_open(%s) request: %s", src,
			    gfarm_error_string(e));
		} else if ((e = gfm_client_save_fd_request(sgfmd))
		    != GFARM_ERR_NO_ERROR) {
			gflog_warning(GFARM_MSG_1000121, "save_fd request: %s",
			    gfarm_error_string(e));
		} else if ((e = gfm_lookup_dir_request(dgfmd, dpath, &dbase))
		    != GFARM_ERR_NO_ERROR) {
			gflog_warning(GFARM_MSG_1000122,
			    "lookup_dir(%s) request: %s", dst,
			    gfarm_error_string(e));
		} else if (dbase[0] == '/' && dbase[1] == '\0') {
			/* "/" is special */
			e_save = GFARM_ERR_OPERATION_NOT_PERMITTED;
		} else if ((e = gfm_client_flink_request(dgfmd, dbase))
		    != GFARM_ERR_NO_ERROR) {
			gflog_warning(GFARM_MSG_1000123, "flink request: %s",
			    gfarm_error_string(e));
		}
		if (e != GFARM_ERR_NO_ERROR)
			break;

		if ((e = gfm_client_compound_end_request(sgfmd))
		    != GFARM_ERR_NO_ERROR) {
			gflog_warning(GFARM_MSG_1000124,
			    "compound_end request: %s",
			    gfarm_error_string(e));

		} else if ((e = gfm_tmp_open_result(sgfmd, spath, NULL))
		    != GFARM_ERR_NO_ERROR) {
			if (gfm_client_is_connection_error(e) && ++retry <= 1){
				gfm_client_connection_free(dgfmd);
				gfm_client_connection_free(sgfmd);
				continue;
			}
#if 0 /* DEBUG */
			gflog_debug(GFARM_MSG_1000125,
			    "tmp_open(%s) result: %s", src,
			    gfarm_error_string(e));
#endif
		} else if ((e = gfm_client_save_fd_result(sgfmd))
		    != GFARM_ERR_NO_ERROR) {
			gflog_warning(GFARM_MSG_1000126, "save_fd result: %s",
			    gfarm_error_string(e));
		} else if ((e = gfm_lookup_dir_result(dgfmd, dpath, &dbase))
		    != GFARM_ERR_NO_ERROR) {
#if 0 /* DEBUG */
			gflog_debug(GFARM_MSG_1000127,
			    "lookup_dir(%s) result: %s", dst,
			    gfarm_error_string(e));
#endif
		} else if (dbase[0] == '/' && dbase[1] == '\0') {
			/* "/" is special */
			e_save = GFARM_ERR_OPERATION_NOT_PERMITTED;
		} else if ((e = gfm_client_flink_result(dgfmd))
		    != GFARM_ERR_NO_ERROR) {
#if 0 /* DEBUG */
			gflog_debug(GFARM_MSG_1000128, "flink result: %s",
			    gfarm_error_string(e));
#endif
		}
		if (e != GFARM_ERR_NO_ERROR)
			break;

		if ((e = gfm_client_compound_end_result(sgfmd))
		    != GFARM_ERR_NO_ERROR) {
			gflog_warning(GFARM_MSG_1000129,
			    "compound_end result: %s",
			    gfarm_error_string(e));
		}

		break;
	}
	gfm_client_connection_free(dgfmd);
	gfm_client_connection_free(sgfmd);

	/* NOTE: the opened descriptor is automatically closed by gfmd */

	return (e_save != GFARM_ERR_NO_ERROR ? e_save : e);
}
예제 #18
0
static gfarm_error_t
gfm_realpath_success(struct gfm_connection *gfm_server, void *closure,
	int type, const char *path, gfarm_ino_t ino)
{
	gfarm_error_t e;
	char *buf, *b;
	const char *p, *q;
	const char *hostname;
	size_t len;
	int level = 0;

	len = strlen(path);
	GFARM_MALLOC_ARRAY(buf, len + 2); /* 2 for b[0]='/' + last '\0' */
	if (buf == NULL) {
		gfm_client_connection_free(gfm_server);
		return (GFARM_ERR_NO_MEMORY);
	}
	b = buf;
	p = path;
	e = GFARM_ERR_NO_ERROR;

	while (*p) {
		while (*p == '/')
			p++;
		q = p;
		while (*q != '/' && *q != 0)
			q++;
		len = q - p;
		if (len == 0) {
			if (*q != 0)
				e = GFARM_ERR_INVALID_ARGUMENT;
			break;
		}
		if (len == 1 && p[0] == '.') {
			p = q;
			continue;
		}
		if (len == 2 && p[0] == '.' && p[1] == '.') {
			if (level <= 0) {
				p = q;
				continue;
			}
			--b;
			while (*b != '/' && b > buf)
				b--;
			p = q;
			--level;
			continue;
		}
		*b++ = '/';
		memcpy(b, p, len);
		p = q;
		b += len;
		++level;
	}

	if (level == 0)
		*b++ = '/';
	*b = 0;

	if (e != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1002669,
		    "gfm_realpath_success(%s) : %s\n",
		    path, gfarm_error_string(e));
		goto end;
	}

	len = strlen(buf);
	hostname = gfm_client_hostname(gfm_server);
	GFARM_MALLOC_ARRAY(b, len + strlen(hostname) + GFARM_URL_PREFIX_LENGTH +
	    2 + 1 + 5 + 1);
	    /* (gfarm:=PREFIX_LENGTH)(//=2)(:=1)(port=5)(\0=1) */
	if (b == NULL) {
		e = GFARM_ERR_NO_MEMORY;
		goto end;
	}
	sprintf(b, "%s//%s:%d%s", GFARM_URL_PREFIX,
	    hostname, gfm_client_port(gfm_server), buf);
	((struct gfm_realpath_closure *)closure)->path = b;
end:
	free(buf);
	gfm_client_connection_free(gfm_server);
	return (e);
}
예제 #19
0
static int
reset_and_reopen(GFS_File gf, void *closure)
{
	gfarm_error_t e = GFARM_ERR_NO_ERROR;
	struct reset_and_reopen_info *ri = closure;
	struct gfm_connection *gfm_server = ri->gfm_server;
	struct gfm_connection *gfm_server1;
	struct gfs_connection *sc;
	struct gfarm_filesystem *fs =
	    gfarm_filesystem_get_by_connection(gfm_server);
	int fc = gfarm_filesystem_failover_count(fs);

	if ((e = gfm_client_connection_acquire(gfm_client_hostname(gfm_server),
	    gfm_client_port(gfm_server), gfm_client_username(gfm_server),
	    &gfm_server1)) != GFARM_ERR_NO_ERROR) {
		gf->error = e;
		gflog_debug(GFARM_MSG_1003383,
		    "gfm_client_connection_acquire: %s",
		    gfarm_error_string(e));
		return (1);
	}

	if (gfm_server != gfm_server1) {
		gfm_client_connection_free(gfm_server1);
		gflog_debug(GFARM_MSG_1003384,
		    "reconnected to other gfmd or gfmd restarted");
		ri->must_retry = 1;
		return (0);
	}

	/* if old gfm_connection is alive, fd must be closed */
	(void)gfm_close_fd(gf->gfm_server, gf->fd);
	gf->fd = GFARM_DESCRIPTOR_INVALID;
	gfm_client_connection_free(gf->gfm_server);
	/* ref count of gfm_server is incremented above */
	gf->gfm_server = gfm_server;

	if ((sc = get_storage_context(gf->view_context)) != NULL) {
		/*
		 * pid will be 0 if gfarm_client_process_reset() resulted
		 * in failure at reset_and_reopen() previously called with
		 * the same gfs_connection.
		 */
		if (gfs_client_pid(sc) == 0) {
			gf->error = GFARM_ERR_CONNECTION_ABORTED;
			gflog_debug(GFARM_MSG_1003385,
			    "%s", gfarm_error_string(gf->error));
			return (1);
		}

		/* reset pid */
		if (fc > gfs_client_connection_failover_count(sc)) {
			gfs_client_connection_set_failover_count(sc, fc);
			/*
			 * gfs_file just in scheduling is not related to
			 * gfs_server.
			 * In that case, gfarm_client_process_reset() is
			 * called in gfs_pio_open_section().
			 *
			 * all fd will be closed in gfsd by
			 * gfarm_client_process_reset().
			 */
			e = gfarm_client_process_reset(sc, gfm_server);
			if (e != GFARM_ERR_NO_ERROR) {
				gf->error = e;
				gflog_debug(GFARM_MSG_1003386,
				    "gfarm_client_process_reset: %s",
				    gfarm_error_string(e));
				return (1);
			}
		}
	}

	/* reopen file */
	if (gfs_pio_error(gf) != GFARM_ERR_STALE_FILE_HANDLE &&
	    (e = gfs_pio_reopen(fs, gf)) != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1003387,
		    "gfs_pio_reopen: %s", gfarm_error_string(e));
	}

	return (1);
}
예제 #20
0
static gfarm_error_t
failover0(struct gfm_connection *gfm_server, const char *host0, int port,
	const char *user0)
{
	gfarm_error_t e;
	struct gfarm_filesystem *fs;
	struct gfs_file_list *gfl = NULL;
	char *host = NULL, *user = NULL;
	int fc, i, ok = 0;

	if (gfm_server) {
		fs = gfarm_filesystem_get_by_connection(gfm_server);
		if (gfarm_filesystem_in_failover_process(fs)) {
			e = GFARM_ERR_OPERATION_NOT_PERMITTED;
			gflog_debug(GFARM_MSG_1003861,
			    "gfmd connection failover process called "
			    "recursively");
			goto error_all;
		}
		gfarm_filesystem_set_in_failover_process(fs, 1);
		fc = gfarm_filesystem_failover_count(fs);
		if ((host = strdup(gfm_client_hostname(gfm_server))) ==  NULL) {
			e = GFARM_ERR_NO_MEMORY;
			gflog_debug(GFARM_MSG_1003388,
			    "%s", gfarm_error_string(e));
			goto error_all;
		}
		if ((user = strdup(gfm_client_username(gfm_server))) ==  NULL) {
			e = GFARM_ERR_NO_MEMORY;
			gflog_debug(GFARM_MSG_1003389,
			    "%s", gfarm_error_string(e));
			goto error_all;
		}
		port = gfm_client_port(gfm_server);

		if (fc > gfm_client_connection_failover_count(gfm_server)) {
			/* already failover occurred */
			e = acquire_valid_connection(gfm_server, host, port,
			    user, fs);
			goto end;
		}
	} else {
		fs = gfarm_filesystem_get(host0, port);
		assert(fs != NULL);
		if (gfarm_filesystem_in_failover_process(fs)) {
			e = GFARM_ERR_OPERATION_NOT_PERMITTED;
			gflog_debug(GFARM_MSG_1003862,
			    "gfmd connection failover process called "
			    "recursively");
			goto error_all;
		}
		gfarm_filesystem_set_in_failover_process(fs, 1);
		fc = gfarm_filesystem_failover_count(fs);
		if ((host = strdup(host0)) ==  NULL) {
			e = GFARM_ERR_NO_MEMORY;
			gflog_debug(GFARM_MSG_1003863,
			    "%s", gfarm_error_string(e));
			goto error_all;
		}
		if ((user = strdup(user0)) ==  NULL) {
			e = GFARM_ERR_NO_MEMORY;
			gflog_debug(GFARM_MSG_1003864,
			    "%s", gfarm_error_string(e));
			goto error_all;
		}
	}
	gfl = gfarm_filesystem_opened_file_list(fs);

	/*
	 * failover_count must be incremented before acquire connection
	 * because failover_count is set at creating new connection
	 * and we use failover_count to indicate whether or not the acquired
	 * connection is new connection.
	 */
	gfarm_filesystem_set_failover_count(fs, fc + 1);

	for (i = 0; i < NUM_FAILOVER_RETRY; ++i) {
		/* reconnect to gfmd */
		if ((e = gfm_client_connection_and_process_acquire(
		    host, port, user, &gfm_server)) != GFARM_ERR_NO_ERROR) {
			gflog_debug(GFARM_MSG_1003390,
			    "gfm_client_connection_acquire failed : %s",
			    gfarm_error_string(e));
			continue;
		}
		if (gfm_client_connection_failover_count(gfm_server)
		    != fc + 1) {
			/*
			 * When this function is called from
			 * gfm_client_connection_failover_pre_connect(),
			 * the acquired connection is possibly an old
			 * connection.
			 */
			gfm_client_purge_from_cache(gfm_server);
			gfm_client_connection_free(gfm_server);
			--i;
			continue;
		}

		/*
		 * close fd, release gfm_connection and set invalid fd,
		 * reset processes and reopen files
		*/
		ok = reset_and_reopen_all(gfm_server, gfl);
		gfm_client_connection_free(gfm_server);
		if (ok)
			break;
	}

	if (ok) {
		gfarm_filesystem_set_failover_detected(fs, 0);
		e = GFARM_ERR_NO_ERROR;
		gflog_notice(GFARM_MSG_1003391,
		    "connection to metadb server was failed over successfully");
	} else {
		gfarm_filesystem_set_failover_detected(fs, 1);
		e = GFARM_ERR_OPERATION_TIMED_OUT;
		gflog_debug(GFARM_MSG_1003392,
		    "falied to fail over: %s", gfarm_error_string(e));
	}
end:
	free(host);
	free(user);
	gfarm_filesystem_set_in_failover_process(fs, 0);

	return (e);

error_all:

	free(host);
	free(user);

	if (gfl != NULL)
		gfs_pio_file_list_foreach(gfl, set_error, &e);
	gfarm_filesystem_set_in_failover_process(fs, 0);

	return (e);
}