SET EC调试版

断点调试

[hadoop@hadoop1 hadoop]$ hdfs ec -setPolicy -path /ec1 -policy RS-3-2-1024k

源码如下:

//FSDirErasureCodingOp#setErasureCodingPolicy
static FileStatus setErasureCodingPolicy(final FSNamesystem fsn,
      final String srcArg, final String ecPolicyName,
      final FSPermissionChecker pc, final boolean logRetryCache)
      throws IOException, AccessControlException {
    assert fsn.hasWriteLock();

    String src = srcArg;
    FSDirectory fsd = fsn.getFSDirectory();
    final INodesInPath iip;
    List<XAttr> xAttrs;
    fsd.writeLock();
    try {
      ErasureCodingPolicy ecPolicy = getErasureCodingPolicyByName(fsn,
          ecPolicyName);
      iip = fsd.resolvePath(pc, src, DirOp.WRITE_LINK);
      // Write access is required to set erasure coding policy
      if (fsd.isPermissionEnabled()) {
        fsd.checkPathAccess(pc, iip, FsAction.WRITE);
      }
      src = iip.getPath();
      xAttrs = setErasureCodingPolicyXAttr(fsn, iip, ecPolicy);
    } finally {
      fsd.writeUnlock();
    }
    fsn.getEditLog().logSetXAttrs(src, xAttrs, logRetryCache);
    return fsd.getAuditFileInfo(iip);
  }

可以看到,主要流程:
根据名称解析到ec策略 --> 获得iip --> 在iip上设置特性 --> 记录到editlog
调试如下:
在这里插入图片描述
通过ec名称解析到的ECPolicy:
在这里插入图片描述
通过path获得INodeInPath:iip

INodesInPath: path = /ec1
  inodes = [, ec1], length=2
  isSnapshot        = false
  snapshotId        = 2147483646

srcPath 和 iip 之间可以相互转化。
在这里插入图片描述


进入setErasureCodingPolicyXAttr代码:

private static List<XAttr> setErasureCodingPolicyXAttr(final FSNamesystem fsn,
      final INodesInPath srcIIP, ErasureCodingPolicy ecPolicy) throws IOException {
    FSDirectory fsd = fsn.getFSDirectory();
    assert fsd.hasWriteLock();
    Preconditions.checkNotNull(srcIIP, "INodes cannot be null");
    Preconditions.checkNotNull(ecPolicy, "EC policy cannot be null");
    String src = srcIIP.getPath();
    //从iip中得到最后一个node节点,设置属性实则设置在最后一个节点上
    final INode inode = srcIIP.getLastINode();
    if (inode == null) {
      throw new FileNotFoundException("Path not found: " + srcIIP.getPath());
    }
    if (!inode.isDirectory()) {
      throw new IOException("Attempt to set an erasure coding policy " +
          "for a file " + src);
    }

    final XAttr ecXAttr;
    DataOutputStream dOut = null;
    try {
      //这里关键 通过名称转化为XATTR
      ByteArrayOutputStream bOut = new ByteArrayOutputStream();
      dOut = new DataOutputStream(bOut);
      WritableUtils.writeString(dOut, ecPolicy.getName());
      ecXAttr = XAttrHelper.buildXAttr(XATTR_ERASURECODING_POLICY,
          bOut.toByteArray());
    } finally {
      IOUtils.closeStream(dOut);
    }
    // check whether the directory already has an erasure coding policy
    // directly on itself.
    final Boolean hasEcXAttr =
        getErasureCodingPolicyXAttrForINode(fsn, inode) == null ? false : true;
    final List<XAttr> xattrs = Lists.newArrayListWithCapacity(1);
    xattrs.add(ecXAttr);
    final EnumSet<XAttrSetFlag> flag = hasEcXAttr ?
        EnumSet.of(XAttrSetFlag.REPLACE) : EnumSet.of(XAttrSetFlag.CREATE);
    FSDirXAttrOp.unprotectedSetXAttrs(fsd, srcIIP, xattrs, flag);
    return xattrs;
  }

INode的属性是INodeDirectory:
在这里插入图片描述
在这里插入图片描述

新加入的XAttr内容为:

XAttr [ns=SYSTEM, name=hdfs.erasurecoding.policy, value=[0, 0, 0, 12, 82, 83, 45, 51, 45, 50, 45, 49, 48, 50, 52, 107]]

在这里插入图片描述


检查inode是否已经设置了其他EC属性。如果没有,这给创建标识;如果有,则给替换标识。

    final Boolean hasEcXAttr =
        getErasureCodingPolicyXAttrForINode(fsn, inode) == null ? false : true;
    final List<XAttr> xattrs = Lists.newArrayListWithCapacity(1);
    xattrs.add(ecXAttr);
    final EnumSet<XAttrSetFlag> flag = hasEcXAttr ?
        EnumSet.of(XAttrSetFlag.REPLACE) : EnumSet.of(XAttrSetFlag.CREATE);
    FSDirXAttrOp.unprotectedSetXAttrs(fsd, srcIIP, xattrs, flag);
    return xattrs;

设置属性 FSDirXAttrOp.unprotectedSetXAttrs(fsd, srcIIP, xattrs, flag); 代码如下:

  static INode unprotectedSetXAttrs(
      FSDirectory fsd, final INodesInPath iip, final List<XAttr> xAttrs,
      final EnumSet<XAttrSetFlag> flag)
      throws IOException {
    assert fsd.hasWriteLock();
    INode inode = FSDirectory.resolveLastINode(iip);
    //查询这个节点已经存在的扩展特性
    List<XAttr> existingXAttrs = XAttrStorage.readINodeXAttrs(inode);
    List<XAttr> newXAttrs = setINodeXAttrs(fsd, existingXAttrs, xAttrs, flag);
    final boolean isFile = inode.isFile();

    //遍历每个属性
    for (XAttr xattr : newXAttrs) {
      final String xaName = XAttrHelper.getPrefixedName(xattr);

      /*
       * If we're adding the encryption zone xattr, then add src to the list
       * of encryption zones.
       */
      //如果是ozone相关额外做些工作 
      if (CRYPTO_XATTR_ENCRYPTION_ZONE.equals(xaName)) {
        final HdfsProtos.ZoneEncryptionInfoProto ezProto =
            HdfsProtos.ZoneEncryptionInfoProto.parseFrom(xattr.getValue());
        fsd.ezManager.addEncryptionZone(inode.getId(),
            PBHelperClient.convert(ezProto.getSuite()),
            PBHelperClient.convert(ezProto.getCryptoProtocolVersion()),
            ezProto.getKeyName());

        if (ezProto.hasReencryptionProto()) {
          ReencryptionInfoProto reProto = ezProto.getReencryptionProto();
          fsd.ezManager.getReencryptionStatus()
              .updateZoneStatus(inode.getId(), iip.getPath(), reProto);
        }
      }

      // Add inode id to movement queue if xattrs contain satisfy xattr.
      if (XATTR_SATISFY_STORAGE_POLICY.equals(xaName)) {
        FSDirSatisfyStoragePolicyOp.unprotectedSatisfyStoragePolicy(inode, fsd);
        continue;
      }

      if (!isFile && SECURITY_XATTR_UNREADABLE_BY_SUPERUSER.equals(xaName)) {
        throw new IOException("Can only set '" +
            SECURITY_XATTR_UNREADABLE_BY_SUPERUSER + "' on a file.");
      }
    }

    XAttrStorage.updateINodeXAttrs(inode, newXAttrs, iip.getLatestSnapshotId());
    return inode;
  }

需要设置的属性是xAttrs,如下:
在这里插入图片描述
现存的属性existingXAttrs为空。

通过调用XAttrStorage.updateINodeXAttrs,将新的属性集合设置到inode上。

public static void updateINodeXAttrs(INode inode, 
      List<XAttr> xAttrs, int snapshotId) throws QuotaExceededException {
    if (inode.getXAttrFeature() != null) {
      inode.removeXAttrFeature(snapshotId);
    }
    if (xAttrs == null || xAttrs.isEmpty()) {
      return;
    }
    inode.addXAttrFeature(new XAttrFeature(xAttrs), snapshotId);
  }

在这里插入图片描述
通过XAttr来构建 XAttrFeature, 然后INode来添加属性。
XAttr被格式化成Bytes类型。

// INodeWithAdditionalFields
  protected void addFeature(Feature f) {
    int size = features.length;
    Feature[] arr = new Feature[size + 1];
    if (size != 0) {
      System.arraycopy(features, 0, arr, 0, size);
    }
    arr[size] = f;
    features = arr;
  }

在这里插入图片描述

原来的feature为0,现在有了1个,所以一共是1个。
为什么XAttr里面还有两个属性,一个是attrs,一个是xAttrs呢?并且为什么xAttrs=null,不是应该有值才对吗???
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值