namenode_operations.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "filesystem.h"
  19. #include "common/continuation/asio.h"
  20. #include <asio/ip/tcp.hpp>
  21. #include <functional>
  22. #include <limits>
  23. #include <future>
  24. #include <tuple>
  25. #include <iostream>
  26. #include <pwd.h>
  27. #include <utility>
  28. #define FMT_THIS_ADDR "this=" << (void*)this
  29. using ::asio::ip::tcp;
  30. namespace hdfs {
  31. /*****************************************************************************
  32. * NAMENODE OPERATIONS
  33. ****************************************************************************/
  34. void NameNodeOperations::Connect(const std::string &cluster_name,
  35. const std::vector<ResolvedNamenodeInfo> &servers,
  36. std::function<void(const Status &)> &&handler) {
  37. engine_.Connect(cluster_name, servers, handler);
  38. }
  39. bool NameNodeOperations::CancelPendingConnect() {
  40. return engine_.CancelPendingConnect();
  41. }
  42. void NameNodeOperations::GetBlockLocations(const std::string & path, uint64_t offset, uint64_t length,
  43. std::function<void(const Status &, std::shared_ptr<const struct FileInfo>)> handler)
  44. {
  45. using ::hadoop::hdfs::GetBlockLocationsRequestProto;
  46. using ::hadoop::hdfs::GetBlockLocationsResponseProto;
  47. LOG_TRACE(kFileSystem, << "NameNodeOperations::GetBlockLocations("
  48. << FMT_THIS_ADDR << ", path=" << path << ", ...) called");
  49. if (path.empty()) {
  50. handler(Status::InvalidArgument("GetBlockLocations: argument 'path' cannot be empty"), nullptr);
  51. return;
  52. }
  53. //Protobuf gives an error 'Negative value is not supported'
  54. //if the high bit is set in uint64 in GetBlockLocations
  55. if (IsHighBitSet(offset)) {
  56. handler(Status::InvalidArgument("GetBlockLocations: argument 'offset' cannot have high bit set"), nullptr);
  57. return;
  58. }
  59. if (IsHighBitSet(length)) {
  60. handler(Status::InvalidArgument("GetBlockLocations: argument 'length' cannot have high bit set"), nullptr);
  61. return;
  62. }
  63. GetBlockLocationsRequestProto req;
  64. req.set_src(path);
  65. req.set_offset(offset);
  66. req.set_length(length);
  67. auto resp = std::make_shared<GetBlockLocationsResponseProto>();
  68. namenode_.GetBlockLocations(&req, resp, [resp, handler](const Status &stat) {
  69. if (stat.ok()) {
  70. auto file_info = std::make_shared<struct FileInfo>();
  71. auto locations = resp->locations();
  72. file_info->file_length_ = locations.filelength();
  73. file_info->last_block_complete_ = locations.islastblockcomplete();
  74. file_info->under_construction_ = locations.underconstruction();
  75. for (const auto &block : locations.blocks()) {
  76. file_info->blocks_.push_back(block);
  77. }
  78. if (!locations.islastblockcomplete() &&
  79. locations.has_lastblock() && locations.lastblock().b().numbytes()) {
  80. file_info->blocks_.push_back(locations.lastblock());
  81. file_info->file_length_ += locations.lastblock().b().numbytes();
  82. }
  83. handler(stat, file_info);
  84. } else {
  85. handler(stat, nullptr);
  86. }
  87. });
  88. }
  89. void NameNodeOperations::GetPreferredBlockSize(const std::string & path,
  90. std::function<void(const Status &, const uint64_t)> handler)
  91. {
  92. using ::hadoop::hdfs::GetPreferredBlockSizeRequestProto;
  93. using ::hadoop::hdfs::GetPreferredBlockSizeResponseProto;
  94. LOG_TRACE(kFileSystem, << "NameNodeOperations::GetPreferredBlockSize("
  95. << FMT_THIS_ADDR << ", path=" << path << ") called");
  96. if (path.empty()) {
  97. handler(Status::InvalidArgument("GetPreferredBlockSize: argument 'path' cannot be empty"), -1);
  98. return;
  99. }
  100. GetPreferredBlockSizeRequestProto req;
  101. req.set_filename(path);
  102. auto resp = std::make_shared<GetPreferredBlockSizeResponseProto>();
  103. namenode_.GetPreferredBlockSize(&req, resp, [resp, handler, path](const Status &stat) {
  104. if (stat.ok() && resp -> has_bsize()) {
  105. uint64_t block_size = resp -> bsize();
  106. handler(stat, block_size);
  107. } else {
  108. handler(stat, -1);
  109. }
  110. });
  111. }
  112. void NameNodeOperations::SetReplication(const std::string & path, int16_t replication,
  113. std::function<void(const Status &)> handler)
  114. {
  115. using ::hadoop::hdfs::SetReplicationRequestProto;
  116. using ::hadoop::hdfs::SetReplicationResponseProto;
  117. LOG_TRACE(kFileSystem,
  118. << "NameNodeOperations::SetReplication(" << FMT_THIS_ADDR << ", path=" << path <<
  119. ", replication=" << replication << ") called");
  120. if (path.empty()) {
  121. handler(Status::InvalidArgument("SetReplication: argument 'path' cannot be empty"));
  122. return;
  123. }
  124. Status replStatus = FileSystemImpl::CheckValidReplication(replication);
  125. if (!replStatus.ok()) {
  126. handler(replStatus);
  127. return;
  128. }
  129. SetReplicationRequestProto req;
  130. req.set_src(path);
  131. req.set_replication(replication);
  132. auto resp = std::make_shared<SetReplicationResponseProto>();
  133. namenode_.SetReplication(&req, resp, [resp, handler, path](const Status &stat) {
  134. if (stat.ok()) {
  135. // Checking resp
  136. if(resp -> has_result() && resp ->result() == 1) {
  137. handler(stat);
  138. } else {
  139. //NameNode does not specify why there is no result, in my testing it was happening when the path is not found
  140. std::string errormsg = "No such file or directory: " + path;
  141. Status statNew = Status::PathNotFound(errormsg.c_str());
  142. handler(statNew);
  143. }
  144. } else {
  145. handler(stat);
  146. }
  147. });
  148. }
  149. void NameNodeOperations::SetTimes(const std::string & path, uint64_t mtime, uint64_t atime,
  150. std::function<void(const Status &)> handler)
  151. {
  152. using ::hadoop::hdfs::SetTimesRequestProto;
  153. using ::hadoop::hdfs::SetTimesResponseProto;
  154. LOG_TRACE(kFileSystem,
  155. << "NameNodeOperations::SetTimes(" << FMT_THIS_ADDR << ", path=" << path <<
  156. ", mtime=" << mtime << ", atime=" << atime << ") called");
  157. if (path.empty()) {
  158. handler(Status::InvalidArgument("SetTimes: argument 'path' cannot be empty"));
  159. return;
  160. }
  161. SetTimesRequestProto req;
  162. req.set_src(path);
  163. req.set_mtime(mtime);
  164. req.set_atime(atime);
  165. auto resp = std::make_shared<SetTimesResponseProto>();
  166. namenode_.SetTimes(&req, resp, [resp, handler, path](const Status &stat) {
  167. handler(stat);
  168. });
  169. }
  170. void NameNodeOperations::GetFileInfo(const std::string & path,
  171. std::function<void(const Status &, const StatInfo &)> handler)
  172. {
  173. using ::hadoop::hdfs::GetFileInfoRequestProto;
  174. using ::hadoop::hdfs::GetFileInfoResponseProto;
  175. LOG_TRACE(kFileSystem, << "NameNodeOperations::GetFileInfo("
  176. << FMT_THIS_ADDR << ", path=" << path << ") called");
  177. if (path.empty()) {
  178. handler(Status::InvalidArgument("GetFileInfo: argument 'path' cannot be empty"), StatInfo());
  179. return;
  180. }
  181. GetFileInfoRequestProto req;
  182. req.set_src(path);
  183. auto resp = std::make_shared<GetFileInfoResponseProto>();
  184. namenode_.GetFileInfo(&req, resp, [resp, handler, path](const Status &stat) {
  185. if (stat.ok()) {
  186. // For non-existant files, the server will respond with an OK message but
  187. // no fs in the protobuf.
  188. if(resp -> has_fs()){
  189. struct StatInfo stat_info;
  190. stat_info.path = path;
  191. stat_info.full_path = path;
  192. HdfsFileStatusProtoToStatInfo(stat_info, resp->fs());
  193. handler(stat, stat_info);
  194. } else {
  195. std::string errormsg = "No such file or directory: " + path;
  196. Status statNew = Status::PathNotFound(errormsg.c_str());
  197. handler(statNew, StatInfo());
  198. }
  199. } else {
  200. handler(stat, StatInfo());
  201. }
  202. });
  203. }
  204. void NameNodeOperations::GetContentSummary(const std::string & path,
  205. std::function<void(const Status &, const ContentSummary &)> handler)
  206. {
  207. using ::hadoop::hdfs::GetContentSummaryRequestProto;
  208. using ::hadoop::hdfs::GetContentSummaryResponseProto;
  209. LOG_TRACE(kFileSystem, << "NameNodeOperations::GetContentSummary("
  210. << FMT_THIS_ADDR << ", path=" << path << ") called");
  211. if (path.empty()) {
  212. handler(Status::InvalidArgument("GetContentSummary: argument 'path' cannot be empty"), ContentSummary());
  213. return;
  214. }
  215. GetContentSummaryRequestProto req;
  216. req.set_path(path);
  217. auto resp = std::make_shared<GetContentSummaryResponseProto>();
  218. namenode_.GetContentSummary(&req, resp, [resp, handler, path](const Status &stat) {
  219. if (stat.ok()) {
  220. // For non-existant files, the server will respond with an OK message but
  221. // no summary in the protobuf.
  222. if(resp -> has_summary()){
  223. struct ContentSummary content_summary;
  224. content_summary.path = path;
  225. ContentSummaryProtoToContentSummary(content_summary, resp->summary());
  226. handler(stat, content_summary);
  227. } else {
  228. std::string errormsg = "No such file or directory: " + path;
  229. Status statNew = Status::PathNotFound(errormsg.c_str());
  230. handler(statNew, ContentSummary());
  231. }
  232. } else {
  233. handler(stat, ContentSummary());
  234. }
  235. });
  236. }
  237. void NameNodeOperations::GetFsStats(
  238. std::function<void(const Status &, const FsInfo &)> handler) {
  239. using ::hadoop::hdfs::GetFsStatusRequestProto;
  240. using ::hadoop::hdfs::GetFsStatsResponseProto;
  241. LOG_TRACE(kFileSystem,
  242. << "NameNodeOperations::GetFsStats(" << FMT_THIS_ADDR << ") called");
  243. GetFsStatusRequestProto req;
  244. auto resp = std::make_shared<GetFsStatsResponseProto>();
  245. namenode_.GetFsStats(&req, resp, [resp, handler](const Status &stat) {
  246. if (stat.ok()) {
  247. struct FsInfo fs_info;
  248. GetFsStatsResponseProtoToFsInfo(fs_info, resp);
  249. handler(stat, fs_info);
  250. } else {
  251. handler(stat, FsInfo());
  252. }
  253. });
  254. }
  255. void NameNodeOperations::GetListing(
  256. const std::string & path,
  257. std::function<void(const Status &, const std::vector<StatInfo> &, bool)> handler,
  258. const std::string & start_after) {
  259. using ::hadoop::hdfs::GetListingRequestProto;
  260. using ::hadoop::hdfs::GetListingResponseProto;
  261. LOG_TRACE(
  262. kFileSystem,
  263. << "NameNodeOperations::GetListing(" << FMT_THIS_ADDR << ", path=" << path << ") called");
  264. if (path.empty()) {
  265. std::vector<StatInfo> empty;
  266. handler(Status::InvalidArgument("GetListing: argument 'path' cannot be empty"), empty, false);
  267. return;
  268. }
  269. GetListingRequestProto req;
  270. req.set_src(path);
  271. req.set_startafter(start_after.c_str());
  272. req.set_needlocation(false);
  273. auto resp = std::make_shared<GetListingResponseProto>();
  274. namenode_.GetListing(&req, resp, [resp, handler, path](const Status &stat) {
  275. std::vector<StatInfo> stat_infos;
  276. if (stat.ok()) {
  277. if(resp -> has_dirlist()){
  278. for (::hadoop::hdfs::HdfsFileStatusProto const& fs : resp->dirlist().partiallisting()) {
  279. StatInfo si;
  280. si.path = fs.path();
  281. si.full_path = path + fs.path();
  282. if(si.full_path.back() != '/'){
  283. si.full_path += "/";
  284. }
  285. HdfsFileStatusProtoToStatInfo(si, fs);
  286. stat_infos.push_back(si);
  287. }
  288. handler(stat, stat_infos, resp->dirlist().remainingentries() > 0);
  289. } else {
  290. std::string errormsg = "No such file or directory: " + path;
  291. handler(Status::PathNotFound(errormsg.c_str()), stat_infos, false);
  292. }
  293. } else {
  294. handler(stat, stat_infos, false);
  295. }
  296. });
  297. }
  298. void NameNodeOperations::Mkdirs(const std::string & path, uint16_t permissions, bool createparent,
  299. std::function<void(const Status &)> handler)
  300. {
  301. using ::hadoop::hdfs::MkdirsRequestProto;
  302. using ::hadoop::hdfs::MkdirsResponseProto;
  303. LOG_TRACE(kFileSystem,
  304. << "NameNodeOperations::Mkdirs(" << FMT_THIS_ADDR << ", path=" << path <<
  305. ", permissions=" << permissions << ", createparent=" << createparent << ") called");
  306. if (path.empty()) {
  307. handler(Status::InvalidArgument("Mkdirs: argument 'path' cannot be empty"));
  308. return;
  309. }
  310. MkdirsRequestProto req;
  311. Status permStatus = FileSystemImpl::CheckValidPermissionMask(permissions);
  312. if (!permStatus.ok()) {
  313. handler(permStatus);
  314. return;
  315. }
  316. req.set_src(path);
  317. hadoop::hdfs::FsPermissionProto *perm = req.mutable_masked();
  318. perm->set_perm(permissions);
  319. req.set_createparent(createparent);
  320. auto resp = std::make_shared<MkdirsResponseProto>();
  321. namenode_.Mkdirs(&req, resp, [resp, handler, path](const Status &stat) {
  322. if (stat.ok()) {
  323. // Checking resp
  324. if(resp -> has_result() && resp ->result() == 1) {
  325. handler(stat);
  326. } else {
  327. //NameNode does not specify why there is no result, in my testing it was happening when the path is not found
  328. std::string errormsg = "No such file or directory: " + path;
  329. Status statNew = Status::PathNotFound(errormsg.c_str());
  330. handler(statNew);
  331. }
  332. } else {
  333. handler(stat);
  334. }
  335. });
  336. }
  337. void NameNodeOperations::Delete(const std::string & path, bool recursive, std::function<void(const Status &)> handler) {
  338. using ::hadoop::hdfs::DeleteRequestProto;
  339. using ::hadoop::hdfs::DeleteResponseProto;
  340. LOG_TRACE(kFileSystem,
  341. << "NameNodeOperations::Delete(" << FMT_THIS_ADDR << ", path=" << path << ", recursive=" << recursive << ") called");
  342. if (path.empty()) {
  343. handler(Status::InvalidArgument("Delete: argument 'path' cannot be empty"));
  344. return;
  345. }
  346. DeleteRequestProto req;
  347. req.set_src(path);
  348. req.set_recursive(recursive);
  349. auto resp = std::make_shared<DeleteResponseProto>();
  350. namenode_.Delete(&req, resp, [resp, handler, path](const Status &stat) {
  351. if (stat.ok()) {
  352. // Checking resp
  353. if(resp -> has_result() && resp ->result() == 1) {
  354. handler(stat);
  355. } else {
  356. //NameNode does not specify why there is no result, in my testing it was happening when the path is not found
  357. std::string errormsg = "No such file or directory: " + path;
  358. Status statNew = Status::PathNotFound(errormsg.c_str());
  359. handler(statNew);
  360. }
  361. } else {
  362. handler(stat);
  363. }
  364. });
  365. }
  366. void NameNodeOperations::Rename(const std::string & oldPath, const std::string & newPath, std::function<void(const Status &)> handler) {
  367. using ::hadoop::hdfs::RenameRequestProto;
  368. using ::hadoop::hdfs::RenameResponseProto;
  369. LOG_TRACE(kFileSystem,
  370. << "NameNodeOperations::Rename(" << FMT_THIS_ADDR << ", oldPath=" << oldPath << ", newPath=" << newPath << ") called");
  371. if (oldPath.empty()) {
  372. handler(Status::InvalidArgument("Rename: argument 'oldPath' cannot be empty"));
  373. return;
  374. }
  375. if (newPath.empty()) {
  376. handler(Status::InvalidArgument("Rename: argument 'newPath' cannot be empty"));
  377. return;
  378. }
  379. RenameRequestProto req;
  380. req.set_src(oldPath);
  381. req.set_dst(newPath);
  382. auto resp = std::make_shared<RenameResponseProto>();
  383. namenode_.Rename(&req, resp, [resp, handler](const Status &stat) {
  384. if (stat.ok()) {
  385. // Checking resp
  386. if(resp -> has_result() && resp ->result() == 1) {
  387. handler(stat);
  388. } else {
  389. //Since NameNode does not specify why the result is not success, we set the general error
  390. std::string errormsg = "oldPath and parent directory of newPath must exist. newPath must not exist.";
  391. Status statNew = Status::InvalidArgument(errormsg.c_str());
  392. handler(statNew);
  393. }
  394. } else {
  395. handler(stat);
  396. }
  397. });
  398. }
  399. void NameNodeOperations::SetPermission(const std::string & path,
  400. uint16_t permissions, std::function<void(const Status &)> handler) {
  401. using ::hadoop::hdfs::SetPermissionRequestProto;
  402. using ::hadoop::hdfs::SetPermissionResponseProto;
  403. LOG_TRACE(kFileSystem,
  404. << "NameNodeOperations::SetPermission(" << FMT_THIS_ADDR << ", path=" << path << ", permissions=" << permissions << ") called");
  405. if (path.empty()) {
  406. handler(Status::InvalidArgument("SetPermission: argument 'path' cannot be empty"));
  407. return;
  408. }
  409. Status permStatus = FileSystemImpl::CheckValidPermissionMask(permissions);
  410. if (!permStatus.ok()) {
  411. handler(permStatus);
  412. return;
  413. }
  414. SetPermissionRequestProto req;
  415. req.set_src(path);
  416. hadoop::hdfs::FsPermissionProto *perm = req.mutable_permission();
  417. perm->set_perm(permissions);
  418. auto resp = std::make_shared<SetPermissionResponseProto>();
  419. namenode_.SetPermission(&req, resp,
  420. [handler](const Status &stat) {
  421. handler(stat);
  422. });
  423. }
  424. void NameNodeOperations::SetOwner(const std::string & path,
  425. const std::string & username, const std::string & groupname, std::function<void(const Status &)> handler) {
  426. using ::hadoop::hdfs::SetOwnerRequestProto;
  427. using ::hadoop::hdfs::SetOwnerResponseProto;
  428. LOG_TRACE(kFileSystem,
  429. << "NameNodeOperations::SetOwner(" << FMT_THIS_ADDR << ", path=" << path << ", username=" << username << ", groupname=" << groupname << ") called");
  430. if (path.empty()) {
  431. handler(Status::InvalidArgument("SetOwner: argument 'path' cannot be empty"));
  432. return;
  433. }
  434. SetOwnerRequestProto req;
  435. req.set_src(path);
  436. if(!username.empty()) {
  437. req.set_username(username);
  438. }
  439. if(!groupname.empty()) {
  440. req.set_groupname(groupname);
  441. }
  442. auto resp = std::make_shared<SetOwnerResponseProto>();
  443. namenode_.SetOwner(&req, resp,
  444. [handler](const Status &stat) {
  445. handler(stat);
  446. });
  447. }
  448. void NameNodeOperations::CreateSnapshot(const std::string & path,
  449. const std::string & name, std::function<void(const Status &)> handler) {
  450. using ::hadoop::hdfs::CreateSnapshotRequestProto;
  451. using ::hadoop::hdfs::CreateSnapshotResponseProto;
  452. LOG_TRACE(kFileSystem,
  453. << "NameNodeOperations::CreateSnapshot(" << FMT_THIS_ADDR << ", path=" << path << ", name=" << name << ") called");
  454. if (path.empty()) {
  455. handler(Status::InvalidArgument("CreateSnapshot: argument 'path' cannot be empty"));
  456. return;
  457. }
  458. CreateSnapshotRequestProto req;
  459. req.set_snapshotroot(path);
  460. if (!name.empty()) {
  461. req.set_snapshotname(name);
  462. }
  463. auto resp = std::make_shared<CreateSnapshotResponseProto>();
  464. namenode_.CreateSnapshot(&req, resp,
  465. [handler](const Status &stat) {
  466. handler(stat);
  467. });
  468. }
  469. void NameNodeOperations::DeleteSnapshot(const std::string & path,
  470. const std::string & name, std::function<void(const Status &)> handler) {
  471. using ::hadoop::hdfs::DeleteSnapshotRequestProto;
  472. using ::hadoop::hdfs::DeleteSnapshotResponseProto;
  473. LOG_TRACE(kFileSystem,
  474. << "NameNodeOperations::DeleteSnapshot(" << FMT_THIS_ADDR << ", path=" << path << ", name=" << name << ") called");
  475. if (path.empty()) {
  476. handler(Status::InvalidArgument("DeleteSnapshot: argument 'path' cannot be empty"));
  477. return;
  478. }
  479. if (name.empty()) {
  480. handler(Status::InvalidArgument("DeleteSnapshot: argument 'name' cannot be empty"));
  481. return;
  482. }
  483. DeleteSnapshotRequestProto req;
  484. req.set_snapshotroot(path);
  485. req.set_snapshotname(name);
  486. auto resp = std::make_shared<DeleteSnapshotResponseProto>();
  487. namenode_.DeleteSnapshot(&req, resp,
  488. [handler](const Status &stat) {
  489. handler(stat);
  490. });
  491. }
  492. void NameNodeOperations::RenameSnapshot(const std::string & path, const std::string & old_name,
  493. const std::string & new_name, std::function<void(const Status &)> handler) {
  494. using ::hadoop::hdfs::RenameSnapshotRequestProto;
  495. using ::hadoop::hdfs::RenameSnapshotResponseProto;
  496. LOG_TRACE(kFileSystem,
  497. << "NameNodeOperations::RenameSnapshot(" << FMT_THIS_ADDR << ", path=" << path <<
  498. ", old_name=" << old_name << ", new_name=" << new_name << ") called");
  499. if (path.empty()) {
  500. handler(Status::InvalidArgument("RenameSnapshot: argument 'path' cannot be empty"));
  501. return;
  502. }
  503. if (old_name.empty()) {
  504. handler(Status::InvalidArgument("RenameSnapshot: argument 'old_name' cannot be empty"));
  505. return;
  506. }
  507. if (new_name.empty()) {
  508. handler(Status::InvalidArgument("RenameSnapshot: argument 'new_name' cannot be empty"));
  509. return;
  510. }
  511. RenameSnapshotRequestProto req;
  512. req.set_snapshotroot(path);
  513. req.set_snapshotoldname(old_name);
  514. req.set_snapshotnewname(new_name);
  515. auto resp = std::make_shared<RenameSnapshotResponseProto>();
  516. namenode_.RenameSnapshot(&req, resp,
  517. [handler](const Status &stat) {
  518. handler(stat);
  519. });
  520. }
  521. void NameNodeOperations::AllowSnapshot(const std::string & path, std::function<void(const Status &)> handler) {
  522. using ::hadoop::hdfs::AllowSnapshotRequestProto;
  523. using ::hadoop::hdfs::AllowSnapshotResponseProto;
  524. LOG_TRACE(kFileSystem,
  525. << "NameNodeOperations::AllowSnapshot(" << FMT_THIS_ADDR << ", path=" << path << ") called");
  526. if (path.empty()) {
  527. handler(Status::InvalidArgument("AllowSnapshot: argument 'path' cannot be empty"));
  528. return;
  529. }
  530. AllowSnapshotRequestProto req;
  531. req.set_snapshotroot(path);
  532. auto resp = std::make_shared<AllowSnapshotResponseProto>();
  533. namenode_.AllowSnapshot(&req, resp,
  534. [handler](const Status &stat) {
  535. handler(stat);
  536. });
  537. }
  538. void NameNodeOperations::DisallowSnapshot(const std::string & path, std::function<void(const Status &)> handler) {
  539. using ::hadoop::hdfs::DisallowSnapshotRequestProto;
  540. using ::hadoop::hdfs::DisallowSnapshotResponseProto;
  541. LOG_TRACE(kFileSystem,
  542. << "NameNodeOperations::DisallowSnapshot(" << FMT_THIS_ADDR << ", path=" << path << ") called");
  543. if (path.empty()) {
  544. handler(Status::InvalidArgument("DisallowSnapshot: argument 'path' cannot be empty"));
  545. return;
  546. }
  547. DisallowSnapshotRequestProto req;
  548. req.set_snapshotroot(path);
  549. auto resp = std::make_shared<DisallowSnapshotResponseProto>();
  550. namenode_.DisallowSnapshot(&req, resp,
  551. [handler](const Status &stat) {
  552. handler(stat);
  553. });
  554. }
  555. void NameNodeOperations::SetFsEventCallback(fs_event_callback callback) {
  556. engine_.SetFsEventCallback(callback);
  557. }
  558. void NameNodeOperations::HdfsFileStatusProtoToStatInfo(
  559. hdfs::StatInfo & stat_info,
  560. const ::hadoop::hdfs::HdfsFileStatusProto & fs) {
  561. stat_info.file_type = fs.filetype();
  562. stat_info.length = fs.length();
  563. stat_info.permissions = fs.permission().perm();
  564. stat_info.owner = fs.owner();
  565. stat_info.group = fs.group();
  566. stat_info.modification_time = fs.modification_time();
  567. stat_info.access_time = fs.access_time();
  568. stat_info.symlink = fs.symlink();
  569. stat_info.block_replication = fs.block_replication();
  570. stat_info.blocksize = fs.blocksize();
  571. stat_info.fileid = fs.fileid();
  572. stat_info.children_num = fs.childrennum();
  573. }
  574. void NameNodeOperations::ContentSummaryProtoToContentSummary(
  575. hdfs::ContentSummary & content_summary,
  576. const ::hadoop::hdfs::ContentSummaryProto & csp) {
  577. content_summary.length = csp.length();
  578. content_summary.filecount = csp.filecount();
  579. content_summary.directorycount = csp.directorycount();
  580. content_summary.quota = csp.quota();
  581. content_summary.spaceconsumed = csp.spaceconsumed();
  582. content_summary.spacequota = csp.spacequota();
  583. }
  584. void NameNodeOperations::GetFsStatsResponseProtoToFsInfo(
  585. hdfs::FsInfo & fs_info,
  586. const std::shared_ptr<::hadoop::hdfs::GetFsStatsResponseProto> & fs) {
  587. fs_info.capacity = fs->capacity();
  588. fs_info.used = fs->used();
  589. fs_info.remaining = fs->remaining();
  590. fs_info.under_replicated = fs->under_replicated();
  591. fs_info.corrupt_blocks = fs->corrupt_blocks();
  592. fs_info.missing_blocks = fs->missing_blocks();
  593. fs_info.missing_repl_one_blocks = fs->missing_repl_one_blocks();
  594. if(fs->has_blocks_in_future()){
  595. fs_info.blocks_in_future = fs->blocks_in_future();
  596. }
  597. }
  598. }