View | Details | Raw Unified | Return to bug 3539
Collapse All | Expand All

(-)frysk-core/frysk/proc/Proc.java (+8 lines)
Lines 51-56 Link Here
51
import java.util.logging.Logger;
51
import java.util.logging.Logger;
52
52
53
import frysk.event.Event;
53
import frysk.event.Event;
54
import frysk.sys.proc.Stat;
54
55
55
/**
56
/**
56
 * A UNIX Process, containing tasks, memory, ...
57
 * A UNIX Process, containing tasks, memory, ...
Lines 77-82 Link Here
77
	// XXX: This needs to be made on-demand.
78
	// XXX: This needs to be made on-demand.
78
    	return this.parent;
79
    	return this.parent;
79
    }
80
    }
81
    
82
    public void requestGetParent(Host.FindProc finder)
83
    {
84
      Stat stat = new Stat();
85
      stat.refresh(id.id);
86
      Manager.host.requestGetProc(new ProcId(stat.ppid), finder);
87
    }
80
88
81
    final Host host;
89
    final Host host;
82
    public Host getHost ()
90
    public Host getHost ()
(-)frysk-core/frysk/proc/HostState.java (+4 lines)
Lines 58-63 Link Here
58
    {
58
    {
59
	throw unhandled (host, "handleRefresh");
59
	throw unhandled (host, "handleRefresh");
60
    }
60
    }
61
    HostState handleGetProc (Host host, ProcId procId, Host.FindProc finder)
62
    {
63
      throw unhandled (host, "handleGetProc");
64
    }
61
    HostState handleCreateAttachedProc (Host host,
65
    HostState handleCreateAttachedProc (Host host,
62
					String stdin, String stdout,
66
					String stdin, String stdout,
63
					String stderr, String[] args,
67
					String stderr, String[] args,
(-)frysk-core/frysk/proc/LinuxPtraceProcState.java (-2 / +3 lines)
Lines 219-225 Link Here
219
		logger.log (Level.FINE, "{0} handleDeleteObservation\n", proc); 
219
		logger.log (Level.FINE, "{0} handleDeleteObservation\n", proc); 
220
		// If the observation was never added, this will
220
		// If the observation was never added, this will
221
		// return false, but that is ok.
221
		// return false, but that is ok.
222
		proc.removeObservation (observation);
222
		if (!proc.removeObservation (observation))
223
          return this;
223
		observation.fail (new RuntimeException ("canceled"));
224
		observation.fail (new RuntimeException ("canceled"));
224
		if (proc.observationsSize() == 0) {
225
		if (proc.observationsSize() == 0) {
225
		    // None of the other tasks are attached, just need
226
		    // None of the other tasks are attached, just need
Lines 367-373 Link Here
367
			proc);
368
			proc);
368
	    // Ouch; request to remove what must be an already
369
	    // Ouch; request to remove what must be an already
369
	    // removed observation.
370
	    // removed observation.
370
	    observation.fail (new RuntimeException ("canceled"));
371
	    observation.fail (new RuntimeException ("already deleted"));
371
	    return this;
372
	    return this;
372
	}
373
	}
373
    }
374
    }
(-)frysk-core/frysk/proc/TestLib.java (-4 / +27 lines)
Lines 168-181 Link Here
168
     */
168
     */
169
    static public boolean isChildOf (int pid, Proc proc)
169
    static public boolean isChildOf (int pid, Proc proc)
170
    {
170
    {
171
      logger.log(Level.FINE, "isChildOf pid: {0} proc: {1}\n", 
172
                 new Object[] {new Integer(pid), proc});
171
	// Process 1 has no parent so can't be a child of mine.
173
	// Process 1 has no parent so can't be a child of mine.
172
	if (proc.getPid () == 1)
174
	if (proc.getPid () == 1)
175
      {
176
        logger.log(Level.FINE, "isChildOf proc is init\n");
173
	    return false;
177
	    return false;
178
      }
174
	// If the parent's pid matches this processes pid, assume that
179
	// If the parent's pid matches this processes pid, assume that
175
	// is sufficient.  Would need a very very long running system
180
	// is sufficient.  Would need a very very long running system
176
	// for that to not be the case.
181
	// for that to not be the case.        
177
	if (proc.parent.getPid () == pid)
182
    
183
    Stat stat = new Stat();
184
    stat.refresh(proc.id.id);
185
    
186
	if (stat.ppid == pid)
187
      {
188
        logger.log(Level.FINE, "isChildOf proc is child\n");
178
	    return true;
189
	    return true;
190
      }
191
    logger.log(Level.FINE, "isChildOf proc {3} not child pid: {0} ppid: {1} parent: {2}\n",
192
               new Object[] {new Integer(pid), new Integer(stat.ppid), proc.getParent(), proc});
193
    
194
    logger.log(Level.FINE, "isChildOf status{0}\n", new Character(stat.state));
179
	return false;
195
	return false;
180
    }
196
    }
