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); }
gfarm_error_t gfm_client_rpc_with_failover( gfarm_error_t (*rpc_op)(struct gfm_connection **, void *), gfarm_error_t (*post_failover_op)(struct gfm_connection *, void *), void (*exit_op)(struct gfm_connection *, gfarm_error_t, void *), int (*must_be_warned_op)(gfarm_error_t, void *), void *closure) { gfarm_error_t e; struct gfm_connection *gfm_server; int nretry = 1, post_nretry = 1; retry: gfm_server = NULL; e = rpc_op(&gfm_server, closure); if (nretry > 0 && gfm_client_connection_should_failover( gfm_server, e)) { if ((e = failover(gfm_server)) != GFARM_ERR_NO_ERROR) { gflog_debug(GFARM_MSG_1003865, "failover: %s", gfarm_error_string(e)); } else if (post_failover_op && (e = post_failover_op(gfm_server, closure)) != GFARM_ERR_NO_ERROR) { gflog_debug(GFARM_MSG_1003866, "post_failover_op: %s", gfarm_error_string(e)); if (gfm_client_is_connection_error(e) && post_nretry > 0) { /* * following cases: * - acquired conneciton in failover() is * created before failover(). * - connection error occurred after failover(). */ post_nretry--; goto retry; } } else { nretry--; goto retry; } } else if (e != GFARM_ERR_NO_ERROR) { gflog_debug(GFARM_MSG_1003867, "gfm_client_rpc_with_failover: rpc_op: %s", gfarm_error_string(e)); if (nretry == 0 && must_be_warned_op && must_be_warned_op(e, closure)) gflog_warning(GFARM_MSG_1003868, "error ocurred at retry for the operation after " "connection to metadb server was failed over, " "so the operation possibly succeeded in the server." " error='%s'", gfarm_error_string(e)); } if (exit_op) exit_op(gfm_server, e, closure); return (e); }
int gfm_client_connection_should_failover(struct gfm_connection *gfm_server, gfarm_error_t e) { #ifndef __KERNEL__ /* failover */ struct gfarm_filesystem *fs; if (gfm_server == NULL || !gfm_client_is_connection_error(e)) return (0); fs = gfarm_filesystem_get_by_connection(gfm_server); return (!gfarm_filesystem_in_failover_process(fs)); #else /* __KERNEL__ */ return (0); #endif /* __KERNEL__ */ }
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_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); }