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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
/* * 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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }