1"""
2Sets up a subprocess to run sar from the sysstat suite
3
4Default options:
5sar -A -f
6"""
7import os, shutil, subprocess, time
8from autotest_lib.client.bin import utils, profiler, os_dep
9
10
11class sar(profiler.profiler):
12    """
13    The sar command writes to standard output the contents of selected
14    cumulative activity counters in the operating system. This profiler
15    executes sar and redirects its output in a file located in the profiler
16    results dir.
17    """
18    version = 1
19
20    def initialize(self, interval=1):
21        """
22        Set sar interval and verify what flags the installed sar supports.
23
24        @param interval: Interval used by sar to produce system data.
25        """
26        self.interval = interval
27        self.sar_path = os_dep.command('sar')
28        # If using older versions of sar, command below means: Measure default
29        # params using interval of 1 second continuously. For newer versions,
30        # behavior has changed - to generate reports continuously just omit the
31        # count parameter.
32        t_cmd = self.sar_path + " 1 0"
33        t_process = subprocess.Popen(t_cmd, shell=True,
34                                     stdout=subprocess.PIPE,
35                                     stderr=subprocess.PIPE)
36        # Wait a little to see if process is going to fail or work
37        time.sleep(3)
38        if t_process.poll():
39            # Sar process returned, so 0 doesn't mean generate continuously
40            self.cmd = self.sar_path + " -o %s %d"
41        else:
42            # Sar process didn't return, so 0 means generate continuously
43            # Just terminate the process
44            self.cmd = self.sar_path + " -o %s %d 0"
45            os.kill(t_process.pid, 15)
46
47
48    def start(self, test):
49        """
50        Starts sar subprocess.
51
52        @param test: Autotest test on which this profiler will operate on.
53        """
54        logfile = open(os.path.join(test.profdir, "sar"), 'w')
55        # Save the sar data as binary, convert to text after the test.
56        raw = os.path.join(test.profdir, "sar.raw")
57        cmd = self.cmd % (raw, self.interval)
58        self.sar_process = subprocess.Popen(cmd, shell=True, stdout=logfile,
59                                            stderr=subprocess.STDOUT)
60
61
62    def stop(self, test):
63        """
64        Stops profiler execution by sending a SIGTERM to sar process.
65
66        @param test: Autotest test on which this profiler will operate on.
67        """
68        try:
69            os.kill(self.sar_process.pid, 15)
70        except OSError:
71            pass
72
73    def report(self, test):
74        """
75        Report function. Convert the binary sar data to text.
76
77        @param test: Autotest test on which this profiler will operate on.
78        """
79        raw = os.path.join(test.profdir, "sar.raw")
80        output = os.path.join(test.profdir, "sar")
81        utils.system('/usr/bin/sar -A -f %s > %s' % (raw, output))
82