181
    /**
197
    /**
Lines 187-193 Link Here
187
     */
203
     */
188
    static public boolean isChildOfMine (Proc proc)
204
    static public boolean isChildOfMine (Proc proc)
189
    {
205
    {
190
	return isChildOf (Pid.get (), proc);
206
    return isChildOf (Pid.get (), proc);
191
    }
207
    }
192
208
193
    /**
209
    /**
Lines 391-396 Link Here
391
	 */	
407
	 */	
392
	public Proc assertFindProcAndTasks ()
408
	public Proc assertFindProcAndTasks ()
393
	{
409
	{
410
      logger.log(Level.FINE, "assertFindProcAndTasks {0}\n", this);
394
	    class FindProc
411
	    class FindProc
395
		implements Host.FindProc
412
		implements Host.FindProc
396
	    {
413
	    {
Lines 1219-1228 Link Here
1219
	{
1236
	{
1220
	    Manager.host.observableProcRemovedXXX.addObserver (this);
1237
	    Manager.host.observableProcRemovedXXX.addObserver (this);
1221
	}
1238
	}
1239
    int pid;
1240
    StopEventLoopWhenChildProcRemoved(int id)
1241
    {
1242
      pid = id;
1243
      Manager.host.observableProcRemovedXXX.addObserver (this);
1244
    }
1222
	public void update (Observable o, Object obj)
1245
	public void update (Observable o, Object obj)
1223
	{
1246
	{
1224
	    Proc proc = (Proc) obj;
1247
	    Proc proc = (Proc) obj;
1225
	    if (isChildOfMine (proc)) {
1248
	    if (isChildOfMine (proc) || proc.id.id  == pid ) {
1226
		// Shut things down.
1249
		// Shut things down.
1227
		logger.log(Level.FINE, "{0} update {1} has been removed stopping event loop\n", new Object[]{this, proc});
1250
		logger.log(Level.FINE, "{0} update {1} has been removed stopping event loop\n", new Object[]{this, proc});
1228
		Manager.eventLoop.requestStop ();
1251
		Manager.eventLoop.requestStop ();
(-)frysk-core/frysk/proc/LinuxPtraceHostState.java (+6 lines)
Lines 86-90 Link Here
86
		host.sendRefresh (procId, finder);
86
		host.sendRefresh (procId, finder);
87
		return running;
87
		return running;
88
	    }
88
	    }
89
        HostState handleGetProc (Host host, ProcId procId, Host.FindProc finder)
90
        {
91
          logger.log (Level.FINE, "{0} handleRefresh\n", host); 
92
        host.sendGetProc (procId, finder);
93
        return running;
94
        }
89
	};
95
	};
90
}
96
}
(-)frysk-core/frysk/proc/DummyHost.java (+4 lines)
Lines 58-61 Link Here
58
  {
58
  {
59
  }
59
  }
60
60
61
  void sendGetProc (ProcId procId, FindProc finder)
62
  {
63
  }
64
61
}
65
}
(-)frysk-core/frysk/proc/Host.java (-2 / +14 lines)
Lines 127-133 Link Here
127
    abstract void sendRefresh (boolean refreshAll);
127
    abstract void sendRefresh (boolean refreshAll);
128
    
128
    
129
    abstract void sendRefresh (ProcId procId, FindProc finder);
129
    abstract void sendRefresh (ProcId procId, FindProc finder);
130
    
130
    abstract void sendGetProc (ProcId procId, FindProc finder);
131
   
131
    /**
132
    /**
132
     * Tell the host to create a running child process.
133
     * Tell the host to create a running child process.
133
     *
134
     *
Lines 193-199 Link Here
193
    }    
194
    }    
194
    
195
    
195
    /**
196
    /**
196
     * Find a specifc process from its Id.
197
     * Find a specific process from its Id.
197
     */
198
     */
198
    public void requestFindProc(final ProcId procId, final FindProc finder)
199
    public void requestFindProc(final ProcId procId, final FindProc finder)
