2 * @(#)Process.java 1.0 6/29/2001
4 * Copyright (c) 2001 International Business Machines Corp.
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
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.
24 package org
.openafs
.jafs
;
26 import java
.util
.GregorianCalendar
;
27 import java
.util
.Date
;
28 import java
.io
.Serializable
;
31 * An abstract representation of an AFS process. It holds information about
32 * the server, such as what its state is.
35 * Constructing an instance of a <code>Process</code> does not mean an actual
36 * AFS process is created on a server -- usually a <code>Process</code>
37 * object is a representation of an already existing AFS process. If,
38 * however, the <code>Process</code> is constructed with the name of a
39 * process that does not exist in the server represented by the provided
40 * <code>Server</code>, a new process with that name can be
41 * created on that server by calling one of the {@link #createSimple(String)},
42 * {@link #createFS(String)}, or {@link #createCron(String,String)} methods. If
43 * such a process does already exist when one of these methods are called,
44 * an exception will be thrown.<BR><BR>
46 * <!--Information on how member values are set-->
48 * <!--Example of how to use class-->
49 * The following is a simple example of how to construct and use a
50 * <code>Process</code> object. This example obtains the list of all
51 * <code>Process</code> objects on a particular server and prints out the
52 * name of each one along with its start time.<BR><BR>
55 * import org.openafs.jafs.Cell;
56 * import org.openafs.jafs.AFSException;
57 * import org.openafs.jafs.Process;
58 * import org.openafs.jafs.Server;
64 * private Server server;
66 * public static void main(String[] args) throws Exception
68 * String username = arg[0];
69 * String password = arg[1];
70 * String cellName = arg[2];
71 * String serverName = arg[3];
73 * token = new Token(username, password, cellName);
74 * cell = new Cell(token);
75 * server = new Server(serverName, cell);
77 * System.out.println("Processes in Server " + server.getName() + ":");
78 * Process[] processes = server.getProcesss();
79 * for (int i = 0; i < processes.length; i++) {
80 * System.out.print("Process " + processes[i].getName());
81 * System.out.print("was started: " +
82 * processes[i].getStartTimeDate().getTime() + "\n");
90 public class Process
implements Serializable
, Comparable
93 * Any standard type of process except for fs (such as kaserver,
96 public static final int SIMPLE_PROCESS
= 0;
99 * Combination of File Server, Volume Server, and Salvager processes
101 public static final int FS_PROCESS
= 1;
104 * A process that should be restarted at a specific time either daily
107 public static final int CRON_PROCESS
= 2;
110 * Process execution state stopped
112 public static final int STOPPED
= 0;
115 * Process execution state running
117 public static final int RUNNING
= 1;
120 * Process execution state stopping
122 public static final int STOPPING
= 2;
125 * Process execution state starting
127 public static final int STARTING
= 3;
129 protected String name
;
130 protected Server server
;
131 protected long serverHandle
;
137 protected long startTime
;
138 protected long numberStarts
;
139 protected long exitTime
;
140 protected long exitErrorTime
;
141 protected long errorCode
;
142 protected long errorSignal
;
144 protected boolean stateOk
;
145 protected boolean stateTooManyErrors
;
146 protected boolean stateBadFileAccess
;
148 protected GregorianCalendar startTimeDate
;
149 protected GregorianCalendar exitTimeDate
;
150 protected GregorianCalendar exitErrorTimeDate
;
152 protected boolean cachedInfo
;
155 * Constructs a new <code>Process</code> object instance given the name
156 * of the AFS process and the AFS server, represented by
157 * <CODE>server</CODE>, to which it belongs. This does not actually
158 * create a new AFS process, it just represents one.
159 * If <code>name</code> is not an actual AFS process, exceptions
160 * will be thrown during subsequent method invocations on this
161 * object, unless one of the {@link #createSimple(String)},
162 * {@link #createFS(String)}, or {@link #createCron(String,String)}
163 * methods are explicitly called to create it.
165 * @param name the name of the server to represent
166 * @param server the server on which the process resides
167 * @exception AFSException If an error occurs in the native code
169 public Process( String name
, Server server
) throws AFSException
172 this.server
= server
;
173 serverHandle
= server
.getBosHandle();
175 startTimeDate
= null;
177 exitErrorTimeDate
= null;
183 * Constructs a new <CODE>Process</CODE> object instance given the name
184 * of the AFS process and the AFS server, represented by
185 * <CODE>server</CODE>, to which it belongs. This does not actually
186 * create a new AFS process, it just represents one.
187 * If <code>name</code> is not an actual AFS process, exceptions
188 * will be thrown during subsequent method invocations on this
189 * object, unless one of the {@link #createSimple(String)},
190 * {@link #createFS(String)}, or {@link #createCron(String,String)}
191 * methods are explicitly called to create it. Note that if he process
192 * doesn't exist and <code>preloadAllMembers</code> is true, an exception
195 * <P> This constructor is ideal for point-in-time representation and
196 * transient applications. It ensures all data member values are set and
197 * available without calling back to the filesystem at the first request
198 * for them. Use the {@link #refresh()} method to address any coherency
201 * @param name the name of the process to represent
202 * @param server the server to which the process belongs.
203 * @param preloadAllMembers true will ensure all object members are
204 * set upon construction; otherwise members will
205 * be set upon access, which is the default
207 * @exception AFSException If an error occurs in the native code
210 public Process( String name
, Server server
, boolean preloadAllMembers
)
214 if (preloadAllMembers
) refresh(true);
218 * Creates a blank <code>Process</code> given the server to which the process
219 * belongs. This blank object can then be passed into other methods to fill
220 * out its properties.
222 * @param server the server to which the process belongs.
223 * @exception AFSException If an error occurs in the native code
225 Process( Server server
) throws AFSException
227 this( null, server
);
230 /*-------------------------------------------------------------------------*/
233 * Refreshes the properties of this Process object instance with values
234 * from the AFS process it represents. All properties that have been
235 * initialized and/or accessed will be renewed according to the values of
236 * the AFS process this Process object instance represents.
238 * <P>Since in most environments administrative changes can be administered
239 * from an AFS command-line program or an alternate GUI application, this
240 * method provides a means to refresh the Java object representation and
241 * thereby ascertain any possible modifications that may have been made
242 * from such alternate administrative programs. Using this method before
243 * an associated instance accessor will ensure the highest level of
244 * representative accuracy, accommodating changes made external to the
245 * Java application space. If administrative changes to the underlying AFS
246 * system are only allowed via this API, then the use of this method is
249 * @exception AFSException If an error occurs in the native code
251 public void refresh() throws AFSException
257 * Refreshes the properties of this Process object instance with values from
258 * the AFS process it represents. If <CODE>all</CODE> is <CODE>true</CODE>
259 * then <U>all</U> of the properties of this Process object instance will be
260 * set, or renewed, according to the values of the AFS process it represents,
261 * disregarding any previously set properties.
263 * <P> Thus, if <CODE>all</CODE> is <CODE>false</CODE> then properties that
264 * are currently set will be refreshed and properties that are not set will
265 * remain uninitialized. See {@link #refresh()} for more information.
267 * @param all if true set or renew all object properties; otherwise renew
269 * @exception AFSException If an error occurs in the native code
272 protected void refresh(boolean all
) throws AFSException
274 if (all
|| cachedInfo
) refreshInfo();
278 * Refreshes the information fields of this <code>Process</code> to reflect
279 * the current state of the AFS process, such as the start time, the state,
282 * @exception AFSException If an error occurs in the native code
284 protected void refreshInfo() throws AFSException
286 getProcessInfo( server
.getBosHandle(), name
, this );
288 startTimeDate
= null;
290 exitErrorTimeDate
= null;
294 * Creates this process as a simple process on the server.
296 * @param executionPath the path to the process's executable
297 * @exception AFSException If an error occurs in the native code
299 public void createSimple( String executionPath
) throws AFSException
301 create( server
.getBosHandle(), name
, SIMPLE_PROCESS
, executionPath
, null,
306 * Creates this process as a file server process on the server.
308 * @param executionPath the path to the process's executable
309 * @exception AFSException If an error occurs in the native code
311 public void createFS( String executionPath
) throws AFSException
313 create( server
.getBosHandle(), name
, FS_PROCESS
, executionPath
, null,
318 * Creates this process as a cron process on the server.
320 * @param executionPath the path to the process's executable
321 * @param cronTime a String representing the time a cron process is
322 * to be run. Acceptable formats are:<ul>
323 * <li>for daily restarts: "23:10" or "11:10 pm"</li>
324 * <li>for weekly restarts: "sunday 11:10pm" or
327 * @exception AFSException If an error occurs in the native code
329 public void createCron( String executionPath
, String cronTime
)
332 create( server
.getBosHandle(), name
, CRON_PROCESS
, executionPath
,
337 * Removes this process from the bos server
339 * @exception AFSException If an error occurs in the native code
341 public void delete() throws AFSException
343 delete( server
.getBosHandle(), name
);
347 * Stops this process.
349 * @exception AFSException If an error occurs in the native code
351 public void stop() throws AFSException
355 stop( server
.getBosHandle(), name
);
359 * Starts this process
361 * @exception AFSException If an error occurs in the native code
363 public void start() throws AFSException
366 start( server
.getBosHandle(), name
);
370 * Restarts this process
372 * @exception AFSException If an error occurs in the native code
374 public void restart() throws AFSException
377 restart( server
.getBosHandle(), name
);
380 //////////////// accessors: ////////////////////////
383 * Returns the name of this process.
385 * @return the name of this process
387 public String
getName()
393 * Returns the server hosting this process.
395 * @return this process' server
397 public Server
getServer()
403 * Returns the process type. Possible values are:<ul>
404 * <li>{@link #SIMPLE_PROCESS}</li>
405 * <li>{@link #FS_PROCESS}</li>
406 * <li>{@link #CRON_PROCESS}</li></ul>
408 * @return the process type
409 * @exception AFSException If an error occurs in the native code
411 public int getType() throws AFSException
413 if (!cachedInfo
) refreshInfo();
418 * Returns the process goal. Possible values are:<ul>
419 * <li>{@link #STOPPED}</li>
420 * <li>{@link #RUNNING}</li>
421 * <li>{@link #STARTING}</li>
422 * <li>{@link #STOPPING}</li></ul>
423 * After this method is called once, it saves the value
424 * and returns that value on subsequent calls,
425 * until the {@link #refresh()} method is called and a more current
428 * @return the process goal
429 * @exception AFSException If an error occurs in the native code
431 public int getGoal() throws AFSException
433 if (!cachedInfo
) refreshInfo();
438 * Returns the process execution state. Possible values are:<ul>
439 * <li>{@link #STOPPED}</li>
440 * <li>{@link #RUNNING}</li>
441 * <li>{@link #STARTING}</li>
442 * <li>{@link #STOPPING}</li></ul>
443 * After this method is called once, it saves the value
444 * and returns that value on subsequent calls,
445 * until the {@link #refresh()} method is called and a more current
448 * @return the process execution state
449 * @exception AFSException If an error occurs in the native code
451 public int getState() throws AFSException
453 if (!cachedInfo
) refreshInfo();
458 * Returns the most recent start time of this process. A
459 * <code>null</code> value
460 * indicates no start time.
461 * After this method is called once, it saves the value
462 * and returns that value on subsequent calls,
463 * until the {@link #refresh()} method is called and a more current
466 * @return the start time
467 * @exception AFSException If an error occurs in the native code
469 public long getStartTime() throws AFSException
471 if (!cachedInfo
) refreshInfo();
476 * Returns the most recent start time of this process. A <code>null</code>
477 * value indicates no start time.
478 * After this method is called once, it saves the value
479 * and returns that value on subsequent calls,
480 * until the {@link #refresh()} method is called and a more current
483 * @return the start time
484 * @exception AFSException If an error occurs in the native code
486 public GregorianCalendar
getStartTimeDate() throws AFSException
491 if( startTimeDate
== null && startTime
!= 0 ) {
492 // make it into a date . . .
493 startTimeDate
= new GregorianCalendar();
494 long longTime
= startTime
* 1000;
495 Date d
= new Date( longTime
);
496 startTimeDate
.setTime( d
);
498 return startTimeDate
;
502 * Returns the number of starts of the process.
503 * After this method is called once, it saves the value
504 * and returns that value on subsequent calls,
505 * until the {@link #refresh()} method is called and a more current
508 * @return the number of starts
509 * @exception AFSException If an error occurs in the native code
511 public long getNumberOfStarts() throws AFSException
513 if (!cachedInfo
) refreshInfo();
518 * Returns the most recent exit time of this process. A <code>null</code>
519 * value indicates no exit time.
520 * After this method is called once, it saves the value
521 * and returns that value on subsequent calls,
522 * until the {@link #refresh()} method is called and a more current
525 * @return the exit time
526 * @exception AFSException If an error occurs in the native code
528 public long getExitTime() throws AFSException
530 if (!cachedInfo
) refreshInfo();
535 * Returns the most recent exit time of this process. A <code>null</code>
536 * value indicates no exit time
537 * After this method is called once, it saves the value
538 * and returns that value on subsequent calls,
539 * until the {@link #refresh()} method is called and a more current
542 * @return the exit time
543 * @exception AFSException If an error occurs in the native code
545 public GregorianCalendar
getExitTimeDate() throws AFSException
547 if (!cachedInfo
) refreshInfo();
548 if( exitTimeDate
== null && exitTime
!= 0 ) {
549 // make it into a date . . .
550 exitTimeDate
= new GregorianCalendar();
551 long longTime
= exitTime
*1000;
552 Date d
= new Date( longTime
);
553 exitTimeDate
.setTime( d
);
559 * Returns the most recent time this process exited with an error. A
560 * <code>null</code> value indicates no exit w/ error time.
561 * After this method is called once, it saves the value
562 * and returns that value on subsequent calls,
563 * until the {@link #refresh()} method is called and a more current
566 * @return the exit w/ error time
567 * @exception AFSException If an error occurs in the native code
569 public long getExitErrorTime() throws AFSException
571 if (!cachedInfo
) refreshInfo();
572 return exitErrorTime
;
576 * Returns the most recent time this process exited with an error. A <
577 * code>null</code> value indicates no exit w/ error time.
578 * After this method is called once, it saves the value
579 * and returns that value on subsequent calls,
580 * until the {@link #refresh()} method is called and a more current
583 * @return the exit w/ error time
584 * @exception AFSException If an error occurs in the native code
586 public GregorianCalendar
getExitErrorTimeDate() throws AFSException
588 if (!cachedInfo
) refreshInfo();
589 if (exitErrorTimeDate
== null && exitErrorTime
!= 0) {
590 // make it into a date . . .
591 exitErrorTimeDate
= new GregorianCalendar();
592 long longTime
= exitErrorTime
*1000;
593 Date d
= new Date( longTime
);
594 exitErrorTimeDate
.setTime( d
);
596 return exitErrorTimeDate
;
600 * Returns the error code of the process. A value of 0 indicates
602 * After this method is called once, it saves the value
603 * and returns that value on subsequent calls,
604 * until the {@link #refresh()} method is called and a more current
607 * @return the error code
608 * @exception AFSException If an error occurs in the native code
610 public long getErrorCode() throws AFSException
612 if (!cachedInfo
) refreshInfo();
617 * Returns the error signal of the process. A value of 0 indicates no
619 * After this method is called once, it saves the value
620 * and returns that value on subsequent calls,
621 * until the {@link #refresh()} method is called and a more current
624 * @return the error signal
625 * @exception AFSException If an error occurs in the native code
627 public long getErrorSignal() throws AFSException
629 if (!cachedInfo
) refreshInfo();
634 * Returns whether or not the state of the process is ok. A value of
635 * <code>false</code> indicates there has been a core dump.
636 * After this method is called once, it saves the value
637 * and returns that value on subsequent calls,
638 * until the {@link #refresh()} method is called and a more current
641 * @return whether or not the state is ok
642 * @exception AFSException If an error occurs in the native code
644 public boolean getStateOk() throws AFSException
646 if (!cachedInfo
) refreshInfo();
651 * Returns whether or not the state of the process indicates too many errors.
652 * After this method is called once, it saves the value
653 * and returns that value on subsequent calls,
654 * until the {@link #refresh()} method is called and a more current
657 * @return whether or not the state indicates too many errors
658 * @exception AFSException If an error occurs in the native code
660 public boolean getStateTooManyErrors() throws AFSException
662 if (!cachedInfo
) refreshInfo();
663 return stateTooManyErrors
;
667 * Returns whether or not the state of the process indicates bad file access.
668 * After this method is called once, it saves the value
669 * and returns that value on subsequent calls,
670 * until the {@link #refresh()} method is called and a more current
673 * @return whether or not the state indicates bad file access
674 * @exception AFSException If an error occurs in the native code
676 public boolean getStateBadFileAccess() throws AFSException
678 if (!cachedInfo
) refreshInfo();
679 return stateBadFileAccess
;
682 /////////////// custom information methods ////////////////////
685 * Returns a <code>String</code> representation of this <code>Process</code>.
686 * Contains the information fields.
688 * @return a <code>String</code> representation of the <code>Process</code>
690 public String
getInfo()
695 r
= "Process: " + name
+ "\n";
698 switch( getType() ) {
709 r
+= "other - " + getType();
714 switch( getState() ) {
728 r
+= "other - " + getState();
733 switch( getGoal() ) {
747 r
+= "other - " + getGoal();
751 r
+= "\tstartTime: ";
752 if( getStartTime() == 0) {
755 r
+= getStartTimeDate().getTime();
759 r
+= "\tnumberStarts: " + getNumberOfStarts() + "\n";
762 if( getExitTime() == 0 ) {
765 r
+= getExitTimeDate().getTime();
769 r
+= "\texitErrorTime: ";
770 if( getExitErrorTimeDate() == null ) {
773 r
+= getExitErrorTimeDate().getTime();
777 r
+= "\terrorCode: " + getErrorCode() + "\n";
778 r
+= "\terrorSignal: " + getErrorSignal() + "\n";
779 r
+= "\tstateOk: " + getStateOk() + "\n";
780 r
+= "\tstateTooManyErrors: " + getStateTooManyErrors() + "\n";
781 r
+= "\tstateBadFileAccess: " + getStateBadFileAccess() + "\n";
783 } catch( Exception e
) {
789 /////////////// custom override methods ////////////////////
792 * Compares two Process objects respective to their names and does not
793 * factor any other attribute. Alphabetic case is significant in
796 * @param process The Process object to be compared to this Process
799 * @return Zero if the argument is equal to this Process' name, a
800 * value less than zero if this Process' name is
801 * lexicographically less than the argument, or a value greater
802 * than zero if this Process' name is lexicographically
803 * greater than the argument
805 public int compareTo(Process process
)
807 return this.getName().compareTo(process
.getName());
811 * Comparable interface method.
813 * @see #compareTo(Process)
815 public int compareTo(Object obj
)
817 return compareTo((Process
)obj
);
821 * Tests whether two <code>Process</code> objects are equal, based on their
822 * names and hosting server.
824 * @param otherProcess the Process to test
825 * @return whether the specifed Process is the same as this Process
827 public boolean equals( Process otherProcess
)
829 return ( name
.equals(otherProcess
.getName()) ) &&
830 ( this.getServer().equals(otherProcess
.getServer()) );
834 * Returns the name of this <CODE>Process</CODE>
836 * @return the name of this <CODE>Process</CODE>
838 public String
toString()
843 /////////////// native methods ////////////////////
846 * Fills in the information fields of the provided <code>Process</code>.
848 * @param cellHandle the handle of the cell to which the process belongs
849 * @see Cell#getCellHandle
850 * @param processName the instance name of the process for which to get
852 * @param theProcess the {@link Process Process} object in which to fill
854 * @exception AFSException If an error occurs in the native code
856 protected static native void getProcessInfo( long cellHandle
,
862 * Creates a processes on a server.
864 * @param serverHandle the bos handle of the server to which the key will
866 * @see Server#getBosServerHandle
867 * @param processName the instance name to give the process. See AFS
868 * documentation for a standard list of instance names
869 * @param processType the type of process this will be.
870 * Acceptable values are:<ul>
871 * <li>{@link #SIMPLE_PROCESS}</li>
872 * <li>{@link #FS_PROCESS}</li>
873 * <li>{@link #CRON_PROCESS}</li></ul>
874 * @param executionPath the execution path process to create
875 * @param cronTime a String representing the time a cron process is to
876 * be run. Acceptable formats are:<ul>
877 * <li>for daily restarts: "23:10" or "11:10 pm"</li>
878 * <li>for weekly restarts: "sunday 11:10pm" or
881 * Can be <code>null</code> for non-cron processes.
882 * @param notifier the execution path to a notifier program that should
883 * be called when the process terminates. Can be
885 * @exception AFSException If an error occurs in the native code
887 protected static native void create( long serverHandle
, String processName
,
888 int processType
, String executionPath
,
889 String cronTime
, String notifier
)
893 * Removes a process from a server.
895 * @param serverHandle the bos handle of the server to which the process
897 * @see Server#getBosServerHandle
898 * @param processName the name of the process to remove
899 * @exception AFSException If an error occurs in the native code
901 protected static native void delete( long serverHandle
, String processName
)
905 * Start this process.
907 * @param serverHandle the bos handle of the server to which the process
909 * @see Server#getBosServerHandle
910 * @param processName the name of the process to start
911 * @exception AFSException If an error occurs in the native code
913 protected static native void start( long serverHandle
, String processName
)
917 * Retart this process.
919 * @param serverHandle the bos handle of the server to which the process
921 * @see Server#getBosServerHandle
922 * @param processName the name of the process to restart
923 * @exception AFSException If an error occurs in the native code
925 protected static native void restart( long serverHandle
, String processName
)
931 * @param serverHandle the bos handle of the server to which the process
933 * @see Server#getBosServerHandle
934 * @param processName the name of the process to stop
935 * @exception AFSException If an error occurs in the native code
937 protected static native void stop( long serverHandle
, String processName
)
941 * Reclaims all memory being saved by the process portion of the native
942 * library. This method should be called when no more <code>Process</code>
943 * objects are expected to be used.
945 protected static native void reclaimProcessMemory();