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: prevent mounted device to unmap #453

Merged
merged 1 commit into from
Jul 21, 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
8 changes: 7 additions & 1 deletion nbd/src/NBDTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <memory>
#include <string>
#include "nbd/src/NBDTool.h"
#include "nbd/src/util.h"
#include "nbd/src/argparse.h"
#include "nbd/src/texttable.h"

Expand Down Expand Up @@ -115,7 +116,12 @@ int NBDTool::Disconnect(const NBDConfig* config) {
pid_t devpid = -1;
std::vector<DeviceInfo> devices;

int ret = List(&devices);
auto ret = check_dev_can_unmap(config);
if (0 != ret) {
return ret;
}

ret = List(&devices);
for (const auto& device : devices) {
if (device.config.devpath == config->devpath) {
devpid = device.pid;
Expand Down
2 changes: 2 additions & 0 deletions nbd/src/define.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ struct NBDConfig {
std::string imgname;
// 指定需要映射的nbd设备路径
std::string devpath;
// force unmap even if the device is mounted
bool force_unmap = false;
// unmap等待进程退出的重试次数
int retry_times = 25;
// unmap重试之间的睡眠间隔
Expand Down
1 change: 1 addition & 0 deletions nbd/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ static void Usage() {
<< " --block-size NBD Devices's block size, default is 4096, support 512 and 4096\n" // NOLINT
<< " --nebd-conf LibNebd config file\n"
<< "Unmap options:\n"
<< " -f, --force Force unmap even if the device is mounted\n" // NOLINT
<< " --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
Expand Down
34 changes: 34 additions & 0 deletions nbd/src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ 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_flag(args, i, "-f", "--force", (char *)NULL)) { // NOLINT
cfg->force_unmap = 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();
Expand Down Expand Up @@ -342,6 +344,38 @@ int get_mapped_info(int pid, NBDConfig *cfg) {
return 0;
}

int check_dev_can_unmap(const NBDConfig *cfg) {
std::ifstream ifs("/proc/mounts", std::ifstream::in);

if (!ifs.is_open()) {
dout << "curve-nbd: failed to open /proc/mounts" << std::endl;
return -EINVAL;
}

std::string line, device, mountPath;
bool mounted = false;
while (std::getline(ifs, line)) {
std::istringstream iss(line);
iss >> device >> mountPath;
if (device == cfg->devpath) {
mounted = true;
break;
}
}

if (!mounted) {
return 0;
} else if (cfg->force_unmap) {
dout << "curve-nbd: the " << device << " is still mount on "
<< mountPath << ", force unmap it" << std::endl;
return 0;
}

dout << "curve-nbd: the " << device << " is still mount on " << mountPath
<< ", you can't unmap it or specify -f parameter" << std::endl;
return -EINVAL;
}

int check_size_from_file(const std::string& path, uint64_t expected_size) {
std::ifstream ifs;
ifs.open(path.c_str(), std::ifstream::in);
Expand Down
2 changes: 2 additions & 0 deletions nbd/src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ extern int check_block_size(int nbd_index, uint64_t expected_size);
extern int check_device_size(int nbd_index, uint64_t expected_size);
// 如果当前系统还未加载nbd模块,则进行加载;如果已经加载,则不作任何操作
extern int load_module(NBDConfig *cfg);
// Check whether the device can be unmap
int check_dev_can_unmap(const NBDConfig *cfg);

// 安全读写文件或socket,对异常情况进行处理后返回
ssize_t safe_read_exact(int fd, void* buf, size_t count);
Expand Down