if (ret == -EINVAL) {
// if shrinking an image, a pagecache writeback might reference
// extents outside of the range of the new image extents
- dout(5) << __func__ << ": masking IO out-of-bounds error" << dendl;
+ dout(0) << __func__ << ": masking IO out-of-bounds error" << dendl;
ctx->data.clear();
ret = 0;
}
unsigned long new_size = info.size;
if (new_size != size) {
+ dout(5) << "resize detected" << dendl;
if (ioctl(fd, BLKFLSBUF, NULL) < 0)
- derr << "invalidate page cache failed: " << cpp_strerror(errno) << dendl;
+ derr << "invalidate page cache failed: " << cpp_strerror(errno)
+ << dendl;
if (ioctl(fd, NBD_SET_SIZE, new_size) < 0) {
derr << "resize failed: " << cpp_strerror(errno) << dendl;
} else {
size = new_size;
}
+ if (ioctl(fd, BLKRRPART, NULL) < 0) {
+ derr << "rescan of partition table failed: " << cpp_strerror(errno)
+ << dendl;
+ }
if (image.invalidate_cache() < 0)
derr << "invalidate rbd cache failed" << dendl;
}
goto close_ret;
}
+ r = rados.init_with_context(g_ceph_context);
+ if (r < 0)
+ goto close_fd;
+
+ r = rados.connect();
+ if (r < 0)
+ goto close_fd;
+
+ r = rados.ioctx_create(cfg->poolname.c_str(), io_ctx);
+ if (r < 0)
+ goto close_fd;
+
+ r = rbd.open(io_ctx, image, cfg->imgname.c_str());
+ if (r < 0)
+ goto close_fd;
+
+ if (cfg->exclusive) {
+ r = image.lock_acquire(RBD_LOCK_MODE_EXCLUSIVE);
+ if (r < 0) {
+ cerr << "rbd-nbd: failed to acquire exclusive lock: " << cpp_strerror(r)
+ << std::endl;
+ goto close_fd;
+ }
+ }
+
+ if (!cfg->snapname.empty()) {
+ r = image.snap_set(cfg->snapname.c_str());
+ if (r < 0)
+ goto close_fd;
+ }
+
+ r = image.stat(info, sizeof(info));
+ if (r < 0)
+ goto close_fd;
+
if (cfg->devpath.empty()) {
char dev[64];
bool try_load_module = true;
+ const char *path = "/sys/module/nbd/parameters/nbds_max";
+ int nbds_max = -1;
+ if (access(path, F_OK) == 0) {
+ std::ifstream ifs;
+ ifs.open(path, std::ifstream::in);
+ if (ifs.is_open()) {
+ ifs >> nbds_max;
+ ifs.close();
+ }
+ }
+
while (true) {
snprintf(dev, sizeof(dev), "/dev/nbd%d", index);
nbd = open_device(dev, cfg, try_load_module);
try_load_module = false;
if (nbd < 0) {
+ if (nbd == -EPERM && nbds_max != -1 && index < (nbds_max-1)) {
+ ++index;
+ continue;
+ }
r = nbd;
cerr << "rbd-nbd: failed to find unused device" << std::endl;
goto close_fd;
read_only = 1;
}
- r = rados.init_with_context(g_ceph_context);
- if (r < 0)
- goto close_nbd;
-
- r = rados.connect();
- if (r < 0)
- goto close_nbd;
-
- r = rados.ioctx_create(cfg->poolname.c_str(), io_ctx);
- if (r < 0)
- goto close_nbd;
-
- r = rbd.open(io_ctx, image, cfg->imgname.c_str());
- if (r < 0)
- goto close_nbd;
-
- if (cfg->exclusive) {
- r = image.lock_acquire(RBD_LOCK_MODE_EXCLUSIVE);
- if (r < 0) {
- cerr << "rbd-nbd: failed to acquire exclusive lock: " << cpp_strerror(r)
- << std::endl;
- goto close_nbd;
- }
- }
-
- if (!cfg->snapname.empty()) {
- r = image.snap_set(cfg->snapname.c_str());
- if (r < 0)
- goto close_nbd;
- }
-
- r = image.stat(info, sizeof(info));
- if (r < 0)
- goto close_nbd;
-
r = ioctl(nbd, NBD_SET_BLKSIZE, RBD_NBD_BLKSIZE);
if (r < 0) {
r = -errno;
std::vector<const char*> args;
ifs.open(path.c_str(), std::ifstream::in);
- assert (ifs.is_open());
+ if (!ifs.is_open())
+ return -1;
ifs >> cmdline;
for (unsigned i = 0; i < cmdline.size(); i++) {
static int parse_args(vector<const char*>& args, std::ostream *err_msg, Config *cfg)
{
- std::vector<const char*>::iterator i;
- std::ostringstream err;
+ std::string conf_file_list;
+ std::string cluster;
+ CephInitParameters iparams = ceph_argparse_early_args(
+ args, CEPH_ENTITY_TYPE_CLIENT, &cluster, &conf_file_list);
md_config_t config;
- config.parse_config_files(nullptr, nullptr, 0);
+ config.name = iparams.name;
+ config.cluster = cluster;
+
+ if (!conf_file_list.empty()) {
+ config.parse_config_files(conf_file_list.c_str(), nullptr, 0);
+ } else {
+ config.parse_config_files(nullptr, nullptr, 0);
+ }
config.parse_env();
config.parse_argv(args);
- cfg->poolname = config.rbd_default_pool;
+ cfg->poolname = config.get_val<std::string>("rbd_default_pool");
+
+ std::vector<const char*>::iterator i;
+ std::ostringstream err;
for (i = args.begin(); i != args.end(); ) {
if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {