]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/cephfs_mirror/Utils.cc
import ceph pacific 16.2.5
[ceph.git] / ceph / src / tools / cephfs_mirror / Utils.cc
CommitLineData
f67539c2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "common/ceph_argparse.h"
5#include "common/ceph_context.h"
6#include "common/common_init.h"
7#include "common/debug.h"
8#include "common/errno.h"
9
10#include "Utils.h"
11
12#define dout_context g_ceph_context
13#define dout_subsys ceph_subsys_cephfs_mirror
14#undef dout_prefix
15#define dout_prefix *_dout << "cephfs::mirror::Utils " << __func__
16
17namespace cephfs {
18namespace mirror {
19
20int connect(std::string_view client_name, std::string_view cluster_name,
b3b6e05e
TL
21 RadosRef *cluster, std::string_view mon_host, std::string_view cephx_key,
22 std::vector<const char *> args) {
f67539c2
TL
23 dout(20) << ": connecting to cluster=" << cluster_name << ", client=" << client_name
24 << ", mon_host=" << mon_host << dendl;
25
26 CephInitParameters iparams(CEPH_ENTITY_TYPE_CLIENT);
27 if (client_name.empty() || !iparams.name.from_str(client_name)) {
28 derr << ": error initializing cluster handle for " << cluster_name << dendl;
29 return -EINVAL;
30 }
31
32 CephContext *cct = common_preinit(iparams, CODE_ENVIRONMENT_LIBRARY,
33 CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS);
b3b6e05e
TL
34 if (mon_host.empty()) {
35 cct->_conf->cluster = cluster_name;
36 }
f67539c2
TL
37
38 int r = cct->_conf.parse_config_files(nullptr, nullptr, 0);
39 if (r < 0 && r != -ENOENT) {
40 derr << ": could not read ceph conf: " << ": " << cpp_strerror(r) << dendl;
41 return r;
42 }
43
44 cct->_conf.parse_env(cct->get_module_type());
45
b3b6e05e
TL
46 if (!args.empty()) {
47 r = cct->_conf.parse_argv(args);
48 if (r < 0) {
49 derr << ": could not parse command line args: " << cpp_strerror(r) << dendl;
50 cct->put();
51 return r;
52 }
f67539c2
TL
53 }
54 cct->_conf.parse_env(cct->get_module_type());
55
56 if (!mon_host.empty()) {
57 r = cct->_conf.set_val("mon_host", std::string(mon_host));
58 if (r < 0) {
59 derr << "failed to set mon_host config: " << cpp_strerror(r) << dendl;
60 cct->put();
61 return r;
62 }
63 }
64 if (!cephx_key.empty()) {
65 r = cct->_conf.set_val("key", std::string(cephx_key));
66 if (r < 0) {
67 derr << "failed to set key config: " << cpp_strerror(r) << dendl;
68 cct->put();
69 return r;
70 }
71 }
72
b3b6e05e
TL
73 dout(10) << ": using mon addr=" << cct->_conf.get_val<std::string>("mon_host") << dendl;
74
f67539c2
TL
75 cluster->reset(new librados::Rados());
76
77 r = (*cluster)->init_with_context(cct);
78 ceph_assert(r == 0);
79 cct->put();
80
81 r = (*cluster)->connect();
82 if (r < 0) {
83 derr << ": error connecting to " << cluster_name << ": " << cpp_strerror(r)
84 << dendl;
85 return r;
86 }
87
88 dout(10) << ": connected to cluster=" << cluster_name << " using client="
89 << client_name << dendl;
90
91 return 0;
92}
93
94int mount(RadosRef cluster, const Filesystem &filesystem, bool cross_check_fscid,
95 MountRef *mount) {
96 dout(20) << ": filesystem=" << filesystem << dendl;
97
98 ceph_mount_info *cmi;
99 int r = ceph_create_with_context(&cmi, reinterpret_cast<CephContext*>(cluster->cct()));
100 if (r < 0) {
101 derr << ": mount error: " << cpp_strerror(r) << dendl;
102 return r;
103 }
104
105 r = ceph_conf_set(cmi, "client_mount_uid", "0");
106 if (r < 0) {
107 derr << ": mount error: " << cpp_strerror(r) << dendl;
108 return r;
109 }
110
111 r = ceph_conf_set(cmi, "client_mount_gid", "0");
112 if (r < 0) {
113 derr << ": mount error: " << cpp_strerror(r) << dendl;
114 return r;
115 }
116
b3b6e05e
TL
117 // mount timeout applies for local and remote mounts.
118 auto mount_timeout = g_ceph_context->_conf.get_val<std::chrono::seconds>
119 ("cephfs_mirror_mount_timeout").count();
120 r = ceph_set_mount_timeout(cmi, mount_timeout);
121 if (r < 0) {
122 derr << ": mount error: " << cpp_strerror(r) << dendl;
123 return r;
124 }
125
f67539c2
TL
126 r = ceph_init(cmi);
127 if (r < 0) {
128 derr << ": mount error: " << cpp_strerror(r) << dendl;
129 return r;
130 }
131
132 r = ceph_select_filesystem(cmi, filesystem.fs_name.c_str());
133 if (r < 0) {
134 derr << ": mount error: " << cpp_strerror(r) << dendl;
135 return r;
136 }
137
138 r = ceph_mount(cmi, NULL);
139 if (r < 0) {
140 derr << ": mount error: " << cpp_strerror(r) << dendl;
141 return r;
142 }
143
144 auto fs_id = ceph_get_fs_cid(cmi);
145 if (cross_check_fscid && fs_id != filesystem.fscid) {
146 // this can happen in the most remotest possibility when a
147 // filesystem is deleted and recreated with the same name.
148 // since all this is driven asynchronously, we were able to
149 // mount the recreated filesystem. so bubble up the error.
150 // cleanup will eventually happen since a mirror disable event
151 // would have been queued.
152 derr << ": filesystem-id mismatch " << fs_id << " vs " << filesystem.fscid
153 << dendl;
154 // ignore errors, we are shutting down anyway.
155 ceph_unmount(cmi);
156 return -EINVAL;
157 }
158
159 dout(10) << ": mounted filesystem=" << filesystem << dendl;
160
161 *mount = cmi;
162 return 0;
163}
164
165} // namespace mirror
166} // namespace cephfs