From 2c149262888c50beb9f480a6cd78f77fd5920d1c Mon Sep 17 00:00:00 2001 From: Li Wang Date: Tue, 27 Nov 2018 03:35:53 +0000 Subject: [PATCH] tools/rados: always call rados.shutdown() before exit() When connected to ceph cluster, if call exit(1) directly, will cause the finisher thread segmentation fault as follows, Caught signal (Segmentation fault) **in thread 7f45377fe700 thread_name:fn_anonymous run 'rados mapext' without other arguments could easily get it. This patch fixes it by calling rados.shutdown() before exit() Fixes: http://tracker.ceph.com/issues/36732 Signed-off-by: Li Wang --- src/tools/rados/rados.cc | 505 ++++++++++++++++++++++----------------- 1 file changed, 290 insertions(+), 215 deletions(-) diff --git a/src/tools/rados/rados.cc b/src/tools/rados/rados.cc index c724ddca1a6..9d42dc33751 100644 --- a/src/tools/rados/rados.cc +++ b/src/tools/rados/rados.cc @@ -2095,27 +2095,26 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, boost::optional pgid(i != opts.end(), pg_t()); if (pgid && (!pgid->parse(i->second.c_str()) || (pool_name && rados.pool_lookup(pool_name) != pgid->pool()))) { cerr << "invalid pgid" << std::endl; - ret = -1; - goto out; + return 1; } // open rados ret = rados.init_with_context(g_ceph_context); if (ret < 0) { cerr << "couldn't initialize rados: " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } ret = rados.connect(); if (ret) { cerr << "couldn't connect to cluster: " << cpp_strerror(ret) << std::endl; - ret = -1; - goto out; + return 1; } if (create_pool && !pool_name) { cerr << "--create-pool requested but pool_name was not specified!" << std::endl; - usage_exit(); + usage(cerr); + return 1; } if (create_pool) { @@ -2123,7 +2122,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error creating pool " << pool_name << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } @@ -2134,7 +2133,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, cerr << "error opening pool " << (pool_name ? pool_name : std::string("with id ") + std::to_string(pgid->pool())) << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } // align op_size @@ -2144,7 +2143,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error checking pool alignment requirement" << cpp_strerror(ret) << std::endl; - goto out; + return 1; } if (requires) { @@ -2153,7 +2152,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error getting pool alignment" << cpp_strerror(ret) << std::endl; - goto out; + return 1; } const uint64_t prev_op_size = op_size; @@ -2173,7 +2172,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (0 != ret) { cerr << "error opening pool " << pool_name << " with striper interface: " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } use_striper = true; } @@ -2184,20 +2183,18 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (snapname) { if (!pool_name) { cerr << "pool name must be specified with --snap" << std::endl; - ret = -1; - goto out; + return 1; } ret = io_ctx.snap_lookup(snapname, &snapid); if (ret < 0) { cerr << "error looking up snap '" << snapname << "': " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } if (oloc.size()) { if (!pool_name) { cerr << "pool name must be specified with --object_locator" << std::endl; - ret = -1; - goto out; + return 1; } io_ctx.locator_set_key(oloc); } @@ -2205,8 +2202,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (opts.find("namespace") != opts.end()) { if (!pool_name) { cerr << "pool name must be specified with --namespace" << std::endl; - ret = -1; - goto out; + return 1; } io_ctx.set_namespace(nspace); // Use wildcard if --all specified and --default NOT specified @@ -2217,15 +2213,14 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (snapid != CEPH_NOSNAP) { if (!pool_name) { cerr << "pool name must be specified with --snapid" << std::endl; - ret = -1; - goto out; + return 1; } string name; ret = io_ctx.snap_get_name(snapid, &name); if (ret < 0) { cerr << "snapid " << snapid << " doesn't exist in pool " << io_ctx.get_pool_name() << std::endl; - goto out; + return 1; } io_ctx.snap_set_read(snapid); cout << "selected snap " << snapid << " '" << name << "'" << std::endl; @@ -2239,7 +2234,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, ret = rados.pool_list(vec); if (ret < 0) { cerr << "error listing pools: " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } for (list::iterator i = vec.begin(); i != vec.end(); ++i) cout << *i << std::endl; @@ -2252,7 +2247,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, ret = rados.pool_list(vec); if (ret < 0) { cerr << "error listing pools: " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else { vec.push_back(pool_name); @@ -2262,7 +2257,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, ret = rados.get_pool_stats(vec, stats); if (ret < 0) { cerr << "error fetching pool stats: " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } TextTable tab; @@ -2337,7 +2332,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, ret = rados.cluster_stat(tstats); if (ret < 0) { cerr << "error getting total cluster usage: " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } if (!formatter) { cout << std::endl; @@ -2363,8 +2358,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, else if (strcmp(nargs[0], "ls") == 0) { if (!pool_name && !pgid) { cerr << "either pool name or pg id needs to be specified" << std::endl; - ret = -1; - goto out; + return 1; } if (wildcard) @@ -2372,8 +2366,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, bool use_stdout = (!output && (nargs.size() < 2 || (strcmp(nargs[1], "-") == 0))); if (!use_stdout && !output) { cerr << "Please use --output to specify the output file name" << std::endl; - ret = -1; - goto out; + return 1; } ostream *outstream; if(use_stdout) @@ -2427,8 +2420,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, } catch (const std::runtime_error& e) { cerr << e.what() << std::endl; - ret = -1; - goto out; + return 1; } } if (formatter) { @@ -2442,14 +2434,16 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, delete outstream; } else if (strcmp(nargs[0], "mapext") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); std::map m; ret = io_ctx.mapext(oid, 0, -1, m); if (ret < 0) { cerr << "mapext error on " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } std::map::iterator iter; for (iter = m.begin(); iter != m.end(); ++iter) { @@ -2457,8 +2451,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, } } else if (strcmp(nargs[0], "stat") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); uint64_t size; time_t mtime; @@ -2468,7 +2464,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << " error stat-ing " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } else { utime_t t(mtime, 0); cout << pool_name << "/" << oid @@ -2476,8 +2472,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, } } else if (strcmp(nargs[0], "stat2") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); uint64_t size; struct timespec mtime; @@ -2487,7 +2485,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << " error stat-ing " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } else { utime_t t(mtime); cout << pool_name << "/" << oid @@ -2495,8 +2493,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, } } else if (strcmp(nargs[0], "touch") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); time_t timestamp = time(NULL); if (nargs.size() > 2) { @@ -2505,7 +2505,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (*endptr) { cerr << "Invalid value for timestamp: '" << nargs[2] << "'" << std::endl; ret = -EINVAL; - goto out; + return 1; } } @@ -2516,39 +2516,47 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << " error touch-ing " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "get") == 0) { - if (!pool_name || nargs.size() < 3) - usage_exit(); + if (!pool_name || nargs.size() < 3) { + usage(cerr); + return 1; + } ret = do_get(io_ctx, nargs[1], nargs[2], op_size, use_striper); if (ret < 0) { cerr << "error getting " << pool_name << "/" << nargs[1] << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "put") == 0) { - if (!pool_name || nargs.size() < 3) - usage_exit(); + if (!pool_name || nargs.size() < 3) { + usage(cerr); + return 1; + } ret = do_put(io_ctx, nargs[1], nargs[2], op_size, obj_offset, use_striper); if (ret < 0) { cerr << "error putting " << pool_name << "/" << nargs[1] << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "append") == 0) { - if (!pool_name || nargs.size() < 3) - usage_exit(); + if (!pool_name || nargs.size() < 3) { + usage(cerr); + return 1; + } ret = do_append(io_ctx, nargs[1], nargs[2], op_size, use_striper); if (ret < 0) { cerr << "error appending " << pool_name << "/" << nargs[1] << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "truncate") == 0) { - if (!pool_name || nargs.size() < 3) - usage_exit(); + if (!pool_name || nargs.size() < 3) { + usage(cerr); + return 1; + } string oid(nargs[1]); char* endptr = NULL; @@ -2556,11 +2564,12 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (*endptr) { cerr << "Invalid value for size: '" << nargs[2] << "'" << std::endl; ret = -EINVAL; - goto out; + return 1; } if (size < 0) { cerr << "error, cannot truncate to negative value" << std::endl; - usage_exit(); + usage(cerr); + return 1; } ret = detail::trunc(io_ctx, oid, size, use_striper); @@ -2574,8 +2583,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, } } else if (strcmp(nargs[0], "setxattr") == 0) { - if (!pool_name || nargs.size() < 3 || nargs.size() > 4) - usage_exit(); + if (!pool_name || nargs.size() < 3 || nargs.size() > 4) { + usage(cerr); + return 1; + } string oid(nargs[1]); string attr_name(nargs[2]); @@ -2587,7 +2598,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, do { ret = bl.read_fd(STDIN_FILENO, 1024); // from stdin if (ret < 0) - goto out; + return 1; } while (ret > 0); } @@ -2595,14 +2606,16 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error setting xattr " << pool_name << "/" << oid << "/" << attr_name << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } else ret = 0; } else if (strcmp(nargs[0], "getxattr") == 0) { - if (!pool_name || nargs.size() < 3) - usage_exit(); + if (!pool_name || nargs.size() < 3) { + usage(cerr); + return 1; + } string oid(nargs[1]); string attr_name(nargs[2]); @@ -2612,15 +2625,17 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error getting xattr " << pool_name << "/" << oid << "/" << attr_name << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } else ret = 0; string s(bl.c_str(), bl.length()); cout << s; } else if (strcmp(nargs[0], "rmxattr") == 0) { - if (!pool_name || nargs.size() < 3) - usage_exit(); + if (!pool_name || nargs.size() < 3) { + usage(cerr); + return 1; + } string oid(nargs[1]); string attr_name(nargs[2]); @@ -2629,11 +2644,13 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error removing xattr " << pool_name << "/" << oid << "/" << attr_name << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "listxattr") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); bufferlist bl; @@ -2643,7 +2660,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error getting xattr set " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } for (map::iterator iter = attrset.begin(); @@ -2651,8 +2668,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, cout << iter->first << std::endl; } } else if (strcmp(nargs[0], "getomapheader") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); string outfile; @@ -2665,7 +2684,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error getting omap header " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } else { if (!outfile.empty()) { cerr << "Writing to " << outfile << std::endl; @@ -2678,8 +2697,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, ret = 0; } } else if (strcmp(nargs[0], "setomapheader") == 0) { - if (!pool_name || nargs.size() < 3) - usage_exit(); + if (!pool_name || nargs.size() < 3) { + usage(cerr); + return 1; + } string oid(nargs[1]); string val(nargs[2]); @@ -2691,14 +2712,15 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error setting omap value " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } else { ret = 0; } } else if (strcmp(nargs[0], "setomapval") == 0) { uint32_t min_args = (omap_key_valid ? 2 : 3); if (!pool_name || nargs.size() < min_args || nargs.size() > min_args + 1) { - usage_exit(); + usage(cerr); + return 1; } string oid(nargs[1]); @@ -2715,7 +2737,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, do { ret = bl.read_fd(STDIN_FILENO, 1024); // from stdin if (ret < 0) { - goto out; + return 1; } } while (ret > 0); } @@ -2727,14 +2749,15 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error setting omap value " << pool_name << "/" << oid << "/" << omap_key_pretty << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } else { ret = 0; } } else if (strcmp(nargs[0], "getomapval") == 0) { uint32_t min_args = (omap_key_valid ? 2 : 3); if (!pool_name || nargs.size() < min_args || nargs.size() > min_args + 1) { - usage_exit(); + usage(cerr); + return 1; } string oid(nargs[1]); @@ -2756,7 +2779,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error getting omap value " << pool_name << "/" << oid << "/" << omap_key_pretty << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } else { ret = 0; } @@ -2774,13 +2797,13 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, } else { cout << "No such key: " << pool_name << "/" << oid << "/" << omap_key_pretty << std::endl; - ret = -1; - goto out; + return 1; } } else if (strcmp(nargs[0], "rmomapkey") == 0) { uint32_t num_args = (omap_key_valid ? 2 : 3); if (!pool_name || nargs.size() != num_args) { - usage_exit(); + usage(cerr); + return 1; } string oid(nargs[1]); @@ -2795,13 +2818,14 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error removing omap key " << pool_name << "/" << oid << "/" << omap_key_pretty << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } else { ret = 0; } } else if (strcmp(nargs[0], "clearomap") == 0) { if (!pool_name || nargs.size() < 2) { - usage_exit(); + usage(cerr); + return 1; } for (unsigned i=1; i < nargs.size(); i++){ @@ -2810,13 +2834,15 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error clearing omap keys " << pool_name << "/" << oid << "/" << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } ret = 0; } else if (strcmp(nargs[0], "listomapvals") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); string last_read = ""; @@ -2852,11 +2878,15 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, ret = 0; } else if (strcmp(nargs[0], "cp") == 0) { - if (!pool_name) - usage_exit(); + if (!pool_name) { + usage(cerr); + return 1; + } - if (nargs.size() < 2 || nargs.size() > 3) - usage_exit(); + if (nargs.size() < 2 || nargs.size() > 3) { + usage(cerr); + return 1; + } const char *target = target_pool_name; if (!target) @@ -2866,8 +2896,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (nargs.size() < 3) { if (strcmp(target, pool_name) == 0) { cerr << "cannot copy object into itself" << std::endl; - ret = -1; - goto out; + return 1; } target_obj = nargs[1]; } else { @@ -2880,7 +2909,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error opening target pool " << target << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } if (target_oloc.size()) { target_ctx.locator_set_key(target_oloc); @@ -2892,11 +2921,13 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, ret = do_copy(io_ctx, nargs[1], target_ctx, target_obj); if (ret < 0) { cerr << "error copying " << pool_name << "/" << nargs[1] << " => " << target << "/" << target_obj << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "rm") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } vector::iterator iter = nargs.begin(); ++iter; for (; iter != nargs.end(); ++iter) { @@ -2912,31 +2943,34 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { string name = (nspace.size() ? nspace + "/" : "" ) + oid; cerr << "error removing " << pool_name << ">" << name << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } } else if (strcmp(nargs[0], "create") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); ret = io_ctx.create(oid, true); if (ret < 0) { cerr << "error creating " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "cppool") == 0) { bool force = nargs.size() == 4 && !strcmp(nargs[3], "--yes-i-really-mean-it"); - if (nargs.size() != 3 && !(nargs.size() == 4 && force)) - usage_exit(); + if (nargs.size() != 3 && !(nargs.size() == 4 && force)) { + usage(cerr); + return 1; + } const char *src_pool = nargs[1]; const char *target_pool = nargs[2]; if (strcmp(src_pool, target_pool) == 0) { cerr << "cannot copy pool into itself" << std::endl; - ret = -1; - goto out; + return 1; } cerr << "WARNING: pool copy does not preserve user_version, which some " @@ -2958,26 +2992,27 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error copying pool " << src_pool << " => " << target_pool << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } cout << "successfully copied pool " << nargs[1] << std::endl; } else if (strcmp(nargs[0], "purge") == 0) { - if (nargs.size() < 2) - usage_exit(); + if (nargs.size() < 2) { + usage(cerr); + return 1; + } if (nargs.size() < 3 || strcmp(nargs[2], "--yes-i-really-really-mean-it") != 0) { cerr << "WARNING:\n" << " This will PERMANENTLY DESTROY all objects from a pool with no way back.\n" << " To confirm, follow pool with --yes-i-really-really-mean-it" << std::endl; - ret = -1; - goto out; + return 1; } ret = rados.ioctx_create(nargs[1], io_ctx); if (ret < 0) { cerr << "error pool " << nargs[1] << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } io_ctx.set_namespace(all_nspaces); io_ctx.set_osdmap_full_try(); @@ -2992,8 +3027,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, } } else if (strcmp(nargs[0], "lssnap") == 0) { - if (!pool_name || nargs.size() != 1) - usage_exit(); + if (!pool_name || nargs.size() != 1) { + usage(cerr); + return 1; + } vector snaps; io_ctx.snap_list(&snaps); @@ -3027,53 +3064,60 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, } else if (strcmp(nargs[0], "mksnap") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } ret = io_ctx.snap_create(nargs[1]); if (ret < 0) { cerr << "error creating pool " << pool_name << " snapshot " << nargs[1] << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } cout << "created pool " << pool_name << " snap " << nargs[1] << std::endl; } else if (strcmp(nargs[0], "rmsnap") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } ret = io_ctx.snap_remove(nargs[1]); if (ret < 0) { cerr << "error removing pool " << pool_name << " snapshot " << nargs[1] << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } cout << "removed pool " << pool_name << " snap " << nargs[1] << std::endl; } else if (strcmp(nargs[0], "rollback") == 0) { - if (!pool_name || nargs.size() < 3) - usage_exit(); + if (!pool_name || nargs.size() < 3) { + usage(cerr); + return 1; + } ret = io_ctx.snap_rollback(nargs[1], nargs[2]); if (ret < 0) { cerr << "error rolling back pool " << pool_name << " to snapshot " << nargs[1] << cpp_strerror(ret) << std::endl; - goto out; + return 1; } cout << "rolled back pool " << pool_name << " to snapshot " << nargs[2] << std::endl; } else if (strcmp(nargs[0], "bench") == 0) { - if (!pool_name || nargs.size() < 3) - usage_exit(); + if (!pool_name || nargs.size() < 3) { + usage(cerr); + return 1; + } char* endptr = NULL; int seconds = strtol(nargs[1], &endptr, 10); if (*endptr) { cerr << "Invalid value for seconds: '" << nargs[1] << "'" << std::endl; - ret = -EINVAL; - goto out; + return 1; } int operation = 0; if (strcmp(nargs[2], "write") == 0) @@ -3082,21 +3126,21 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, operation = OP_SEQ_READ; else if (strcmp(nargs[2], "rand") == 0) operation = OP_RAND_READ; - else - usage_exit(); + else { + usage(cerr); + return 1; + } if (operation != OP_WRITE) { if (block_size_specified) { cerr << "-b|--block_size option can be used only with 'write' bench test" << std::endl; - ret = -EINVAL; - goto out; + return 1; } if (bench_write_dest != 0) { cerr << "--write-object, --write-omap and --write-xattr options can " "only be used with the 'write' bench test" << std::endl; - ret = -EINVAL; - goto out; + return 1; } } else if (bench_write_dest == 0) { @@ -3106,8 +3150,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (!formatter && output) { cerr << "-o|--output option can only be used with '--format' option" << std::endl; - ret = -EINVAL; - goto out; + return 1; } RadosBencher bencher(g_ceph_context, rados, io_ctx); bencher.set_show_time(show_time); @@ -3136,8 +3179,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, delete outstream; } else if (strcmp(nargs[0], "cleanup") == 0) { - if (!pool_name) - usage_exit(); + if (!pool_name) { + usage(cerr); + return 1; + } if (wildcard) io_ctx.set_namespace(all_nspaces); RadosBencher bencher(g_ceph_context, rados, io_ctx); @@ -3146,8 +3191,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, cerr << "error during cleanup: " << cpp_strerror(ret) << std::endl; } else if (strcmp(nargs[0], "watch") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); RadosWatchCtx ctx(io_ctx, oid.c_str()); uint64_t cookie; @@ -3162,8 +3209,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, } } else if (strcmp(nargs[0], "notify") == 0) { - if (!pool_name || nargs.size() < 3) - usage_exit(); + if (!pool_name || nargs.size() < 3) { + usage(cerr); + return 1; + } string oid(nargs[1]); string msg(nargs[2]); bufferlist bl, replybl; @@ -3193,30 +3242,35 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, } } } else if (strcmp(nargs[0], "set-alloc-hint") == 0) { - if (!pool_name || nargs.size() < 4) - usage_exit(); + if (!pool_name || nargs.size() < 4) { + usage(cerr); + return 1; + } string err; string oid(nargs[1]); uint64_t expected_object_size = strict_strtoll(nargs[2], 10, &err); if (!err.empty()) { cerr << "couldn't parse expected_object_size: " << err << std::endl; - usage_exit(); + usage(cerr); + return 1; } uint64_t expected_write_size = strict_strtoll(nargs[3], 10, &err); if (!err.empty()) { cerr << "couldn't parse expected_write_size: " << err << std::endl; - usage_exit(); + usage(cerr); + return 1; } ret = io_ctx.set_alloc_hint(oid, expected_object_size, expected_write_size); if (ret < 0) { cerr << "error setting alloc-hint " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "load-gen") == 0) { if (!pool_name) { cerr << "error: must specify pool" << std::endl; - usage_exit(); + usage(cerr); + return 1; } LoadGen lg(&rados); if (min_obj_len) @@ -3245,21 +3299,23 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, ret = lg.bootstrap(pool_name); if (ret < 0) { cerr << "load-gen bootstrap failed" << std::endl; - exit(1); + return 1; } cout << "load-gen will run " << lg.run_length << " seconds" << std::endl; lg.run(); lg.cleanup(); } else if (strcmp(nargs[0], "listomapkeys") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } set out_keys; ret = io_ctx.omap_get_keys(nargs[1], "", LONG_MAX, &out_keys); if (ret < 0) { cerr << "error getting omap key set " << pool_name << "/" << nargs[1] << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } for (set::iterator iter = out_keys.begin(); @@ -3267,16 +3323,20 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, cout << *iter << std::endl; } } else if (strcmp(nargs[0], "lock") == 0) { - if (!pool_name) - usage_exit(); + if (!pool_name) { + usage(cerr); + return 1; + } if (!formatter) { - formatter = new JSONFormatter(pretty_format); + formatter = std::make_unique(pretty_format); } - ret = do_lock_cmd(nargs, opts, &io_ctx, formatter); + ret = do_lock_cmd(nargs, opts, &io_ctx, formatter.get()); } else if (strcmp(nargs[0], "listwatchers") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); std::list lw; @@ -3284,7 +3344,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, ret = io_ctx.list_watchers(oid, &lw); if (ret < 0) { cerr << "error listing watchers " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } else ret = 0; @@ -3293,8 +3353,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, cout << "watcher=" << i->addr << " client." << i->watcher_id << " cookie=" << i->cookie << std::endl; } } else if (strcmp(nargs[0], "listsnaps") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); snap_set_t ls; @@ -3303,7 +3365,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, ret = io_ctx.list_snaps(oid, &ls); if (ret < 0) { cerr << "error listing snap shots " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } else ret = 0; @@ -3432,8 +3494,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, } ret = do_get_inconsistent_cmd(nargs, rados, *formatter); } else if (strcmp(nargs[0], "cache-flush") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); if (with_clones) { snap_set_t ls; @@ -3442,7 +3506,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error listing snapshots " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } for (std::vector::iterator ci = ls.clones.begin(); ci != ls.clones.end(); ++ci) { @@ -3453,7 +3517,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error from cache-flush " << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } } else { @@ -3461,12 +3525,14 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error from cache-flush " << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } } else if (strcmp(nargs[0], "cache-try-flush") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); if (with_clones) { snap_set_t ls; @@ -3475,7 +3541,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error listing snapshots " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } for (std::vector::iterator ci = ls.clones.begin(); ci != ls.clones.end(); ++ci) { @@ -3486,7 +3552,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error from cache-flush " << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } } else { @@ -3494,12 +3560,14 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error from cache-flush " << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } } else if (strcmp(nargs[0], "cache-evict") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); if (with_clones) { snap_set_t ls; @@ -3508,7 +3576,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error listing snapshots " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } for (std::vector::iterator ci = ls.clones.begin(); ci != ls.clones.end(); ++ci) { @@ -3519,7 +3587,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error from cache-flush " << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } } else { @@ -3527,28 +3595,34 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error from cache-flush " << oid << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } } else if (strcmp(nargs[0], "cache-flush-evict-all") == 0) { - if (!pool_name) - usage_exit(); + if (!pool_name) { + usage(cerr); + return 1; + } ret = do_cache_flush_evict_all(io_ctx, true); if (ret < 0) { cerr << "cache-flush-evict-all finished with errors" << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "cache-try-flush-evict-all") == 0) { - if (!pool_name) - usage_exit(); + if (!pool_name) { + usage(cerr); + return 1; + } ret = do_cache_flush_evict_all(io_ctx, false); if (ret < 0) { cerr << "cache-try-flush-evict-all finished with errors" << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "set-redirect") == 0) { - if (!pool_name) - usage_exit(); + if (!pool_name) { + usage(cerr); + return 1; + } const char *target = target_pool_name; if (!target) @@ -3558,8 +3632,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (nargs.size() < 3) { if (strcmp(target, pool_name) == 0) { cerr << "cannot copy object into itself" << std::endl; - ret = -1; - goto out; + return 1; } target_obj = nargs[1]; } else { @@ -3584,11 +3657,13 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, ret = io_ctx.operate(nargs[1], &op); if (ret < 0) { cerr << "error set-redirect " << pool_name << "/" << nargs[1] << " => " << target << "/" << target_obj << ": " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "set-chunk") == 0) { - if (!pool_name) - usage_exit(); + if (!pool_name) { + usage(cerr); + return 1; + } const char *target = target_pool_name; if (!target) @@ -3599,27 +3674,25 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, uint64_t tgt_offset; string tgt_oid; if (nargs.size() < 6) { - usage_exit(); + usage(cerr); + return 1; } else { char* endptr = NULL; offset = strtoull(nargs[2], &endptr, 10); if (*endptr) { cerr << "Invalid value for size: '" << nargs[2] << "'" << std::endl; - ret = -EINVAL; - goto out; + return 1; } length = strtoull(nargs[3], &endptr, 10); if (*endptr) { cerr << "Invalid value for size: '" << nargs[2] << "'" << std::endl; - ret = -EINVAL; - goto out; + return 1; } tgt_oid = string(nargs[4]); tgt_offset = strtoull(nargs[5], &endptr, 10); if (*endptr) { cerr << "Invalid value for size: '" << nargs[2] << "'" << std::endl; - ret = -EINVAL; - goto out; + return 1; } } @@ -3636,11 +3709,13 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, cerr << "error set-chunk " << pool_name << "/" << nargs[1] << " " << " offset " << offset << " length " << length << " target_pool " << target << "tgt_offset: " << tgt_offset << " : " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "tier-promote") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); ObjectWriteOperation op; @@ -3649,11 +3724,13 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error tier-promote " << pool_name << "/" << oid << " : " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "unset-manifest") == 0) { - if (!pool_name || nargs.size() < 2) - usage_exit(); + if (!pool_name || nargs.size() < 2) { + usage(cerr); + return 1; + } string oid(nargs[1]); ObjectWriteOperation op; @@ -3662,12 +3739,13 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error unset-manifest " << pool_name << "/" << oid << " : " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "export") == 0) { // export [filename] if (!pool_name || nargs.size() > 2) { - usage_exit(); + usage(cerr); + return 1; } int file_fd; @@ -3678,8 +3756,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (file_fd < 0) { cerr << "Error opening '" << nargs[1] << "': " << cpp_strerror(file_fd) << std::endl; - ret = file_fd; - goto out; + return 1; } } @@ -3692,12 +3769,13 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error from export: " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else if (strcmp(nargs[0], "import") == 0) { // import [--no-overwrite] [--dry-run] if (!pool_name || nargs.size() > 4 || nargs.size() < 2) { - usage_exit(); + usage(cerr); + return 1; } // Last arg is the filename @@ -3715,8 +3793,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, dry_run = true; } else { std::cerr << "Invalid argument '" << arg << "'" << std::endl; - ret = -EINVAL; - goto out; + return 1; } } @@ -3728,8 +3805,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (file_fd < 0) { cerr << "Error opening '" << filename << "': " << cpp_strerror(file_fd) << std::endl; - ret = file_fd; - goto out; + return 1; } } @@ -3742,12 +3818,11 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (ret < 0) { cerr << "error from import: " << cpp_strerror(ret) << std::endl; - goto out; + return 1; } } else { cerr << "unrecognized command " << nargs[0] << "; -h or --help for usage" << std::endl; ret = -EINVAL; - goto out; } if (ret < 0) -- 2.39.5