summaryrefslogtreecommitdiffstats
path: root/src/tools/rbd/action/ObjectMap.cc
blob: 40ee2d472f2c4647e60ca94ad0fab5710d453ee8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab

#include "tools/rbd/ArgumentTypes.h"
#include "tools/rbd/Shell.h"
#include "tools/rbd/Utils.h"
#include "common/errno.h"
#include <iostream>
#include <boost/program_options.hpp>

namespace rbd {
namespace action {
namespace object_map {

namespace at = argument_types;
namespace po = boost::program_options;

static int do_object_map_rebuild(librbd::Image &image, bool no_progress)
{
  utils::ProgressContext pc("Object Map Rebuild", no_progress);
  int r = image.rebuild_object_map(pc);
  if (r < 0) {
    pc.fail();
    return r;
  }
  pc.finish();
  return 0;
}

void get_rebuild_arguments(po::options_description *positional,
			   po::options_description *options) {
  at::add_image_or_snap_spec_options(positional, options,
                                     at::ARGUMENT_MODIFIER_NONE);
  at::add_no_progress_option(options);
}

int execute_rebuild(const po::variables_map &vm,
                    const std::vector<std::string> &ceph_global_init_args) {
  size_t arg_index = 0;
  std::string pool_name;
  std::string namespace_name;
  std::string image_name;
  std::string snap_name;
  int r = utils::get_pool_image_snapshot_names(
    vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name,
    &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED,
    utils::SPEC_VALIDATION_NONE);
  if (r < 0) {
    return r;
  }

  librados::Rados rados;
  librados::IoCtx io_ctx;
  librbd::Image image;
  r = utils::init_and_open_image(pool_name, namespace_name, image_name, "",
                                 snap_name, false, &rados, &io_ctx, &image);
  if (r < 0) {
    return r;
  }

  r = do_object_map_rebuild(image, vm[at::NO_PROGRESS].as<bool>());
  if (r < 0) {
    std::cerr << "rbd: rebuilding object map failed: " << cpp_strerror(r)
              << std::endl;
    return r;
  }
  return 0;
}

static int do_object_map_check(librbd::Image &image, bool no_progress)
{
  utils::ProgressContext pc("Object Map Check", no_progress);
  int r = image.check_object_map(pc);
  if (r < 0) {
    pc.fail();
    return r;
  }
  pc.finish();
  return 0;
}

void get_check_arguments(po::options_description *positional,
		   po::options_description *options) {
  at::add_image_or_snap_spec_options(positional, options,
				     at::ARGUMENT_MODIFIER_NONE);
  at::add_no_progress_option(options);
}

int execute_check(const po::variables_map &vm,
                  const std::vector<std::string> &ceph_global_init_args) {
  size_t arg_index = 0;
  std::string pool_name;
  std::string namespace_name;
  std::string image_name;
  std::string snap_name;
  int r = utils::get_pool_image_snapshot_names(
    vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name,
    &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED,
    utils::SPEC_VALIDATION_NONE);
  if (r < 0) {
    return r;
  }

  librados::Rados rados;
  librados::IoCtx io_ctx;
  librbd::Image image;
  r = utils::init_and_open_image(pool_name, namespace_name, image_name, "",
                                 snap_name, false, &rados, &io_ctx, &image);
  if (r < 0) {
    return r;
  }

  r = do_object_map_check(image, vm[at::NO_PROGRESS].as<bool>());
  if (r < 0) {
    std::cerr << "rbd: checking object map failed: " << cpp_strerror(r)
	      << std::endl;
    return r;
  }
  return 0;
}

Shell::Action action_rebuild(
  {"object-map", "rebuild"}, {}, "Rebuild an invalid object map.", "",
  &get_rebuild_arguments, &execute_rebuild);
Shell::Action action_check(
  {"object-map", "check"}, {}, "Verify the object map is correct.", "",
  &get_check_arguments, &execute_check);

} // namespace object_map
} // namespace action
} // namespace rbd