Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nbd: unmap wait process exit #228

Merged
merged 1 commit into from
Jan 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions nbd/src/NBDTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,27 @@ int NBDTool::Connect(NBDConfig *cfg) {
return 0;
}

int NBDTool::Disconnect(const std::string& devpath) {
int NBDTool::Disconnect(const NBDConfig* config) {
pid_t devpid = -1;
std::vector<DeviceInfo> devices;

int ret = List(&devices);
for (const auto& device : devices) {
if (device.config.devpath == config->devpath) {
devpid = device.pid;
break;
}
}

NBDControllerPtr nbdCtrl = GetController(false);
return nbdCtrl->DisconnectByPath(devpath);
ret = nbdCtrl->DisconnectByPath(config->devpath);
if (ret != 0) {
return ret;
}

ret = WaitForTerminate(devpid, config);

return 0;
}

int NBDTool::List(std::vector<DeviceInfo>* infos) {
Expand All @@ -137,6 +155,8 @@ void NBDTool::RunServerUntilQuit() {
} else {
ctrl->RunUntilQuit();
}

nbdWatchCtx_->StopWatch();
}

ImagePtr g_test_image = nullptr;
Expand All @@ -150,5 +170,29 @@ ImagePtr NBDTool::GenerateImage(const std::string& imageName) {
return result;
}

int NBDTool::WaitForTerminate(pid_t pid, const NBDConfig* config) {
if (pid < 0) {
return 0;
}

int times = config->retry_times;
while (times-- > 0) {
if (kill(pid, 0) == -1) {
if (errno == ESRCH) {
return 0;
}
std::cerr << "curve-nbd test device failed, dev: "
<< config->devpath << ", err = " << cpp_strerror(-errno)
<< std::endl;
return -errno;
}

std::this_thread::sleep_for(
std::chrono::milliseconds(config->sleep_ms));
}

return -ETIMEDOUT;
}

} // namespace nbd
} // namespace curve
7 changes: 5 additions & 2 deletions nbd/src/NBDTool.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ class NBDTool {

// 与nbd内核建立通信,将文件映射到本地
int Connect(NBDConfig *cfg);
// 根据设备路径卸载已经映射的文件
int Disconnect(const std::string& devpath);
// 根据配置卸载已经映射的文件
int Disconnect(const NBDConfig* config);
// 获取已经映射文件的映射信息,包括进程pid、文件名、设备路径
int List(std::vector<DeviceInfo>* infos);
// 阻塞直到nbd server退出
Expand All @@ -68,6 +68,9 @@ class NBDTool {
// 生成image instance
ImagePtr GenerateImage(const std::string& imageName);

// wait curve-nbd process to exit
int WaitForTerminate(pid_t pid, const NBDConfig* config);

private:
class NBDSocketPair {
public:
Expand Down
4 changes: 4 additions & 0 deletions nbd/src/define.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ struct NBDConfig {
std::string imgname;
// 指定需要映射的nbd设备路径
std::string devpath;
// unmap等待进程退出的重试次数
int retry_times = 25;
// unmap重试之间的睡眠间隔
int sleep_ms = 200;
};

// 用户命令类型
Expand Down
18 changes: 10 additions & 8 deletions nbd/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static void HandleSignal(int signum) {
std::cout << "Got signal " << sys_siglist[signum] << "\n"
<< ", disconnect now" << std::endl;

ret = nbdTool->Disconnect(nbdConfig->devpath);
ret = nbdTool->Disconnect(nbdConfig.get());
if (ret != 0) {
std::cout << "curve-nbd: disconnect failed. Error: " << ret
<< std::endl;
Expand All @@ -77,19 +77,21 @@ static void HandleSignal(int signum) {

static void Usage() {
std::cout
<< "Usage: curve-nbd [options] map <image> Map an image "
"to nbd device\n" // NOLINT
<< " unmap <device|image> Unmap nbd "
"device\n" // NOLINT
<< " [options] list-mapped List mapped "
"nbd devices\n" // NOLINT
<< "Usage: curve-nbd [options] map <image> Map an image to nbd device\n" // NOLINT
<< " [options] unmap <device|image> Unmap nbd device\n" // NOLINT
<< " [options] list-mapped List mapped nbd devices\n" // NOLINT
<< "Map options:\n"
<< " --device <device path> Specify nbd device path (/dev/nbd{num})\n"
<< " --read-only Map read-only\n"
<< " --nbds_max <limit> Override for module param nbds_max\n"
<< " --max_part <limit> Override for module param max_part\n"
<< " --timeout <seconds> Set nbd request timeout\n"
<< " --try-netlink Use the nbd netlink interface\n"
<< "Unmap options:\n"
<< " --retry_times <limit> The number of retries waiting for the process to exit\n" // NOLINT
<< " (default: " << nbdConfig->retry_times << ")\n" // NOLINT
<< " --sleep_ms <milliseconds> Retry interval in milliseconds\n" // NOLINT
<< " (default: " << nbdConfig->sleep_ms << ")\n" // NOLINT
<< std::endl;
}

Expand Down Expand Up @@ -185,7 +187,7 @@ static int CurveNbdMain(int argc, const char* argv[]) {
break;
}
case Command::Disconnect: {
r = nbdTool->Disconnect(nbdConfig->devpath);
r = nbdTool->Disconnect(nbdConfig.get());
if (r < 0) {
return -EINVAL;
}
Expand Down
18 changes: 18 additions & 0 deletions nbd/src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,24 @@ int parse_args(std::vector<const char*>& args, std::ostream *err_msg, // NOLIN
}
} else if (argparse_flag(args, i, "--try-netlink", (char *)NULL)) { // NOLINT
cfg->try_netlink = true;
} else if (argparse_witharg(args, i, &cfg->retry_times, err, "--retry_times", (char*)(NULL))) { // NOLINT
if (!err.str().empty()) {
*err_msg << "curve-nbd: " << err.str();
return -EINVAL;
}
if (cfg->retry_times < 0) {
*err_msg << "curve-nbd: Invalid argument for retry_times!";
return -EINVAL;
}
} else if (argparse_witharg(args, i, &cfg->sleep_ms, err, "--sleep_ms", (char*)(NULL))) { // NOLINT
if (!err.str().empty()) {
*err_msg << "curve-nbd: " << err.str();
return -EINVAL;
}
if (cfg->sleep_ms < 0) {
*err_msg << "curve-nbd: Invalid argument for sleep_ms!";
return -EINVAL;
}
} else {
++i;
}
Expand Down
8 changes: 4 additions & 4 deletions nbd/test/nbd_tool_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ TEST_F(NBDToolTest, ioctl_connect_test) {
StartInAnotherThread(&config);
ASSERT_TRUE(isRunning_);
AssertWriteSuccess(config.devpath);
ASSERT_EQ(0, tool_.Disconnect(config.devpath));
ASSERT_EQ(0, tool_.Disconnect(&config));
sleep(1);
ASSERT_FALSE(isRunning_);
}
Expand All @@ -158,7 +158,7 @@ TEST_F(NBDToolTest, netlink_connect_test) {
config.try_netlink = true;
StartInAnotherThread(&config);
ASSERT_TRUE(isRunning_);
ASSERT_EQ(0, tool_.Disconnect(config.devpath));
ASSERT_EQ(0, tool_.Disconnect(&config));
sleep(1);
ASSERT_FALSE(isRunning_);
}
Expand All @@ -170,7 +170,7 @@ TEST_F(NBDToolTest, readonly_test) {
StartInAnotherThread(&config);
ASSERT_TRUE(isRunning_);
AssertWriteFailed(config.devpath);
ASSERT_EQ(0, tool_.Disconnect(config.devpath));
ASSERT_EQ(0, tool_.Disconnect(&config));
sleep(1);
ASSERT_FALSE(isRunning_);
}
Expand All @@ -183,7 +183,7 @@ TEST_F(NBDToolTest, timeout_test) {
ASSERT_TRUE(isRunning_);
AssertWriteTimeout(config.devpath, 5);
// io timeout 情况下,nbd_do_it这边会退出,所以这里disconnect会失败
ASSERT_EQ(-1, tool_.Disconnect(config.devpath));
ASSERT_EQ(-1, tool_.Disconnect(&config));
}

} // namespace nbd
Expand Down
1 change: 1 addition & 0 deletions robot/Resources/keywords/test_curve_stability_nbd.py
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,7 @@ def test_snapshot_all(vol_uuid):
test_clone_iovol_consistency(lazy)
# test_clone_vol_same_uuid(lazy)
test_recover_snapshot(lazy)
config.snapshot_thrash.nbd_unmap()
config.snapshot_thrash.nbd_delete()
return "finally"

Expand Down