Skip to content

Commit b4fbabd

Browse files
rbd: add --estimated-size option for import from stdin
One issue with importing from stdin is that it's not easy to track progress. The only feasible option is to process messages on the highest log level looking for lines like librbd::io::ImageRequestWQ: 0x56342ecc7a50 aio_write: ... off=1187840, len=864256 ... but when it comes to large images it takes a lot of effort. This commit introduces --estimated-size option, that makes it possible to print out progress in percents via the standard mechanism. Obviously, it requires the knowledge of the amount of provided data in advance and in case of an error nonsensical percents might be printed, but I don't think it's that big of a deal. Also use `estimated size` as the base image size, making resizing not necessary in cases where we know the exact amount of data provided from stdin. Co-authored-by: Ilya Dryomov <[email protected]> Signed-off-by: Kirill Nazarov <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 82aafe4 commit b4fbabd

File tree

5 files changed

+44
-7
lines changed

5 files changed

+44
-7
lines changed

doc/man/8/rbd.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ Commands
392392
:command:`image-meta set` *image-spec* *key* *value*
393393
Set metadata key with the value. They will displayed in `image-meta list`.
394394

395-
:command:`import` [--export-format *format (1 or 2)*] [--image-format *format-id*] [--object-size *size-in-B/K/M*] [--stripe-unit *size-in-B/K/M* --stripe-count *num*] [--image-feature *feature-name*]... [--image-shared] *src-path* [*image-spec*]
395+
:command:`import` [--export-format *format (1 or 2)*] [--image-format *format-id*] [--object-size *size-in-B/K/M*] [--stripe-unit *size-in-B/K/M* --stripe-count *num*] [--image-feature *feature-name*] [--estimated-size *size-in-M/G/T*]... [--image-shared] *src-path* [*image-spec*]
396396
Create a new image and import its data from path (use - for
397397
stdin). The import operation will try to create sparse rbd images
398398
if possible. For import from stdin, the sparsification unit is

src/test/cli/rbd/help.t

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1258,7 +1258,8 @@
12581258
[--journal-object-size <journal-object-size>]
12591259
[--journal-pool <journal-pool>]
12601260
[--sparse-size <sparse-size>] [--no-progress]
1261-
[--export-format <export-format>] [--pool <pool>]
1261+
[--export-format <export-format>]
1262+
[--estimated-size <estimated-size>] [--pool <pool>]
12621263
[--image <image>]
12631264
<path-name> <dest-image-spec>
12641265

@@ -1290,6 +1291,8 @@
12901291
--sparse-size arg sparse size in B/K/M [default: 4K]
12911292
--no-progress disable progress output
12921293
--export-format arg format of image file
1294+
--estimated-size arg estimated image size (valid only for raw import
1295+
from stdin, in M/G/T) [default: M]
12931296
12941297
Image Features:
12951298
(*) supports enabling/disabling on existing images

src/tools/rbd/ArgumentTypes.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,12 @@ void add_size_option(boost::program_options::options_description *opt) {
279279
"image size (in M/G/T) [default: M]");
280280
}
281281

