/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2019 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#include "namespace/ns_quarkdb/inspector/Printing.hh"
#include "common/LayoutId.hh"
#include "namespace/utils/Checksum.hh"
#include "namespace/interface/IFileMD.hh"
#include "namespace/utils/Etag.hh"
#include "common/StringConversion.hh"
#include
EOSNSNAMESPACE_BEGIN
//------------------------------------------------------------------------------
// Escape non-printable string
//------------------------------------------------------------------------------
std::string Printing::escapeNonPrintable(const std::string &str) {
std::stringstream ss;
for(size_t i = 0; i < str.size(); i++) {
if(isprint(str[i])) {
ss << str[i];
}
else if(str[i] == '\0') {
ss << "\\x00";
}
else {
char buff[16];
snprintf(buff, 16, "\\x%02X", (unsigned char) str[i]);
ss << buff;
}
}
return ss.str();
}
//------------------------------------------------------------------------------
// Serialize locations vector
//------------------------------------------------------------------------------
template
static std::string serializeLocations(const T& vec) {
std::ostringstream stream;
stream << "[";
for(int i = 0; i < vec.size(); i++) {
stream << vec[i];
if(i != vec.size() - 1) {
stream << ", ";
}
}
stream << "]";
return stream.str();
}
//------------------------------------------------------------------------------
// timespec to fileinfo: Convert a timespec into
// "1447252711.38412918"
//------------------------------------------------------------------------------
std::string Printing::timespecToTimestamp(const struct timespec &val) {
std::ostringstream ss;
ss << val.tv_sec << "." << val.tv_nsec;
return ss.str();
}
//------------------------------------------------------------------------------
// timespec to fileinfo: Convert a timespec into
// "Wed Nov 11 15:38:31 2015 Timestamp: 1447252711.38412918"
//------------------------------------------------------------------------------
void Printing::timespecToFileinfo(const struct timespec &val, std::ostream &stream) {
time_t tv_sec = (time_t) val.tv_sec;
char buffer[4096];
stream << ctime_r(&tv_sec, buffer);
stream.seekp(-1, std::ios_base::end);
stream << " Timestamp: " << timespecToTimestamp(val);
}
std::string Printing::timespecToFileinfo(const struct timespec &val) {
std::ostringstream ss;
timespecToFileinfo(val, ss);
return ss.str();
}
//------------------------------------------------------------------------------
// Serialize protobuf time
//------------------------------------------------------------------------------
template
static std::string serializeTime(const T& bytes) {
std::ostringstream ss;
Printing::timespecToFileinfo(Printing::parseTimespec(bytes), ss);
return ss.str();
}
//----------------------------------------------------------------------------
// Print the given ContainerMd protobuf using multiple lines, full information
//----------------------------------------------------------------------------
void Printing::printMultiline(const eos::ns::ContainerMdProto &proto, std::ostream &stream) {
stream << "ID: " << proto.id() << std::endl;
stream << "Parent ID: " << proto.parent_id() << std::endl;
stream << "Name: " << proto.name() << std::endl;
stream << "uid: " << proto.uid() << ", gid: " << proto.gid() << std::endl;
stream << "ctime: " << serializeTime(proto.ctime()) << std::endl;
stream << "mtime: " << serializeTime(proto.mtime()) << std::endl;
stream << "stime: " << serializeTime(proto.stime()) << std::endl;
stream << "Tree size: " << proto.tree_size() << std::endl;
stream << "Mode: " << proto.mode() << std::endl;
stream << "Flags: " << proto.flags() << std::endl;
stream << "Extended attributes (" << proto.xattrs().size() << "):" << std::endl;
for(auto it = proto.xattrs().begin(); it != proto.xattrs().end(); it++) {
stream << " " << it->first << "=" << it->second << std::endl;
}
}
//------------------------------------------------------------------------------
// Print the given FileMd protobuf using multiple lines, full information
//------------------------------------------------------------------------------
void Printing::printMultiline(const eos::ns::FileMdProto &proto, std::ostream &stream) {
stream << "ID: " << proto.id() << std::endl;
stream << "Name: " << proto.name() << std::endl;
stream << "Link name: " << proto.link_name() << std::endl;
stream << "Container ID: " << proto.cont_id() << std::endl;
stream << "uid: " << proto.uid() << ", gid: " << proto.gid() << std::endl;
stream << "Size: " << proto.size() << std::endl;
stream << "Modify: " << serializeTime(proto.mtime()) << std::endl;
stream << "Change: " << serializeTime(proto.ctime()) << std::endl;
stream << "Access: " << serializeTime(proto.atime()) << std::endl;
stream << "Flags: " << common::StringConversion::IntToOctal( (int) proto.flags(), 4) << std::endl;
std::string checksum;
appendChecksumOnStringProtobuf(proto, checksum);
stream << "Checksum type: " << common::LayoutId::GetChecksumString(proto.layout_id()) << ", checksum bytes: " << checksum << std::endl;
stream << "Expected number of replicas / stripes: " << eos::common::LayoutId::GetStripeNumber(proto.layout_id()) + 1 << std::endl;
std::string etag;
eos::calculateEtag(proto, etag);
stream << "Etag: " << etag << std::endl;
stream << "Locations: " << serializeLocations(proto.locations()) << std::endl;
stream << "Unlinked locations: " << serializeLocations(proto.unlink_locations()) << std::endl;
stream << "Extended attributes (" << proto.xattrs().size() << "):" << std::endl;
for(auto it = proto.xattrs().begin(); it != proto.xattrs().end(); it++) {
stream << " " << it->first << "=" << it->second << std::endl;
}
}
std::string Printing::printMultiline(const eos::ns::FileMdProto &proto) {
std::ostringstream ss;
printMultiline(proto, ss);
return ss.str();
}
EOSNSNAMESPACE_END