Skip to content

Commit

Permalink
pnfsmanager: Create base upload directories without tags and acls
Browse files Browse the repository at this point in the history
Motivation:

Temporary upload directories get the tags and ACLs of the actual target
directory (mostly) rather than the inherited tags and ACLs from the base upload
directory. Yet we have triggers that needlesly copy the tags and ACLs from the
base directory.

Modification:

When first creating the base upload directories, these are created without
ACLs and tags, i.e. without inheriting those from their parent directory.

Result:

Faster creation of temporary upload directories because we do not have to
copy ACLs and tags that will be immediately deleted. The patch will not
affect existing base upload directories, as the change only has an effect
when initially creating them.

Target: trunk
Require-notes: yes
Require-book: no
Request: 2.13
Request: 2.12
Request: 2.11
Request: 2.10
Acked-by: Paul Millar <paul.millar@desy.de>
Patch: https://rb.dcache.org/r/8305/
(cherry picked from commit fae7341)
  • Loading branch information
gbehrmann committed Jun 15, 2015
1 parent b5a9992 commit e98b145
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 35 deletions.
12 changes: 12 additions & 0 deletions modules/chimera/src/main/java/org/dcache/chimera/FsInode.java
Expand Up @@ -18,6 +18,10 @@

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.dcache.acl.ACE;
import org.dcache.chimera.posix.Stat;

/**
Expand Down Expand Up @@ -317,6 +321,14 @@ public FsInode mkdir(String name, int owner, int group, int mode) throws Chimera
return _fs.mkdir(this, name, owner, group, mode);
}

/**
* crate a directory with name 'newDir' in current inode with different access rights
*/
public FsInode mkdir(String name, int owner, int group, int mode, List<ACE> acl, Map<String, byte[]> tags)
throws ChimeraFsException {
return _fs.mkdir(this, name, owner, group, mode, acl, tags);
}

