File: run_module.py

package info (click to toggle)
systemtap 5.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 47,556 kB
  • sloc: cpp: 81,117; ansic: 54,933; xml: 49,795; exp: 43,595; sh: 11,526; python: 5,003; perl: 2,252; tcl: 1,312; makefile: 1,006; javascript: 149; lisp: 105; awk: 101; asm: 91; java: 70; sed: 16
file content (140 lines) | stat: -rwxr-xr-x 4,447 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/python

# Copyright (C) 2008, 2010 Red Hat Inc.
# 
# This file is part of systemtap, and is free software.  You can
# redistribute it and/or modify it under the terms of the GNU General
# Public License (GPL); either version 2, or (at your option) any
# later version.

import sys
import os
import os.path
import time
import select
from config_opts import config_opts

def run_module():
    # Find the current size of /var/log/messages
    logfile = '/var/log/messages'
    print >>sys.stderr, "Getting size of %s..." % logfile

    start_pos = os.path.getsize(logfile)
    l = open(logfile, 'r')
    l.seek(start_pos)

    # Insert the module
    print >>sys.stderr, "Inserting module..."
    rc = os.system("/sbin/insmod %s" % os.path.join(os.getcwd(),
                                                    'kprobe_module.ko'))
    if os.WEXITSTATUS(rc) != 0:
        # This is actually semi-OK, which is why there is no error
        # message here, only a notice.  This might mean that every
        # probe tried cannot be registered.
        print >>sys.stderr, "Notice: insmod failed"
    else:
        # Run the load generate commands (if any).  Note we ignore the
        # return values, since we don't really care if the commands
        # succeed or not.
        if config_opts.has_key('load_cmds'):
            print >>sys.stderr, "Running commands..."
            num_waits = 0

            # Redirect the output to 'run_module.log' by modifying
            # what stdout/stderr points to.
            sys.stdout.flush()
            old_stdout = os.dup(sys.stdout.fileno())
            sys.stderr.flush()
            old_stderr = os.dup(sys.stderr.fileno())
            fd = os.open('run_module.log', os.O_CREAT | os.O_WRONLY)
            os.dup2(fd, sys.stdout.fileno())
            os.dup2(fd, sys.stderr.fileno())

            # Run the commands.
            pid_list = list()
            for cmd in config_opts['load_cmds']:
                pid = os.spawnvp(os.P_NOWAIT, cmd[0], cmd)
                pid_list.append(pid)
            for pid in pid_list:
                (childpid, status) = os.waitpid(pid, 0)

            # Restore old value of stdout/stderr.
            os.close(fd)
            os.dup2(old_stdout, sys.stdout.fileno())
            os.dup2(old_stderr, sys.stderr.fileno())

        # Remove the module
        print >>sys.stderr, "Removing module..."
        rc = os.system("/sbin/rmmod kprobe_module")
        if os.WEXITSTATUS(rc) != 0:
            print >>sys.stderr, "Error: rmmod failed"
            return -1

    # Now we have to wait until everything is flushed to the logfile
    print >>sys.stderr, "Looking for output..."
    rc = 0
    f = open(config_opts['probes_result'], 'w')
    attempts = 0
    while 1:
        # Find the ending size of /var/log/messages
        end_pos = os.path.getsize(logfile)

        if end_pos < start_pos:
            # The log files have been rotated.  Read any leftover data,
            # then reopen file.
            data = l.read()
            if data:
                f.write(data)

                # See if we can find 'kprobe_module unloaded' in the
                # data we just read.
                if data.find('kprobe_module unloaded') != -1:
                    break
        
            l.close()
            l = open(logfile, 'r')
            start_pos = 0
            continue

        # Try to wait until data is available
        while 1:
            try:
                input, output, exc = select.select([l.fileno()], [], [], 60)
                break
            except select.error, err:
                if err[0] != EINTR:
                    raise

        # Get the new stuff logged to /var/log/messages
        data = l.read(end_pos - start_pos + 1)
        if not data:
            # ignore EOF
            time.sleep(2)
            attempts += 1
            if attempts < 30:
                continue
            else:
                print >>sys.stderr, "Error: Couldn't find data"
                rc = -1
                break

        # Write results data
        f.write(data)

        # See if we can find 'kprobe_module unloaded' in the data we
        # just read.
        if data.find('kprobe_module unloaded') == -1:
            start_pos = end_pos
        else:
            break

    l.close()
    f.close()
    return rc

def main():
    rc = run_module()
    sys.exit(rc)

if __name__ == "__main__":
    main()