199
    {
200
    {
Lines 205-210 Link Here
205
        }});
206
        }});
206
    }
207
    }
207
    
208
    
209
    
210
    public void requestGetProc(final ProcId procId, final FindProc finder)
211
    {
212
      Manager.eventLoop.add(new HostEvent("FindProc") {
213
214
        public void execute ()
215
        {
216
          newState = oldState().handleGetProc (Host.this, procId, finder);
217
        }});
218
    }
219
    
208
    /**
220
    /**
209
     * Interface to be used with requestFindProc.
221
     * Interface to be used with requestFindProc.
210
     */
222
     */
(-)frysk-core/frysk/proc/LinuxPtraceHost.java (+63 lines)
Lines 478-482 Link Here
478
  {
478
  {
479
    ProcChanges procChanges = new ProcChanges();
479
    ProcChanges procChanges = new ProcChanges();
480
    return procChanges.update(Pid.get());
480
    return procChanges.update(Pid.get());
481
  }  
482
483
  void sendGetProc (final ProcId procId, final FindProc finder)
484
  {
485
    ProcBuilder pidBuilder = new ProcBuilder()
486
    {
487
      public void buildId (int pid)
488
      {
489
        Proc proc = (Proc) procPool.get(procId);
490
        if (proc == null)
491
          {
492
            // New, unknown process. Try to find both the process
493
            // and its parent. In the case of a daemon process, a
494
            // second attempt may be needed.
495
            Stat stat = new Stat();
496
            int attempt = 0;
497
            while (true)
498
              {
499
                // Should take no more than two attempts - one for
500
                // a normal process, and one for a daemon.
501
                if (attempt++ >= 2)
502
                  break;
503
                // Scan in the process's stat file. Of course, if
504
                // the stat file disappeared indicating that the
505
                // process exited, return NULL.
506
                if (! stat.refresh(procId.id))
507
                  return;                
508
              }
509
            // .. and then add this process.
510
            new LinuxPtraceProc(LinuxPtraceHost.this, null, procId, stat);
511
          }
512
      }
513
    };
514
    pidBuilder.construct(procId.id);
515
516
    if (!(procPool.containsKey(procId)))
517
      {
518
519
        Manager.eventLoop.add(new Event()
520
        {
521
522
          public void execute ()
523
          {
524
            finder.procNotFound(procId, new RuntimeException(
525
                                                             "Couldn't find the"
526
                                                             + "proc with id: "
527
                                                                 + procId.id));
528
          }
529
        });
530
        return;
531
      }
532
    
533
    LinuxPtraceProc proc = (LinuxPtraceProc) Manager.host.getProc(procId);
534
    proc.sendRefresh();
535
    
536
    Manager.eventLoop.add(new Event()
537
    {
538
539
      public void execute ()
540
      {
541
        finder.procFound(procId);
542
      }
543
    });
481
  }
544
  }
482
}
545
}
(-)frysk-core/frysk/proc/TestGetProc.java (+173 lines)
Added Link Here
1
// This file is part of the program FRYSK.
2
//
3
// Copyright 2006, Red Hat Inc.
4
//
5
// FRYSK is free software; you can redistribute it and/or modify it
6
// under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; version 2 of the License.
8
//
9
// FRYSK is distributed in the hope that it will be useful, but
10
// WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
// General Public License for more details.
13
// 
14
// You should have received a copy of the GNU General Public License
15
// along with FRYSK; if not, write to the Free Software Foundation,
16
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17
// 
18
// In addition, as a special exception, Red Hat, Inc. gives You the
19
// additional right to link the code of FRYSK with code not covered
20
// under the GNU General Public License ("Non-GPL Code") and to
21
// distribute linked combinations including the two, subject to the
22
// limitations in this paragraph. Non-GPL Code permitted under this
23
// exception must only link to the code of FRYSK through those well
24
// defined interfaces identified in the file named EXCEPTION found in
25
// the source code files (the "Approved Interfaces"). The files of
26
// Non-GPL Code may instantiate templates or use macros or inline
27
// functions from the Approved Interfaces without causing the
28
// resulting work to be covered by the GNU General Public
29
// License. Only Red Hat, Inc. may make changes or additions to the
30
// list of Approved Interfaces. You must obey the GNU General Public
31
// License in all respects for all of the FRYSK code and other code
32
// used in conjunction with FRYSK except the Non-GPL Code covered by
33
// this exception. If you modify this file, you may extend this
34
// exception to your version of the file, but you are not obligated to
35
// do so. If you do not wish to provide this exception without
36
// modification, you must delete this exception statement from your
37
// version and license this file solely under the GPL without
38
// exception.
39
40
41
package frysk.proc;
42
43
import java.util.Observable;
44
import java.util.Observer;
45
import java.util.logging.Level;
46
47
import frysk.event.RequestStopEvent;
48
49
public class TestGetProc
50
    extends TestLib
