use of diskCacheV111.services.space.Space in project dcache by dCache.
the class NFSv41Door method getDeviceInfo.
// NFSv41DeviceManager interface
/*
The most important calls is LAYOUTGET, OPEN, CLOSE, LAYOUTRETURN
The READ, WRITE and COMMIT goes to storage device.
We assume the following mapping between nfs and dcache:
NFS | dCache
_____________|________________________________________
LAYOUTGET : get pool, bind the answer to the client
OPEN : send IO request to the pool
CLOSE : sent end-of-IO to the pool, LAYOUTRECALL
LAYOUTRETURN : unbind pool from client
*/
@Override
public device_addr4 getDeviceInfo(CompoundContext context, GETDEVICEINFO4args args) throws ChimeraNFSException {
layouttype4 layoutType = layouttype4.valueOf(args.gdia_layout_type);
LayoutDriver layoutDriver = getLayoutDriver(layoutType);
PoolDS ds = _poolDeviceMap.getByDeviceId(args.gdia_device_id);
if (ds == null) {
return null;
}
// limit addresses returned to client to the same 'type' as clients own address
// NOTICE: according to rfc1918 we allow access to private networks from public ip address
// Site must take care that private IP space is not visible to site external clients.
InetAddress clientAddress = context.getRemoteSocketAddress().getAddress();
InetSocketAddress[] usableAddresses = Stream.of(ds.getDeviceAddr()).filter(a -> !a.getAddress().isLoopbackAddress() || clientAddress.isLoopbackAddress()).filter(a -> !a.getAddress().isLinkLocalAddress() || clientAddress.isLinkLocalAddress()).filter(a -> clientAddress.getAddress().length >= a.getAddress().getAddress().length).toArray(InetSocketAddress[]::new);
return layoutDriver.getDeviceAddress(usableAddresses);
}
use of diskCacheV111.services.space.Space in project dcache by dCache.
the class ConsistentReplicaStore method get.
/**
* Retrieves a CacheRepositoryEntry from the wrapped meta data store. If the entry is missing or
* fails consistency checks, the entry is reconstructed with information from PNFS.
*/
@Override
public ReplicaRecord get(PnfsId id) throws IllegalArgumentException, CacheException {
ReplicaRecord entry = _replicaStore.get(id);
if (entry != null && isBroken(entry)) {
LOGGER.warn("Recovering {}...", id);
try {
/* It is safe to remove FROM_STORE/FROM_POOL replicas: We have
* another copy anyway. Files in REMOVED or DESTROYED
* were about to be deleted, so we can finish the job.
*/
switch(entry.getState()) {
case FROM_POOL:
case FROM_STORE:
case REMOVED:
case DESTROYED:
_replicaStore.remove(id);
_pnfsHandler.clearCacheLocation(id);
LOGGER.info("Recovering: Removed {} because it was not fully staged.", id);
return null;
}
entry = rebuildEntry(entry);
} catch (IOException e) {
throw new DiskErrorCacheException("I/O error in healer: " + messageOrClassName(e), e);
} catch (FileNotFoundCacheException e) {
_replicaStore.remove(id);
LOGGER.warn("Recovering: Removed {} because name space entry was deleted.", id);
return null;
} catch (FileIsNewCacheException e) {
_replicaStore.remove(id);
LOGGER.warn("Recovering: Removed {}: {}", id, e.getMessage());
return null;
} catch (TimeoutCacheException e) {
throw e;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new CacheException("Pool is shutting down", e);
} catch (CacheException | NoSuchAlgorithmException e) {
entry.update("Failed to recover replica: " + e.getMessage(), r -> r.setState(ReplicaState.BROKEN));
LOGGER.error(AlarmMarkerFactory.getMarker(PredefinedAlarm.BROKEN_FILE, id.toString(), _poolName), "Marked {} bad: {}.", id, e.getMessage());
}
}
return entry;
}
use of diskCacheV111.services.space.Space in project dcache by dCache.
the class ConsistentReplicaStoreTest method shouldDeleteBrokenReplicasWithNoNameSpaceEntry.
@Test
public void shouldDeleteBrokenReplicasWithNoNameSpaceEntry() throws Exception {
// Given a replica with no meta data
givenStoreHasFileOfSize(PNFSID, 17);
// and given the name space entry does not exist
given(_pnfs.getFileAttributes(eq(PNFSID), Mockito.anySet())).willThrow(new FileNotFoundCacheException("No such file"));
// when reading the meta data record
ReplicaRecord record = _consistentReplicaStore.get(PNFSID);
// then recovery is attempted
verify(_pnfs).getFileAttributes(eq(PNFSID), Mockito.anySet());
// but nothing is returned
assertThat(record, is(nullValue()));
// and the replica is deleted
assertThat(_replicaStore.get(PNFSID), is(nullValue()));
assertThat(_fileStore.contains(PNFSID), is(false));
// and the name space entry is not touched
verify(_pnfs, never()).setFileAttributes(eq(PNFSID), Mockito.any(FileAttributes.class));
}
use of diskCacheV111.services.space.Space in project dcache by dCache.
the class ChimeraNameSpaceProvider method createUploadPath.
@Override
public FsPath createUploadPath(Subject subject, FsPath path, FsPath rootPath, Long size, AccessLatency al, RetentionPolicy rp, String spaceToken, Set<CreateOption> options) throws CacheException {
checkState(_uploadDirectory != null, "Upload directory is not configured.");
try {
/* Parent directory must exist.
*/
ExtendedInode parentOfPath = options.contains(CreateOption.CREATE_PARENTS) ? installDirectory(subject, path.parent(), INHERIT_MODE) : lookupDirectory(subject, path.parent());
FileAttributes attributesOfParent = !Subjects.isExemptFromNamespaceChecks(subject) ? getFileAttributesForPermissionHandler(parentOfPath) : null;
/* File must not exist unless overwrite is enabled.
*/
try {
ExtendedInode inodeOfPath = parentOfPath.inodeOf(path.name(), STAT);
if (!options.contains(CreateOption.OVERWRITE_EXISTING) || (inodeOfPath.statCache().getMode() & UnixPermission.S_TYPE) != UnixPermission.S_IFREG) {
throw new FileExistsCacheException("File exists: " + path);
}
/* User must be authorized to delete existing file.
*/
if (!Subjects.isExemptFromNamespaceChecks(subject)) {
FileAttributes attributesOfPath = getFileAttributesForPermissionHandler(inodeOfPath);
if (_permissionHandler.canDeleteFile(subject, attributesOfParent, attributesOfPath) != ACCESS_ALLOWED) {
throw new PermissionDeniedCacheException("Access denied: " + path);
}
}
} catch (FileNotFoundChimeraFsException ignored) {
}
/* User must be authorized to create file.
*/
if (!Subjects.isExemptFromNamespaceChecks(subject)) {
if (_permissionHandler.canCreateFile(subject, attributesOfParent) != ACCESS_ALLOWED) {
throw new PermissionDeniedCacheException("Access denied: " + path);
}
}
/* Attributes are inherited from real parent directory.
*/
int mode = parentOfPath.statCache().getMode() & UnixPermission.S_PERMS;
int gid;
if ((mode & UnixPermission.S_ISGID) != 0) {
gid = parentOfPath.statCache().getGid();
} else if (Subjects.isNobody(subject) || _inheritFileOwnership) {
gid = parentOfPath.statCache().getGid();
} else {
gid = Ints.checkedCast(Subjects.getPrimaryGid(subject));
}
int uid;
if (Subjects.isNobody(subject) || _inheritFileOwnership) {
uid = parentOfPath.statCache().getUid();
} else {
uid = Ints.checkedCast(Subjects.getUid(subject));
}
/* ACLs are copied from real parent to the temporary upload directory
* such that the upload is allowed (in case write permissions rely
* on ACLs) and such that the file will inherit the correct ACLs.
*/
List<ACE> acl = _fs.getACL(parentOfPath);
/* The temporary upload directory has the same tags as the real parent,
* except target file specific properties are stored as tags local to
* the upload directory.
*/
Map<String, byte[]> tags = Maps.newHashMap(parentOfPath.getTags());
if (spaceToken != null) {
tags.put(TAG_WRITE_TOKEN, spaceToken.getBytes(UTF_8));
/* If client provides space token to upload to, the access latency and
* retention policy tags of the upload directory must be disregarded.
*/
tags.remove(TAG_ACCESS_LATENCY);
tags.remove(TAG_RETENTION_POLICY);
}
if (al != null) {
tags.put(TAG_ACCESS_LATENCY, al.toString().getBytes(UTF_8));
}
if (rp != null) {
tags.put(TAG_RETENTION_POLICY, rp.toString().getBytes(UTF_8));
}
if (size != null) {
tags.put(TAG_EXPECTED_SIZE, size.toString().getBytes(UTF_8));
}
tags.put(TAG_PATH, path.toString().getBytes(UTF_8));
/* Upload directory may optionally be relative to the user's root path. Whether
* that's the case depends on if the configured upload directory is an absolute
* or relative path.
*/
FsPath uploadDirectory = rootPath.resolve(_uploadDirectory);
if (_uploadSubDirectory != null) {
uploadDirectory = uploadDirectory.chroot(String.format(_uploadSubDirectory, threadId.get()));
}
/* Upload directory must exist and have the right permissions.
*/
ExtendedInode inodeOfUploadDir = installSystemDirectory(uploadDirectory, 0711, Collections.emptyList(), Collections.emptyMap());
if (inodeOfUploadDir.statCache().getUid() != 0) {
LOGGER.error("Owner must be root: {}", uploadDirectory);
throw new CacheException("Owner must be root: " + uploadDirectory);
}
if ((inodeOfUploadDir.statCache().getMode() & UnixPermission.S_PERMS) != 0711) {
LOGGER.error("File mode must be 0711: {}", uploadDirectory);
throw new CacheException("File mode must be 0711: " + uploadDirectory);
}
/* Use cryptographically strong pseudo random UUID to create temporary upload directory.
*/
UUID uuid = UUID.randomUUID();
_fs.mkdir(inodeOfUploadDir, uuid.toString(), uid, gid, mode, acl, tags);
return uploadDirectory.child(uuid.toString()).child(path.name());
} catch (ChimeraFsException e) {
LOGGER.error("Problem with database: {}", e.getMessage());
throw new CacheException(CacheException.UNEXPECTED_SYSTEM_EXCEPTION, e.getMessage());
}
}
use of diskCacheV111.services.space.Space in project dcache by dCache.
the class CostModuleTest method buildPoolUpMessageWithCost.
/**
* Create a pool-up message for a pool with the given space parameters
*
* @param poolName name of the pool
* @param totalSpace total capacity of the pool in Gigabytes
* @param freeSpace space not yet used in Gigabytes
* @param preciousSpace space used by files marked precious in Gigabytes
* @param removableSpace space used by files that are removable in Gigabytes
* @return
*/
private static PoolManagerPoolUpMessage buildPoolUpMessageWithCost(String poolName, long totalSpace, long freeSpace, long preciousSpace, long removableSpace) {
PoolV2Mode poolMode = new PoolV2Mode(PoolV2Mode.ENABLED);
PoolCostInfo poolCost = new PoolCostInfo(poolName, IoQueueManager.DEFAULT_QUEUE);
poolCost.setSpaceUsage(GiB.toBytes(totalSpace), GiB.toBytes(freeSpace), GiB.toBytes(preciousSpace), GiB.toBytes(removableSpace));
long serialId = System.currentTimeMillis();
return new PoolManagerPoolUpMessage(poolName, serialId, poolMode, poolCost);
}
Aggregations