On Nov 2, 4:58am, Jeffrey T. Hutzelman wrote:
> Subject: Perl interface to cache manager?
> Has anyone gone to the trouble of putting together a perl-based interface
> to the various cache manager calls? I'm currently performing several
> operatios by parsing the output of "fs" commands, but I'd much rather
> use a direct interface.
>
Funny you should ask :-) I'm in the process of writing a Perl5 module for
AFS (dynamically loadable). I've basically finished the fs/pts commands, and
was going to start on the kas-ish commands next, probably followed by the
vos-ish commands.
Here is a list of the functions I've finished so far. Note that some of the
names may get changed. I'm basically going through an implementing a lot of the
commands, using names from either the external commands, or the internal APIs.
They probably need to be cleaned up.
I'm making heavy use of references and objects in Perl 5. For example, here
is the perl5 equiv of "fs la /path":
#!/usr/local/bin/perl5
use AFS getacl;
die "Usage: $0 path\n" if ($#ARGV!=0);
$path = shift;
$acl = getacl($path) || die "$0: $AFS::CODE\n";
print "Access list for $path is\n";
print "Normal rights: \n" if ($acl->length);
foreach $key ($acl->keys) {
print " $key ",$acl->get($key),"\n";
}
print "Negative rights: \n" if ($acl->nlength);
foreach $key ($acl->nkeys) {
print " $key ",$acl->nget($key),"\n";
}
When it gets a little more polished I'll probably ask for alpha-testers.
I also need to check with Transarc to see if people will need a source-license
to play with it. The majority of the code I figured out by reading the
programmer's docs, but some small sections I had to dig through source to
figure
out.
$AFS::CODE
Result of last AFS library call. Magical "numeric" or "string" value.
i.e: $AFS::CODE=="User or group doesn't exist", $AFS::CODE+0 == 267268
$value = convert_numeric_names([$newvalue])
Sets/gets the behavior when looking up a PTS id. If the name looks like a
number (matches /^-?[0-9]*/) the lookup is skipped and the numeric value
of the name is returned. Default value is 1.
$flag = follow_symlinks([$newvalue]);
Sets or gets the default behavior for pioctl calls. pioctl calls
are made for all the fs-ish commands (commands that take a pathname
as the first parameter). The default value is "1", which means symlinks
will be followed.
###### Cell/Config functions --------------------
$cellname = expandcell($cell);
Expands cell to fully qualified cellname. Returns undef on error.
$cellname = localcell;
Returns local cellname. Returns undef on error.
$realm = celltorealm($cell);
Expands cell and converts to upper case.
($cell @servers) = getcellinfo([$cell=0 [,$ip=0]]);
Gets information on $cell using CellServDB. If $ip is
set to 1 then IP addresses will be returned instead of hostnames.
($cell, @servers) = getcell($index [,$ip=0]);
Iterates through the Cache Manager's internal cell configuration,
using $index as an index. The index starts at 0. $AFS::CODE will
be set to a non-zero value when passed an invalid index. If $ip is
set to 1 then IP addresses will be returned instead of hostnames.
$ok = config_dir($dir);
Set configuration directory. Default is /usr/vice/etc.
$config_dir = config_dir();
Get current configuration directory. Returns undef on error.
# Error codes and constants
$mess = error_message($code);
Converts numeric code into a string.
$value = constant($name);
Converts a constant (i.e, #define) into scaler. Returns undef for
unknown constants. For example:
$value = constant("PRIDEXIST"); # value = 267265
&AFS::CONSTANT
All values referenced through the constant function can
by referenced as functions in the AFS package. This is the
preferred way of accessing constants. For example:
$value = constant("PRIDEXIST"); # value = 267265
$value = &AFS::PRIDEXIST; # value = 267265, preferred method
########## Misc ---------------------------------------------------------
$ok = setpag();
Creates a new PAG.
($name, $inst, $cell) = parselogin($login);
Calls ka_ParseLoginName. Should probably be re-written in Perl...
$DESKEY = stringtokey($str, $cell=0);
Calls the AFS/Andrew string-to-key function.
$DESKEY = des_string_to_key($str);
Calls the des_string_to_key function.
########## ACLs ---------------------------------------------------------
$acl = AFS::ACL::new([\%pos [, \%neg]]);
$acl = newacl([\%pos [, \%neg]]);
Used to create an ACL object. The second form is exported by the AFS
module and is therefore a little easier to use.
Examples:
$acl = newacl({"schemers"=>"all", "system:anyuser"=>"l"});
$acl = newacl({"schemers"=>"all"}, {"rjs"=>read"});
$acl->copy;
Returns a copy of an existing ACL.
$newacl = $acl->copy;
Changes made to $newacl do not change $acl.
$acl ->addacl($newacl);
Adds all the ACL entries in $newacl to $acl.
$acl ->empty;
Removes all positive and negative entries from an ACL.
$acl->keys
Returns all the keys (PTS names) from the positive ACL hash.
$acl->length
Returns the length (number of keys) in the postive ACL hash.
$acl->get($key)
Returns the access rights for the given key in the positive ACL hash.
$acl->exists($key)
Returns 1 if the given key exists in the positive ACL hash.
$acl->add($key, $rights);
Adds the given key and access rights to the positive ACL hash.
$acl->remove($key)
Removes the given key from the positive ACL hash.
$acl->clear
Removes all positive entries from the ACL.
$acl->nkeys
$acl->nlength
$acl->nget($key)
$acl->nexists($key)
$acl->nadd($key, $rights);
$acl->nremove($key)
$acl->nclear
Same as above but work on the negative ACL hash instead of the positive.
$acl = getacl($path);
Retrieves the ACL for the given path.
For example:
$acl = getacl("/afs/ir.stanford.edu");
$ok = setacl($path, $acl);
Sets the ACL for the given path. This call replaces the existing ACL
value with the new ACLs.
$ok = modifyacl($path, $acl)
Sets the ACL to the union of the given ACL and the current ACL.
An access right of "none" or "" will cause an entry to be removed from
the ACL.
Example:
$ok = modifyacl($path,newacl({"schemers" => "none"}));
Will remove "schemers" from the ACL on $path. Since this function does
a union on both hash tables it is not an error if "schemers" is not
on the existing ACl.
$ok = copyacl($from_path, $to_path);
Copies the ACL on $from_path to $to_path.
$ok = cleanacl($path);
Removes any "orphan" ids on an ACL. An orphan id is an ID that
corresponds to an ID that is longer in the PTS database. Orphan
ids are also removed during a setacl or modifyacl call.
$flags = ascii2rights($rights);
Returns -1 if $rights are not valid (rlidwka, read, write, all, none).
or returns the internal value (int32 with flags set).
$print = rights2ascii($flags);
Converts $internal_value to ascii.
# rest of the fs'ish commands ---------------------------------------------
$volstats = getvolstats($path);
$ok = getvolstats($path, \%stats);
Emulates the VIOCGETVOLSTAT pioctl function. Blocks are returned
in 1K values. Type is ReadWrite or ReadOnly.
Returns an associative array containg the following values:
Blessed 1
BlocksInUse 38790
InService 1
MaxQuota 105000
MinQuota 0
Motd
Name user.schemers
NeedsSalvage 0
OffMsg
Online 1
ParentId 669036111
PartBlocksAvail 255972
PartMaxBlocks 1161063
Type ReadWrite
Vid 669036111
$quota = getquota($path);
Returns current volume quota (MaxQuota from Volume Status).
$ok = setquota($path, $quota);
Sets volume's quota.
@hosts = whereis($path[,$ip=0]);
Returns the location of $path. If $ip is set to 1 then IP addresses
will be returned instead of hostnames. Example:
@hosts = whereis("/afs",1);
# @hosts = ( 36.21.0.73, 36.21.0.108, 36.83.0.11, 36.83.0.227);
$name = sysname([$newname]);
Gets (or sets) the value of @sys.
$cell = whichcell($path);
Returns the cell hosting $path. Returns undef and sets CODE on error.
$mount = lsmount($path);
Returns mount point for $path. Returns undef and sets CODE on error.
$ok = rmmount($path);
Removes given mount point. Returns 0 and sets CODE on error.
$ok = mkmount($mountp, $volume [, $rw=0 [, $cell=0]]);
Creates given mount point.
$ok = flushvolume($path);
Flushes the volume containing path.
$ok = flush($path); # flush the file
Flushes $path from the cache.
$ok = flushcb($path); # flush the callbacks on the file
Remove any callbacks on $path kept by the Cache Manager.
$ok = checkvolumes;
Check validity of all cached volume information.
$ok = checkconn;
Check status of all the Callers tokens held by the Cache Manager.
Returns success if the caller has tokens, and all those tokens
are valid (i.e, not expired).
($max, $inuse) = getcacheparms;
Returns the current cache parameters. All values are expressed as
1K blocks. $max is the maximum size of the cache and $inuse is the number
of blocks in use.
$ok = setcachesize($size);
Sets the maximum cache size.
$ok = unlog;
Discard all tokens.
($cell, $volume, $vnode, $unique ) = getfid($path);
Get the internal augmented file identifier for $PATH.
See also "struct VenusFID".
$ok = isafs($path);
Returns 1 if $path is in AFS.
$ok = access($path [, $perm="read"]);
Returns 1 if caller has access to given path.
$setuid = getcellstatus([$cell=0]);
Returns 1 if setuid programs are allowed for given (default local) cell.
$ok = setcellstatus($setuid_allowed[,$cell=0]);
Sets the setuid flag for the given (default local) cell.
$cell = wscell;
Returns local cell.
# PTS ---------------------------------------------------------------- PTS
$pts = AFS::PTS::new([$sec=1 [, $cell=0]]);
$pts = AFS::newpts([$sec=1 [, $cell=0]]);
$pts = ''; #DESTROY connection
$id = $pts->id($name [, $annon=1]) # return $ANONYMOUSID or undef
@id = $pts->id(\@names [, $annon=1])
$sucess = $pts->id(\%names [, $annon=1])
$name = $pts->name($id [, $annon=1]); # return numeric value or undef
@name = $pts->name(@ids [, $annon=1]);
$success = $pts->name(\%ids [, $annon=1]);
@members = $pts -> members($NAME [, $lookupids = 1 [, $wentover]]);
@members = $pts -> getcps($NAME [, $lookupids = 1 [, $wentover]]);
@members = $pts -> owned($NAME|0, [, $lookupids = 1 [, $wentover]]);
$id = $pts -> createuser($name [, $id = 0])
$id = $pts -> creategroup($name [, $OWNER = 0, [, $id = 0]]);
$entry = $pts -> listentry($NAME [, $lookupids=1 [, $convertflags=1]]);
%$entry=
flags id owner creater
ngroups count name
$pos = $pts -> whereisit($NAME);
$entry = $pts -> dumpentry($pos [, $lookupids=1 [,$convertflags=1]]);
%$entry=
cellid child count creator
entries0-entries9 flags id instance
name next nextID nextOwned
nextname ngroups nusers owned
owner parent sibling reserved0-4
$success = $pts -> chid($NAME, $newid);
$success = $pts -> rename($NAME, $newname);
$success = $pts -> chown($NAME, $OWNER);
$succes = $pts -> adduser($NAME, $GROUP)
$success = $pts -> removeuser($NAME, $GROUP)
$success = $pts -> delete($NAME);
($id, $gid) = $pts -> listmax;
$max = $pts -> setmax($id [, $isgroup]);
$success = $pts -> setgroupquota ($NAME, $ngroups);
$success = $pts -> setaccess ($NAME, $newflags);
$success = $pts -> ismember($NAME, $GROUP);
--
Roland J. Schemers III | 414 Sweet Hall +1 (415) 723-6740
Authentication Services Programmer | Stanford, CA 94305-3090
Distributed Computing Operations | [EMAIL PROTECTED]
Stanford University | http://www-leland.stanford.edu/~schemers/