Each object in the Pnfs Namespace owns a unique ID. This ID consists of 96 bits. The highest two bytes specify the database ID and the lowest three bits specify whether the object is virtual or persistent. All objects which actually reside in one of the databases must have the last three bits zero. The result is that a system can't hold more then 64K of databases and one database can not have more then 2 to the power of 77 entries. PnfsIDs are not reused.
The pnfsID of a file or a directory inside pnfs can by obtained by reading from .(id)(<ObjectName>) were <ObjectName> is the name of the file or directory. This syntax only is valid if the object resides in the current working directory or if specified as last item of the path string.Example
cd /pnfs/fs/usr/patrick touch waste cat .(id)(waste) or cd /tmp touch /pnfs/fs/usr/patrick/waste cat /pnfs/fs/usr/patrick/.(id)(waste)
Generally it's not possible to get the full path of a given pnfsID because the full path depends on the mountpoint, and the mountpoint is not known by the nfs server. But there is a way to obtain the path of the pfnsID seen from the database itself. The path has to be requested step by step. First you need to get the objectname itself. The name is the result of reading from .(nameof)(<pnfsID>). Now you need the pnfsID of the parent directory. This ID is only defined because pnfs doesn't allow hard links. To get the parent pnfsID read from .(parent)(<pnfsID>). Now you can get the name of the parent directory by using (nameof) of the parentDirectoryID, and so forth. There is a tools called pathfinder which follows exactly this procedure. The printout is shown in the example below. First it iterates down to the database root and then it assembles the full path. This path of course doesn't exist on a host, it is the way the database sees the world. To map it to the local mounted condition, you need to know the pnfsID where the mount starts. See the next section for that.Example
# cd /pnfs/fs/usr/usr/patrick # touch waste # pathfinder waste 000100000000000000015700 waste 000100000000000000015220 patrick 000100000000000000001060 usr 000000000000000000001080 usr 000000000000000000001040 fs 000000000000000000001020 root 000000000000000000001000 - 000000000000000000000100 - 000000000000000000000000 - /root/fs/usr/usr/patrick/waste #
The current position inside pnfs is defined by the pnfsID and pnfs Permission of the current directory and the pnfsID for the mount. Those three values can be read from.(get)(cursor). See the example for the format. If you compare the mountID with the list from pathfinder you will find the point where the path of pnfs ends and the local path starts. Example
# pwd /pnfs/fs/usr/usr/patrick # cat .(get)(cursor) dirID=000100000000000000015220 dirPerm=0000001400000000 mountID=000000000000000000001040 #
The size of a fileentry which will only be used as a reference to a tapefile can be set by the .(fset) command. The file has to exist and must have zero bytes. Let's say the filename is <filename> then the creation of .(fset)(<filename>)(size)(<size>) will set the size of <filename> to <size> bytes. In a shell script touch will do and in an application you need to open the file with O_CREAT. Trying to change the size with a second open or create will be silently ignored. To change the filesize the pseodofile .(fset)(<filename>)(size) has to be removed first.Example
# pwd /pnfs/fs/usr/usr/patrick # touch waste # touch .(fset)(waste)(size)(123456) # ls -l waste -rw-r--r-- 1 root sys 123456 Jan 22 18:28 waste # touch .(fset)(waste)(size)(123) # ls -l waste -rw-r--r-- 1 root sys 123456 Jan 22 18:28 waste # rm .(fset)(waste)(size) # ls -l waste -rw-r--r-- 1 root sys 0 Jan 22 18:28 waste # touch .(fset)(waste)(size)(123) # ls -l waste -rw-r--r-- 1 root sys 123 Jan 22 18:28 waste #
When mounting the pnfs filesystem the first time, there is only one entry into the system (/pnfs/fs) which resides on the admin database. To make use of other databases there must be link created from the admin to the new one. This link can be produced, using the standard unix mkdir command.Syntax : mkdir .(<databaseId>)(<directoryName>)
REMARK : Eventually this mkdir command returns some error like Directory already exists. Nevertheless, the directory has been created sucessfully on the correct database.
The subdirectory <directoryName> will now point to the database with the ID <databaseId>. Use mdb show to determine the databaseIDs.
Although it is possible to create these links from each database to each other database and to create an arbitrary amount of links to each database it is wise to setup the links in a very simple manner, mainly one link from the admin database ( /pnfs/fs/usr ) to each group database.Example
Create a subdirectory for group hermes and create a new database for this group.root@watphrakeo:/ > . /usr/etc/pnfsSetup root@watphrakeo:/ > PATH=$PATH:$pnfs/tools root@watphrakeo:/ > mdb create hermes /needSpaceForHermes/hermesDbFile root@watphrakeo:/ > mdb update Starting hermes root@watphrakeo:/ > mdb show ID Name Type Status Path ---------------------------------------------- 0 admin r enabled (r) /uss/db/info.x/admin 1 user1 r enabled (r) /uss/db/info.x/user-db-1 2 hermes r enabled (r) /uss/db/info.x/hermesDbFile # # The ID of the hermes database seems to be 2. # root@watphrakeo:/ > cd /pnfs/fs/usr root@watphrakeo:/ > mkdir .(2)(hermes) # # check if everything went o.k. # root@watphrakeo:/ > cd hermes root@watphrakeo:/ > touch waste root@watphrakeo:/ > cat .(id)(waste) 000200000000000000001060 root@watphrakeo:/ >000200000000000000001060 indicates that the new directory resides on database 2.