use of diskCacheV111.util.FileLocality in project dcache by dCache.
the class DCacheAwareJdbcFs method getFileLocality.
/**
* Callout to get pool monitor and check for live (network) status of a file instead of simply
* its status as recorded in the Chimera database.
*/
private String getFileLocality(PnfsId pnfsId) throws ChimeraFsException {
FileLocality locality = FileLocality.UNAVAILABLE;
try {
Set<FileAttribute> requestedAttributes = EnumSet.of(FileAttribute.TYPE, FileAttribute.SIZE, FileAttribute.STORAGEINFO, FileAttribute.LOCATIONS);
Set<AccessMask> accessMask = EnumSet.of(AccessMask.READ_DATA);
FileAttributes attributes = pnfsHandler.getFileAttributes(pnfsId, requestedAttributes, accessMask, false);
/*
* TODO improve code to pass in the actual InetAddress of the
* client so that link net masks do not interfere; note that SRM uses
* "localhost", so it is not a deviation from existing behavior.
*/
locality = poolMonitor.getFileLocality(attributes, "localhost");
} catch (CacheException t) {
throw new ChimeraFsException("getFileLocality", t);
}
return locality.toString();
}
use of diskCacheV111.util.FileLocality in project dcache by dCache.
the class QoSTransitionEngine method adjustQoS.
public void adjustQoS(FsPath path, String target, String remoteHost) throws UnsupportedOperationException, URISyntaxException, CacheException, InterruptedException, NoRouteToCellException {
attributes = pnfsHandler.getFileAttributes(path, TRANSITION_ATTRIBUTES);
FileLocality locality = getLocality(remoteHost);
PnfsId id = attributes.getPnfsId();
LOGGER.debug("{} locality: {}", id, locality);
if (locality == FileLocality.NONE) {
throw new UnsupportedOperationException("Transition for directories " + "not supported");
}
Qos qosTarget;
try {
qosTarget = Qos.fromDisplayName(target);
LOGGER.debug("{}, new target QoS {}.", id, qosTarget);
} catch (IllegalArgumentException e) {
throw new UnsupportedOperationException("Bad QoS Target type", e);
}
AccessLatency currentAccessLatency = attributes.getAccessLatency();
RetentionPolicy currentRetentionPolicy = attributes.getRetentionPolicy();
LOGGER.debug("{}, AccessLatency {}, Retention Policy {}.", id, currentAccessLatency, currentRetentionPolicy);
FileAttributes modifiedAttr = new FileAttributes();
ListenableFuture<PoolMigrationMessage> migrationFuture = null;
ListenableFuture<PinManagerPinMessage> pinFuture = null;
switch(qosTarget) {
case DISK_TAPE:
if (locality == FileLocality.ONLINE) {
LOGGER.debug("{}, attempting to migrate.", id);
migrationFuture = conditionallyMigrateToTapePool(modifiedAttr, currentRetentionPolicy);
}
if (!currentAccessLatency.equals(AccessLatency.ONLINE)) {
LOGGER.debug("{}, changing access latency to ONLINE", id);
modifiedAttr.setAccessLatency(AccessLatency.ONLINE);
}
updateNamespace(modifiedAttr, id, path);
// REVISIT when Resilience manages QoS for all files, remove
if (!isPinnedForQoS()) {
LOGGER.debug("{}, pinning for QoS.", id);
pinFuture = pinForQoS(remoteHost);
}
break;
case DISK:
if (locality == FileLocality.ONLINE) {
/*
* ONLINE locality may not denote ONLINE access latency.
* ONLINE locality and NEARLINE access latency should
* not translate to 'Disk' qos.
*/
if (!currentAccessLatency.equals(AccessLatency.ONLINE)) {
LOGGER.debug("{}, changing access latency to ONLINE", id);
modifiedAttr.setAccessLatency(AccessLatency.ONLINE);
updateNamespace(modifiedAttr, id, path);
}
// REVISIT when Resilience manages QoS for all files, remove
if (!isPinnedForQoS()) {
LOGGER.debug("{}, pinning for QoS.", id);
pinFuture = pinForQoS(remoteHost);
}
} else if (currentRetentionPolicy.equals(RetentionPolicy.CUSTODIAL)) {
/*
* Technically, to make the QoS semantics in
* Chimera consistent, one would need to change this
* to REPLICA, even though this would not trigger
* deletion from tape. It is probably best to
* continue not supporting this transition.
*/
throw new UnsupportedOperationException("Unsupported QoS transition");
}
break;
case TAPE:
if (locality == FileLocality.ONLINE) {
LOGGER.debug("{}, attempting to migrate.", id);
migrationFuture = conditionallyMigrateToTapePool(modifiedAttr, currentRetentionPolicy);
}
if (!currentAccessLatency.equals(AccessLatency.NEARLINE)) {
LOGGER.debug("{}, changing access latency to NEARLINE", id);
modifiedAttr.setAccessLatency(AccessLatency.NEARLINE);
}
updateNamespace(modifiedAttr, id, path);
// REVISIT when Resilience manages QoS for all files, remove
LOGGER.debug("{}, unpinning QoS.", id);
unpinForQoS();
break;
default:
throw new UnsupportedOperationException("Unsupported QoS target for transition");
}
if (replyHandler != null) {
replyHandler.setMigrationFuture(migrationFuture);
replyHandler.setPinFuture(pinFuture);
replyHandler.listen();
}
}
use of diskCacheV111.util.FileLocality in project dcache by dCache.
the class QoSTransitionEngine method getQosStatus.
/*
* REVISIT when Resilience can handle all file QoS, remove pinned checks
* REVISIT use of VOLATILE (DOES NOT ACTUALLY MEAN THIS ...)
*/
public QosStatus getQosStatus(FileAttributes attributes, String remoteHost) throws InterruptedException, CacheException, NoRouteToCellException {
this.attributes = attributes;
boolean isPinnedForQoS = QoSTransitionEngine.isPinnedForQoS(attributes, pinManager);
FileLocality locality = getLocality(remoteHost);
AccessLatency currentAccessLatency = attributes.getAccessLatencyIfPresent().orElse(null);
RetentionPolicy currentRetentionPolicy = attributes.getRetentionPolicyIfPresent().orElse(null);
boolean policyIsTape = currentRetentionPolicy == RetentionPolicy.CUSTODIAL;
boolean latencyIsDisk = currentAccessLatency == AccessLatency.ONLINE || isPinnedForQoS;
switch(locality) {
case NEARLINE:
if (policyIsTape) {
if (latencyIsDisk) {
/*
* In transition.
*/
return new QosStatus(TAPE, DISK_TAPE);
}
return new QosStatus(TAPE);
} else {
/*
* not possible according to present
* locality definition of NEARLINE; but eventually,
* if this happens, something has happened
* to the file (could be a REPLICA NEARLINE
* file whose only copy has been removed
* from the pool).
*/
return new QosStatus(UNAVAILABLE);
}
case ONLINE:
if (latencyIsDisk) {
if (policyIsTape) {
/*
* In transition.
*/
return new QosStatus(DISK, DISK_TAPE);
}
return new QosStatus(DISK);
} else {
/*
* This is the case where we have found a
* cached file. Since locality here means
* this cannot be CUSTODIAL, and it is not AL ONLINE,
* it must be REPLICA NEARLINE. What is the QoS?
*/
if (policyIsTape) {
/*
* In transition.
*/
return new QosStatus(VOLATILE, TAPE);
}
return new QosStatus(VOLATILE);
}
case ONLINE_AND_NEARLINE:
if (latencyIsDisk) {
return new QosStatus(DISK_TAPE);
} else {
/*
* This is ambiguous. It could be that the file
* is present on disk, but it is 'unpinned' or has
* an access latency of NEARLINE (a cached replica)
* now, or it could be a transition to a TAPE
* from DISK+TAPE (i.e., is it the current or
* target QoS which is TAPE?).
*
* The situation is undecidable. So we leave
* the target Qos blank for the moment.
*/
return new QosStatus(TAPE);
}
/*
* Transitions away from tape are currently forbidden.
*/
case NONE:
// implies the target is a directory.
return directoryQoS();
case UNAVAILABLE:
return new QosStatus(UNAVAILABLE);
case LOST:
// currently not used by dCache
default:
throw new CacheException("Unexpected file locality: " + locality);
}
}
use of diskCacheV111.util.FileLocality in project dcache by dCache.
the class NamespaceUtils method chimeraToJsonAttributes.
/**
* <p>Map returned attributes to JsonFileAttributes object.</p>
*
* @param name of file
* @param json mapped from attributes
* @param attributes returned by the query to namespace
* @param isLocality used to check weather user queried locality of the file
* @param isLocations add locations if true
* @param isLabels add label if true
* @param isOptional add optional attributes if true
* @param isXattr add xattr if true
* @param isChecksum add checksums if true
* @param request to check for client info
* @param poolMonitor for access to remote PoolMonitor
*/
public static void chimeraToJsonAttributes(String name, JsonFileAttributes json, FileAttributes attributes, boolean isLocality, boolean isLocations, boolean isLabels, boolean isOptional, boolean isXattr, boolean isChecksum, HttpServletRequest request, PoolMonitor poolMonitor) throws CacheException {
json.setPnfsId(attributes.getPnfsId());
if (attributes.isDefined(FileAttribute.NLINK)) {
json.setNlink(attributes.getNlink());
}
if (attributes.isDefined(FileAttribute.MODIFICATION_TIME)) {
json.setMtime(attributes.getModificationTime());
}
if (attributes.isDefined(FileAttribute.CREATION_TIME)) {
json.setCreationTime(attributes.getCreationTime());
}
if (attributes.isDefined(FileAttribute.SIZE)) {
json.setSize(attributes.getSize());
}
if (attributes.isDefined(FileAttribute.MODE)) {
json.setMode(attributes.getMode());
}
FileType fileType = null;
if (attributes.isDefined(FileAttribute.TYPE)) {
fileType = attributes.getFileType();
json.setFileType(fileType);
json.setFileMimeType(mimeTypeOf(name, attributes));
}
// the locality should be returned only for directories
if ((isLocality) && fileType != FileType.DIR) {
String client = request.getRemoteHost();
FileLocality fileLocality = poolMonitor.getFileLocality(attributes, client);
json.setFileLocality(fileLocality);
}
if (isLocations) {
if (attributes.isDefined(FileAttribute.LOCATIONS)) {
json.setLocations(attributes.getLocations());
}
}
if (isOptional) {
addAllOptionalAttributes(json, attributes);
}
if (isXattr) {
Map<String, String> xattr = attributes.getXattrs();
json.setExtendedAttributes(xattr);
}
if (isChecksum) {
if (attributes.isDefined(FileAttribute.CHECKSUM)) {
json.setChecksums(attributes.getChecksums());
}
}
if (isLabels) {
if (attributes.isDefined(FileAttribute.LABELS)) {
json.setLabels(attributes.getLabels());
}
}
}
use of diskCacheV111.util.FileLocality in project dcache by dCache.
the class PoolMonitorV5 method getFileLocality.
@Override
public FileLocality getFileLocality(FileAttributes attributes, String hostName) {
if (attributes.getFileType() == FileType.DIR || !attributes.isDefined(SIZE)) {
return FileLocality.NONE;
}
PoolPreferenceLevel[] levels = _selectionUnit.match(DirectionType.READ, hostName, "*/*", attributes, null, s -> false);
Collection<String> locations = attributes.getLocations();
for (PoolPreferenceLevel level : levels) {
if (!Collections.disjoint(level.getPoolList(), locations)) {
return (attributes.getStorageInfo().isStored() ? FileLocality.ONLINE_AND_NEARLINE : FileLocality.ONLINE);
}
}
if (attributes.getStorageInfo().isStored()) {
return FileLocality.NEARLINE;
}
for (String name : locations) {
PoolSelectionUnit.SelectionPool pool = _selectionUnit.getPool(name);
if (pool == null || !pool.canReadForP2P()) {
continue;
}
PoolCostInfo cost = _costModule.getPoolCostInfo(name);
if (cost == null) {
continue;
}
// SelectionPool.canReadForP2P
if (cost.getP2pQueue().getMaxActive() > 0) {
return FileLocality.NEARLINE;
}
}
return FileLocality.UNAVAILABLE;
}
Aggregations