Skip to content

Commit

Permalink
nfs: add functionallity to do ls on file labels
Browse files Browse the repository at this point in the history
Motivation

this is the work continuing an  experemental test to add listing on labels for all protocols in dCache.

This patch add the changes only for nfs.

Result

this is still work in progress.

it is possible to do ls for labels:

[marina@zitpcx35188 dcache]$ ls  -l /mnt/".(collection)(red)"
total 1
-rw-r--r--. 1 marina marina 387 Apr 24 17:43 test_1.log-7
-rw-r--r--. 1 marina marina 387 Apr 24 17:43 test_2.log-7

Target: master
Require-book: yes
Require-notes: yes
Act-by: Tigran Mkrtchyan
  • Loading branch information
mksahakyan committed Jul 19, 2024
1 parent 9655c37 commit 03a27be
Show file tree
Hide file tree
Showing 8 changed files with 276 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,15 @@ enum SetXattrMode {
Set<String> getLabels(FsInode inode) throws ChimeraFsException;


/**
* Returns the Label name.
*
* @param ino of a file.
* @throws ChimeraFsException
*/
String getLabelById(long ino) throws ChimeraFsException;


/**
* Delete a given labels of a given file system object.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,21 @@
*/
package org.dcache.chimera;

import java.util.Set;

public class FsInode_LABEL extends FsInode {

public String getLabel() {
return _label;
}

private final String _label;

/**
* @param fs pointer to 'File System'
* @param ino inode number of the label_id
* @param label
*/
public FsInode_LABEL(FileSystemProvider fs, long ino, String label) {
public FsInode_LABEL(FileSystemProvider fs, long ino) {
super(fs, ino, FsInodeType.LABEL);
_label = label;
}

@Override
public boolean exists() {
boolean rc = false;
try {
Set<String> list = _fs.getLabels(this);
if (list.contains(_label)) {
if (!_fs.getLabelById(ino()).isEmpty()) {
rc = true;
}
} catch (Exception e) {
Expand Down
91 changes: 82 additions & 9 deletions modules/chimera/src/main/java/org/dcache/chimera/FsSqlDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -386,6 +387,12 @@ public Stat stat(FsInode inode) {
}

public Stat stat(FsInode inode, int level) {
if (inode.type() == FsInodeType.LABEL) {
return _jdbc.query(
"SELECT * FROM t_labels_ref where label_id=?",
ps -> ps.setLong(1, inode.ino()),
rs -> rs.next() ? toStatForLabel(rs) : null);
}
if (level == 0) {
return _jdbc.query(
"SELECT * FROM t_inodes WHERE inumber=?",
Expand All @@ -399,6 +406,53 @@ public Stat stat(FsInode inode, int level) {
}
}

private Stat toStatForLabel(ResultSet rs) throws SQLException {
Timestamp now = new Timestamp(System.currentTimeMillis());
Stat stat = new Stat();
// TODO create fake pnfsid for label
String pnfsIdSecond = "0000000000000000";
String pnfsIdThird = "F0000000000000000000";
int lenghtLabelId = ("F" + rs.getLong("label_id") + "A").length();
String temp = "F" + rs.getLong("label_id") + "A";
String replace = pnfsIdThird.substring(0, lenghtLabelId);
String pnfsID = pnfsIdSecond + pnfsIdThird.replaceAll(replace, temp);
stat.setIno(rs.getLong("label_id"));
// TODO could be changed latter or should be deleted
stat.setId(pnfsID);
stat.setCrTime(now.getTime());
stat.setGeneration(LocalDateTime.now().getMinute());
stat.setSize(512);
stat.setATime(now.getTime());
stat.setCTime(now.getTime());
stat.setMTime(now.getTime());
stat.setUid(0000);
stat.setGid(0000);
stat.setMode(0755 | UnixPermission.S_IFDIR);
stat.setDev(19);
stat.setRdev(23);
stat.setNlink(13);
return stat;
}


/**
* Returns the Label name.
*
* @param labelId of a label.
* @throws ChimeraFsException
*/
String getLabelById(Long labelId) throws ChimeraFsException {
try {
return _jdbc.queryForObject("SELECT labelname FROM t_labels where label_id=?",
(rs, rn) -> {
return (rs.getString("labelname"));
}, labelId);

} catch (EmptyResultDataAccessException e) {
throw new NoLabelChimeraException("wrong id");
}
}

private Stat toStat(ResultSet rs) throws SQLException {
Stat stat = new Stat();
stat.setIno(rs.getLong("inumber"));
Expand Down Expand Up @@ -543,13 +597,28 @@ FsInode inodeOf(FsInode parent, String name, StatCacheOption stat) {
rs -> rs.next() ? new FsInode(parent.getFs(), rs.getLong("inumber"),
FsInodeType.INODE, 0, toStat(rs)) : null);
} else {
return _jdbc.query("SELECT ichild FROM t_dirs WHERE iparent=? AND iname=?",
ps -> {
ps.setLong(1, parent.ino());
ps.setString(2, name);
},
rs -> rs.next() ? new FsInode(parent.getFs(), rs.getLong("ichild"))
: null);

Long parentIno;
String nameChild;
int prefixParent = name.lastIndexOf("-");
if (parent.type() == FsInodeType.LABEL) {

parentIno = Long.valueOf(
name.substring( prefixParent + 1, name.length()));
nameChild = name.substring(0, prefixParent);
}else {
parentIno = parent.ino();
nameChild = name;

}
return _jdbc.query("SELECT ichild FROM t_dirs WHERE iparent=? AND iname=?",
ps -> {
ps.setLong(1, parentIno);
ps.setString(2, nameChild);
},
rs -> rs.next() ? new FsInode(parent.getFs(), rs.getLong("ichild"))
: null);

}
}
}
Expand Down Expand Up @@ -2138,11 +2207,15 @@ void removeXattr(FsInode inode, String attr) throws ChimeraFsException {
setInodeAttributes(inode, 0, new Stat());
}

Long getLabel(String labelname) {
return _jdbc.queryForObject("SELECT label_id FROM t_labels where labelname=?",
Long getLabel(String labelname) throws NoLabelChimeraException {
try {
return _jdbc.queryForObject("SELECT label_id FROM t_labels where labelname=?",
(rs, rn) -> {
return (rs.getLong("label_id"));
}, labelname);
} catch (EmptyResultDataAccessException e) {
throw new NoLabelChimeraException("wrong label");
}

}

Expand Down
18 changes: 9 additions & 9 deletions modules/chimera/src/main/java/org/dcache/chimera/JdbcFs.java
Original file line number Diff line number Diff line change
Expand Up @@ -539,9 +539,8 @@ public void createFileWithId(FsInode parent, String id, String name, int owner,
@Override
public DirectoryStreamB<ChimeraDirectoryEntry> newDirectoryStream(FsInode dir)
throws ChimeraFsException {
if ((dir instanceof FsInode_LABEL)) {
//TODO the casting to FsInode_LABEL should be reconsidered
return _sqlDriver.virtualDirectoryStream(dir, ((FsInode_LABEL) dir).getLabel());
if ((dir.type() == FsInodeType.LABEL)) {
return _sqlDriver.virtualDirectoryStream(dir, _sqlDriver.getLabelById(dir.ino()));
} else {
return _sqlDriver.newDirectoryStream(dir);
}
Expand Down Expand Up @@ -621,7 +620,7 @@ public Stat stat(FsInode inode, int level) throws ChimeraFsException {
if (stat == null) {
throw FileNotFoundChimeraFsException.of(inode);
}
if (level == 0) {
if (level == 0 ){
_inoCache.put(stat.getId(), stat.getIno());
_idCache.put(stat.getIno(), stat.getId());
}
Expand Down Expand Up @@ -747,7 +746,6 @@ public String inode2id(FsInode inode) throws ChimeraFsException {
throw new RuntimeException(e.getCause());
}
}

@Override
public FsInode id2inode(String id, StatCacheOption option) throws ChimeraFsException {
if (option == NO_STAT) {
Expand Down Expand Up @@ -873,8 +871,7 @@ public FsInode inodeOf(FsInode parent, String name, StatCacheOption cacheOption)
if (cmd.length != 2) {
throw FileNotFoundChimeraFsException.ofFileInDirectory(parent, name);
}

FsInode labelInode = new FsInode_LABEL(this, _sqlDriver.getLabel(cmd[1]), cmd[1]);
FsInode labelInode = new FsInode_LABEL(this, _sqlDriver.getLabel(cmd[1]));
if (!(labelInode.type() == FsInodeType.LABEL)) {
if (!labelInode.exists()) {
throw FileNotFoundChimeraFsException.ofFileInDirectory(parent, name);
Expand Down Expand Up @@ -1570,13 +1567,16 @@ public void addLabel(FsInode inode, String labelname) throws ChimeraFsException
return null;
});
}


@Override
public Set<String> getLabels(FsInode inode) throws ChimeraFsException {
return inTransaction(status -> _sqlDriver.getLabels(inode));
}

@Override
public String getLabelById(long ino) throws ChimeraFsException {
return inTransaction(status -> _sqlDriver.getLabelById(ino));
}

@Override
public void removeLabel(FsInode inode, String labelname) throws ChimeraFsException {
inTransaction(status -> {
Expand Down
6 changes: 6 additions & 0 deletions modules/dcache-nfs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,11 @@
<groupId>org.dcache</groupId>
<artifactId>nfs4j-core</artifactId>
</dependency>

<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.dcache.chimera.FsInode_CKSTYP;
import org.dcache.chimera.FsInode_CONST;
import org.dcache.chimera.FsInode_ID;
import org.dcache.chimera.FsInode_LABEL;
import org.dcache.chimera.FsInode_NAMEOF;
import org.dcache.chimera.FsInode_PARENT;
import org.dcache.chimera.FsInode_PATHOF;
Expand All @@ -71,6 +72,7 @@
import org.dcache.chimera.InvalidArgumentChimeraException;
import org.dcache.chimera.IsDirChimeraException;
import org.dcache.chimera.JdbcFs;
import org.dcache.chimera.NoLabelChimeraException;
import org.dcache.chimera.NoXdataChimeraException;
import org.dcache.chimera.NotDirChimeraException;
import org.dcache.chimera.PermissionDeniedChimeraFsException;
Expand Down Expand Up @@ -202,6 +204,8 @@ public Inode lookup(Inode parent, String path) throws IOException {
return toInode(fsInode);
} catch (FileNotFoundChimeraFsException e) {
throw new NoEntException("Path Do not exist.");
} catch (NoLabelChimeraException e) {
throw new NoEntException("Label Do not exist.");
}
}

Expand Down Expand Up @@ -348,7 +352,6 @@ public DirectoryStream list(Inode inode, byte[] verifier, long cookie) throws IO
directoryCookieOf(e.getStat(), e.getName()))
)
.collect(Collectors.toCollection(TreeSet::new));

return new DirectoryStream(currentVerifier, list);
}
}
Expand Down Expand Up @@ -960,6 +963,10 @@ public static FsInode inodeFromBytes(FileSystemProvider fs, byte[] handle)
inode = new FsInode_CKSTYP(fs, ino);
break;

case LABEL:
inode = new FsInode_LABEL(fs, ino);
break;

default:
throw new BadHandleException("Unsupported file handle type: " + inodeType);
}
Expand Down
Loading

0 comments on commit 03a27be

Please sign in to comment.