blob: 39fd7658ef54d733e65282175b380168beb0de23 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hdfs.tools.offlineImageViewer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.PermissionStatus;
import org.apache.hadoop.hdfs.protocol.ErasureCodingPolicy;
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
import org.apache.hadoop.hdfs.server.namenode.ErasureCodingPolicyManager;
import org.apache.hadoop.hdfs.server.namenode.FsImageProto.INodeSection.INode;
import org.apache.hadoop.hdfs.server.namenode.FsImageProto.INodeSection.INodeDirectory;
import org.apache.hadoop.hdfs.server.namenode.FsImageProto.INodeSection.INodeFile;
import org.apache.hadoop.hdfs.server.namenode.FsImageProto.INodeSection.INodeSymlink;
import java.io.IOException;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
/**
* A PBImageDelimitedTextWriter generates a text representation of the PB fsimage,
* with each element separated by a delimiter string. All of the elements
* common to both inodes and inodes-under-construction are included. When
* processing an fsimage with a layout version that did not include an
* element, such as AccessTime, the output file will include a column
* for the value, but no value will be included.
*
* Individual block information for each file is not currently included.
*
* The default delimiter is tab, as this is an unlikely value to be included in
* an inode path or other text metadata. The delimiter value can be via the
* constructor.
*/
public class PBImageDelimitedTextWriter extends PBImageTextWriter {
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm";
private boolean printStoragePolicy;
private boolean printECPolicy;
private ErasureCodingPolicyManager ecManager;
static class OutputEntryBuilder {
private final SimpleDateFormat dateFormatter =
new SimpleDateFormat(DATE_FORMAT);
private PBImageDelimitedTextWriter writer;
private Path path;
private int replication = 0;
private long modificationTime;
private long accessTime = 0;
private long preferredBlockSize = 0;
private int blocksCount = 0;
private long fileSize = 0;
private long nsQuota = 0;
private long dsQuota = 0;
private int storagePolicy = 0;
private String ecPolicy = "-";
private String dirPermission = "-";
private PermissionStatus permissionStatus;
private String aclPermission = "";
OutputEntryBuilder(PBImageDelimitedTextWriter writer, INode inode) {
this.writer = writer;
switch (inode.getType()) {
case FILE:
INodeFile file = inode.getFile();
replication = file.getReplication();
modificationTime = file.getModificationTime();
accessTime = file.getAccessTime();
preferredBlockSize = file.getPreferredBlockSize();
blocksCount = file.getBlocksCount();
fileSize = FSImageLoader.getFileSize(file);
permissionStatus = writer.getPermission(file.getPermission());
if (file.hasAcl() && file.getAcl().getEntriesCount() > 0){
aclPermission = "+";
}
storagePolicy = file.getStoragePolicyID();
if (writer.printECPolicy && file.hasErasureCodingPolicyID()) {
ErasureCodingPolicy policy = writer.ecManager.
getByID((byte) file.getErasureCodingPolicyID());
if (policy != null) {
ecPolicy = policy.getName();
}
}
break;
case DIRECTORY:
INodeDirectory dir = inode.getDirectory();
modificationTime = dir.getModificationTime();
nsQuota = dir.getNsQuota();
dsQuota = dir.getDsQuota();
dirPermission = "d";
permissionStatus = writer.getPermission(dir.getPermission());
if (dir.hasAcl() && dir.getAcl().getEntriesCount() > 0) {
aclPermission = "+";
}
storagePolicy = writer.getStoragePolicy(dir.getXAttrs());
if (writer.printECPolicy) {
String name= writer.getErasureCodingPolicyName(dir.getXAttrs());
if (name != null) {
ecPolicy = name;
}
}
break;
case SYMLINK:
INodeSymlink s = inode.getSymlink();
modificationTime = s.getModificationTime();
accessTime = s.getAccessTime();
permissionStatus = writer.getPermission(s.getPermission());
storagePolicy = HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;
break;
default:
break;
}
}
void setPath(Path path) {
this.path = path;
}
public String build() {
assert permissionStatus != null : "The PermissionStatus is null!";
assert permissionStatus.getUserName() != null : "User name is null!";
assert permissionStatus.getGroupName() != null : "Group name is null!";
StringBuffer buffer = new StringBuffer();
writer.append(buffer, path.toString());
writer.append(buffer, replication);
writer.append(buffer, dateFormatter.format(modificationTime));
writer.append(buffer, dateFormatter.format(accessTime));
writer.append(buffer, preferredBlockSize);
writer.append(buffer, blocksCount);
writer.append(buffer, fileSize);
writer.append(buffer, nsQuota);
writer.append(buffer, dsQuota);
writer.append(buffer, dirPermission +
permissionStatus.getPermission().toString() + aclPermission);
writer.append(buffer, permissionStatus.getUserName());
writer.append(buffer, permissionStatus.getGroupName());
if (writer.printStoragePolicy) {
writer.append(buffer, storagePolicy);
}
if (writer.printECPolicy) {
writer.append(buffer, ecPolicy);
}
return buffer.substring(1);
}
}
PBImageDelimitedTextWriter(PrintStream out, String delimiter, String tempPath)
throws IOException {
this(out, delimiter, tempPath, false);
}
PBImageDelimitedTextWriter(PrintStream out, String delimiter,
String tempPath, boolean printStoragePolicy)
throws IOException {
this(out, delimiter, tempPath, printStoragePolicy, false, 1, "-", null);
}
PBImageDelimitedTextWriter(PrintStream out, String delimiter,
String tempPath, boolean printStoragePolicy,
boolean printECPolicy, int threads,
String parallelOut, Configuration conf)
throws IOException {
super(out, delimiter, tempPath, threads, parallelOut);
this.printStoragePolicy = printStoragePolicy;
if (printECPolicy && conf != null) {
this.printECPolicy = true;
ecManager = ErasureCodingPolicyManager.getInstance();
ecManager.init(conf);
}
}
@Override
public String getEntry(String parent, INode inode) {
OutputEntryBuilder entryBuilder =
new OutputEntryBuilder(this, inode);
String inodeName = inode.getName().toStringUtf8();
Path path = new Path(parent.isEmpty() ? "/" : parent,
inodeName.isEmpty() ? "/" : inodeName);
entryBuilder.setPath(path);
return entryBuilder.build();
}
@Override
public String getHeader() {
StringBuffer buffer = new StringBuffer();
buffer.append("Path");
append(buffer, "Replication");
append(buffer, "ModificationTime");
append(buffer, "AccessTime");
append(buffer, "PreferredBlockSize");
append(buffer, "BlocksCount");
append(buffer, "FileSize");
append(buffer, "NSQUOTA");
append(buffer, "DSQUOTA");
append(buffer, "Permission");
append(buffer, "UserName");
append(buffer, "GroupName");
if (printStoragePolicy) {
append(buffer, "StoragePolicyId");
}
if (printECPolicy) {
append(buffer, "ErasureCodingPolicy");
}
return buffer.toString();
}
@Override
public void afterOutput() {
// do nothing
}
}