How does “sar” worked at the kernel level?

As noted from below:

http://www.princeton.edu/~unix/Solaris/troubleshoot/sar.html

http://www.princeton.edu/~unix/Solaris/troubleshoot/ram.html

“sar” is used to collect system statistics, eg, runqueue of the CPU in order to determine CPU loading.

How does it worked? Started via “/etc/init.d/sysstat start”, and configured via /etc/sysstat/sysstat, enabled via /etc/default/sysstat (the line ENABLED=”true” must be entered). The cron script “/etc/cron.d/sysstat” will start it (by default) every 10 minutes.

Doing a “apt-get source sysstat” from a Ubuntu box:

And looking into the header files:

grep proc.*stat *.h

common.h:#define STAT “/proc/stat”
common.h:#define DISKSTATS “/proc/diskstats”
common.h:#define NFSMOUNTSTATS “/proc/self/mountstats”
iostat.h: * or the number of “disk_io:” entries in /proc/stat (2.4 kernels),
iostat.h: * for the first four devices in /proc/stat).
mpstat.h: * mpstat: per-processor statistics
pidstat.h: * pidstat: Display per-process statistics.
pidstat.h:#define PID_STAT “/proc/%u/stat”
pidstat.h:#define PID_STATUS “/proc/%u/status”
pidstat.h:#define TASK_STAT “/proc/%u/task/%u/stat”
pidstat.h:#define TASK_STATUS “/proc/%u/task/%u/status”
rd_stats.h:#define FDENTRY_STATE “/proc/sys/fs/dentry-state”
rd_stats.h:#define FINODE_STATE “/proc/sys/fs/inode-state”
rd_stats.h:#define NET_SOCKSTAT “/proc/net/sockstat”
rd_stats.h:#define NET_SOCKSTAT6 “/proc/net/sockstat6”
rd_stats.h:#define VMSTAT “/proc/vmstat”

We can see that it uses the procfs for statistics collection from userspace.

Looking up kernel source, fs/proc/stat.c (just one statistics out of the many possible):

}
sum += arch_irq_stat();

seq_printf(p, “cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu ”
“%llu\n”,
(unsigned long long)cputime64_to_clock_t(user),
(unsigned long long)cputime64_to_clock_t(nice),
(unsigned long long)cputime64_to_clock_t(system),
(unsigned long long)cputime64_to_clock_t(idle),
(unsigned long long)cputime64_to_clock_t(iowait),
(unsigned long long)cputime64_to_clock_t(irq),
(unsigned long long)cputime64_to_clock_t(softirq),
(unsigned long long)cputime64_to_clock_t(steal),
(unsigned long long)cputime64_to_clock_t(guest),
(unsigned long long)cputime64_to_clock_t(guest_nice));
for_each_online_cpu(i) {

/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
user = kstat_cpu(i).cpustat.user;
nice = kstat_cpu(i).cpustat.nice;
system = kstat_cpu(i).cpustat.system;
idle = kstat_cpu(i).cpustat.idle;
idle = cputime64_add(idle, arch_idle_time(i));
iowait = kstat_cpu(i).cpustat.iowait;
irq = kstat_cpu(i).cpustat.irq;
softirq = kstat_cpu(i).cpustat.softirq;
steal = kstat_cpu(i).cpustat.steal;
guest = kstat_cpu(i).cpustat.guest;
guest_nice = kstat_cpu(i).cpustat.guest_nice;
seq_printf(p,
“cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu ”
“%llu\n”,
i,
(unsigned long long)cputime64_to_clock_t(user),
(unsigned long long)cputime64_to_clock_t(nice),
(unsigned long long)cputime64_to_clock_t(system),
(unsigned long long)cputime64_to_clock_t(idle),
(unsigned long long)cputime64_to_clock_t(iowait),
(unsigned long long)cputime64_to_clock_t(irq),
(unsigned long long)cputime64_to_clock_t(softirq),
(unsigned long long)cputime64_to_clock_t(steal),
(unsigned long long)cputime64_to_clock_t(guest),
(unsigned long long)cputime64_to_clock_t(guest_nice));
}

Here CPU specific statistics are calculated and updated to the procfs virtual filesystem, where userspace application can periodically collect and analyzed for differences.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: