예제 #1
0
  @Override
  public device_addr4 getDeviceInfo(CompoundContext context, deviceid4 deviceId) {
    /* in case of MDS access we return the same interface which client already connected to */
    if (deviceId.equals(MDS_ID)) {
      return deviceAddrOf(
          new RoundRobinStripingPattern<InetSocketAddress[]>(),
          new InetSocketAddress[] {context.getRpcCall().getTransport().getLocalSocketAddress()});
    }

    PoolDS ds = _poolDeviceMap.getByDeviceId(deviceId);
    if (ds == null) {
      return null;
    }
    return ds.getDeviceAddr();
  }
예제 #2
0
  @Override
  public void process(CompoundContext context, nfs_resop4 result) {

    final WRITE4res res = result.opwrite;

    try {

      NfsMover mover = _activeIO.get(_args.opwrite.stateid);
      if (mover == null) {
        throw new ChimeraNFSException(
            nfsstat.NFSERR_BAD_STATEID, "No mover associated with given stateid");
      }

      mover.attachSession(context.getSession());
      if (mover.getIoMode() != IoMode.WRITE) {
        throw new ChimeraNFSException(
            nfsstat.NFSERR_PERM, "an attempt to write without IO mode enabled");
      }

      long offset = _args.opwrite.offset.value;

      RepositoryChannel fc = mover.getMoverChannel();

      _args.opwrite.data.rewind();
      int bytesWritten = fc.write(_args.opwrite.data, offset);

      res.status = nfsstat.NFS_OK;
      res.resok4 = new WRITE4resok();
      res.resok4.count = new count4(bytesWritten);
      res.resok4.committed = stable_how4.FILE_SYNC4;
      res.resok4.writeverf = new verifier4();
      res.resok4.writeverf.value = new byte[nfs4_prot.NFS4_VERIFIER_SIZE];

      _log.debug("MOVER: {}@{} written, {} requested.", bytesWritten, offset, bytesWritten);

    } catch (ChimeraNFSException he) {
      _log.debug(he.getMessage());
      res.status = he.getStatus();
    } catch (IOException ioe) {
      _log.error("DSWRITE: ", ioe);
      res.status = nfsstat.NFSERR_IO;
    } catch (Exception e) {
      _log.error("DSWRITE: ", e);
      res.status = nfsstat.NFSERR_SERVERFAULT;
    }
  }
예제 #3
0
  /**
   * ask pool manager for a file
   *
   * <p>On successful reply from pool manager corresponding O request will be sent to the pool to
   * start a NFS mover.
   *
   * @throws ChimeraNFSException in case of NFS friendly errors ( like ACCESS )
   * @throws IOException in case of any other errors
   */
  @Override
  public Layout layoutGet(CompoundContext context, Inode nfsInode, int ioMode, stateid4 stateid)
      throws IOException {

    FsInode inode = _fileFileSystemProvider.inodeFromBytes(nfsInode.getFileId());
    CDC cdc = CDC.reset(_cellName, _domainName);
    try {
      NDC.push(inode.toString());
      NDC.push(context.getRpcCall().getTransport().getRemoteSocketAddress().toString());
      deviceid4 deviceid;
      if (inode.type() != FsInodeType.INODE || inode.getLevel() != 0) {
        /*
         * all non regular files ( AKA pnfs dot files ) provided by door itself.
         */
        deviceid = MDS_ID;
      } else {

        final InetSocketAddress remote =
            context.getRpcCall().getTransport().getRemoteSocketAddress();
        final PnfsId pnfsId = new PnfsId(inode.toString());
        final NFS4ProtocolInfo protocolInfo =
            new NFS4ProtocolInfo(remote, new org.dcache.chimera.nfs.v4.xdr.stateid4(stateid));

        Transfer.initSession();
        NfsTransfer transfer = _ioMessages.get(stateid);
        if (transfer == null) {
          transfer =
              new NfsTransfer(_pnfsHandler, context.getRpcCall().getCredential().getSubject());

          transfer.setProtocolInfo(protocolInfo);
          transfer.setCellName(this.getCellName());
          transfer.setDomainName(this.getCellDomainName());
          transfer.setBillingStub(_billingStub);
          transfer.setPoolStub(_poolManagerStub);
          transfer.setPoolManagerStub(_poolManagerStub);
          transfer.setPnfsId(pnfsId);
          transfer.setClientAddress(remote);
          transfer.readNameSpaceEntry();

          _ioMessages.put(stateid, transfer);

          PoolDS ds = getPool(transfer, ioMode);
          deviceid = ds.getDeviceId();
        } else {
          PoolDS ds = transfer.waitForRedirect(NFS_RETRY_PERIOD);
          deviceid = ds.getDeviceId();
        }
      }

      nfs_fh4 fh = new nfs_fh4(nfsInode.toNfsHandle());

      //  -1 is special value, which means entire file
      layout4 layout = Layout.getLayoutSegment(deviceid, fh, ioMode, 0, nfs4_prot.NFS4_UINT64_MAX);

      return new Layout(true, stateid, new layout4[] {layout});

    } catch (FileInCacheException e) {
      cleanStateAndKillMover(stateid);
      throw new ChimeraNFSException(nfsstat.NFSERR_IO, e.getMessage());
    } catch (CacheException e) {
      cleanStateAndKillMover(stateid);
      /*
       * error 243: file is broken on tape.
       * can't do a much. Tell it to client.
       */
      int status =
          e.getRc() == CacheException.BROKEN_ON_TAPE
              ? nfsstat.NFSERR_IO
              : nfsstat.NFSERR_LAYOUTTRYLATER;
      throw new ChimeraNFSException(status, e.getMessage());
    } catch (InterruptedException e) {
      cleanStateAndKillMover(stateid);
      throw new ChimeraNFSException(nfsstat.NFSERR_LAYOUTTRYLATER, e.getMessage());
    } finally {
      cdc.close();
    }
  }