/**
* get inode of file in the current directory with name 'name'
*/
Expand Down
70 changes: 36 additions & 34 deletions modules/chimera/src/main/java/org/dcache/chimera/FsSqlDriver.java
Expand Up @@ -2003,41 +2003,43 @@ boolean isTagOwner(Connection dbConnection, FsInode dir, String tagName) throws
void createTags(Connection dbConnection, FsInode inode, int uid, int gid, int mode, Map<String, byte[]> tags)
throws SQLException
{
PreparedStatement stmt = null;
try {
Map<String,String> ids = new HashMap<>();
Timestamp now = new Timestamp(System.currentTimeMillis());

stmt = dbConnection.prepareStatement("INSERT INTO t_tags_inodes VALUES(?,?,1,?,?,?,?,?,?,?)");
for (Map.Entry<String, byte[]> tag : tags.entrySet()) {
String id = UUID.randomUUID().toString().toUpperCase();
ids.put(tag.getKey(), id);
byte[] value = tag.getValue();
int len = value.length;
stmt.setString(1, id);
stmt.setInt(2, mode | UnixPermission.S_IFREG);
stmt.setInt(3, uid);
stmt.setInt(4, gid);
stmt.setLong(5, len);
stmt.setTimestamp(6, now);
stmt.setTimestamp(7, now);
stmt.setTimestamp(8, now);
stmt.setBinaryStream(9, new ByteArrayInputStream(value), len);
stmt.addBatch();
}
stmt.executeBatch();
stmt.close();

stmt = dbConnection.prepareStatement("INSERT INTO t_tags VALUES(?,?,?,1)");
for (Map.Entry<String, String> tag : ids.entrySet()) {
stmt.setString(1, inode.toString()); // ipnfsid
stmt.setString(2, tag.getKey()); // itagname
stmt.setString(3, tag.getValue()); // itagid
stmt.addBatch();
if (!tags.isEmpty()) {
PreparedStatement stmt = null;
try {
Map<String, String> ids = new HashMap<>();
Timestamp now = new Timestamp(System.currentTimeMillis());

stmt = dbConnection.prepareStatement("INSERT INTO t_tags_inodes VALUES(?,?,1,?,?,?,?,?,?,?)");
for (Map.Entry<String, byte[]> tag : tags.entrySet()) {
String id = UUID.randomUUID().toString().toUpperCase();
ids.put(tag.getKey(), id);
byte[] value = tag.getValue();
int len = value.length;
stmt.setString(1, id);
stmt.setInt(2, mode | UnixPermission.S_IFREG);
stmt.setInt(3, uid);
stmt.setInt(4, gid);
stmt.setLong(5, len);
stmt.setTimestamp(6, now);
stmt.setTimestamp(7, now);
stmt.setTimestamp(8, now);
stmt.setBinaryStream(9, new ByteArrayInputStream(value), len);
stmt.addBatch();
}
stmt.executeBatch();
stmt.close();

stmt = dbConnection.prepareStatement("INSERT INTO t_tags VALUES(?,?,?,1)");
for (Map.Entry<String, String> tag : ids.entrySet()) {
stmt.setString(1, inode.toString()); // ipnfsid
stmt.setString(2, tag.getKey()); // itagname
stmt.setString(3, tag.getValue()); // itagid
stmt.addBatch();
}
stmt.executeBatch();
} finally {
SqlHelper.tryToClose(stmt);
}
stmt.executeBatch();
} finally {
SqlHelper.tryToClose(stmt);
}
}

Expand Down
Expand Up @@ -1085,6 +1085,25 @@ private ExtendedInode mkdir(Subject subject, ExtendedInode parent, String name,
return parent.mkdir(name, uid, gid, mode);
}

private ExtendedInode installSystemDirectory(FsPath path, int mode, List<ACE> acl, Map<String, byte[]> tags)
throws ChimeraFsException, CacheException
{
ExtendedInode inode;
try {
inode = lookupDirectory(Subjects.ROOT, path);
} catch (FileNotFoundCacheException e) {
ExtendedInode parentOfPath = installDirectory(Subjects.ROOT, path.getParent(), 0, 0, mode);
try {
inode = parentOfPath.mkdir(path.getName(), 0, 0, mode, acl, tags);
} catch (FileExistsChimeraFsException e1) {
/* Concurrent directory creation. Do another lookup.
*/
inode = lookupDirectory(Subjects.ROOT, path);
}
}
return inode;
}

private ExtendedInode installDirectory(Subject subject, FsPath path, int uid, int gid, int mode) throws ChimeraFsException, CacheException
{
ExtendedInode inode;
Expand Down Expand Up @@ -1226,7 +1245,7 @@ public FsPath createUploadPath(Subject subject, FsPath path, FsPath rootPath,

/* Upload directory must exist and have the right permissions.
*/
FsInode inodeOfUploadDir = installDirectory(Subjects.ROOT, uploadDirectory, 0, 0, 0711);
FsInode inodeOfUploadDir = installSystemDirectory(uploadDirectory, 0711, Collections.emptyList(), Collections.emptyMap());
if (inodeOfUploadDir.statCache().getUid() != 0) {
_log.error("Owner must be root: {}", uploadDirectory);
throw new CacheException("Owner must be root: " + uploadDirectory);
Expand Down
Expand Up @@ -28,13 +28,15 @@

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import diskCacheV111.util.AccessLatency;
import diskCacheV111.util.FsPath;
import diskCacheV111.util.PnfsId;
import diskCacheV111.util.RetentionPolicy;

import org.dcache.acl.ACE;
import org.dcache.acl.ACL;
import org.dcache.acl.enums.RsType;
import org.dcache.chimera.ChimeraFsException;
Expand Down Expand Up @@ -122,6 +124,13 @@ public ExtendedInode mkdir(String name, int owner, int group, int mode) throws C
return new ExtendedInode(this, super.mkdir(name, owner, group, mode));
}

@Override
public ExtendedInode mkdir(String name, int owner, int group, int mode, List<ACE> acl, Map<String, byte[]> tags)
throws ChimeraFsException
{
return new ExtendedInode(this, super.mkdir(name, owner, group, mode, acl, tags));
}

@Override
public ExtendedInode create(String name, int uid, int gid, int mode) throws ChimeraFsException
{
Expand Down

0 comments on commit e98b145

Please sign in to comment.