From f7fbb62a87d05f76141cd03cac65b1f33057760f Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Mon, 11 Dec 2017 19:29:00 +0200 Subject: [PATCH] rbd-nbd: support optionally setting device timeout Fixes: http://tracker.ceph.com/issues/22333 Signed-off-by: Mykola Golub (cherry picked from commit bad51ffe7fbfe8c2e33eb0db2ef7acb89a03bd1d) --- src/test/cli/rbd/help.t | 2 ++ src/tools/rbd/action/Nbd.cc | 7 ++++++- src/tools/rbd_nbd/rbd-nbd.cc | 22 ++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t index f9a7a6f84a660..ee63e52a44d64 100644 --- a/src/test/cli/rbd/help.t +++ b/src/test/cli/rbd/help.t @@ -1032,6 +1032,7 @@ Skip test on FreeBSD as it generates different output there. usage: rbd nbd map [--pool ] [--image ] [--snap ] [--read-only] [--exclusive] [--device ] [--nbds_max ] [--max_part ] + [--timeout ] Map image to a nbd device. @@ -1049,6 +1050,7 @@ Skip test on FreeBSD as it generates different output there. --device arg specify nbd device --nbds_max arg override module param nbds_max --max_part arg override module param max_part + --timeout arg set nbd request timeout (seconds) rbd help nbd unmap usage: rbd nbd unmap [--pool ] [--image ] [--snap ] diff --git a/src/tools/rbd/action/Nbd.cc b/src/tools/rbd/action/Nbd.cc index 266d368fb7f7a..43f547704e5fe 100644 --- a/src/tools/rbd/action/Nbd.cc +++ b/src/tools/rbd/action/Nbd.cc @@ -127,7 +127,8 @@ void get_map_arguments(po::options_description *positional, ("exclusive", po::bool_switch(), "forbid writes by other clients") ("device", po::value(), "specify nbd device") ("nbds_max", po::value(), "override module param nbds_max") - ("max_part", po::value(), "override module param max_part"); + ("max_part", po::value(), "override module param max_part") + ("timeout", po::value(), "set nbd request timeout (seconds)"); } int execute_map(const po::variables_map &vm) @@ -160,6 +161,10 @@ int execute_map(const po::variables_map &vm) args.push_back("--max_part"); args.push_back(vm["max_part"].as().c_str()); } + if (vm.count("timeout")) { + args.push_back("--timeout"); + args.push_back(vm["timeout"].as().c_str()); + } return call_nbd_cmd(vm, args); } diff --git a/src/tools/rbd_nbd/rbd-nbd.cc b/src/tools/rbd_nbd/rbd-nbd.cc index faca9a564a5a1..e59f95435a542 100644 --- a/src/tools/rbd_nbd/rbd-nbd.cc +++ b/src/tools/rbd_nbd/rbd-nbd.cc @@ -64,6 +64,7 @@ struct Config { int nbds_max = 0; int max_part = 255; + int timeout = -1; bool exclusive = false; bool readonly = false; @@ -86,6 +87,7 @@ static void usage() << " --nbds_max Override for module param nbds_max\n" << " --max_part Override for module param max_part\n" << " --exclusive Forbid writes by other clients\n" + << " --timeout Set nbd request timeout\n" << std::endl; generic_server_usage(); } @@ -826,6 +828,16 @@ static int do_map(int argc, const char *argv[], Config *cfg) goto close_nbd; } + if (cfg->timeout >= 0) { + r = ioctl(nbd, NBD_SET_TIMEOUT, (unsigned long)cfg->timeout); + if (r < 0) { + r = -errno; + cerr << "rbd-nbd: failed to set timeout: " << cpp_strerror(r) + << std::endl; + goto close_nbd; + } + } + { uint64_t handle; @@ -1021,6 +1033,16 @@ static int parse_args(vector& args, std::ostream *err_msg, cfg->readonly = true; } else if (ceph_argparse_flag(args, i, "--exclusive", (char *)NULL)) { cfg->exclusive = true; + } else if (ceph_argparse_witharg(args, i, &cfg->timeout, err, "--timeout", + (char *)NULL)) { + if (!err.str().empty()) { + *err_msg << "rbd-nbd: " << err.str(); + return -EINVAL; + } + if (cfg->timeout < 0) { + *err_msg << "rbd-nbd: Invalid argument for timeout!"; + return -EINVAL; + } } else { ++i; } -- 2.39.5