/* * @(#)Volume.java 1.0 6/29/2001 * * Copyright (c) 2001 International Business Machines Corp. * All rights reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.openafs.jafs; import java.util.GregorianCalendar; import java.util.Date; import java.io.Serializable; /** * An abstract representation of an AFS volume. It holds information about * the server, such as what its quota is. *

* * Constructing an instance of a Volume does not mean an actual * AFS partition is created on a partition -- usually a Volume * object is a representation of an already existing AFS volume. If, * however, the Volume is constructed with the name of a * volume that does not exist in the cell to which the provided * Partition belongs, a new AFS volume with that name can be * created on that partition by calling the {@link #create(int)} method. If * such a volume does already exist when this method is called, an exception * will be thrown.

* * * The following is a simple example of how to construct and use a * Volume object. This example obtains the list of * Volume objects residing on a particular partition, and prints * out the name and id of each one.

* *
 * import org.openafs.jafs.Cell;
 * import org.openafs.jafs.AFSException;
 * import org.openafs.jafs.Partition;
 * import org.openafs.jafs.Server;
 * import org.openafs.jafs.Volume;
 * ...
 * public class ...
 * {
 *   ...
 *   private Cell cell;
 *   private Server server;
 *   private Partition partition;
 *   ...
 *   public static void main(String[] args) throws Exception
 *   {
 *     String username      = arg[0];
 *     String password      = arg[1];
 *     String cellName      = arg[2];
 *     String serverName    = arg[3];
 *     String partitionName = arg[4];
 * 
 *     token  = new Token(username, password, cellName);
 *     cell   = new Cell(token);
 *     server = cell.getServer(serverName);
 *     partition = cell.getPartition(partitionName);
 * 
 *     System.out.println("Volumes in Partition " + partition.getName() + ":");
 *     Volume[] volumes = partition.getVolumes();
 *     for (int i = 0; i < volumes.length; i++) {
 *       System.out.println(" -> " + volumes[i] + ": " + volumes[i].getID());
 *     }
 *   }
 *   ...
 * }
 * 
* */ public class Volume implements Serializable, Comparable { /** * Read-write volume type */ public static final int VOLUME_TYPE_READ_WRITE = 0; /** * Read-only volume type */ public static final int VOLUME_TYPE_READ_ONLY = 1; /** * Backup volume type */ public static final int VOLUME_TYPE_BACKUP = 2; /** * Status/disposition ok */ public static final int VOLUME_OK = 0; /** * Status/disposition salvage */ public static final int VOLUME_SALVAGE = 1; /** * Status/disposition no vnode */ public static final int VOLUME_NO_VNODE = 2; /** * Status/disposition no volume */ public static final int VOLUME_NO_VOL = 3; /** * Status/disposition volume exists */ public static final int VOLUME_VOL_EXISTS = 4; /** * Status/disposition no service */ public static final int VOLUME_NO_SERVICE = 5; /** * Status/disposition offline */ public static final int VOLUME_OFFLINE = 6; /** * Status/disposition online */ public static final int VOLUME_ONLINE = 7; /** * Status/disposition disk full */ public static final int VOLUME_DISK_FULL = 8; /** * Status/disposition over quota */ public static final int VOLUME_OVER_QUOTA = 9; /** * Status/disposition busy */ public static final int VOLUME_BUSY = 10; /** * Status/disposition moved */ public static final int VOLUME_MOVED = 11; protected Cell cell; protected Server server; protected Partition partition; protected String name; protected int id; protected int readWriteID; protected int readOnlyID; protected int backupID; protected long creationDate; protected long lastAccessDate; protected long lastUpdateDate; protected long lastBackupDate; protected long copyCreationDate; protected int accessesSinceMidnight; protected int fileCount; protected int maxQuota; protected int currentSize; protected int status; protected int disposition; protected int type; protected GregorianCalendar creationDateCal; protected GregorianCalendar lastUpdateDateCal; protected GregorianCalendar copyCreationDateCal; protected boolean cachedInfo; /** * Constructs a new Volume object instance given the name of * the AFS volume and the AFS cell, represented by partition, * to which it belongs. This does not actually * create a new AFS volume, it just represents one. * If name is not an actual AFS volume, exceptions * will be thrown during subsequent method invocations on this * object, unless the {@link #create(int)} method is explicitly called * to create it. * * @param name the name of the volume to represent * @param partition the partition on which the volume resides * @exception AFSException If an error occurs in the native code */ public Volume( String name, Partition partition ) throws AFSException { this.partition = partition; this.server = partition.getServer(); this.cell = server.getCell(); this.name = name; creationDateCal = null; lastUpdateDateCal = null; copyCreationDateCal = null; id = -1; cachedInfo = false; } /** * Constructs a new Volume object instance given the name of * the AFS volume and the AFS partition, represented by * partition, to which it belongs. This does not actually * create a new AFS volume, it just represents one. * If name is not an actual AFS volume, exceptions * will be thrown during subsequent method invocations on this * object, unless the {@link #create(int)} method is explicitly called * to create it. Note that if the volume doesn't exist and * preloadAllMembers is true, an exception will be thrown. * *

This constructor is ideal for point-in-time representation and * transient applications. It ensures all data member values are set * and available without calling back to the filesystem at the first request * for them. Use the {@link #refresh()} method to address any coherency * concerns. * * @param name the name of the volume to represent * @param partition the partition on which the volume resides. * @param preloadAllMembers true will ensure all object members are set * upon construction; otherwise members will be * set upon access, which is the default behavior. * @exception AFSException If an error occurs in the native code * @see #refresh */ public Volume( String name, Partition partition, boolean preloadAllMembers ) throws AFSException { this(name, partition); if (preloadAllMembers) refresh(true); } /** * Creates a blank Volume given the cell to which the volume * belongs, the server on which the partition resides, and * the partition on which the volume resides. This blank * object can then be passed into other methods to fill out its properties. * * @exception AFSException If an error occurs in the native code * @param cell the cell to which the server belongs. * @param server the server on which the partition resides * @param partition the partition on which the volume resides */ Volume( Partition partition ) throws AFSException { this( null, partition ); } /*-------------------------------------------------------------------------*/ /** * Refreshes the properties of this Volume object instance with values from * the AFS volume it represents. All properties that have been initialized * and/or accessed will be renewed according to the values of the AFS volume * this Volume object instance represents. * *

Since in most environments administrative changes can be administered * from an AFS command-line program or an alternate GUI application, this * method provides a means to refresh the Java object representation and * thereby ascertain any possible modifications that may have been made * from such alternate administrative programs. Using this method before * an associated instance accessor will ensure the highest level of * representative accuracy, accommodating changes made external to the * Java application space. If administrative changes to the underlying AFS * system are only allowed via this API, then the use of this method is * unnecessary. * * @exception AFSException If an error occurs in the native code */ public void refresh() throws AFSException { refresh(false); } /** * Refreshes the properties of this Volume object instance with values from * the AFS volume it represents. If all is true * then all of the properties of this Volume object instance will be * set, or renewed, according to the values of the AFS volume it represents, * disregarding any previously set properties. * *

Thus, if all is false then properties that * are currently set will be refreshed and properties that are not set will * remain uninitialized. See {@link #refresh()} for more information. * * @param all if true set or renew all object properties; otherwise renew * all set properties * @exception AFSException If an error occurs in the native code * @see #refresh() */ protected void refresh(boolean all) throws AFSException { if (all || cachedInfo) refreshInfo(); } /** * Refreshes the information fields of this Volume to reflect * the current state of the AFS volume. These include the last update time, * file count, etc. * * @exception AFSException If an error occurs in the native code */ protected void refreshInfo() throws AFSException { getVolumeInfo( cell.getCellHandle(), server.getVosHandle(), partition.getID(), getID(), this ); cachedInfo = true; creationDateCal = null; lastUpdateDateCal = null; copyCreationDateCal = null; } /** * Creates a new volume on the server and partition given upon construction. * * @param quota the quota for the volume in K, 0 indicates an unlimited * quota * * @exception AFSException If an error occurs in the native code */ public void create( int quota ) throws AFSException { id = create( cell.getCellHandle(), server.getVosHandle(), partition.getID(), name, quota ); maxQuota = quota; } /** * Creates a backup volume for this volume. * * @return the Volume object representation for the * backup volume that was created * @exception AFSException If an error occurs in the native code */ public Volume createBackup( ) throws AFSException { createBackupVolume( cell.getCellHandle(), getID() ); return new Volume( name + ".backup", partition ); } /** * Creates a readonly site for this volume on the specified server and * partition. Automatically releases the volume. * * @param sitePartition the partition on which the readonly volume is * to reside * * @return the Volume representation for the * read-only volume that was created * @exception AFSException If an error occurs in the native code */ public Volume createReadOnly( Partition sitePartition ) throws AFSException { Server siteServer = sitePartition.getServer(); createReadOnlyVolume( cell.getCellHandle(), siteServer.getVosHandle(), sitePartition.getID(), getID() ); release( false ); return new Volume( name + ".readonly", sitePartition ); } /** * Deletes the volume from the cell. * * @exception AFSException If an error occurs in the native code */ public void delete() throws AFSException { delete( cell.getCellHandle(), server.getVosHandle(), partition.getID(), getID() ); name = null; creationDateCal = null; lastUpdateDateCal = null; copyCreationDateCal = null; cell = null; server = null; partition = null; } /** * Releases this volume, which updates the read-only copies of it. * *

This method will force a complete release; a complete release updates * all read-only sites even if the VLDB entry has a flag. * * @exception AFSException If an error occurs in the native code */ public void release() throws AFSException { this.release( true ); } /** * Releases this volume, which updates the read-only copies of it. * * @param forceComplete whether or not to force a complete release; * a complete release updates all read-only sites * even if the VLDB entry has a flag * @exception AFSException If an error occurs in the native code */ public void release( boolean forceComplete ) throws AFSException { release( cell.getCellHandle(), getID(), forceComplete ); } /** * Dumps this volume to a file. If you use the dumpSince argument you will * create an incremental dump, but you can leave it null * for a full dump. * * @param fileName the path name of the file on the client machine to * which to dump this volume * @param dumpSince dump only files that have been modified more recently * than this date * @exception AFSException If an error occurs in the native code */ public void dump( String fileName, GregorianCalendar dumpSince ) throws AFSException { int startTime = 0; if ( dumpSince != null ) { startTime = (int) ((dumpSince.getTime().getTime())/((long) 1000)); } dump( cell.getCellHandle(), server.getVosHandle(), partition.getID(), getID(), startTime, fileName ); } /** * Dumps this volume to a file. Creates a full dump. * * @param fileName the path name of the file to which to dump this volume * @exception AFSException If an error occurs in the native code */ public void dump( String fileName ) throws AFSException { this.dump( fileName, null ); } /** * Restores a file to this volume. Note that this does not have to be an * existing volume in order to be restored - you may create a * Volume as a volume that doesn't yet exist and then restore * a file to it. Or you can restore over an existing volume. If a new * volume is being created with this method, the id will be automatically * assigned. * * @param fileName the path name of the file on the client machine from * which to restore this volume * @param incremental if true, restores an incremental dump over an * existing volume * @exception AFSException If an error occurs in the native code */ public void restore( String fileName, boolean incremental ) throws AFSException { restore( fileName, incremental, 0 ); } /** * Restores a file to this volume. Note that this does not have to be an * existing volume in order to be restored - you may create a * Volume as a volume that doesn't yet exist and then restore * a file to it. Or you can restore over an existing volume. * * @param fileName the path name of the file on the client machine from * which to restore this volume * @param incremental if true, restores an incremental dump over an * existing volume * @param id the id to assign this volume * @exception AFSException If an error occurs in the native code */ public void restore( String fileName, boolean incremental, int id ) throws AFSException { restore( cell.getCellHandle(), server.getVosHandle(), partition.getID(), id, name, fileName, incremental ); } /** * Mounts this volume, bringing it online and making it accessible. * * @exception AFSException If an error occurs in the native code */ public void mount( ) throws AFSException { mount( server.getVosHandle(), partition.getID(), getID(), 0, true ); } /** * Unmounts this volume, bringing it offline and making it inaccessible. * * @exception AFSException If an error occurs in the native code */ public void unmount( ) throws AFSException { unmount( server.getVosHandle(), partition.getID(), getID() ); } /** * Locks the VLDB enrty for this volume * * @exception AFSException If an error occurs in the native code */ public void lock( ) throws AFSException { lock( cell.getCellHandle(), getID() ); } /** * Unlocks the VLDB entry for this volume * * @exception AFSException If an error occurs in the native code */ public void unlock( ) throws AFSException { unlock( cell.getCellHandle(), getID() ); } /** * Moves this volume to the specified partition (which indirectly * specifies a new server, as well). Caution: This will remove any backup * volumes at the original site. * * @param newPartition the partition to which to move the volume * * @exception AFSException If an error occurs in the native code */ public void moveTo( Partition newPartition ) throws AFSException { Server newServer = newPartition.getServer(); move( cell.getCellHandle(), server.getVosHandle(), partition.getID(), newServer.getVosHandle(), newPartition.getID(), getID() ); server = newServer; partition = newPartition; } /** * Renames this volume. * * @param newName the new name for this volume * @exception AFSException If an error occurs in the native code */ public void rename( String newName ) throws AFSException { rename( cell.getCellHandle(), getID(), newName ); name = newName; } /** * Salvages (restores consistency to) this volume. Uses default values for * most salvager options in order to simplify the API. * * @exception AFSException If an error occurs in the native code */ public void salvage() throws AFSException { Server.salvage( cell.getCellHandle(), server.getBosHandle(), partition.getName(), name, 4, null, null, false, false, false, false, false, false ); } /** * Creates a read-write mount point for this volume. Does not ensure the * volume already exists. * * @param directory the name of the directory where this volume * should be mounted * @exception AFSException If an error occurs in the native code */ public void createMountPoint( String directory ) throws AFSException { createMountPoint(directory, true); } /** * Creates a mount point for this volume. Does not ensure the volume * already exists. * * @param directory the name of the directory where this volume should be * mounted * @param readWrite whether or not this mount point should be read-write * @exception AFSException If an error occurs in the native code */ public void createMountPoint( String directory, boolean readWrite ) throws AFSException { Cell.createMountPoint( cell.getCellHandle(), directory, getName(), readWrite, false ); } //////////////// accessors: //////////////////////// /** * Returns the name of this volume. * * @return the name of this volume */ public String getName() { return name; } /** * Returns this volume's hosting partition. * * @return this volume's partition */ public Partition getPartition() { return partition; } /** * Returns the id of this volume. * * @exception AFSException If an error occurs in the native code * @return the id of this volume */ public int getID() throws AFSException { if( id == -1 && name != null ) { String nameNoSuffix; if( name.endsWith( "backup" ) ) { type = VOLUME_TYPE_BACKUP; nameNoSuffix = name.substring( 0, name.lastIndexOf( '.' ) ); } else if( name.endsWith( "readonly" ) ) { type = VOLUME_TYPE_READ_ONLY; nameNoSuffix = name.substring( 0, name.lastIndexOf( '.' ) ); } else { type = VOLUME_TYPE_READ_WRITE; nameNoSuffix = name; } id = translateNameToID( cell.getCellHandle(), nameNoSuffix, type ); } return id; } /** * Returns the read-write ID of this volume * * @exception AFSException If an error occurs in the native code * @return the read-write id */ public int getReadWriteID() throws AFSException { if( !cachedInfo ) { refreshInfo(); } return readWriteID; } /** * Returns the read-only ID of this volume * * @exception AFSException If an error occurs in the native code * @return the read-only id */ public int getReadOnlyID() throws AFSException { if( !cachedInfo ) { refreshInfo(); } return readOnlyID; } /** * Returns the backup ID of this volume * * @exception AFSException If an error occurs in the native code * @return the backup id */ public int getBackupID() throws AFSException { if( !cachedInfo ) { refreshInfo(); } return backupID; } /** * Returns the date the volume was created * * @return the date the volume was created * @exception AFSException If an error occurs in the native code */ public GregorianCalendar getCreationDate() throws AFSException { if( !cachedInfo ) { refreshInfo(); } if( creationDateCal == null ) { // make it into a date . . . creationDateCal = new GregorianCalendar(); Date d = new Date( creationDate*1000 ); creationDateCal.setTime( d ); } return creationDateCal; } /** * Returns the date the volume was last updated. * After this method is called once, it saves the date * and returns that date on subsequent calls, * until the {@link #refresh()} method is called and a more current * value is obtained. * * @return the date the volume was last updated * @exception AFSException If an error occurs in the native code */ public GregorianCalendar getLastUpdateDate() throws AFSException { if( !cachedInfo ) { refreshInfo(); } if( lastUpdateDateCal == null ) { // make it into a date . . . lastUpdateDateCal = new GregorianCalendar(); Date d = new Date( lastUpdateDate*1000 ); lastUpdateDateCal.setTime( d ); } return lastUpdateDateCal; } /** * Returns the date the volume was copied. * After this method is called once, it saves the date * and returns that date on subsequent calls, * until the {@link #refresh()} method is called and a more current * value is obtained. * * @return the date the volume was copied * @exception AFSException If an error occurs in the native code */ public GregorianCalendar getCopyCreationDate() throws AFSException { if( !cachedInfo ) { refreshInfo(); } if( copyCreationDateCal == null ) { // make it into a date . . . copyCreationDateCal = new GregorianCalendar(); Date d = new Date( copyCreationDate*1000 ); copyCreationDateCal.setTime( d ); } return copyCreationDateCal; } /** * Returns the number of accesses since midnight. * After this method is called once, it saves the value * and returns that value on subsequent calls, * until the {@link #refresh()} method is called and a more current * value is obtained. * * @exception AFSException If an error occurs in the native code * @return the number of accesses since midnight */ public int getAccessesSinceMidnight() throws AFSException { if( !cachedInfo ) { refreshInfo(); } return accessesSinceMidnight; } /** * Returns file count. * After this method is called once, it saves the value * and returns that value on subsequent calls, * until the {@link #refresh()} method is called and a more current * value is obtained. * * @exception AFSException If an error occurs in the native code * @return the file count */ public int getFileCount() throws AFSException { if( !cachedInfo ) { refreshInfo(); } return fileCount; } /** * Returns current volume size in K. * After this method is called once, it saves the value * and returns that value on subsequent calls, * until the {@link #refresh()} method is called and a more current * value is obtained. * * @exception AFSException If an error occurs in the native code * @return the current volume size in K */ public int getCurrentSize() throws AFSException { if( !cachedInfo ) refreshInfo(); return currentSize; } /** * Returns the difference between quota and current volume size (in K). * *

Please note: the product of this method is not saved. * * @exception AFSException If an error occurs in the native code * @return the current free space in K */ public int getTotalFreeSpace() throws AFSException { if ( !cachedInfo ) refreshInfo(); return (maxQuota - currentSize); } /** * Returns this volume's quota, expressed in kilobyte blocks (1024 * kilobyte blocks equal one megabyte). After this method is called once, * it saves the value and returns that value on subsequent calls, * until the {@link #refresh()} method is called and a more current * value is obtained. * *

Note: A quota value of zero, "0", grants an unlimited quota * in AFS. Consequently, to avoid delusion this method will throw an * {@link AFSException} if the returning value is zero. * * @exception AFSException If an error occurs in the native code or * this volume's quota is configured as * unlimited. * @return the volume quota in K * @see #isQuotaUnlimited() */ public int getQuota() throws AFSException { if ( !cachedInfo ) refreshInfo(); if (maxQuota == 0) { throw new AFSException("Volume with id " + id + " has an unlimited quota configured.", 0); } return maxQuota; } /** * Tests whether this volume's quota is configured as unlimited. * *

After this method is called once, it saves the value and returns * that value on subsequent calls, until the {@link #refresh()} * method is called and a more current value is obtained. * * @exception AFSException If an error occurs in the native code * @return true if this volume's quota is configured as * unlimited; otherwise false. * @see #getQuota() */ public boolean isQuotaUnlimited() throws AFSException { if ( !cachedInfo ) refreshInfo(); return (maxQuota == 0); } /** * Returns volume status. Possible values are:

* Typical value is VOLUME_OK. * After this method is called once, it saves the value * and returns that value on subsequent calls, * until the {@link #refresh()} method is called and a more current * value is obtained. * * @exception AFSException If an error occurs in the native code * @return volume status */ public int getStatus() throws AFSException { if( !cachedInfo ) refreshInfo(); return status; } /** * Returns volume disposition. Possible values are: * Typical value is VOLUME_ONLINE. * After this method is called once, it saves the value * and returns that value on subsequent calls, * until the {@link #refresh()} method is called and a more current * value is obtained. * * @exception AFSException If an error occurs in the native code * @return volume disposition */ public int getDisposition() throws AFSException { if( !cachedInfo ) refreshInfo(); return disposition; } /** * Returns volume type. Possible values are: * * @exception AFSException If an error occurs in the native code * @return volume type */ public int getType() throws AFSException { if( !cachedInfo ) refreshInfo(); return type; } //////////////// mutators: //////////////////////// /** * Sets quota of volume, 0 denotes an unlimited quota. * * @exception AFSException If an error occurs in the native code * @param quota the new volume quota in K (0 for unlimited) */ public void setQuota( int quota ) throws AFSException { this.changeQuota( cell.getCellHandle(), server.getVosHandle(), partition.getID(), getID(), quota ); maxQuota = quota; } /////////////// custom information methods //////////////////// /** * Returns a String representation of this Volume. * Contains the information fields. * * @return a String representation of the Volume */ protected String getInfo() { String r; try { r = "Volume: " + name + "\tid: " + getID() + "\n"; r += "\tread-write id: " + getReadWriteID() + "\tread-only id: " + getReadOnlyID() + "\n"; r += "\tbackup id: " + getBackupID() + "\n"; r += "\tcreation date: " + getCreationDate().getTime() + "\n"; r += "\tlast update date: " + getLastUpdateDate().getTime() + "\n"; r += "\tcopy creation date: " + getCopyCreationDate().getTime() + "\n"; r += "\taccesses since midnight: " + getAccessesSinceMidnight() + "\n"; r += "\tfile count: " + getFileCount() + "\n"; r += "\tcurrent size: " + getCurrentSize() + " K\tquota: " + getQuota() + " K\n"; r += "\tstatus: "; switch( getStatus() ) { case VOLUME_OK: r += "OK"; break; default: r += "OTHER"; } r += "\tdisposition: "; switch( getDisposition() ) { case VOLUME_ONLINE: r += "ONLINE"; break; default: r += "OTHER - " + getDisposition(); } r += "\n"; r += "\ttype: "; switch( getType() ) { case VOLUME_TYPE_READ_WRITE: r += "read-write"; break; case VOLUME_TYPE_READ_ONLY: r += "read-only"; break; case VOLUME_TYPE_BACKUP: r += "backup"; break; default: r += "OTHER"; } r += "\n"; } catch( Exception e ) { return e.toString(); } return r; } /////////////// custom override methods //////////////////// /** * Compares two Volume objects respective to their names and does not * factor any other attribute. Alphabetic case is significant in * comparing names. * * @param volume The Volume object to be compared to this Volume * instance * * @return Zero if the argument is equal to this Volume's name, a * value less than zero if this Volume's name is * lexicographically less than the argument, or a value greater * than zero if this Volume's name is lexicographically * greater than the argument */ public int compareTo(Volume volume) { return this.getName().compareTo(volume.getName()); } /** * Comparable interface method. * * @see #compareTo(Volume) */ public int compareTo(Object obj) { return compareTo((Volume)obj); } /** * Tests whether two Volume objects are equal, based on their * names and hosting partition. * * @param otherVolume the Volume to test * @return whether the specifed Volume is the same as this Volume */ public boolean equals( Volume otherVolume ) { return ( name.equals(otherVolume.getName()) ) && ( this.getPartition().equals(otherVolume.getPartition()) ); } /** * Returns the name of this Volume * * @return the name of this Volume */ public String toString() { return getName(); } /////////////// native methods //////////////////// /** * Fills in the information fields of the provided Volume. * * @param cellHandle the handle of the cell to which the volume belongs * @see Cell#getCellHandle * @param serverHandle the vos handle of the server on which the volume * resides * @see Server#getVosServerHandle * @param partition the numeric id of the partition on which the volume * resides * @param volId the numeric id of the volume for which to get the info * @param theVolume the {@link Volume Volume} object in which to fill in * the information * @exception AFSException If an error occurs in the native code */ protected static native void getVolumeInfo( int cellHandle, int serverHandle, int partition, int volId, Volume theVolume ) throws AFSException; /** * Creates a volume on a particular partition. * * @param cellHandle the handle of the cell in which to create the volume * @see Cell#getCellHandle * @param serverHandle the vos handle of the server on which to create * the volume * @see Server#getVosServerHandle * @param partition the numeric id of the partition on which to create * the volume * @param volumeName the name of the volume to create * @param quota the amount of space (in KB) to set as this volume's quota * @return the numeric ID assigned to the volume * @exception AFSException If an error occurs in the native code */ protected static native int create( int cellHandle, int serverHandle, int partition, String volumeName, int quota ) throws AFSException; /** * Deletes a volume from a particular partition. * * @param cellHandle the handle of the cell in which to delete the volume * @see Cell#getCellHandle * @param serverHandle the vos handle of the server from which to delete * the volume * @see Server#getVosServerHandle * @param partition the numeric id of the partition from which to delete * the volume * @param volId the numeric id of the volume to delete * @exception AFSException If an error occurs in the native code */ protected static native void delete( int cellHandle, int serverHandle, int partition, int volId ) throws AFSException; /** * Creates a backup volume for the specified regular volume. * * @param cellHandle the handle of the cell to which the volume belongs * @param volId the numeric id of the volume for which to create a backup * volume * @see Cell#getCellHandle */ protected static native void createBackupVolume( int cellHandle, int volId ) throws AFSException; /** * Creates a read-only volume for the specified regular volume. * * @param cellHandle the handle of the cell to which the volume belongs * @param serverHandle the vos handle of the server on which the read-only * volume is to reside * @see Server#getVosServerHandle * @param partition the numeric id of the partition on which the read-only volume is to reside * @param volId the numeric id of the volume for which to create a read-only volume * @see Cell#getCellHandle */ protected static native void createReadOnlyVolume( int cellHandle, int serverHandle, int partition, int volId ) throws AFSException; /** * Deletes a read-only volume for the specified regular volume. * * @param cellHandle the handle of the cell to which the volume belongs * @param serverHandle the vos handle of the server on which the read-only * volume residea * @see Server#getVosServerHandle * @param partition the numeric id of the partition on which the read-only * volume resides * @param volId the numeric read-write id of the volume for which to * delete the read-only volume * @see Cell#getCellHandle */ protected static native void deleteReadOnlyVolume( int cellHandle, int serverHandle, int partition, int volId ) throws AFSException; /** * Changes the quota of the specified volume. * * @param cellHandle the handle of the cell to which the volume belongs * @see Cell#getCellHandle * @param serverHandle the vos handle of the server on which the volume * resides * @see Server#getVosServerHandle * @param partition the numeric id of the partition on which the volume * resides * @param volId the numeric id of the volume for which to change the quota * @param newQuota the new quota (in KB) to assign the volume * @exception AFSException If an error occurs in the native code */ protected static native void changeQuota( int cellHandle, int serverHandle, int partition, int volId, int newQuota ) throws AFSException; /** * Move the specified volume to a different site. * * @param cellHandle the handle of the cell to which the volume belongs * @see Cell#getCellHandle * @param fromServerHandle the vos handle of the server on which the volume * currently resides * @see Server#getVosServerHandle * @param fromPartition the numeric id of the partition on which the volume * currently resides * @param toServerHandle the vos handle of the server to which the volume * should be moved * @param toPartition the numeric id of the partition to which the volume * should be moved * @param volId the numeric id of the volume to move * @exception AFSException If an error occurs in the native code */ protected static native void move( int cellHandle, int fromServerHandle, int fromPartition, int toServerHandle, int toPartition, int volId ) throws AFSException; /** * Releases the specified volume that has readonly volume sites. * * @param cellHandle the handle of the cell to which the volume belongs * @param volId the numeric id of the volume to release * @param forceComplete whether or not to force a complete release * @see Cell#getCellHandle */ protected static native void release( int cellHandle, int volId, boolean forceComplete ) throws AFSException; /** * Dumps the specified volume to a file. * * @param cellHandle the handle of the cell to which the volume belongs * @see Cell#getCellHandle * @param serverHandle the vos handle of the server on which the volume * resides * @see Server#getVosServerHandle * @param partition the numeric id of the partition on which the * volume resides * @param volId the numeric id of the volume to dump * @param startTime files with a modification time >= to this time will * be dumped * @param dumpFile the full path of the file to which to dump * @exception AFSException If an error occurs in the native code */ protected static native void dump( int cellHandle, int serverHandle, int partition, int volId, int startTime, String dumpFile ) throws AFSException; /** * Restores the specified volume from a dump file. * * @param cellHandle the handle of the cell to which the volume belongs * @see Cell#getCellHandle * @param serverHandle the vos handle of the server on which the volume is * to reside * @see Server#getVosServerHandle * @param partition the numeric id of the partition on which the volume is * to reside * @param volId the numeric id to assign the restored volume (can be 0) * @param volumeName the name of the volume to restore as * @param dumpFile the full path of the dump file from which to restore * @param incremental if true, restores an incremental dump over an existing * volume (server and partition values must correctly * indicate the current position of the existing volume), * otherwise restores a full dump * @exception AFSException If an error occurs in the native code */ protected static native void restore( int cellHandle, int serverHandle, int partition, int volId, String volumeName, String dumpFile, boolean incremental ) throws AFSException; /** * Renames the specified read-write volume. * * @param cellHandle the handle of the cell to which the volume belongs * @see Cell#getCellHandle * @param volId the numeric id of the read-write volume to rename * @param newVolumeName the new name for the volume * @exception AFSException If an error occurs in the native code */ protected static native void rename( int cellHandle, int volId, String newVolumeName ) throws AFSException; /** * "Mounts" the specified volume, bringing it online. * * @param serverHandle the vos handle of the server on which the volume * resides * @see Server#getVosServerHandle * @param partition the numeric id of the partition on which the volume * resides * @param volId the numeric id of the volume to bring online * @param sleepTime ? (not sure what this is yet, possibly a time to wait * before brining it online) * @param offline ? (not sure what this is either, probably the current * status of the volume -- busy or offline) * @exception AFSException If an error occurs in the native code */ protected static native void mount( int serverHandle, int partition, int volId, int sleepTime, boolean offline ) throws AFSException; /** * "Unmounts" the specified volume, bringing it offline. * * @param serverHandle the vos handle of the server on which the volume * resides * @see Server#getVosServerHandle * @param partition the numeric id of the partition on which the volume * resides * @param volId the numeric id of the volume to bring offline * @exception AFSException If an error occurs in the native code */ protected static native void unmount( int serverHandle, int partition, int volId ) throws AFSException; /** * Locks the VLDB entry specified volume * * @param cellHandle the handle of the cell on which the volume resides * @see Cell#getCellHandle * @param volId the numeric id of the volume to lock * @exception AFSException If an error occurs in the native code */ protected static native void lock( int cellHandle, int volId ) throws AFSException; /** * Unlocks the VLDB entry of the specified volume * * @param cellHandle the handle of the cell on which the volume resides * @see Cell#getCellHandle * @param volId the numeric id of the volume to unlock * @exception AFSException If an error occurs in the native code */ protected static native void unlock( int cellHandle, int volId ) throws AFSException; /** * Translates a volume name into a volume id * * @param cellHandle the handle of the cell to which the volume belongs * @see Cell#getCellHandle * @param name the name of the volume in question, cannot end in backup or * readonly * @param type the type of volume: read-write, read-only, or backup. * Acceptable values are: * @return the id of the volume in question * @exception AFSException If an error occurs in the native code */ protected static native int translateNameToID( int cellHandle, String name, int volumeType ) throws AFSException; /** * Reclaims all memory being saved by the volume portion of the native * library. This method should be called when no more Volume * objects are expected to be used. */ protected static native void reclaimVolumeMemory(); }