mirror of
https://github.com/ceph/ceph
synced 2025-01-20 10:01:45 +00:00
rbd: refactor do_import_diff to accept fd.
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
This commit is contained in:
parent
bc80b147ac
commit
58c8e8cd00
@ -20,10 +20,10 @@
|
||||
namespace rbd {
|
||||
namespace action {
|
||||
|
||||
int do_import_diff(librbd::Image &image, const char *path,
|
||||
bool no_progress)
|
||||
int do_import_diff_fd(librbd::Image &image, int fd,
|
||||
bool no_progress)
|
||||
{
|
||||
int fd, r;
|
||||
int r;
|
||||
struct stat stat_buf;
|
||||
utils::ProgressContext pc("Importing image diff", no_progress);
|
||||
uint64_t size = 0;
|
||||
@ -31,16 +31,8 @@ int do_import_diff(librbd::Image &image, const char *path,
|
||||
string from, to;
|
||||
char buf[utils::RBD_DIFF_BANNER.size() + 1];
|
||||
|
||||
bool from_stdin = !strcmp(path, "-");
|
||||
if (from_stdin) {
|
||||
fd = 0;
|
||||
} else {
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
r = -errno;
|
||||
std::cerr << "rbd: error opening " << path << std::endl;
|
||||
return r;
|
||||
}
|
||||
bool from_stdin = (fd == 0);
|
||||
if (!from_stdin) {
|
||||
r = ::fstat(fd, &stat_buf);
|
||||
if (r < 0)
|
||||
goto done;
|
||||
@ -53,7 +45,7 @@ int do_import_diff(librbd::Image &image, const char *path,
|
||||
buf[utils::RBD_DIFF_BANNER.size()] = '\0';
|
||||
if (strcmp(buf, utils::RBD_DIFF_BANNER.c_str())) {
|
||||
std::cerr << "invalid banner '" << buf << "', expected '"
|
||||
<< utils::RBD_DIFF_BANNER << "'" << std::endl;
|
||||
<< utils::RBD_DIFF_BANNER << "'" << std::endl;
|
||||
r = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
@ -70,43 +62,43 @@ int do_import_diff(librbd::Image &image, const char *path,
|
||||
} else if (tag == RBD_DIFF_FROM_SNAP) {
|
||||
r = utils::read_string(fd, 4096, &from); // 4k limit to make sure we don't get a garbage string
|
||||
if (r < 0)
|
||||
goto done;
|
||||
goto done;
|
||||
|
||||
bool exists;
|
||||
r = image.snap_exists2(from.c_str(), &exists);
|
||||
if (r < 0)
|
||||
goto done;
|
||||
goto done;
|
||||
|
||||
if (!exists) {
|
||||
std::cerr << "start snapshot '" << from
|
||||
<< "' does not exist in the image, aborting" << std::endl;
|
||||
r = -EINVAL;
|
||||
goto done;
|
||||
std::cerr << "start snapshot '" << from
|
||||
<< "' does not exist in the image, aborting" << std::endl;
|
||||
r = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else if (tag == RBD_DIFF_TO_SNAP) {
|
||||
r = utils::read_string(fd, 4096, &to); // 4k limit to make sure we don't get a garbage string
|
||||
if (r < 0)
|
||||
goto done;
|
||||
goto done;
|
||||
|
||||
// verify this snap isn't already present
|
||||
bool exists;
|
||||
r = image.snap_exists2(to.c_str(), &exists);
|
||||
if (r < 0)
|
||||
goto done;
|
||||
goto done;
|
||||
|
||||
if (exists) {
|
||||
std::cerr << "end snapshot '" << to
|
||||
<< "' already exists, aborting" << std::endl;
|
||||
r = -EEXIST;
|
||||
goto done;
|
||||
std::cerr << "end snapshot '" << to
|
||||
<< "' already exists, aborting" << std::endl;
|
||||
r = -EEXIST;
|
||||
goto done;
|
||||
}
|
||||
} else if (tag == RBD_DIFF_IMAGE_SIZE) {
|
||||
uint64_t end_size;
|
||||
char buf[8];
|
||||
r = safe_read_exact(fd, buf, 8);
|
||||
if (r < 0)
|
||||
goto done;
|
||||
goto done;
|
||||
bufferlist bl;
|
||||
bl.append(buf, 8);
|
||||
bufferlist::iterator p = bl.begin();
|
||||
@ -114,17 +106,16 @@ int do_import_diff(librbd::Image &image, const char *path,
|
||||
uint64_t cur_size;
|
||||
image.size(&cur_size);
|
||||
if (cur_size != end_size) {
|
||||
image.resize(end_size);
|
||||
} else {
|
||||
image.resize(end_size);
|
||||
}
|
||||
if (from_stdin)
|
||||
size = end_size;
|
||||
size = end_size;
|
||||
} else if (tag == RBD_DIFF_WRITE || tag == RBD_DIFF_ZERO) {
|
||||
uint64_t len;
|
||||
char buf[16];
|
||||
r = safe_read_exact(fd, buf, 16);
|
||||
if (r < 0)
|
||||
goto done;
|
||||
goto done;
|
||||
bufferlist bl;
|
||||
bl.append(buf, 16);
|
||||
bufferlist::iterator p = bl.begin();
|
||||
@ -132,19 +123,19 @@ int do_import_diff(librbd::Image &image, const char *path,
|
||||
::decode(len, p);
|
||||
|
||||
if (tag == RBD_DIFF_WRITE) {
|
||||
bufferptr bp = buffer::create(len);
|
||||
r = safe_read_exact(fd, bp.c_str(), len);
|
||||
if (r < 0)
|
||||
goto done;
|
||||
bufferlist data;
|
||||
data.append(bp);
|
||||
image.write2(off, len, data, LIBRADOS_OP_FLAG_FADVISE_NOCACHE);
|
||||
bufferptr bp = buffer::create(len);
|
||||
r = safe_read_exact(fd, bp.c_str(), len);
|
||||
if (r < 0)
|
||||
goto done;
|
||||
bufferlist data;
|
||||
data.append(bp);
|
||||
image.write2(off, len, data, LIBRADOS_OP_FLAG_FADVISE_NOCACHE);
|
||||
} else {
|
||||
image.discard(off, len);
|
||||
image.discard(off, len);
|
||||
}
|
||||
} else {
|
||||
std::cerr << "unrecognized tag byte " << (int)tag
|
||||
<< " in stream; aborting" << std::endl;
|
||||
<< " in stream; aborting" << std::endl;
|
||||
r = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
@ -163,12 +154,33 @@ int do_import_diff(librbd::Image &image, const char *path,
|
||||
r = image.snap_create(to.c_str());
|
||||
}
|
||||
|
||||
done:
|
||||
done:
|
||||
if (r < 0)
|
||||
pc.fail();
|
||||
else
|
||||
pc.finish();
|
||||
if (!from_stdin)
|
||||
return r;
|
||||
}
|
||||
|
||||
int do_import_diff(librbd::Image &image, const char *path,
|
||||
bool no_progress)
|
||||
{
|
||||
int r;
|
||||
int fd;
|
||||
|
||||
if (strcmp(path, "-") == 0) {
|
||||
fd = 0;
|
||||
} else {
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
r = -errno;
|
||||
std::cerr << "rbd: error opening " << path << std::endl;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
r = do_import_diff_fd(image, fd, no_progress);
|
||||
|
||||
if (fd != 0)
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user