51
{
52
  class ProcCounter
53
      implements Observer
54
  {
55
56
    int count = 0;
57
58
    public void update (Observable o, Object arg)
59
    {
60
      count++;
61
    }
62
63
    public int getCount ()
64
    {
65
      return count;
66
    }
67
  }
68
69
  class MyFinder
70
      implements Host.FindProc
71
  {
72
    ProcId expectedId;
73
74
    boolean shouldParent;
75
    public MyFinder (ProcId pid, boolean shouldHaveParent)
76
    {
77
      expectedId = pid;
78
      shouldParent = shouldHaveParent;
79
    }
80
81
    public void procFound (ProcId procId)
82
    {
83
      Proc proc = Manager.host.getProc(procId);
84
      logger.log(Level.FINE, "proc: {0} proc parent: {1} \n",
85
                 new Object[] { proc, proc.getParent() });
86
      assertEquals(expectedId, procId);
87
      if (!shouldParent)
88
        assertNull("Should not have parent", proc.getParent());
89
      else
90
        assertNotNull("Should have parent", proc.getParent());
91
        
92
      Manager.eventLoop.add(new RequestStopEvent(Manager.eventLoop));
93
    }
94
95
    public void procNotFound (ProcId procId, Exception e)
96
    {
97
      logger.log(Level.FINE, "{0} procId\n", procId);
98
      fail("Could not find process with ID" + procId.id);
99
    }
100
  }
101
102
  private void doGetProc (AckProcess ackProc, int expectedCount, boolean shouldHaveParent)
103
  {
104
    logger.log(Level.FINE, "doGetProc ackProc {0}\n", ackProc);
105
    ProcCounter o = new ProcCounter();
106
    Manager.host.observableProcAddedXXX.addObserver(o);
107
108
    /*
109
     * This finds out how many processes are associated with the frysk process.
110
     * For example: init->gnome terminal->bash->frysk.
111
     */
112
    Manager.host.getSelf();
113
    int preFind = o.getCount();
114
115
    /*
116
     * Find out how many processes are associated with the test process. Should
117
     * be just the one.
118
     */
119
    Host.FindProc finder = new MyFinder(new ProcId(ackProc.getPid()), shouldHaveParent);
120
    Manager.host.requestGetProc(new ProcId(ackProc.getPid()), finder);
121
    assertRunUntilStop("testGetProc");
122
123
    int postFind = o.getCount();
124
125
    assertEquals(expectedCount, postFind - preFind);
126
    logger.log(Level.FINE, "doGetProc exiting");
127
  }
128
129
  public void testGetAndRefreshFailed ()
130
  {
131
132
    Host.FindProc finder = new Host.FindProc()
133
    {
134
      public void procFound (ProcId procId)
135
      {
136
        logger.log(Level.FINE, "{0} procId\n", procId);
137
        fail("Found proc 0, should have failed.");
138
      }
139
140
      public void procNotFound (ProcId procId, Exception e)
141
      {
142
        logger.log(Level.FINE, "{0} procId\n", procId);
143
        Manager.eventLoop.add(new RequestStopEvent(Manager.eventLoop));
144
145
      }
146
    };
147
148
    Manager.host.requestGetProc(new ProcId(0), finder);
149
    assertRunUntilStop("testFindFailed");
150
151
  }
152
  
153
  public void testGetProcDetached ()
154
  {
155
    AckProcess ackProc = new DetachedAckProcess();
156
    doGetProc(ackProc, 1, false);  
157
  }
158
159
  public void testGetProcAttached ()
160
  {
161
    AckProcess ackProc = new AttachedAckProcess();
162
163
    // expect no additional processes to be added to the procPool.
164
    doGetProc(ackProc, 0, true);
165
  }
166
167
  public void testGetProcAckDaemon ()
168
  {
169
    AckProcess ackProc = new AckDaemonProcess();
170
    doGetProc(ackProc, 1, false);   
171
  }
172
  
173
}

Return to bug 3539