282+
void add_estimated_size_option(boost::program_options::options_description *opt) {
283+
opt->add_options()
284+
(IMAGE_ESTIMATED_SIZE.c_str(), po::value<ImageSize>(),
285+
"estimated image size (valid only for raw import from stdin, in M/G/T) [default: M]");
286+
}
287+
282288
void add_sparse_size_option(boost::program_options::options_description *opt) {
283289
opt->add_options()
284290
(IMAGE_SPARSE_SIZE.c_str(), po::value<ImageObjectSize>(),

src/tools/rbd/ArgumentTypes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static const std::string IMAGE_OBJECT_SIZE("object-size");
6767
static const std::string IMAGE_FEATURES("image-feature");
6868
static const std::string IMAGE_SHARED("image-shared");
6969
static const std::string IMAGE_SIZE("size");
70+
static const std::string IMAGE_ESTIMATED_SIZE("estimated-size");
7071
static const std::string IMAGE_STRIPE_UNIT("stripe-unit");
7172
static const std::string IMAGE_STRIPE_COUNT("stripe-count");
7273
static const std::string IMAGE_DATA_POOL("data-pool");
@@ -186,6 +187,8 @@ void add_create_journal_options(
186187

187188
void add_size_option(boost::program_options::options_description *opt);
188189

190+
void add_estimated_size_option(boost::program_options::options_description *opt);
191+
189192
void add_sparse_size_option(boost::program_options::options_description *opt);
190193

191194
void add_path_options(boost::program_options::options_description *pos,

src/tools/rbd/action/Import.cc

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ static int do_import_v2(librados::Rados &rados, int fd, librbd::Image &image,
725725

726726
static int do_import_v1(int fd, librbd::Image &image, uint64_t size,
727727
size_t imgblklen, utils::ProgressContext &pc,
728-
size_t sparse_size)
728+
size_t sparse_size, size_t estimated_size)
729729
{
730730
int r = 0;
731731
size_t reqlen = imgblklen; // amount requested from read
@@ -758,6 +758,8 @@ static int do_import_v1(int fd, librbd::Image &image, uint64_t size,
758758
}
759759
if (!from_stdin)
760760
pc.update_progress(image_pos, size);
761+
else if (estimated_size != 0)
762+
pc.update_progress(image_pos, estimated_size);
761763

762764
bufferptr blkptr(p, blklen);
763765
// resize output image by binary expansion as we go for stdin
@@ -823,7 +825,8 @@ static int do_import_v1(int fd, librbd::Image &image, uint64_t size,
823825
static int do_import(librados::Rados &rados, librbd::RBD &rbd,
824826
librados::IoCtx& io_ctx, const char *imgname,
825827
const char *path, librbd::ImageOptions& opts,
826-
bool no_progress, int import_format, size_t sparse_size)
828+
bool no_progress, int import_format, size_t sparse_size,
829+
size_t estimated_size)
827830
{
828831
int fd, r;
829832
struct stat stat_buf;
@@ -845,7 +848,11 @@ static int do_import(librados::Rados &rados, librbd::RBD &rbd,
845848
bool from_stdin = !strcmp(path, "-");
846849
if (from_stdin) {
847850
fd = STDIN_FILENO;
848-
size = 1ULL << order;
851+
if (estimated_size == 0) {
852+
size = 1ULL << order;
853+
} else {
854+
size = estimated_size;
855+
}
849856
} else {
850857
if ((fd = open(path, O_RDONLY|O_BINARY)) < 0) {
851858
r = -errno;
@@ -908,7 +915,8 @@ static int do_import(librados::Rados &rados, librbd::RBD &rbd,
908915
}
909916

910917
if (import_format == 1) {
911-
r = do_import_v1(fd, image, size, imgblklen, pc, sparse_size);
918+
r = do_import_v1(fd, image, size, imgblklen, pc, sparse_size,
919+
estimated_size);
912920
} else {
913921
r = do_import_v2(rados, fd, image, size, imgblklen, pc, sparse_size);
914922
}
@@ -942,6 +950,7 @@ void get_arguments(po::options_description *positional,
942950
at::add_sparse_size_option(options);
943951
at::add_no_progress_option(options);
944952
at::add_export_format_option(options);
953+
at::add_estimated_size_option(options);
945954

946955
// TODO legacy rbd allowed import to accept both 'image'/'dest' and
947956
// 'pool'/'dest-pool'
@@ -1017,9 +1026,25 @@ int execute(const po::variables_map &vm,
10171026
if (vm.count("export-format"))
10181027
format = vm["export-format"].as<uint64_t>();
10191028

1029+
size_t estimated_size = 0;
1030+
if (vm.count(at::IMAGE_ESTIMATED_SIZE)) {
1031+
if (path != "-") {
1032+
std::cerr << "rbd: --estimated-size can be specified "
1033+
<< "only for import from stdin" << std::endl;
1034+
return -EINVAL;
1035+
}
1036+
if (format != 1) {
1037+
std::cerr << "rbd: --estimated-size can be specified "
1038+
<< "only for raw import (--export-format 1)" << std::endl;
1039+
return -EINVAL;
1040+
}
1041+
estimated_size = vm[at::IMAGE_ESTIMATED_SIZE].as<size_t>();
1042+
}
1043+
10201044
librbd::RBD rbd;
10211045
r = do_import(rados, rbd, io_ctx, image_name.c_str(), path.c_str(),
1022-
opts, vm[at::NO_PROGRESS].as<bool>(), format, sparse_size);
1046+
opts, vm[at::NO_PROGRESS].as<bool>(), format, sparse_size,
1047+
estimated_size);
10231048
if (r < 0) {
10241049
std::cerr << "rbd: import failed: " << cpp_strerror(r) << std::endl;
10251050
return r;

0 commit comments

Comments
 (0)