Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / JAVA / classes / org / openafs / jafs / Volume.java
1 /*
2 * @(#)Volume.java 1.0 6/29/2001
3 *
4 * Copyright (c) 2001 International Business Machines Corp.
5 * All rights reserved.
6 *
7 * This software has been released under the terms of the IBM Public
8 * License. For details, see the LICENSE file in the top-level source
9 * directory or online at http://www.openafs.org/dl/license10.html
10 *
11 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
12 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
13 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
14 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
15 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
16 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
18 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
19 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 */
23
24 package org.openafs.jafs;
25
26 import java.util.GregorianCalendar;
27 import java.util.Date;
28 import java.io.Serializable;
29
30 /**
31 * An abstract representation of an AFS volume. It holds information about
32 * the server, such as what its quota is.
33 * <BR><BR>
34 *
35 * Constructing an instance of a <code>Volume</code> does not mean an actual
36 * AFS partition is created on a partition -- usually a <code>Volume</code>
37 * object is a representation of an already existing AFS volume. If,
38 * however, the <code>Volume</code> is constructed with the name of a
39 * volume that does not exist in the cell to which the provided
40 * <code>Partition</code> belongs, a new AFS volume with that name can be
41 * created on that partition by calling the {@link #create(int)} method. If
42 * such a volume does already exist when this method is called, an exception
43 * will be thrown.<BR><BR>
44 *
45 * <!--Example of how to use class-->
46 * The following is a simple example of how to construct and use a
47 * <code>Volume</code> object. This example obtains the list of
48 * <code>Volume</code> objects residing on a particular partition, and prints
49 * out the name and id of each one.<BR><BR>
50 *
51 * <PRE>
52 * import org.openafs.jafs.Cell;
53 * import org.openafs.jafs.AFSException;
54 * import org.openafs.jafs.Partition;
55 * import org.openafs.jafs.Server;
56 * import org.openafs.jafs.Volume;
57 * ...
58 * public class ...
59 * {
60 * ...
61 * private Cell cell;
62 * private Server server;
63 * private Partition partition;
64 * ...
65 * public static void main(String[] args) throws Exception
66 * {
67 * String username = arg[0];
68 * String password = arg[1];
69 * String cellName = arg[2];
70 * String serverName = arg[3];
71 * String partitionName = arg[4];
72 *
73 * token = new Token(username, password, cellName);
74 * cell = new Cell(token);
75 * server = cell.getServer(serverName);
76 * partition = cell.getPartition(partitionName);
77 *
78 * System.out.println("Volumes in Partition " + partition.getName() + ":");
79 * Volume[] volumes = partition.getVolumes();
80 * for (int i = 0; i < volumes.length; i++) {
81 * System.out.println(" -> " + volumes[i] + ": " + volumes[i].getID());
82 * }
83 * }
84 * ...
85 * }
86 * </PRE>
87 *
88 */
89 public class Volume implements Serializable, Comparable
90 {
91 /**
92 * Read-write volume type
93 */
94 public static final int VOLUME_TYPE_READ_WRITE = 0;
95 /**
96 * Read-only volume type
97 */
98 public static final int VOLUME_TYPE_READ_ONLY = 1;
99 /**
100 * Backup volume type
101 */
102 public static final int VOLUME_TYPE_BACKUP = 2;
103
104 /**
105 * Status/disposition ok
106 */
107 public static final int VOLUME_OK = 0;
108 /**
109 * Status/disposition salvage
110 */
111 public static final int VOLUME_SALVAGE = 1;
112 /**
113 * Status/disposition no vnode
114 */
115 public static final int VOLUME_NO_VNODE = 2;
116 /**
117 * Status/disposition no volume
118 */
119 public static final int VOLUME_NO_VOL = 3;
120 /**
121 * Status/disposition volume exists
122 */
123 public static final int VOLUME_VOL_EXISTS = 4;
124 /**
125 * Status/disposition no service
126 */
127 public static final int VOLUME_NO_SERVICE = 5;
128 /**
129 * Status/disposition offline
130 */
131 public static final int VOLUME_OFFLINE = 6;
132 /**
133 * Status/disposition online
134 */
135 public static final int VOLUME_ONLINE = 7;
136 /**
137 * Status/disposition disk full
138 */
139 public static final int VOLUME_DISK_FULL = 8;
140 /**
141 * Status/disposition over quota
142 */
143 public static final int VOLUME_OVER_QUOTA = 9;
144 /**
145 * Status/disposition busy
146 */
147 public static final int VOLUME_BUSY = 10;
148 /**
149 * Status/disposition moved
150 */
151 public static final int VOLUME_MOVED = 11;
152
153 protected Cell cell;
154 protected Server server;
155 protected Partition partition;
156
157 protected String name;
158
159 protected int id;
160 protected int readWriteID;
161 protected int readOnlyID;
162 protected int backupID;
163
164 protected long creationDate;
165 protected long lastAccessDate;
166 protected long lastUpdateDate;
167 protected long lastBackupDate;
168 protected long copyCreationDate;
169
170 protected int accessesSinceMidnight;
171 protected int fileCount;
172 protected int maxQuota;
173 protected int currentSize;
174 protected int status;
175 protected int disposition;
176 protected int type;
177
178 protected GregorianCalendar creationDateCal;
179 protected GregorianCalendar lastUpdateDateCal;
180 protected GregorianCalendar copyCreationDateCal;
181
182 protected boolean cachedInfo;
183
184 /**
185 * Constructs a new <CODE>Volume</CODE> object instance given the name of
186 * the AFS volume and the AFS cell, represented by <CODE>partition</CODE>,
187 * to which it belongs. This does not actually
188 * create a new AFS volume, it just represents one.
189 * If <code>name</code> is not an actual AFS volume, exceptions
190 * will be thrown during subsequent method invocations on this
191 * object, unless the {@link #create(int)} method is explicitly called
192 * to create it.
193 *
194 * @param name the name of the volume to represent
195 * @param partition the partition on which the volume resides
196 * @exception AFSException If an error occurs in the native code
197 */
198 public Volume( String name, Partition partition ) throws AFSException
199 {
200 this.partition = partition;
201 this.server = partition.getServer();
202 this.cell = server.getCell();
203 this.name = name;
204
205 creationDateCal = null;
206 lastUpdateDateCal = null;
207 copyCreationDateCal = null;
208
209 id = -1;
210 cachedInfo = false;
211 }
212
213 /**
214 * Constructs a new <CODE>Volume</CODE> object instance given the name of
215 * the AFS volume and the AFS partition, represented by
216 * <CODE>partition</CODE>, to which it belongs. This does not actually
217 * create a new AFS volume, it just represents one.
218 * If <code>name</code> is not an actual AFS volume, exceptions
219 * will be thrown during subsequent method invocations on this
220 * object, unless the {@link #create(int)} method is explicitly called
221 * to create it. Note that if the volume doesn't exist and
222 * <code>preloadAllMembers</code> is true, an exception will be thrown.
223 *
224 * <P> This constructor is ideal for point-in-time representation and
225 * transient applications. It ensures all data member values are set
226 * and available without calling back to the filesystem at the first request
227 * for them. Use the {@link #refresh()} method to address any coherency
228 * concerns.
229 *
230 * @param name the name of the volume to represent
231 * @param partition the partition on which the volume resides.
232 * @param preloadAllMembers true will ensure all object members are set
233 * upon construction; otherwise members will be
234 * set upon access, which is the default behavior.
235 * @exception AFSException If an error occurs in the native code
236 * @see #refresh
237 */
238 public Volume( String name, Partition partition, boolean preloadAllMembers )
239 throws AFSException
240 {
241 this(name, partition);
242 if (preloadAllMembers) refresh(true);
243 }
244
245 /**
246 * Creates a blank <code>Volume</code> given the cell to which the volume
247 * belongs, the server on which the partition resides, and
248 * the partition on which the volume resides. This blank
249 * object can then be passed into other methods to fill out its properties.
250 *
251 * @exception AFSException If an error occurs in the native code
252 * @param cell the cell to which the server belongs.
253 * @param server the server on which the partition resides
254 * @param partition the partition on which the volume resides
255 */
256 Volume( Partition partition ) throws AFSException
257 {
258 this( null, partition );
259 }
260
261 /*-------------------------------------------------------------------------*/
262
263 /**
264 * Refreshes the properties of this Volume object instance with values from
265 * the AFS volume it represents. All properties that have been initialized
266 * and/or accessed will be renewed according to the values of the AFS volume
267 * this Volume object instance represents.
268 *
269 * <P>Since in most environments administrative changes can be administered
270 * from an AFS command-line program or an alternate GUI application, this
271 * method provides a means to refresh the Java object representation and
272 * thereby ascertain any possible modifications that may have been made
273 * from such alternate administrative programs. Using this method before
274 * an associated instance accessor will ensure the highest level of
275 * representative accuracy, accommodating changes made external to the
276 * Java application space. If administrative changes to the underlying AFS
277 * system are only allowed via this API, then the use of this method is
278 * unnecessary.
279 *
280 * @exception AFSException If an error occurs in the native code
281 */
282 public void refresh() throws AFSException
283 {
284 refresh(false);
285 }
286
287 /**
288 * Refreshes the properties of this Volume object instance with values from
289 * the AFS volume it represents. If <CODE>all</CODE> is <CODE>true</CODE>
290 * then <U>all</U> of the properties of this Volume object instance will be
291 * set, or renewed, according to the values of the AFS volume it represents,
292 * disregarding any previously set properties.
293 *
294 * <P> Thus, if <CODE>all</CODE> is <CODE>false</CODE> then properties that
295 * are currently set will be refreshed and properties that are not set will
296 * remain uninitialized. See {@link #refresh()} for more information.
297 *
298 * @param all if true set or renew all object properties; otherwise renew
299 * all set properties
300 * @exception AFSException If an error occurs in the native code
301 * @see #refresh()
302 */
303 protected void refresh(boolean all) throws AFSException
304 {
305 if (all || cachedInfo) refreshInfo();
306 }
307
308 /**
309 * Refreshes the information fields of this <code>Volume</code> to reflect
310 * the current state of the AFS volume. These include the last update time,
311 * file count, etc.
312 *
313 * @exception AFSException If an error occurs in the native code
314 */
315 protected void refreshInfo() throws AFSException
316 {
317 getVolumeInfo( cell.getCellHandle(), server.getVosHandle(),
318 partition.getID(), getID(), this );
319 cachedInfo = true;
320 creationDateCal = null;
321 lastUpdateDateCal = null;
322 copyCreationDateCal = null;
323 }
324
325 /**
326 * Creates a new volume on the server and partition given upon construction.
327 *
328 * @param quota the quota for the volume in K, 0 indicates an unlimited
329 * quota
330 *
331 * @exception AFSException If an error occurs in the native code
332 */
333 public void create( int quota ) throws AFSException
334 {
335 id = create( cell.getCellHandle(), server.getVosHandle(),
336 partition.getID(), name, quota );
337 maxQuota = quota;
338 }
339
340 /**
341 * Creates a backup volume for this volume.
342 *
343 * @return the <code>Volume</code> object representation for the
344 * backup volume that was created
345 * @exception AFSException If an error occurs in the native code
346 */
347 public Volume createBackup( ) throws AFSException
348 {
349 createBackupVolume( cell.getCellHandle(), getID() );
350 return new Volume( name + ".backup", partition );
351 }
352
353 /**
354 * Creates a readonly site for this volume on the specified server and
355 * partition. Automatically releases the volume.
356 *
357 * @param sitePartition the partition on which the readonly volume is
358 * to reside
359 *
360 * @return the <code>Volume</code> representation for the
361 * read-only volume that was created
362 * @exception AFSException If an error occurs in the native code
363 */
364 public Volume createReadOnly( Partition sitePartition )
365 throws AFSException
366 {
367 Server siteServer = sitePartition.getServer();
368 createReadOnlyVolume( cell.getCellHandle(), siteServer.getVosHandle(),
369 sitePartition.getID(), getID() );
370 release( false );
371 return new Volume( name + ".readonly", sitePartition );
372 }
373
374 /**
375 * Deletes the volume from the cell.
376 *
377 * @exception AFSException If an error occurs in the native code
378 */
379 public void delete() throws AFSException
380 {
381 delete( cell.getCellHandle(), server.getVosHandle(), partition.getID(),
382 getID() );
383 name = null;
384 creationDateCal = null;
385 lastUpdateDateCal = null;
386 copyCreationDateCal = null;
387 cell = null;
388 server = null;
389 partition = null;
390 }
391
392 /**
393 * Releases this volume, which updates the read-only copies of it.
394 *
395 * <P> This method will force a complete release; a complete release updates
396 * all read-only sites even if the VLDB entry has a flag.
397 *
398 * @exception AFSException If an error occurs in the native code
399 */
400 public void release() throws AFSException
401 {
402 this.release( true );
403 }
404
405 /**
406 * Releases this volume, which updates the read-only copies of it.
407 *
408 * @param forceComplete whether or not to force a complete release;
409 * a complete release updates all read-only sites
410 * even if the VLDB entry has a flag
411 * @exception AFSException If an error occurs in the native code
412 */
413 public void release( boolean forceComplete ) throws AFSException
414 {
415 release( cell.getCellHandle(), getID(), forceComplete );
416 }
417
418 /**
419 * Dumps this volume to a file. If you use the dumpSince argument you will
420 * create an incremental dump, but you can leave it <code>null</code>
421 * for a full dump.
422 *
423 * @param fileName the path name of the file on the client machine to
424 * which to dump this volume
425 * @param dumpSince dump only files that have been modified more recently
426 * than this date
427 * @exception AFSException If an error occurs in the native code
428 */
429 public void dump( String fileName, GregorianCalendar dumpSince )
430 throws AFSException
431 {
432 int startTime = 0;
433 if ( dumpSince != null ) {
434 startTime = (int) ((dumpSince.getTime().getTime())/((long) 1000));
435 }
436 dump( cell.getCellHandle(), server.getVosHandle(), partition.getID(),
437 getID(), startTime, fileName );
438 }
439
440 /**
441 * Dumps this volume to a file. Creates a full dump.
442 *
443 * @param fileName the path name of the file to which to dump this volume
444 * @exception AFSException If an error occurs in the native code
445 */
446 public void dump( String fileName ) throws AFSException
447 {
448 this.dump( fileName, null );
449 }
450
451 /**
452 * Restores a file to this volume. Note that this does not have to be an
453 * existing volume in order to be restored - you may create a
454 * <code>Volume</code> as a volume that doesn't yet exist and then restore
455 * a file to it. Or you can restore over an existing volume. If a new
456 * volume is being created with this method, the id will be automatically
457 * assigned.
458 *
459 * @param fileName the path name of the file on the client machine from
460 * which to restore this volume
461 * @param incremental if true, restores an incremental dump over an
462 * existing volume
463 * @exception AFSException If an error occurs in the native code
464 */
465 public void restore( String fileName, boolean incremental )
466 throws AFSException
467 {
468 restore( fileName, incremental, 0 );
469 }
470
471 /**
472 * Restores a file to this volume. Note that this does not have to be an
473 * existing volume in order to be restored - you may create a
474 * <code>Volume</code> as a volume that doesn't yet exist and then restore
475 * a file to it. Or you can restore over an existing volume.
476 *
477 * @param fileName the path name of the file on the client machine from
478 * which to restore this volume
479 * @param incremental if true, restores an incremental dump over an
480 * existing volume
481 * @param id the id to assign this volume
482 * @exception AFSException If an error occurs in the native code
483 */
484 public void restore( String fileName, boolean incremental, int id )
485 throws AFSException
486 {
487 restore( cell.getCellHandle(), server.getVosHandle(), partition.getID(),
488 id, name, fileName, incremental );
489 }
490
491 /**
492 * Mounts this volume, bringing it online and making it accessible.
493 *
494 * @exception AFSException If an error occurs in the native code
495 */
496 public void mount( ) throws AFSException
497 {
498 mount( server.getVosHandle(), partition.getID(), getID(), 0, true );
499 }
500
501 /**
502 * Unmounts this volume, bringing it offline and making it inaccessible.
503 *
504 * @exception AFSException If an error occurs in the native code
505 */
506 public void unmount( ) throws AFSException
507 {
508 unmount( server.getVosHandle(), partition.getID(), getID() );
509 }
510
511 /**
512 * Locks the VLDB enrty for this volume
513 *
514 * @exception AFSException If an error occurs in the native code
515 */
516 public void lock( ) throws AFSException
517 {
518 lock( cell.getCellHandle(), getID() );
519 }
520
521 /**
522 * Unlocks the VLDB entry for this volume
523 *
524 * @exception AFSException If an error occurs in the native code
525 */
526 public void unlock( ) throws AFSException
527 {
528 unlock( cell.getCellHandle(), getID() );
529 }
530
531 /**
532 * Moves this volume to the specified partition (which indirectly
533 * specifies a new server, as well). Caution: This will remove any backup
534 * volumes at the original site.
535 *
536 * @param newPartition the partition to which to move the volume
537 *
538 * @exception AFSException If an error occurs in the native code
539 */
540 public void moveTo( Partition newPartition ) throws AFSException
541 {
542 Server newServer = newPartition.getServer();
543 move( cell.getCellHandle(), server.getVosHandle(), partition.getID(),
544 newServer.getVosHandle(), newPartition.getID(), getID() );
545
546 server = newServer;
547 partition = newPartition;
548 }
549
550 /**
551 * Renames this volume.
552 *
553 * @param newName the new name for this volume
554 * @exception AFSException If an error occurs in the native code
555 */
556 public void rename( String newName ) throws AFSException
557 {
558 rename( cell.getCellHandle(), getID(), newName );
559 name = newName;
560 }
561
562 /**
563 * Salvages (restores consistency to) this volume. Uses default values for
564 * most salvager options in order to simplify the API.
565 *
566 * @exception AFSException If an error occurs in the native code
567 */
568 public void salvage() throws AFSException
569 {
570 Server.salvage( cell.getCellHandle(), server.getBosHandle(),
571 partition.getName(), name, 4, null, null, false, false,
572 false, false, false, false );
573 }
574
575 /**
576 * Creates a read-write mount point for this volume. Does not ensure the
577 * volume already exists.
578 *
579 * @param directory the name of the directory where this volume
580 * should be mounted
581 * @exception AFSException If an error occurs in the native code
582 */
583 public void createMountPoint( String directory ) throws AFSException
584 {
585 createMountPoint(directory, true);
586 }
587
588 /**
589 * Creates a mount point for this volume. Does not ensure the volume
590 * already exists.
591 *
592 * @param directory the name of the directory where this volume should be
593 * mounted
594 * @param readWrite whether or not this mount point should be read-write
595 * @exception AFSException If an error occurs in the native code
596 */
597 public void createMountPoint( String directory, boolean readWrite )
598 throws AFSException
599 {
600 Cell.createMountPoint( cell.getCellHandle(), directory, getName(),
601 readWrite, false );
602 }
603
604 //////////////// accessors: ////////////////////////
605
606 /**
607 * Returns the name of this volume.
608 *
609 * @return the name of this volume
610 */
611 public String getName()
612 {
613 return name;
614 }
615
616 /**
617 * Returns this volume's hosting partition.
618 *
619 * @return this volume's partition
620 */
621 public Partition getPartition()
622 {
623 return partition;
624 }
625
626 /**
627 * Returns the id of this volume.
628 *
629 * @exception AFSException If an error occurs in the native code
630 * @return the id of this volume
631 */
632 public int getID() throws AFSException
633 {
634 if( id == -1 && name != null ) {
635 String nameNoSuffix;
636 if( name.endsWith( "backup" ) ) {
637 type = VOLUME_TYPE_BACKUP;
638 nameNoSuffix = name.substring( 0, name.lastIndexOf( '.' ) );
639 } else if( name.endsWith( "readonly" ) ) {
640 type = VOLUME_TYPE_READ_ONLY;
641 nameNoSuffix = name.substring( 0, name.lastIndexOf( '.' ) );
642 } else {
643 type = VOLUME_TYPE_READ_WRITE;
644 nameNoSuffix = name;
645 }
646 id = translateNameToID( cell.getCellHandle(),
647 nameNoSuffix, type );
648 }
649 return id;
650 }
651
652 /**
653 * Returns the read-write ID of this volume
654 *
655 * @exception AFSException If an error occurs in the native code
656 * @return the read-write id
657 */
658 public int getReadWriteID() throws AFSException
659 {
660 if( !cachedInfo ) {
661 refreshInfo();
662 }
663 return readWriteID;
664 }
665
666 /**
667 * Returns the read-only ID of this volume
668 *
669 * @exception AFSException If an error occurs in the native code
670 * @return the read-only id
671 */
672 public int getReadOnlyID() throws AFSException
673 {
674 if( !cachedInfo ) {
675 refreshInfo();
676 }
677 return readOnlyID;
678 }
679
680 /**
681 * Returns the backup ID of this volume
682 *
683 * @exception AFSException If an error occurs in the native code
684 * @return the backup id
685 */
686 public int getBackupID() throws AFSException
687 {
688 if( !cachedInfo ) {
689 refreshInfo();
690 }
691 return backupID;
692 }
693
694 /**
695 * Returns the date the volume was created
696 *
697 * @return the date the volume was created
698 * @exception AFSException If an error occurs in the native code
699 */
700 public GregorianCalendar getCreationDate() throws AFSException
701 {
702 if( !cachedInfo ) {
703 refreshInfo();
704 }
705 if( creationDateCal == null ) {
706 // make it into a date . . .
707 creationDateCal = new GregorianCalendar();
708 Date d = new Date( creationDate*1000 );
709 creationDateCal.setTime( d );
710 }
711 return creationDateCal;
712 }
713
714 /**
715 * Returns the date the volume was last updated.
716 * After this method is called once, it saves the date
717 * and returns that date on subsequent calls,
718 * until the {@link #refresh()} method is called and a more current
719 * value is obtained.
720 *
721 * @return the date the volume was last updated
722 * @exception AFSException If an error occurs in the native code
723 */
724 public GregorianCalendar getLastUpdateDate() throws AFSException
725 {
726 if( !cachedInfo ) {
727 refreshInfo();
728 }
729 if( lastUpdateDateCal == null ) {
730 // make it into a date . . .
731 lastUpdateDateCal = new GregorianCalendar();
732 Date d = new Date( lastUpdateDate*1000 );
733 lastUpdateDateCal.setTime( d );
734 }
735 return lastUpdateDateCal;
736 }
737
738 /**
739 * Returns the date the volume was copied.
740 * After this method is called once, it saves the date
741 * and returns that date on subsequent calls,
742 * until the {@link #refresh()} method is called and a more current
743 * value is obtained.
744 *
745 * @return the date the volume was copied
746 * @exception AFSException If an error occurs in the native code
747 */
748 public GregorianCalendar getCopyCreationDate() throws AFSException
749 {
750 if( !cachedInfo ) {
751 refreshInfo();
752 }
753 if( copyCreationDateCal == null ) {
754 // make it into a date . . .
755 copyCreationDateCal = new GregorianCalendar();
756 Date d = new Date( copyCreationDate*1000 );
757 copyCreationDateCal.setTime( d );
758 }
759 return copyCreationDateCal;
760 }
761
762 /**
763 * Returns the number of accesses since midnight.
764 * After this method is called once, it saves the value
765 * and returns that value on subsequent calls,
766 * until the {@link #refresh()} method is called and a more current
767 * value is obtained.
768 *
769 * @exception AFSException If an error occurs in the native code
770 * @return the number of accesses since midnight
771 */
772 public int getAccessesSinceMidnight() throws AFSException
773 {
774 if( !cachedInfo ) {
775 refreshInfo();
776 }
777 return accessesSinceMidnight;
778 }
779
780 /**
781 * Returns file count.
782 * After this method is called once, it saves the value
783 * and returns that value on subsequent calls,
784 * until the {@link #refresh()} method is called and a more current
785 * value is obtained.
786 *
787 * @exception AFSException If an error occurs in the native code
788 * @return the file count
789 */
790 public int getFileCount() throws AFSException
791 {
792 if( !cachedInfo ) {
793 refreshInfo();
794 }
795 return fileCount;
796 }
797
798 /**
799 * Returns current volume size in K.
800 * After this method is called once, it saves the value
801 * and returns that value on subsequent calls,
802 * until the {@link #refresh()} method is called and a more current
803 * value is obtained.
804 *
805 * @exception AFSException If an error occurs in the native code
806 * @return the current volume size in K
807 */
808 public int getCurrentSize() throws AFSException
809 {
810 if( !cachedInfo ) refreshInfo();
811 return currentSize;
812 }
813
814 /**
815 * Returns the difference between quota and current volume size (in K).
816 *
817 * <P> Please note: the product of this method is <U>not</U> saved.
818 *
819 * @exception AFSException If an error occurs in the native code
820 * @return the current free space in K
821 */
822 public int getTotalFreeSpace() throws AFSException
823 {
824 if ( !cachedInfo ) refreshInfo();
825 return (maxQuota - currentSize);
826 }
827
828 /**
829 * Returns this volume's quota, expressed in kilobyte blocks (1024
830 * kilobyte blocks equal one megabyte). After this method is called once,
831 * it saves the value and returns that value on subsequent calls,
832 * until the {@link #refresh()} method is called and a more current
833 * value is obtained.
834 *
835 * <P><B>Note:</B> A quota value of zero, "0", grants an unlimited quota
836 * in AFS. Consequently, to avoid delusion this method will throw an
837 * {@link AFSException} if the returning value is zero.
838 *
839 * @exception AFSException If an error occurs in the native code or
840 * this volume's quota is configured as
841 * unlimited.
842 * @return the volume quota in K
843 * @see #isQuotaUnlimited()
844 */
845 public int getQuota() throws AFSException
846 {
847 if ( !cachedInfo ) refreshInfo();
848 if (maxQuota == 0) {
849 throw new AFSException("Volume with id " + id +
850 " has an unlimited quota configured.", 0);
851 }
852 return maxQuota;
853 }
854
855 /**
856 * Tests whether this volume's quota is configured as unlimited.
857 *
858 * <P>After this method is called once, it saves the value and returns
859 * that value on subsequent calls, until the {@link #refresh()}
860 * method is called and a more current value is obtained.
861 *
862 * @exception AFSException If an error occurs in the native code
863 * @return <CODE>true</CODE> if this volume's quota is configured as
864 * unlimited; otherwise <CODE>false</CODE>.
865 * @see #getQuota()
866 */
867 public boolean isQuotaUnlimited() throws AFSException
868 {
869 if ( !cachedInfo ) refreshInfo();
870 return (maxQuota == 0);
871 }
872
873 /**
874 * Returns volume status. Possible values are:<ul>
875 * <li>{@link #VOLUME_OK}</li>
876 * <li>{@link #VOLUME_SALVAGE}</li>
877 * <li>{@link #VOLUME_NO_VNODE}</li>
878 * <li>{@link #VOLUME_NO_VOL}</li>
879 * <li>{@link #VOLUME_VOL_EXISTS}</li>
880 * <li>{@link #VOLUME_NO_SERVICE}</li>
881 * <li>{@link #VOLUME_OFFLINE}</li>
882 * <li>{@link #VOLUME_ONLINE}</li>
883 * <li>{@link #VOLUME_DISK_FULL}</li>
884 * <li>{@link #VOLUME_OVER_QUOTA}</li>
885 * <li>{@link #VOLUME_BUSY}</li>
886 * <li>{@link #VOLUME_MOVED}</li></ul>
887 * Typical value is VOLUME_OK.
888 * After this method is called once, it saves the value
889 * and returns that value on subsequent calls,
890 * until the {@link #refresh()} method is called and a more current
891 * value is obtained.
892 *
893 * @exception AFSException If an error occurs in the native code
894 * @return volume status
895 */
896 public int getStatus() throws AFSException
897 {
898 if( !cachedInfo ) refreshInfo();
899 return status;
900 }
901
902 /**
903 * Returns volume disposition. Possible values are:<ul>
904 * <li>{@link #VOLUME_OK}</li>
905 * <li>{@link #VOLUME_SALVAGE}</li>
906 * <li>{@link #VOLUME_NO_VNODE}</li>
907 * <li>{@link #VOLUME_NO_VOL}</li>
908 * <li>{@link #VOLUME_VOL_EXISTS}</li>
909 * <li>{@link #VOLUME_NO_SERVICE}</li>
910 * <li>{@link #VOLUME_OFFLINE}</li>
911 * <li>{@link #VOLUME_ONLINE}</li>
912 * <li>{@link #VOLUME_DISK_FULL}</li>
913 * <li>{@link #VOLUME_OVER_QUOTA}</li>
914 * <li>{@link #VOLUME_BUSY}</li>
915 * <li>{@link #VOLUME_MOVED}</li></ul>
916 * Typical value is VOLUME_ONLINE.
917 * After this method is called once, it saves the value
918 * and returns that value on subsequent calls,
919 * until the {@link #refresh()} method is called and a more current
920 * value is obtained.
921 *
922 * @exception AFSException If an error occurs in the native code
923 * @return volume disposition
924 */
925 public int getDisposition() throws AFSException
926 {
927 if( !cachedInfo ) refreshInfo();
928 return disposition;
929 }
930
931 /**
932 * Returns volume type. Possible values are:<ul>
933 * <li>{@link #VOLUME_TYPE_READ_WRITE}</li>
934 * <li>{@link #VOLUME_TYPE_READ_ONLY}</li>
935 * <li>{@link #VOLUME_TYPE_BACKUP}</li></ul>
936 *
937 * @exception AFSException If an error occurs in the native code
938 * @return volume type
939 */
940 public int getType() throws AFSException
941 {
942 if( !cachedInfo ) refreshInfo();
943 return type;
944 }
945
946 //////////////// mutators: ////////////////////////
947
948 /**
949 * Sets quota of volume, 0 denotes an unlimited quota.
950 *
951 * @exception AFSException If an error occurs in the native code
952 * @param quota the new volume quota in K (0 for unlimited)
953 */
954 public void setQuota( int quota ) throws AFSException
955 {
956 this.changeQuota( cell.getCellHandle(), server.getVosHandle(),
957 partition.getID(), getID(), quota );
958 maxQuota = quota;
959 }
960
961 /////////////// custom information methods ////////////////////
962
963 /**
964 * Returns a <code>String</code> representation of this <code>Volume</code>.
965 * Contains the information fields.
966 *
967 * @return a <code>String</code> representation of the <code>Volume</code>
968 */
969 public String getInfo()
970 {
971 String r;
972 try {
973 r = "Volume: " + name + "\tid: " + getID() + "\n";
974
975 r += "\tread-write id: " + getReadWriteID() + "\tread-only id: "
976 + getReadOnlyID() + "\n";
977 r += "\tbackup id: " + getBackupID() + "\n";
978
979 r += "\tcreation date: " + getCreationDate().getTime() + "\n";
980 r += "\tlast update date: " + getLastUpdateDate().getTime() + "\n";
981 r += "\tcopy creation date: " + getCopyCreationDate().getTime() + "\n";
982 r += "\taccesses since midnight: " + getAccessesSinceMidnight() + "\n";
983 r += "\tfile count: " + getFileCount() + "\n";
984 r += "\tcurrent size: " + getCurrentSize() + " K\tquota: " +
985 getQuota() + " K\n";
986 r += "\tstatus: ";
987 switch( getStatus() ) {
988 case VOLUME_OK:
989 r += "OK";
990 break;
991 default:
992 r += "OTHER";
993 }
994
995 r += "\tdisposition: ";
996 switch( getDisposition() ) {
997 case VOLUME_ONLINE:
998 r += "ONLINE";
999 break;
1000 default:
1001 r += "OTHER - " + getDisposition();
1002 }
1003 r += "\n";
1004
1005 r += "\ttype: ";
1006 switch( getType() ) {
1007 case VOLUME_TYPE_READ_WRITE:
1008 r += "read-write";
1009 break;
1010 case VOLUME_TYPE_READ_ONLY:
1011 r += "read-only";
1012 break;
1013 case VOLUME_TYPE_BACKUP:
1014 r += "backup";
1015 break;
1016 default:
1017 r += "OTHER";
1018 }
1019 r += "\n";
1020
1021 } catch( Exception e ) {
1022 return e.toString();
1023 }
1024 return r;
1025 }
1026
1027 /////////////// custom override methods ////////////////////
1028
1029 /**
1030 * Compares two Volume objects respective to their names and does not
1031 * factor any other attribute. Alphabetic case is significant in
1032 * comparing names.
1033 *
1034 * @param volume The Volume object to be compared to this Volume
1035 * instance
1036 *
1037 * @return Zero if the argument is equal to this Volume's name, a
1038 * value less than zero if this Volume's name is
1039 * lexicographically less than the argument, or a value greater
1040 * than zero if this Volume's name is lexicographically
1041 * greater than the argument
1042 */
1043 public int compareTo(Volume volume)
1044 {
1045 return this.getName().compareTo(volume.getName());
1046 }
1047
1048 /**
1049 * Comparable interface method.
1050 *
1051 * @see #compareTo(Volume)
1052 */
1053 public int compareTo(Object obj)
1054 {
1055 return compareTo((Volume)obj);
1056 }
1057
1058 /**
1059 * Tests whether two <code>Volume</code> objects are equal, based on their
1060 * names and hosting partition.
1061 *
1062 * @param otherVolume the Volume to test
1063 * @return whether the specifed Volume is the same as this Volume
1064 */
1065 public boolean equals( Volume otherVolume )
1066 {
1067 return ( name.equals(otherVolume.getName()) ) &&
1068 ( this.getPartition().equals(otherVolume.getPartition()) );
1069 }
1070
1071 /**
1072 * Returns the name of this <CODE>Volume</CODE>
1073 *
1074 * @return the name of this <CODE>Volume</CODE>
1075 */
1076 public String toString()
1077 {
1078 return getName();
1079 }
1080
1081
1082 /////////////// native methods ////////////////////
1083
1084 /**
1085 * Fills in the information fields of the provided <code>Volume</code>.
1086 *
1087 * @param cellHandle the handle of the cell to which the volume belongs
1088 * @see Cell#getCellHandle
1089 * @param serverHandle the vos handle of the server on which the volume
1090 * resides
1091 * @see Server#getVosServerHandle
1092 * @param partition the numeric id of the partition on which the volume
1093 * resides
1094 * @param volId the numeric id of the volume for which to get the info
1095 * @param theVolume the {@link Volume Volume} object in which to fill in
1096 * the information
1097 * @exception AFSException If an error occurs in the native code
1098 */
1099 protected static native void getVolumeInfo( long cellHandle, long serverHandle,
1100 int partition, int volId,
1101 Volume theVolume )
1102 throws AFSException;
1103
1104 /**
1105 * Creates a volume on a particular partition.
1106 *
1107 * @param cellHandle the handle of the cell in which to create the volume
1108 * @see Cell#getCellHandle
1109 * @param serverHandle the vos handle of the server on which to create
1110 * the volume
1111 * @see Server#getVosServerHandle
1112 * @param partition the numeric id of the partition on which to create
1113 * the volume
1114 * @param volumeName the name of the volume to create
1115 * @param quota the amount of space (in KB) to set as this volume's quota
1116 * @return the numeric ID assigned to the volume
1117 * @exception AFSException If an error occurs in the native code
1118 */
1119 protected static native int create( long cellHandle, long serverHandle,
1120 int partition, String volumeName,
1121 int quota )
1122 throws AFSException;
1123
1124 /**
1125 * Deletes a volume from a particular partition.
1126 *
1127 * @param cellHandle the handle of the cell in which to delete the volume
1128 * @see Cell#getCellHandle
1129 * @param serverHandle the vos handle of the server from which to delete
1130 * the volume
1131 * @see Server#getVosServerHandle
1132 * @param partition the numeric id of the partition from which to delete
1133 * the volume
1134 * @param volId the numeric id of the volume to delete
1135 * @exception AFSException If an error occurs in the native code
1136 */
1137 protected static native void delete( long cellHandle, long serverHandle,
1138 int partition, int volId )
1139 throws AFSException;
1140
1141 /**
1142 * Creates a backup volume for the specified regular volume.
1143 *
1144 * @param cellHandle the handle of the cell to which the volume belongs
1145 * @param volId the numeric id of the volume for which to create a backup
1146 * volume
1147 * @see Cell#getCellHandle
1148 */
1149 protected static native void createBackupVolume( long cellHandle, int volId )
1150 throws AFSException;
1151
1152 /**
1153 * Creates a read-only volume for the specified regular volume.
1154 *
1155 * @param cellHandle the handle of the cell to which the volume belongs
1156 * @param serverHandle the vos handle of the server on which the read-only
1157 * volume is to reside
1158 * @see Server#getVosServerHandle
1159 * @param partition the numeric id of the partition on which the read-only
1160 volume is to reside
1161 * @param volId the numeric id of the volume for which to create a read-only volume
1162 * @see Cell#getCellHandle
1163 */
1164 protected static native void createReadOnlyVolume( long cellHandle,
1165 long serverHandle,
1166 int partition, int volId )
1167 throws AFSException;
1168
1169 /**
1170 * Deletes a read-only volume for the specified regular volume.
1171 *
1172 * @param cellHandle the handle of the cell to which the volume belongs
1173 * @param serverHandle the vos handle of the server on which the read-only
1174 * volume residea
1175 * @see Server#getVosServerHandle
1176 * @param partition the numeric id of the partition on which the read-only
1177 * volume resides
1178 * @param volId the numeric read-write id of the volume for which to
1179 * delete the read-only volume
1180 * @see Cell#getCellHandle
1181 */
1182 protected static native void deleteReadOnlyVolume( long cellHandle,
1183 long serverHandle,
1184 int partition, int volId )
1185 throws AFSException;
1186
1187 /**
1188 * Changes the quota of the specified volume.
1189 *
1190 * @param cellHandle the handle of the cell to which the volume belongs
1191 * @see Cell#getCellHandle
1192 * @param serverHandle the vos handle of the server on which the volume
1193 * resides
1194 * @see Server#getVosServerHandle
1195 * @param partition the numeric id of the partition on which the volume
1196 * resides
1197 * @param volId the numeric id of the volume for which to change the quota
1198 * @param newQuota the new quota (in KB) to assign the volume
1199 * @exception AFSException If an error occurs in the native code
1200 */
1201 protected static native void changeQuota( long cellHandle, long serverHandle,
1202 int partition, int volId,
1203 int newQuota )
1204 throws AFSException;
1205
1206 /**
1207 * Move the specified volume to a different site.
1208 *
1209 * @param cellHandle the handle of the cell to which the volume belongs
1210 * @see Cell#getCellHandle
1211 * @param fromServerHandle the vos handle of the server on which the volume
1212 * currently resides
1213 * @see Server#getVosServerHandle
1214 * @param fromPartition the numeric id of the partition on which the volume
1215 * currently resides
1216 * @param toServerHandle the vos handle of the server to which the volume
1217 * should be moved
1218 * @param toPartition the numeric id of the partition to which the volume
1219 * should be moved
1220 * @param volId the numeric id of the volume to move
1221 * @exception AFSException If an error occurs in the native code
1222 */
1223 protected static native void move( long cellHandle, long fromServerHandle,
1224 int fromPartition, long toServerHandle,
1225 int toPartition, int volId )
1226 throws AFSException;
1227
1228 /**
1229 * Releases the specified volume that has readonly volume sites.
1230 *
1231 * @param cellHandle the handle of the cell to which the volume belongs
1232 * @param volId the numeric id of the volume to release
1233 * @param forceComplete whether or not to force a complete release
1234 * @see Cell#getCellHandle
1235 */
1236 protected static native void release( long cellHandle, int volId,
1237 boolean forceComplete )
1238 throws AFSException;
1239
1240 /**
1241 * Dumps the specified volume to a file.
1242 *
1243 * @param cellHandle the handle of the cell to which the volume belongs
1244 * @see Cell#getCellHandle
1245 * @param serverHandle the vos handle of the server on which the volume
1246 * resides
1247 * @see Server#getVosServerHandle
1248 * @param partition the numeric id of the partition on which the
1249 * volume resides
1250 * @param volId the numeric id of the volume to dump
1251 * @param startTime files with a modification time >= to this time will
1252 * be dumped
1253 * @param dumpFile the full path of the file to which to dump
1254 * @exception AFSException If an error occurs in the native code
1255 */
1256 protected static native void dump( long cellHandle, long serverHandle,
1257 int partition, int volId, int startTime,
1258 String dumpFile )
1259 throws AFSException;
1260
1261 /**
1262 * Restores the specified volume from a dump file.
1263 *
1264 * @param cellHandle the handle of the cell to which the volume belongs
1265 * @see Cell#getCellHandle
1266 * @param serverHandle the vos handle of the server on which the volume is
1267 * to reside
1268 * @see Server#getVosServerHandle
1269 * @param partition the numeric id of the partition on which the volume is
1270 * to reside
1271 * @param volId the numeric id to assign the restored volume (can be 0)
1272 * @param volumeName the name of the volume to restore as
1273 * @param dumpFile the full path of the dump file from which to restore
1274 * @param incremental if true, restores an incremental dump over an existing
1275 * volume (server and partition values must correctly
1276 * indicate the current position of the existing volume),
1277 * otherwise restores a full dump
1278 * @exception AFSException If an error occurs in the native code
1279 */
1280 protected static native void restore( long cellHandle, long serverHandle,
1281 int partition, int volId,
1282 String volumeName, String dumpFile,
1283 boolean incremental )
1284 throws AFSException;
1285
1286 /**
1287 * Renames the specified read-write volume.
1288 *
1289 * @param cellHandle the handle of the cell to which the volume belongs
1290 * @see Cell#getCellHandle
1291 * @param volId the numeric id of the read-write volume to rename
1292 * @param newVolumeName the new name for the volume
1293 * @exception AFSException If an error occurs in the native code
1294 */
1295 protected static native void rename( long cellHandle, int volId,
1296 String newVolumeName )
1297 throws AFSException;
1298
1299 /**
1300 * "Mounts" the specified volume, bringing it online.
1301 *
1302 * @param serverHandle the vos handle of the server on which the volume
1303 * resides
1304 * @see Server#getVosServerHandle
1305 * @param partition the numeric id of the partition on which the volume
1306 * resides
1307 * @param volId the numeric id of the volume to bring online
1308 * @param sleepTime ? (not sure what this is yet, possibly a time to wait
1309 * before brining it online)
1310 * @param offline ? (not sure what this is either, probably the current
1311 * status of the volume -- busy or offline)
1312 * @exception AFSException If an error occurs in the native code
1313 */
1314 protected static native void mount( long serverHandle, int partition,
1315 int volId, int sleepTime,
1316 boolean offline )
1317 throws AFSException;
1318
1319 /**
1320 * "Unmounts" the specified volume, bringing it offline.
1321 *
1322 * @param serverHandle the vos handle of the server on which the volume
1323 * resides
1324 * @see Server#getVosServerHandle
1325 * @param partition the numeric id of the partition on which the volume
1326 * resides
1327 * @param volId the numeric id of the volume to bring offline
1328 * @exception AFSException If an error occurs in the native code
1329 */
1330 protected static native void unmount( long serverHandle, int partition,
1331 int volId )
1332 throws AFSException;
1333
1334 /**
1335 * Locks the VLDB entry specified volume
1336 *
1337 * @param cellHandle the handle of the cell on which the volume resides
1338 * @see Cell#getCellHandle
1339 * @param volId the numeric id of the volume to lock
1340 * @exception AFSException If an error occurs in the native code
1341 */
1342 protected static native void lock( long cellHandle, int volId )
1343 throws AFSException;
1344
1345 /**
1346 * Unlocks the VLDB entry of the specified volume
1347 *
1348 * @param cellHandle the handle of the cell on which the volume resides
1349 * @see Cell#getCellHandle
1350 * @param volId the numeric id of the volume to unlock
1351 * @exception AFSException If an error occurs in the native code
1352 */
1353 protected static native void unlock( long cellHandle, int volId )
1354 throws AFSException;
1355
1356 /**
1357 * Translates a volume name into a volume id
1358 *
1359 * @param cellHandle the handle of the cell to which the volume belongs
1360 * @see Cell#getCellHandle
1361 * @param name the name of the volume in question, cannot end in backup or
1362 * readonly
1363 * @param type the type of volume: read-write, read-only, or backup.
1364 * Acceptable values are:<ul>
1365 * <li>{@link #VOLUME_TYPE_READ_WRITE}</li>
1366 * <li>{@link #VOLUME_TYPE_READ_ONLY}</li>
1367 * <li>{@link #VOLUME_TYPE_BACKUP}</li></ul>
1368 * @return the id of the volume in question
1369 * @exception AFSException If an error occurs in the native code
1370 */
1371 protected static native int translateNameToID( long cellHandle, String name,
1372 int volumeType )
1373 throws AFSException;
1374
1375 /**
1376 * Reclaims all memory being saved by the volume portion of the native
1377 * library. This method should be called when no more <code>Volume</code>
1378 * objects are expected to be used.
1379 */
1380 protected static native void reclaimVolumeMemory();
1381 }
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394