6 Star 13 Fork 3

Gitee 极速下载/atop

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/Atoptool/atop
克隆/下载
deviate.c 56.97 KB
一键复制 编辑 原始数据 按行查看 历史
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826
/*
** ATOP - System & Process Monitor
**
** The program 'atop' offers the possibility to view the activity of
** the system on system-level as well as process-level.
**
** This source-file contains functions to calculate the differences for
** the system-level and process-level counters since the previous sample.
** ==========================================================================
** Author: Gerlof Langeveld
** E-mail: gerlof.langeveld@atoptool.nl
** Date: November 1996
** LINUX-port: June 2000
** --------------------------------------------------------------------------
** Copyright (C) 2000-2021 Gerlof Langeveld
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
** Free Software Foundation; either version 2, or (at your option) any
** later version.
**
** This program is distributed in the hope that it will be useful, but
** WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
** See the GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
** --------------------------------------------------------------------------
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <signal.h>
#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include <memory.h>
#include <string.h>
#include "atop.h"
#include "ifprop.h"
#include "photoproc.h"
#include "photosyst.h"
static void calcdiff(struct tstat *, const struct tstat *,
const struct tstat *,
char, count_t);
static inline count_t subcount(count_t, count_t);
/*
** calculate the process-activity during the last sample
*/
void
deviattask(struct tstat *curtpres, unsigned long ntaskpres,
struct tstat *curpexit, unsigned long nprocexit,
struct devtstat *devtstat,
struct sstat *devsstat)
{
register int c, d, pall=0, pact=0;
register struct tstat *curstat, *devstat, *thisproc;
struct tstat prestat, *pprestat;
struct pinfo *pinfo;
count_t totusedcpu;
char hashtype = 'p';
/*
** needed for sanity check later on...
*/
totusedcpu = devsstat->cpu.all.stime + devsstat->cpu.all.utime +
devsstat->cpu.all.ntime + devsstat->cpu.all.itime +
devsstat->cpu.all.wtime + devsstat->cpu.all.Itime +
devsstat->cpu.all.Stime + devsstat->cpu.all.steal;
/*
** make new list of all tasks in the task-database;
** after handling all task, the left-overs are tasks
** that have disappeared since the previous sample
*/
pdb_makeresidue();
/*
** remove allocated lists of previous sample and initialize counters
*/
if (devtstat->taskall)
free(devtstat->taskall);
if (devtstat->procall)
free(devtstat->procall);
if (devtstat->procactive)
free(devtstat->procactive);
memset(devtstat, 0, sizeof *devtstat);
/*
** create list for the sample deviations of all tasks
*/
devtstat->ntaskall = ntaskpres + nprocexit;
devtstat->taskall = malloc(devtstat->ntaskall * sizeof(struct tstat));
ptrverify(devtstat->taskall, "Malloc failed for %lu deviated tasks\n",
devtstat->ntaskall);
/*
** calculate deviations per present task
*/
for (c=0, thisproc = devtstat->taskall; c < ntaskpres; c++)
{
char newtask = 0;
curstat = curtpres+c;
devstat = devtstat->taskall+c;
if (curstat->gen.isproc)
{
thisproc = devstat; // remember last process seen
devtstat->nprocall++;
if (curstat->gen.state == 'Z')
{
devtstat->totzombie++;
}
else
{
devtstat->totrun += curstat->gen.nthrrun;
devtstat->totslpi += curstat->gen.nthrslpi;
devtstat->totslpu += curstat->gen.nthrslpu;
devtstat->totidle += curstat->gen.nthridle;
}
}
/*
** get previous figures from task-database
*/
if ( pdb_gettask(curstat->gen.pid, curstat->gen.isproc,
curstat->gen.btime, &pinfo))
{
/*
** task already present in the previous sample
**
** save stats from previous sample (to use for
** further calculations) and store new statistics
** in task-database
*/
if (memcmp(curstat, &pinfo->tstat,
sizeof(struct tstat)) == EQ)
{
/*
** no activity for task
*/
curstat->gen.wasinactive = 1;
pprestat = curstat;
}
else
{
/*
** save the values of the previous sample
** and overwrite the previous sample in
** the database with the current sample
*/
prestat = pinfo->tstat;
pprestat = &prestat;
pinfo->tstat = *curstat;
curstat->gen.wasinactive = 0;
devtstat->ntaskactive++;
if (curstat->gen.isproc)
{
devtstat->nprocactive++;
}
else
{
if (thisproc->gen.wasinactive)
{
thisproc->gen.wasinactive = 0;
devtstat->ntaskactive++;
devtstat->nprocactive++;
}
}
}
}
else
{
/*
** new task which must have been started during
** last interval
*/
memset(&prestat, 0, sizeof(prestat));
pprestat = &prestat;
curstat->gen.wasinactive = 0;
devtstat->ntaskactive++;
if (curstat->gen.isproc)
{
devtstat->nprocactive++;
}
else
{
if (thisproc->gen.wasinactive)
{
thisproc->gen.wasinactive = 0;
devtstat->ntaskactive++;
devtstat->nprocactive++;
}
}
/*
** create new task struct
*/
pinfo = calloc(1, sizeof(struct pinfo));
ptrverify(pinfo, "Malloc failed for new pinfo\n");
pinfo->tstat = *curstat;
/*
** add new task to task-database
*/
pdb_addtask(curstat->gen.pid, pinfo);
newtask = 1;
}
/*
** do the difference calculations
*/
calcdiff(devstat, curstat, pprestat, newtask, totusedcpu);
}
/*
** calculate deviations per exited process
*/
if (nprocexit > 0 && supportflags&NETATOPD)
{
if (curpexit->gen.pid)
hashtype = 'p';
else
hashtype = 'b';
netatop_exithash(hashtype);
}
for (d=c, c=0; c < nprocexit; c++)
{
/*
** check if this process has been started AND
** finished since previous sample;
** if so, it has no use to check if there is still
** existing info present in the process-database
*/
curstat = curpexit+c;
curstat->gen.wasinactive = 0;
devtstat->nprocall++;
devtstat->nprocactive++;
devtstat->ntaskactive++;
if (curstat->gen.pid) /* acctrecord contains pid? */
{
if ( pdb_gettask(curstat->gen.pid, 1,
curstat->gen.btime, &pinfo))
prestat = pinfo->tstat;
else
memset(&prestat, 0, sizeof(prestat));
}
else
{
if ( curstat->gen.btime > pretime )
{
/*
** process-start and -finish in same interval
*/
memset(&prestat, 0, sizeof(prestat));
}
else
{
/*
** process must be known in process-database;
** try to match one of the remaining processes
** against this exited one
*/
if ( pdb_srchresidue(curstat, &pinfo) )
prestat = pinfo->tstat;
else
memset(&prestat, 0, sizeof(prestat));
}
}
/*
** now do the calculations
*/
devstat = devtstat->taskall+d;
memset(devstat, 0, sizeof *devstat);
devstat->gen = curstat->gen;
if ( curstat->gen.pid == 0 )
devstat->gen.pid = prestat.gen.pid;
if (!prestat.gen.pid)
devstat->gen.excode |= ~(INT_MAX);
strcpy(devstat->gen.cmdline, prestat.gen.cmdline);
strcpy(devstat->gen.utsname, prestat.gen.utsname);
devstat->cpu.curcpu = -1;
/*
** due to the strange exponent-type storage of values
** in the process accounting record, the resource-value
** in the exit-record might have been smaller than the
** stored value of the last registered sample; in that
** case the deviation should be set to zero
*/
if (curstat->cpu.stime > prestat.cpu.stime)
devstat->cpu.stime = curstat->cpu.stime -
prestat.cpu.stime;
if (curstat->cpu.utime > prestat.cpu.utime)
devstat->cpu.utime = curstat->cpu.utime -
prestat.cpu.utime;
if (curstat->mem.minflt > prestat.mem.minflt)
devstat->mem.minflt = curstat->mem.minflt -
prestat.mem.minflt;
if (curstat->mem.majflt > prestat.mem.majflt)
devstat->mem.majflt = curstat->mem.majflt -
prestat.mem.majflt;
if (curstat->dsk.rio > (prestat.dsk.rio + prestat.dsk.wio))
devstat->dsk.rio = curstat->dsk.rio -
prestat.dsk.rio -
prestat.dsk.wio;
/*
** try to match the network counters of netatop
*/
if (supportflags & NETATOPBPF)
{
unsigned long val = (hashtype == 'p' ?
curstat->gen.pid :
curstat->gen.btime);
netatop_bpf_exitfind(val, devstat, &prestat);
}
else if (supportflags & NETATOPD)
{
unsigned long val = (hashtype == 'p' ?
curstat->gen.pid :
curstat->gen.btime);
netatop_exitfind(val, devstat, &prestat);
}
/*
** handle the gpu counters
*/
if (curstat->gpu.state || prestat.gpu.state) // GPU use?
{
if (curstat->gpu.state)
devstat->gpu.state = curstat->gpu.state;
else
devstat->gpu.state = prestat.gpu.state;
devstat->gpu.nrgpus = curstat->gpu.nrgpus;
devstat->gpu.gpulist = curstat->gpu.gpulist;
devstat->gpu.gpubusy = curstat->gpu.gpubusy;
devstat->gpu.membusy = curstat->gpu.membusy;
devstat->gpu.timems = curstat->gpu.timems;
devstat->gpu.memnow = curstat->gpu.memnow;
devstat->gpu.memcum = curstat->gpu.memcum -
prestat.gpu.memcum;
devstat->gpu.sample = curstat->gpu.sample -
prestat.gpu.sample;
}
else
{
devstat->gpu.state = '\0';
}
if (prestat.gen.pid > 0)
pdb_deltask(prestat.gen.pid, prestat.gen.isproc);
d++;
}
/*
** remove unused entries from RESIDUE chain
*/
pdb_cleanresidue();
/*
** create and fill other pointer lists
*/
devtstat->procall = malloc(devtstat->nprocall *
sizeof(struct tstat *));
devtstat->procactive = malloc(devtstat->nprocactive *
sizeof(struct tstat *));
ptrverify(devtstat->procall, "Malloc failed for %d processes\n",
devtstat->nprocall);
ptrverify(devtstat->procactive, "Malloc failed for %d active procs\n",
devtstat->nprocactive);
for (c=0, thisproc=devstat=devtstat->taskall; c < devtstat->ntaskall;
c++, devstat++)
{
if (devstat->gen.isproc)
{
devtstat->procall[pall++] = devstat;
if (! devstat->gen.wasinactive)
devtstat->procactive[pact++] = devstat;
}
}
}
/*
** calculate the differences between the current sample and
** the previous sample for a task
*/
static void
calcdiff(struct tstat *devstat, const struct tstat *curstat,
const struct tstat *prestat,
char newtask, count_t totusedcpu)
{
/*
** for inactive tasks, set all counters to zero to avoid calculating
** the deviations (after all, there are no deviations)
*/
if (curstat->gen.wasinactive)
{
memset(devstat, 0, sizeof *devstat);
}
/*
** copy all STATIC values from the current task settings
*/
devstat->gen = curstat->gen;
if (newtask)
devstat->gen.excode |= ~(INT_MAX);
devstat->cpu.nice = curstat->cpu.nice;
devstat->cpu.prio = curstat->cpu.prio;
devstat->cpu.rtprio = curstat->cpu.rtprio;
devstat->cpu.policy = curstat->cpu.policy;
devstat->cpu.curcpu = curstat->cpu.curcpu;
devstat->cpu.sleepavg = curstat->cpu.sleepavg;
if (curstat->cpu.wchan[0])
strcpy(devstat->cpu.wchan, curstat->cpu.wchan);
else
devstat->cpu.wchan[0] = 0;
devstat->mem.vexec = curstat->mem.vexec;
devstat->mem.vmem = curstat->mem.vmem;
devstat->mem.rmem = curstat->mem.rmem;
devstat->mem.pmem = curstat->mem.pmem;
devstat->mem.vdata = curstat->mem.vdata;
devstat->mem.vstack = curstat->mem.vstack;
devstat->mem.vlibs = curstat->mem.vlibs;
devstat->mem.vswap = curstat->mem.vswap;
devstat->mem.vlock = curstat->mem.vlock;
if (curstat->gpu.state || prestat->gpu.state) // GPU use?
{
if (curstat->gpu.state)
devstat->gpu.state = curstat->gpu.state;
else
devstat->gpu.state = prestat->gpu.state;
devstat->gpu.nrgpus = curstat->gpu.nrgpus;
devstat->gpu.gpulist = curstat->gpu.gpulist;
devstat->gpu.gpubusy = curstat->gpu.gpubusy;
devstat->gpu.membusy = curstat->gpu.membusy;
devstat->gpu.memnow = curstat->gpu.memnow;
devstat->gpu.timems = curstat->gpu.timems;
}
else
{
devstat->gpu.state = '\0';
}
/*
** for inactive tasks, only the static values had to be copied, while
** all use counters have already been set to zero
*/
if (curstat->gen.wasinactive)
return;
/*
** calculate deviations for tasks that were really active
** (i.e. modified) during the sample
*/
devstat->cpu.stime =
subcount(curstat->cpu.stime, prestat->cpu.stime);
devstat->cpu.utime =
subcount(curstat->cpu.utime, prestat->cpu.utime);
/*
** particular kernel versions sometimes supply a smaller
** amount for consumed CPU-ticks than a previous sample;
** with unsigned calculations this results in 497 days of
** CPU-consumption so a sanity-check is needed here...
*/
if (devstat->cpu.stime > totusedcpu)
devstat->cpu.stime = 1;
if (devstat->cpu.utime > totusedcpu)
devstat->cpu.utime = 1;
devstat->cpu.rundelay =
subcount(curstat->cpu.rundelay, prestat->cpu.rundelay);
devstat->cpu.blkdelay =
subcount(curstat->cpu.blkdelay, prestat->cpu.blkdelay);
if (curstat->cpu.nvcsw >= prestat->cpu.nvcsw)
devstat->cpu.nvcsw =
subcount(curstat->cpu.nvcsw, prestat->cpu.nvcsw);
else
devstat->cpu.nvcsw = curstat->cpu.nvcsw;
if (curstat->cpu.nivcsw >= prestat->cpu.nivcsw)
devstat->cpu.nivcsw =
subcount(curstat->cpu.nivcsw, prestat->cpu.nivcsw);
else
devstat->cpu.nivcsw = curstat->cpu.nivcsw;
devstat->dsk.rio =
subcount(curstat->dsk.rio, prestat->dsk.rio);
devstat->dsk.rsz =
subcount(curstat->dsk.rsz, prestat->dsk.rsz);
devstat->dsk.wio =
subcount(curstat->dsk.wio, prestat->dsk.wio);
devstat->dsk.wsz =
subcount(curstat->dsk.wsz, prestat->dsk.wsz);
devstat->dsk.cwsz =
subcount(curstat->dsk.cwsz, prestat->dsk.cwsz);
devstat->mem.vgrow = curstat->mem.vmem - prestat->mem.vmem;
devstat->mem.rgrow = curstat->mem.rmem - prestat->mem.rmem;
devstat->mem.minflt =
subcount(curstat->mem.minflt, prestat->mem.minflt);
devstat->mem.majflt =
subcount(curstat->mem.majflt, prestat->mem.majflt);
/*
** network counters: due to an unload/load of the netatop module,
** previous counters might be larger than the current
*/
if (curstat->net.tcpsnd >= prestat->net.tcpsnd)
devstat->net.tcpsnd =
subcount(curstat->net.tcpsnd, prestat->net.tcpsnd);
else
devstat->net.tcpsnd = curstat->net.tcpsnd;
if (curstat->net.tcpssz >= prestat->net.tcpssz)
devstat->net.tcpssz =
subcount(curstat->net.tcpssz, prestat->net.tcpssz);
else
devstat->net.tcpssz = curstat->net.tcpssz;
if (curstat->net.tcprcv >= prestat->net.tcprcv)
devstat->net.tcprcv =
subcount(curstat->net.tcprcv, prestat->net.tcprcv);
else
devstat->net.tcprcv = curstat->net.tcprcv;
if (curstat->net.tcprsz >= prestat->net.tcprsz)
devstat->net.tcprsz =
subcount(curstat->net.tcprsz, prestat->net.tcprsz);
else
devstat->net.tcprsz = curstat->net.tcprsz;
if (curstat->net.udpsnd >= prestat->net.udpsnd)
devstat->net.udpsnd =
subcount(curstat->net.udpsnd, prestat->net.udpsnd);
else
devstat->net.udpsnd = curstat->net.udpsnd;
if (curstat->net.udpssz >= prestat->net.udpssz)
devstat->net.udpssz =
subcount(curstat->net.udpssz, prestat->net.udpssz);
else
devstat->net.udpssz = curstat->net.udpssz;
if (curstat->net.udprcv >= prestat->net.udprcv)
devstat->net.udprcv =
subcount(curstat->net.udprcv, prestat->net.udprcv);
else
devstat->net.udprcv = curstat->net.udprcv;
if (curstat->net.udprsz >= prestat->net.udprsz)
devstat->net.udprsz =
subcount(curstat->net.udprsz, prestat->net.udprsz);
else
devstat->net.udprsz = curstat->net.udprsz;
if (curstat->gpu.state)
{
devstat->gpu.memcum = curstat->gpu.memcum - prestat->gpu.memcum;
devstat->gpu.sample = curstat->gpu.sample - prestat->gpu.sample;
}
}
/*
** calculate the system-activity during the last sample
*/
void
deviatsyst(struct sstat *cur, struct sstat *pre, struct sstat *dev,
long interval)
{
register int i, j;
count_t *cdev, *ccur, *cpre;
struct ifprop ifprop;
dev->cpu.nrcpu = cur->cpu.nrcpu;
dev->cpu.devint = subcount(cur->cpu.devint, pre->cpu.devint);
dev->cpu.csw = subcount(cur->cpu.csw, pre->cpu.csw);
dev->cpu.nprocs = subcount(cur->cpu.nprocs, pre->cpu.nprocs);
dev->cpu.all.stime = subcount(cur->cpu.all.stime, pre->cpu.all.stime);
dev->cpu.all.utime = subcount(cur->cpu.all.utime, pre->cpu.all.utime);
dev->cpu.all.ntime = subcount(cur->cpu.all.ntime, pre->cpu.all.ntime);
dev->cpu.all.itime = subcount(cur->cpu.all.itime, pre->cpu.all.itime);
dev->cpu.all.wtime = subcount(cur->cpu.all.wtime, pre->cpu.all.wtime);
dev->cpu.all.Itime = subcount(cur->cpu.all.Itime, pre->cpu.all.Itime);
dev->cpu.all.Stime = subcount(cur->cpu.all.Stime, pre->cpu.all.Stime);
dev->cpu.all.steal = subcount(cur->cpu.all.steal, pre->cpu.all.steal);
dev->cpu.all.guest = subcount(cur->cpu.all.guest, pre->cpu.all.guest);
dev->cpu.all.instr = subcount(cur->cpu.all.instr, pre->cpu.all.instr);
dev->cpu.all.cycle = subcount(cur->cpu.all.cycle, pre->cpu.all.cycle);
for (i=0; i < dev->cpu.nrcpu; i++)
{
count_t ticks;
dev->cpu.cpu[i].cpunr = cur->cpu.cpu[i].cpunr;
dev->cpu.cpu[i].stime = subcount(cur->cpu.cpu[i].stime,
pre->cpu.cpu[i].stime);
dev->cpu.cpu[i].utime = subcount(cur->cpu.cpu[i].utime,
pre->cpu.cpu[i].utime);
dev->cpu.cpu[i].ntime = subcount(cur->cpu.cpu[i].ntime,
pre->cpu.cpu[i].ntime);
dev->cpu.cpu[i].itime = subcount(cur->cpu.cpu[i].itime,
pre->cpu.cpu[i].itime);
dev->cpu.cpu[i].wtime = subcount(cur->cpu.cpu[i].wtime,
pre->cpu.cpu[i].wtime);
dev->cpu.cpu[i].Itime = subcount(cur->cpu.cpu[i].Itime,
pre->cpu.cpu[i].Itime);
dev->cpu.cpu[i].Stime = subcount(cur->cpu.cpu[i].Stime,
pre->cpu.cpu[i].Stime);
dev->cpu.cpu[i].steal = subcount(cur->cpu.cpu[i].steal,
pre->cpu.cpu[i].steal);
dev->cpu.cpu[i].guest = subcount(cur->cpu.cpu[i].guest,
pre->cpu.cpu[i].guest);
dev->cpu.cpu[i].instr = subcount(cur->cpu.cpu[i].instr,
pre->cpu.cpu[i].instr);
dev->cpu.cpu[i].cycle = subcount(cur->cpu.cpu[i].cycle,
pre->cpu.cpu[i].cycle);
ticks = cur->cpu.cpu[i].freqcnt.ticks;
dev->cpu.cpu[i].freqcnt.maxfreq =
cur->cpu.cpu[i].freqcnt.maxfreq;
dev->cpu.cpu[i].freqcnt.cnt = ticks ?
subcount(cur->cpu.cpu[i].freqcnt.cnt,
pre->cpu.cpu[i].freqcnt.cnt)
: cur->cpu.cpu[i].freqcnt.cnt;
dev->cpu.cpu[i].freqcnt.ticks = ticks ?
subcount(cur->cpu.cpu[i].freqcnt.ticks,
pre->cpu.cpu[i].freqcnt.ticks)
: cur->cpu.cpu[i].freqcnt.ticks;
}
dev->cpu.lavg1 = cur->cpu.lavg1;
dev->cpu.lavg5 = cur->cpu.lavg5;
dev->cpu.lavg15 = cur->cpu.lavg15;
dev->mem.physmem = cur->mem.physmem;
dev->mem.freemem = cur->mem.freemem;
dev->mem.availablemem = cur->mem.availablemem;
dev->mem.buffermem = cur->mem.buffermem;
dev->mem.slabmem = cur->mem.slabmem;
dev->mem.slabreclaim = cur->mem.slabreclaim;
dev->mem.committed = cur->mem.committed;
dev->mem.commitlim = cur->mem.commitlim;
dev->mem.cachemem = cur->mem.cachemem;
dev->mem.cachedrt = cur->mem.cachedrt;
dev->mem.totswap = cur->mem.totswap;
dev->mem.freeswap = cur->mem.freeswap;
dev->mem.swapcached = cur->mem.swapcached;
dev->mem.pagetables = cur->mem.pagetables;
dev->mem.zswap = cur->mem.zswap;
dev->mem.zswapped = cur->mem.zswapped;
dev->mem.shmem = cur->mem.shmem;
dev->mem.shmrss = cur->mem.shmrss;
dev->mem.shmswp = cur->mem.shmswp;
dev->mem.stothugepage = cur->mem.stothugepage;
dev->mem.sfreehugepage = cur->mem.sfreehugepage;
dev->mem.shugepagesz = cur->mem.shugepagesz;
dev->mem.ltothugepage = cur->mem.ltothugepage;
dev->mem.lfreehugepage = cur->mem.lfreehugepage;
dev->mem.lhugepagesz = cur->mem.lhugepagesz;
dev->mem.anonhugepage = cur->mem.anonhugepage;
dev->mem.vmwballoon = cur->mem.vmwballoon;
dev->mem.zfsarcsize = cur->mem.zfsarcsize;
dev->mem.ksmsharing = cur->mem.ksmsharing;
dev->mem.ksmshared = cur->mem.ksmshared;
dev->mem.tcpsock = cur->mem.tcpsock;
dev->mem.udpsock = cur->mem.udpsock;
dev->mem.pgouts = subcount(cur->mem.pgouts, pre->mem.pgouts);
dev->mem.pgins = subcount(cur->mem.pgins, pre->mem.pgins);
dev->mem.swouts = subcount(cur->mem.swouts, pre->mem.swouts);
dev->mem.swins = subcount(cur->mem.swins, pre->mem.swins);
dev->mem.zswouts = subcount(cur->mem.zswouts, pre->mem.zswouts);
dev->mem.zswins = subcount(cur->mem.zswins, pre->mem.zswins);
dev->mem.pgscans = subcount(cur->mem.pgscans, pre->mem.pgscans);
dev->mem.pgsteal = subcount(cur->mem.pgsteal, pre->mem.pgsteal);
dev->mem.allocstall = subcount(cur->mem.allocstall,
pre->mem.allocstall);
if (cur->mem.oomkills != -1)
dev->mem.oomkills = subcount(cur->mem.oomkills, pre->mem.oomkills);
else
dev->mem.oomkills = -1;
dev->mem.compactstall = subcount(cur->mem.compactstall,
pre->mem.compactstall);
dev->mem.numamigrate = subcount(cur->mem.numamigrate, pre->mem.numamigrate);
dev->mem.pgmigrate = subcount(cur->mem.pgmigrate, pre->mem.pgmigrate);
dev->memnuma.nrnuma = cur->memnuma.nrnuma;
for (i=0; i < dev->memnuma.nrnuma; i++)
{
dev->memnuma.numa[i].numanr = cur->memnuma.numa[i].numanr;
dev->memnuma.numa[i].totmem = cur->memnuma.numa[i].totmem;
dev->memnuma.numa[i].freemem = cur->memnuma.numa[i].freemem;
dev->memnuma.numa[i].filepage = cur->memnuma.numa[i].filepage;
dev->memnuma.numa[i].active = cur->memnuma.numa[i].active;
dev->memnuma.numa[i].inactive = cur->memnuma.numa[i].inactive;
dev->memnuma.numa[i].dirtymem = cur->memnuma.numa[i].dirtymem;
dev->memnuma.numa[i].shmem = cur->memnuma.numa[i].shmem;
dev->memnuma.numa[i].slabmem = cur->memnuma.numa[i].slabmem;
dev->memnuma.numa[i].slabreclaim = cur->memnuma.numa[i].slabreclaim;
dev->memnuma.numa[i].tothp = cur->memnuma.numa[i].tothp;
dev->memnuma.numa[i].freehp = cur->memnuma.numa[i].freehp;
dev->memnuma.numa[i].frag = cur->memnuma.numa[i].frag;
}
dev->cpunuma.nrnuma = cur->cpunuma.nrnuma;
if (dev->cpunuma.nrnuma > 1)
{
for (i=0; i < dev->cpunuma.nrnuma; i++)
{
dev->cpunuma.numa[i].nrcpu = cur->cpunuma.numa[i].nrcpu;
dev->cpunuma.numa[i].numanr = cur->cpunuma.numa[i].numanr;
dev->cpunuma.numa[i].utime = subcount(cur->cpunuma.numa[i].utime,
pre->cpunuma.numa[i].utime);
dev->cpunuma.numa[i].ntime = subcount(cur->cpunuma.numa[i].ntime,
pre->cpunuma.numa[i].ntime);
dev->cpunuma.numa[i].stime = subcount(cur->cpunuma.numa[i].stime,
pre->cpunuma.numa[i].stime);
dev->cpunuma.numa[i].itime = subcount(cur->cpunuma.numa[i].itime,
pre->cpunuma.numa[i].itime);
dev->cpunuma.numa[i].wtime = subcount(cur->cpunuma.numa[i].wtime,
pre->cpunuma.numa[i].wtime);
dev->cpunuma.numa[i].Itime = subcount(cur->cpunuma.numa[i].Itime,
pre->cpunuma.numa[i].Itime);
dev->cpunuma.numa[i].Stime = subcount(cur->cpunuma.numa[i].Stime,
pre->cpunuma.numa[i].Stime);
dev->cpunuma.numa[i].steal = subcount(cur->cpunuma.numa[i].steal,
pre->cpunuma.numa[i].steal);
dev->cpunuma.numa[i].guest = subcount(cur->cpunuma.numa[i].guest,
pre->cpunuma.numa[i].guest);
}
}
dev->psi = cur->psi;
if (cur->psi.present)
{
dev->psi.cpusome.total = cur->psi.cpusome.total -
pre->psi.cpusome.total;
dev->psi.memsome.total = cur->psi.memsome.total -
pre->psi.memsome.total;
dev->psi.memfull.total = cur->psi.memfull.total -
pre->psi.memfull.total;
dev->psi.iosome.total = cur->psi.iosome.total -
pre->psi.iosome.total;
dev->psi.iofull.total = cur->psi.iofull.total -
pre->psi.iofull.total;
}
/*
** structures with network-related counters are considered
** as tables of frequency-counters that have to be subtracted;
** values that do not represent a frequency are corrected afterwards
*/
for (cdev = (count_t *)&dev->net.ipv4,
ccur = (count_t *)&cur->net.ipv4,
cpre = (count_t *)&pre->net.ipv4,
i = 0;
i < (sizeof dev->net.ipv4 / sizeof(count_t));
cdev++, ccur++, cpre++, i++)
*cdev = *ccur - *cpre;
dev->net.ipv4.Forwarding = cur->net.ipv4.Forwarding;
dev->net.ipv4.DefaultTTL = cur->net.ipv4.DefaultTTL;
/* ------------- */
for (cdev = (count_t *)&dev->net.icmpv4,
ccur = (count_t *)&cur->net.icmpv4,
cpre = (count_t *)&pre->net.icmpv4,
i = 0;
i < (sizeof dev->net.icmpv4 / sizeof(count_t));
cdev++, ccur++, cpre++, i++)
*cdev = *ccur - *cpre;
/* ------------- */
for (cdev = (count_t *)&dev->net.udpv4,
ccur = (count_t *)&cur->net.udpv4,
cpre = (count_t *)&pre->net.udpv4,
i = 0;
i < (sizeof dev->net.udpv4 / sizeof(count_t));
cdev++, ccur++, cpre++, i++)
*cdev = *ccur - *cpre;
/* ------------- */
for (cdev = (count_t *)&dev->net.ipv6,
ccur = (count_t *)&cur->net.ipv6,
cpre = (count_t *)&pre->net.ipv6,
i = 0;
i < (sizeof dev->net.ipv6 / sizeof(count_t));
cdev++, ccur++, cpre++, i++)
*cdev = *ccur - *cpre;
/* ------------- */
for (cdev = (count_t *)&dev->net.icmpv6,
ccur = (count_t *)&cur->net.icmpv6,
cpre = (count_t *)&pre->net.icmpv6,
i = 0;
i < (sizeof dev->net.icmpv6 / sizeof(count_t));
cdev++, ccur++, cpre++, i++)
*cdev = *ccur - *cpre;
/* ------------- */
for (cdev = (count_t *)&dev->net.udpv6,
ccur = (count_t *)&cur->net.udpv6,
cpre = (count_t *)&pre->net.udpv6,
i = 0;
i < (sizeof dev->net.udpv6 / sizeof(count_t));
cdev++, ccur++, cpre++, i++)
*cdev = *ccur - *cpre;
/* ------------- */
for (cdev = (count_t *)&dev->net.tcp,
ccur = (count_t *)&cur->net.tcp,
cpre = (count_t *)&pre->net.tcp,
i = 0;
i < (sizeof dev->net.tcp / sizeof(count_t));
cdev++, ccur++, cpre++, i++)
*cdev = *ccur - *cpre;
dev->net.tcp.RtoAlgorithm = cur->net.tcp.RtoAlgorithm;
dev->net.tcp.RtoMin = cur->net.tcp.RtoMin;
dev->net.tcp.RtoMax = cur->net.tcp.RtoMax;
dev->net.tcp.MaxConn = cur->net.tcp.MaxConn;
dev->net.tcp.CurrEstab = cur->net.tcp.CurrEstab;
/*
** calculate deviations for interfaces
*/
for (i=0; cur->intf.intf[i].name[0]; i++)
{
// fill current properties for each valid interface
strcpy(ifprop.name, cur->intf.intf[i].name);
getifprop(&ifprop);
cur->intf.intf[i].type = ifprop.type;
cur->intf.intf[i].speed = ifprop.speed;
cur->intf.intf[i].speedp = ifprop.speed;
cur->intf.intf[i].duplex = ifprop.fullduplex;
}
if (pre->intf.intf[0].name[0] == '\0') /* first sample? */
{
for (i=0; cur->intf.intf[i].name[0]; i++)
{
strcpy(pre->intf.intf[i].name, cur->intf.intf[i].name);
pre->intf.intf[i].type = cur->intf.intf[i].type;
pre->intf.intf[i].speed = cur->intf.intf[i].speed;
pre->intf.intf[i].speedp = cur->intf.intf[i].speedp;
pre->intf.intf[i].duplex = cur->intf.intf[i].duplex;
}
}
for (i=0, j=0; cur->intf.intf[i].name[0]; i++, j++)
{
/*
** be sure that we have the same interface
** (interfaces could have been added or removed since
** previous sample)
*/
if (strcmp(cur->intf.intf[i].name, pre->intf.intf[j].name) != 0)
{
// try to resync
for (j=0; pre->intf.intf[j].name[0]; j++)
{
if (strcmp(cur->intf.intf[i].name,
pre->intf.intf[j].name) == 0)
break;
}
// resync not succeeded?
if (! pre->intf.intf[j].name[0])
{
memcpy(&dev->intf.intf[i],
&cur->intf.intf[i],
sizeof cur->intf.intf[i]);
j = 0;
continue;
}
}
/*
** calculate interface deviations for this sample
*/
strcpy(dev->intf.intf[i].name, cur->intf.intf[i].name);
dev->intf.intf[i].rbyte = subcount(cur->intf.intf[i].rbyte,
pre->intf.intf[j].rbyte);
dev->intf.intf[i].rpack = subcount(cur->intf.intf[i].rpack,
pre->intf.intf[j].rpack);
dev->intf.intf[i].rerrs = subcount(cur->intf.intf[i].rerrs,
pre->intf.intf[j].rerrs);
dev->intf.intf[i].rdrop = subcount(cur->intf.intf[i].rdrop,
pre->intf.intf[j].rdrop);
dev->intf.intf[i].rfifo = subcount(cur->intf.intf[i].rfifo,
pre->intf.intf[j].rfifo);
dev->intf.intf[i].rframe= subcount(cur->intf.intf[i].rframe,
pre->intf.intf[j].rframe);
dev->intf.intf[i].rcompr= subcount(cur->intf.intf[i].rcompr,
pre->intf.intf[j].rcompr);
dev->intf.intf[i].rmultic=subcount(cur->intf.intf[i].rmultic,
pre->intf.intf[j].rmultic);
dev->intf.intf[i].sbyte = subcount(cur->intf.intf[i].sbyte,
pre->intf.intf[j].sbyte);
dev->intf.intf[i].spack = subcount(cur->intf.intf[i].spack,
pre->intf.intf[j].spack);
dev->intf.intf[i].serrs = subcount(cur->intf.intf[i].serrs,
pre->intf.intf[j].serrs);
dev->intf.intf[i].sdrop = subcount(cur->intf.intf[i].sdrop,
pre->intf.intf[j].sdrop);
dev->intf.intf[i].sfifo = subcount(cur->intf.intf[i].sfifo,
pre->intf.intf[j].sfifo);
dev->intf.intf[i].scollis= subcount(cur->intf.intf[i].scollis,
pre->intf.intf[j].scollis);
dev->intf.intf[i].scarrier= subcount(cur->intf.intf[i].scarrier,
pre->intf.intf[j].scarrier);
dev->intf.intf[i].scompr= subcount(cur->intf.intf[i].scompr,
pre->intf.intf[j].scompr);
dev->intf.intf[i].type = cur->intf.intf[i].type;
dev->intf.intf[i].duplex = cur->intf.intf[i].duplex;
dev->intf.intf[i].speed = cur->intf.intf[i].speed;
dev->intf.intf[i].speedp = pre->intf.intf[j].speed;
cur->intf.intf[i].speedp = pre->intf.intf[j].speed;
}
dev->intf.intf[i].name[0] = '\0';
dev->intf.nrintf = i;
/*
** calculate deviations for disks
*/
for (i=j=0; cur->dsk.dsk[i].name[0]; i++)
{
int realj = j;
/*
** check if disk has been added or removed since
** previous interval
*/
if ( strcmp(cur->dsk.dsk[i].name, pre->dsk.dsk[j].name) != 0)
{
for (j++; pre->dsk.dsk[j].name[0]; j++)
{
if ( strcmp(cur->dsk.dsk[i].name,
pre->dsk.dsk[j].name) == 0)
break;
}
/*
** either the corresponding entry has been found
** in the case that a disk has been removed, or
** an empty entry has been found (all counters
** on zero) in the case that a disk has been added
** during the last sample
*/
}
strcpy(dev->dsk.dsk[i].name, cur->dsk.dsk[i].name);
dev->dsk.dsk[i].nread = subcount(cur->dsk.dsk[i].nread,
pre->dsk.dsk[j].nread);
dev->dsk.dsk[i].nrsect = subcount(cur->dsk.dsk[i].nrsect,
pre->dsk.dsk[j].nrsect);
dev->dsk.dsk[i].nwrite = subcount(cur->dsk.dsk[i].nwrite,
pre->dsk.dsk[j].nwrite);
dev->dsk.dsk[i].nwsect = subcount(cur->dsk.dsk[i].nwsect,
pre->dsk.dsk[j].nwsect);
dev->dsk.dsk[i].inflight = cur->dsk.dsk[i].inflight;
dev->dsk.dsk[i].io_ms = subcount(cur->dsk.dsk[i].io_ms,
pre->dsk.dsk[j].io_ms);
dev->dsk.dsk[i].avque = subcount(cur->dsk.dsk[i].avque,
pre->dsk.dsk[j].avque);
if (cur->dsk.dsk[i].ndisc != -1) // discards supported?
{
dev->dsk.dsk[i].ndisc = subcount(cur->dsk.dsk[i].ndisc,
pre->dsk.dsk[j].ndisc);
dev->dsk.dsk[i].ndsect = subcount(cur->dsk.dsk[i].ndsect,
pre->dsk.dsk[j].ndsect);
}
else
{
dev->dsk.dsk[i].ndisc = -1;
dev->dsk.dsk[i].ndsect = 0;
}
/*
** determine new j
*/
if (pre->dsk.dsk[j].name[0]) // existing matching entry
j++;
else
j = realj; // empty entry: stick to old j
}
dev->dsk.dsk[i].name[0] = '\0';
dev->dsk.ndsk = i;
/*
** calculate deviations for multiple devices
*/
for (i=j=0; cur->dsk.mdd[i].name[0]; i++)
{
int realj = j;
/*
** check if md has been added or removed since
** previous interval
*/
if ( strcmp(cur->dsk.mdd[i].name, pre->dsk.mdd[j].name) != 0)
{
for (j++; pre->dsk.mdd[j].name[0]; j++)
{
if ( strcmp(cur->dsk.mdd[i].name,
pre->dsk.mdd[j].name) == 0)
break;
}
/*
** either the corresponding entry has been found
** in the case that a md has been removed, or
** an empty entry has been found (all counters
** on zero) in the case that a md has been added
** during the last sample
*/
}
strcpy(dev->dsk.mdd[i].name, cur->dsk.mdd[i].name);
dev->dsk.mdd[i].nread = subcount(cur->dsk.mdd[i].nread,
pre->dsk.mdd[j].nread);
dev->dsk.mdd[i].nrsect = subcount(cur->dsk.mdd[i].nrsect,
pre->dsk.mdd[j].nrsect);
dev->dsk.mdd[i].nwrite = subcount(cur->dsk.mdd[i].nwrite,
pre->dsk.mdd[j].nwrite);
dev->dsk.mdd[i].nwsect = subcount(cur->dsk.mdd[i].nwsect,
pre->dsk.mdd[j].nwsect);
dev->dsk.mdd[i].io_ms = subcount(cur->dsk.mdd[i].io_ms,
pre->dsk.mdd[j].io_ms);
dev->dsk.mdd[i].avque = subcount(cur->dsk.mdd[i].avque,
pre->dsk.mdd[j].avque);
if (cur->dsk.mdd[i].ndisc != -1) // discards supported?
{
dev->dsk.mdd[i].ndisc = subcount(cur->dsk.mdd[i].ndisc,
pre->dsk.mdd[j].ndisc);
dev->dsk.mdd[i].ndsect = subcount(cur->dsk.mdd[i].ndsect,
pre->dsk.mdd[j].ndsect);
}
else
{
dev->dsk.mdd[i].ndisc = -1;
dev->dsk.mdd[i].ndsect = 0;
}
/*
** determine new j
*/
if (pre->dsk.mdd[j].name[0]) // existing matching entry
j++;
else
j = realj; // empty entry: stick to old j
}
dev->dsk.mdd[i].name[0] = '\0';
dev->dsk.nmdd = i;
/*
** calculate deviations for LVM logical volumes
*/
for (i=j=0; cur->dsk.lvm[i].name[0]; i++)
{
int realj = j;
/*
** check if logical volume has been added or removed since
** previous interval
*/
if ( strcmp(cur->dsk.lvm[i].name, pre->dsk.lvm[j].name) != 0)
{
for (j++; pre->dsk.lvm[j].name[0]; j++)
{
if ( strcmp(cur->dsk.lvm[i].name,
pre->dsk.lvm[j].name) == 0)
break;
}
/*
** either the corresponding entry has been found
** in the case that a logical volume has been removed,
** or an empty entry has been found (all counters
** on zero) in the case that a logical volume has
** been added during the last sample
*/
}
strcpy(dev->dsk.lvm[i].name, cur->dsk.lvm[i].name);
dev->dsk.lvm[i].nread = subcount(cur->dsk.lvm[i].nread,
pre->dsk.lvm[j].nread);
dev->dsk.lvm[i].nrsect = subcount(cur->dsk.lvm[i].nrsect,
pre->dsk.lvm[j].nrsect);
dev->dsk.lvm[i].nwrite = subcount(cur->dsk.lvm[i].nwrite,
pre->dsk.lvm[j].nwrite);
dev->dsk.lvm[i].nwsect = subcount(cur->dsk.lvm[i].nwsect,
pre->dsk.lvm[j].nwsect);
dev->dsk.lvm[i].io_ms = subcount(cur->dsk.lvm[i].io_ms,
pre->dsk.lvm[j].io_ms);
dev->dsk.lvm[i].avque = subcount(cur->dsk.lvm[i].avque,
pre->dsk.lvm[j].avque);
if (cur->dsk.lvm[i].ndisc != -1) // discards supported?
{
dev->dsk.lvm[i].ndisc = subcount(cur->dsk.lvm[i].ndisc,
pre->dsk.lvm[j].ndisc);
dev->dsk.lvm[i].ndsect = subcount(cur->dsk.lvm[i].ndsect,
pre->dsk.lvm[j].ndsect);
}
else
{
dev->dsk.lvm[i].ndisc = -1;
dev->dsk.lvm[i].ndsect = 0;
}
/*
** determine new j
*/
if (pre->dsk.lvm[j].name[0]) // existing matching entry
j++;
else
j = realj; // empty entry: stick to old j
}
dev->dsk.lvm[i].name[0] = '\0';
dev->dsk.nlvm = i;
/*
** calculate deviations for NFS
*/
dev->nfs.server.netcnt = subcount(cur->nfs.server.netcnt,
pre->nfs.server.netcnt);
dev->nfs.server.netudpcnt = subcount(cur->nfs.server.netudpcnt,
pre->nfs.server.netudpcnt);
dev->nfs.server.nettcpcnt = subcount(cur->nfs.server.nettcpcnt,
pre->nfs.server.nettcpcnt);
dev->nfs.server.nettcpcon = subcount(cur->nfs.server.nettcpcon,
pre->nfs.server.nettcpcon);
dev->nfs.server.rpccnt = subcount(cur->nfs.server.rpccnt,
pre->nfs.server.rpccnt);
dev->nfs.server.rpcread = subcount(cur->nfs.server.rpcread,
pre->nfs.server.rpcread);
dev->nfs.server.rpcwrite = subcount(cur->nfs.server.rpcwrite,
pre->nfs.server.rpcwrite);
dev->nfs.server.rpcbadfmt = subcount(cur->nfs.server.rpcbadfmt,
pre->nfs.server.rpcbadfmt);
dev->nfs.server.rpcbadaut = subcount(cur->nfs.server.rpcbadaut,
pre->nfs.server.rpcbadaut);
dev->nfs.server.rpcbadcln = subcount(cur->nfs.server.rpcbadcln,
pre->nfs.server.rpcbadcln);
dev->nfs.server.rchits = subcount(cur->nfs.server.rchits,
pre->nfs.server.rchits);
dev->nfs.server.rcmiss = subcount(cur->nfs.server.rcmiss,
pre->nfs.server.rcmiss);
dev->nfs.server.rcnoca = subcount(cur->nfs.server.rcnoca,
pre->nfs.server.rcnoca);
dev->nfs.server.nrbytes = subcount(cur->nfs.server.nrbytes,
pre->nfs.server.nrbytes);
dev->nfs.server.nwbytes = subcount(cur->nfs.server.nwbytes,
pre->nfs.server.nwbytes);
dev->nfs.client.rpccnt = subcount(cur->nfs.client.rpccnt,
pre->nfs.client.rpccnt);
dev->nfs.client.rpcread = subcount(cur->nfs.client.rpcread,
pre->nfs.client.rpcread);
dev->nfs.client.rpcwrite = subcount(cur->nfs.client.rpcwrite,
pre->nfs.client.rpcwrite);
dev->nfs.client.rpcretrans = subcount(cur->nfs.client.rpcretrans,
pre->nfs.client.rpcretrans);
dev->nfs.client.rpcautrefresh = subcount(cur->nfs.client.rpcautrefresh,
pre->nfs.client.rpcautrefresh);
for (i=j=0; i < cur->nfs.nfsmounts.nrmounts; i++, j++)
{
/*
** check if nfsmounts have been added or removed since
** previous interval
*/
if ( strcmp(cur->nfs.nfsmounts.nfsmnt[i].mountdev,
pre->nfs.nfsmounts.nfsmnt[j].mountdev) != 0)
{
for (j=0; j < pre->nfs.nfsmounts.nrmounts; j++)
{
if ( strcmp(cur->nfs.nfsmounts.nfsmnt[i].mountdev,
pre->nfs.nfsmounts.nfsmnt[j].mountdev)
== 0)
break;
}
/*
** either the corresponding entry has been found
** in the case that a container has been removed,
** or an empty entry has been found (all counters
** on zero) in the case that a container has
** been added during the last sample
*/
}
strcpy(dev->nfs.nfsmounts.nfsmnt[i].mountdev,
cur->nfs.nfsmounts.nfsmnt[i].mountdev);
dev->nfs.nfsmounts.nfsmnt[i].age =
cur->nfs.nfsmounts.nfsmnt[i].age;
if (dev->nfs.nfsmounts.nfsmnt[i].age <= interval)
memset(&(pre->nfs.nfsmounts.nfsmnt[j]), 0,
sizeof(struct pernfsmount));
dev->nfs.nfsmounts.nfsmnt[i].bytesread =
subcount(cur->nfs.nfsmounts.nfsmnt[i].bytesread,
pre->nfs.nfsmounts.nfsmnt[j].bytesread);
dev->nfs.nfsmounts.nfsmnt[i].byteswrite =
subcount(cur->nfs.nfsmounts.nfsmnt[i].byteswrite,
pre->nfs.nfsmounts.nfsmnt[j].byteswrite);
dev->nfs.nfsmounts.nfsmnt[i].bytesdread =
subcount(cur->nfs.nfsmounts.nfsmnt[i].bytesdread,
pre->nfs.nfsmounts.nfsmnt[j].bytesdread);
dev->nfs.nfsmounts.nfsmnt[i].bytesdwrite =
subcount(cur->nfs.nfsmounts.nfsmnt[i].bytesdwrite,
pre->nfs.nfsmounts.nfsmnt[j].bytesdwrite);
dev->nfs.nfsmounts.nfsmnt[i].bytestotread =
subcount(cur->nfs.nfsmounts.nfsmnt[i].bytestotread,
pre->nfs.nfsmounts.nfsmnt[j].bytestotread);
dev->nfs.nfsmounts.nfsmnt[i].bytestotwrite =
subcount(cur->nfs.nfsmounts.nfsmnt[i].bytestotwrite,
pre->nfs.nfsmounts.nfsmnt[j].bytestotwrite);
dev->nfs.nfsmounts.nfsmnt[i].pagesmread =
subcount(cur->nfs.nfsmounts.nfsmnt[i].pagesmread,
pre->nfs.nfsmounts.nfsmnt[j].pagesmread);
dev->nfs.nfsmounts.nfsmnt[i].pagesmwrite =
subcount(cur->nfs.nfsmounts.nfsmnt[i].pagesmwrite,
pre->nfs.nfsmounts.nfsmnt[j].pagesmwrite);
}
dev->nfs.nfsmounts.nrmounts = cur->nfs.nfsmounts.nrmounts;
/*
** calculate deviations for containers
*/
for (i=j=0; i < cur->cfs.nrcontainer; i++, j++)
{
/*
** check if containers have been added or removed since
** previous interval
*/
if (cur->cfs.cont[i].ctid != pre->cfs.cont[j].ctid)
{
for (j=0; j < pre->cfs.nrcontainer; j++)
{
if (cur->cfs.cont[i].ctid ==
pre->cfs.cont[j].ctid)
break;
}
/*
** either the corresponding entry has been found
** in the case that a container has been removed,
** or an empty entry has been found (all counters
** on zero) in the case that a container has
** been added during the last sample
*/
}
dev->cfs.cont[i].ctid = cur->cfs.cont[i].ctid;
dev->cfs.cont[i].numproc = cur->cfs.cont[i].numproc;
dev->cfs.cont[i].physpages = cur->cfs.cont[i].physpages;
dev->cfs.cont[i].system = subcount(cur->cfs.cont[i].system,
pre->cfs.cont[j].system);
dev->cfs.cont[i].user = subcount(cur->cfs.cont[i].user,
pre->cfs.cont[j].user);
dev->cfs.cont[i].nice = subcount(cur->cfs.cont[i].nice,
pre->cfs.cont[j].nice);
dev->cfs.cont[i].uptime = subcount(cur->cfs.cont[i].uptime,
pre->cfs.cont[j].uptime);
}
dev->cfs.nrcontainer = cur->cfs.nrcontainer;
/*
** calculate deviations for GPUs
*/
for (i=0; i < cur->gpu.nrgpus; i++)
{
dev->gpu.gpu[i].gpunr = i;
strcpy(dev->gpu.gpu[i].type, cur->gpu.gpu[i].type);
strcpy(dev->gpu.gpu[i].busid, cur->gpu.gpu[i].busid);
dev->gpu.gpu[i].taskstats = cur->gpu.gpu[i].taskstats;
dev->gpu.gpu[i].nrprocs = cur->gpu.gpu[i].nrprocs;
dev->gpu.gpu[i].gpupercnow = cur->gpu.gpu[i].gpupercnow;
dev->gpu.gpu[i].mempercnow = cur->gpu.gpu[i].mempercnow;
dev->gpu.gpu[i].memtotnow = cur->gpu.gpu[i].memtotnow;
dev->gpu.gpu[i].memusenow = cur->gpu.gpu[i].memusenow;
dev->gpu.gpu[i].samples = subcount(cur->gpu.gpu[i].samples,
pre->gpu.gpu[i].samples);
if (cur->gpu.gpu[i].gpuperccum >= 0)
dev->gpu.gpu[i].gpuperccum = subcount(cur->gpu.gpu[i].gpuperccum,
pre->gpu.gpu[i].gpuperccum);
else
dev->gpu.gpu[i].gpuperccum = -1;
if (cur->gpu.gpu[i].memusecum >= 0)
dev->gpu.gpu[i].memusecum = subcount(cur->gpu.gpu[i].memusecum,
pre->gpu.gpu[i].memusecum);
else
dev->gpu.gpu[i].memusecum = -1;
if (cur->gpu.gpu[i].memperccum >= 0)
dev->gpu.gpu[i].memperccum = subcount(cur->gpu.gpu[i].memperccum,
pre->gpu.gpu[i].memperccum);
else
dev->gpu.gpu[i].memperccum = -1;
}
dev->gpu.nrgpus = cur->gpu.nrgpus;
/*
** calculate deviations for InfiniBand
*/
for (i=0; i < cur->ifb.nrports; i++)
{
strcpy(dev->ifb.ifb[i].ibname, cur->ifb.ifb[i].ibname);
dev->ifb.ifb[i].portnr = cur->ifb.ifb[i].portnr;
dev->ifb.ifb[i].lanes = cur->ifb.ifb[i].lanes;
dev->ifb.ifb[i].rate = cur->ifb.ifb[i].rate;
dev->ifb.ifb[i].rcvb = cur->ifb.ifb[i].rcvb -
pre->ifb.ifb[i].rcvb;
dev->ifb.ifb[i].sndb = cur->ifb.ifb[i].sndb -
pre->ifb.ifb[i].sndb;
dev->ifb.ifb[i].rcvp = cur->ifb.ifb[i].rcvp -
pre->ifb.ifb[i].rcvp;
dev->ifb.ifb[i].sndp = cur->ifb.ifb[i].sndp -
pre->ifb.ifb[i].sndp;
}
dev->ifb.nrports = cur->ifb.nrports;
/*
** calculate deviations for Last Level Cache
*/
for (i = 0; i < cur->llc.nrllcs; i++)
{
dev->llc.perllc[i].id = cur->llc.perllc[i].id;
dev->llc.perllc[i].occupancy = cur->llc.perllc[i].occupancy;
dev->llc.perllc[i].mbm_local = cur->llc.perllc[i].mbm_local -
pre->llc.perllc[i].mbm_local;
dev->llc.perllc[i].mbm_total = cur->llc.perllc[i].mbm_total -
pre->llc.perllc[i].mbm_total;
}
dev->llc.nrllcs = cur->llc.nrllcs;
#if HTTPSTATS
/*
** application-specific counters
*/
if (cur->www.uptime >= pre->www.uptime)
{
dev->www.accesses = subcount(cur->www.accesses,
pre->www.accesses);
dev->www.totkbytes = subcount(cur->www.totkbytes,
pre->www.totkbytes);
}
else
{
dev->www.accesses = cur->www.accesses;
dev->www.totkbytes = cur->www.totkbytes;
}
dev->www.bworkers = cur->www.bworkers;
dev->www.iworkers = cur->www.iworkers;
#endif
}
/*
** add the values of a new sample to a structure holding the totals
** for the indicated category (c=cpu, m=memory, d=disk, n=network).
*/
void
totalsyst(char category, struct sstat *new, struct sstat *tot)
{
register int i;
count_t *ctot, *cnew;
switch (category)
{
case 'c': /* accumulate cpu-related counters */
tot->cpu.nrcpu = new->cpu.nrcpu;
tot->cpu.devint += new->cpu.devint;
tot->cpu.csw += new->cpu.csw;
tot->cpu.nprocs += new->cpu.nprocs;
tot->cpu.all.stime += new->cpu.all.stime;
tot->cpu.all.utime += new->cpu.all.utime;
tot->cpu.all.ntime += new->cpu.all.ntime;
tot->cpu.all.itime += new->cpu.all.itime;
tot->cpu.all.wtime += new->cpu.all.wtime;
tot->cpu.all.Itime += new->cpu.all.Itime;
tot->cpu.all.Stime += new->cpu.all.Stime;
tot->cpu.all.steal += new->cpu.all.steal;
tot->cpu.all.guest += new->cpu.all.guest;
if (new->cpu.nrcpu == 1)
{
tot->cpu.cpu[0] = tot->cpu.all;
}
else
{
for (i=0; i < new->cpu.nrcpu; i++)
{
tot->cpu.cpu[i].cpunr = new->cpu.cpu[i].cpunr;
tot->cpu.cpu[i].stime += new->cpu.cpu[i].stime;
tot->cpu.cpu[i].utime += new->cpu.cpu[i].utime;
tot->cpu.cpu[i].ntime += new->cpu.cpu[i].ntime;
tot->cpu.cpu[i].itime += new->cpu.cpu[i].itime;
tot->cpu.cpu[i].wtime += new->cpu.cpu[i].wtime;
tot->cpu.cpu[i].Itime += new->cpu.cpu[i].Itime;
tot->cpu.cpu[i].Stime += new->cpu.cpu[i].Stime;
tot->cpu.cpu[i].steal += new->cpu.cpu[i].steal;
tot->cpu.cpu[i].guest += new->cpu.cpu[i].guest;
}
}
tot->cpu.lavg1 = new->cpu.lavg1;
tot->cpu.lavg5 = new->cpu.lavg5;
tot->cpu.lavg15 = new->cpu.lavg15;
break;
case 'm': /* accumulate memory-related counters */
tot->mem.physmem = new->mem.physmem;
tot->mem.freemem = new->mem.freemem;
tot->mem.buffermem = new->mem.buffermem;
tot->mem.slabmem = new->mem.slabmem;
tot->mem.slabreclaim = new->mem.slabreclaim;
tot->mem.committed = new->mem.committed;
tot->mem.commitlim = new->mem.commitlim;
tot->mem.cachemem = new->mem.cachemem;
tot->mem.cachedrt = new->mem.cachedrt;
tot->mem.totswap = new->mem.totswap;
tot->mem.freeswap = new->mem.freeswap;
tot->mem.swapcached = new->mem.swapcached;
tot->mem.pagetables = new->mem.pagetables;
tot->mem.zswap = new->mem.zswap;
tot->mem.zswapped = new->mem.zswapped;
tot->mem.shmem = new->mem.shmem;
tot->mem.shmrss = new->mem.shmrss;
tot->mem.shmswp = new->mem.shmswp;
tot->mem.tcpsock = new->mem.tcpsock;
tot->mem.udpsock = new->mem.udpsock;
tot->mem.pgouts += new->mem.pgouts;
tot->mem.pgins += new->mem.pgins;
tot->mem.swouts += new->mem.swouts;
tot->mem.swins += new->mem.swins;
tot->mem.zswouts += new->mem.zswouts;
tot->mem.zswins += new->mem.zswins;
tot->mem.pgscans += new->mem.pgscans;
tot->mem.allocstall += new->mem.allocstall;
tot->mem.compactstall += new->mem.compactstall;
break;
case 'n': /* accumulate network-related counters */
tot->nfs.server.rpccnt += new->nfs.server.rpccnt;
tot->nfs.server.rpcread += new->nfs.server.rpcread;
tot->nfs.server.rpcwrite += new->nfs.server.rpcwrite;
tot->nfs.server.rpcbadfmt += new->nfs.server.rpcbadfmt;
tot->nfs.server.rpcbadaut += new->nfs.server.rpcbadaut;
tot->nfs.server.rpcbadcln += new->nfs.server.rpcbadcln;
tot->nfs.server.netcnt += new->nfs.server.netcnt;
tot->nfs.server.nettcpcnt += new->nfs.server.nettcpcnt;
tot->nfs.server.netudpcnt += new->nfs.server.netudpcnt;
tot->nfs.server.nettcpcon += new->nfs.server.nettcpcon;
tot->nfs.server.rchits += new->nfs.server.rchits;
tot->nfs.server.rcmiss += new->nfs.server.rcmiss;
tot->nfs.server.rcnoca += new->nfs.server.rcnoca;
tot->nfs.server.nrbytes += new->nfs.server.nrbytes;
tot->nfs.server.nwbytes += new->nfs.server.nwbytes;
tot->nfs.client.rpccnt += new->nfs.client.rpccnt;
tot->nfs.client.rpcread += new->nfs.client.rpcread;
tot->nfs.client.rpcwrite += new->nfs.client.rpcwrite;
tot->nfs.client.rpcretrans += new->nfs.client.rpcretrans;
tot->nfs.client.rpcautrefresh += new->nfs.client.rpcautrefresh;
/*
** other structures with network counters are considered
** as tables of frequency-counters that will be accumulated;
** values that do not represent a frequency are corrected
** afterwards
*/
for (ctot = (count_t *)&tot->net.ipv4,
cnew = (count_t *)&new->net.ipv4, i = 0;
i < (sizeof tot->net.ipv4 / sizeof(count_t));
ctot++, cnew++, i++)
*ctot += *cnew;
tot->net.ipv4.Forwarding = new->net.ipv4.Forwarding;
tot->net.ipv4.DefaultTTL = new->net.ipv4.DefaultTTL;
/* ------------- */
for (ctot = (count_t *)&tot->net.icmpv4,
cnew = (count_t *)&new->net.icmpv4, i = 0;
i < (sizeof tot->net.icmpv4 / sizeof(count_t));
ctot++, cnew++, i++)
*ctot += *cnew;
/* ------------- */
for (ctot = (count_t *)&tot->net.udpv4,
cnew = (count_t *)&new->net.udpv4, i = 0;
i < (sizeof tot->net.udpv4 / sizeof(count_t));
ctot++, cnew++, i++)
*ctot += *cnew;
/* ------------- */
for (ctot = (count_t *)&tot->net.ipv6,
cnew = (count_t *)&new->net.ipv6, i = 0;
i < (sizeof tot->net.ipv6 / sizeof(count_t));
ctot++, cnew++, i++)
*ctot += *cnew;
/* ------------- */
for (ctot = (count_t *)&tot->net.icmpv6,
cnew = (count_t *)&new->net.icmpv6, i = 0;
i < (sizeof tot->net.icmpv6 / sizeof(count_t));
ctot++, cnew++, i++)
*ctot += *cnew;
/* ------------- */
for (ctot = (count_t *)&tot->net.udpv6,
cnew = (count_t *)&new->net.udpv6, i = 0;
i < (sizeof tot->net.udpv6 / sizeof(count_t));
ctot++, cnew++, i++)
*ctot += *cnew;
/* ------------- */
for (ctot = (count_t *)&tot->net.tcp,
cnew = (count_t *)&new->net.tcp, i = 0;
i < (sizeof tot->net.tcp / sizeof(count_t));
ctot++, cnew++, i++)
*ctot += *cnew;
tot->net.tcp.RtoAlgorithm = new->net.tcp.RtoAlgorithm;
tot->net.tcp.RtoMin = new->net.tcp.RtoMin;
tot->net.tcp.RtoMax = new->net.tcp.RtoMax;
tot->net.tcp.MaxConn = new->net.tcp.MaxConn;
tot->net.tcp.CurrEstab = new->net.tcp.CurrEstab;
for (i=0; new->intf.intf[i].name[0]; i++)
{
/*
** check if an interface has been added or removed;
** in that case, zero all counters
*/
if (strcmp(new->intf.intf[i].name,
tot->intf.intf[i].name) != 0)
{
tot->intf.intf[i].rbyte = 0;
tot->intf.intf[i].rpack = 0;
tot->intf.intf[i].rerrs = 0;
tot->intf.intf[i].rdrop = 0;
tot->intf.intf[i].rfifo = 0;
tot->intf.intf[i].rframe = 0;
tot->intf.intf[i].rcompr = 0;
tot->intf.intf[i].rmultic = 0;
tot->intf.intf[i].sbyte = 0;
tot->intf.intf[i].spack = 0;
tot->intf.intf[i].serrs = 0;
tot->intf.intf[i].sdrop = 0;
tot->intf.intf[i].sfifo = 0;
tot->intf.intf[i].scollis = 0;
tot->intf.intf[i].scarrier = 0;
tot->intf.intf[i].scompr = 0;
}
/*
** accumulate counters for this sample
*/
strcpy(tot->intf.intf[i].name, new->intf.intf[i].name);
tot->intf.intf[i].rbyte += new->intf.intf[i].rbyte;
tot->intf.intf[i].rpack += new->intf.intf[i].rpack;
tot->intf.intf[i].rerrs += new->intf.intf[i].rerrs;
tot->intf.intf[i].rdrop += new->intf.intf[i].rdrop;
tot->intf.intf[i].rfifo += new->intf.intf[i].rfifo;
tot->intf.intf[i].rframe += new->intf.intf[i].rframe;
tot->intf.intf[i].rcompr += new->intf.intf[i].rcompr;
tot->intf.intf[i].rmultic += new->intf.intf[i].rmultic;
tot->intf.intf[i].sbyte += new->intf.intf[i].sbyte;
tot->intf.intf[i].spack += new->intf.intf[i].spack;
tot->intf.intf[i].serrs += new->intf.intf[i].serrs;
tot->intf.intf[i].sdrop += new->intf.intf[i].sdrop;
tot->intf.intf[i].sfifo += new->intf.intf[i].sfifo;
tot->intf.intf[i].scollis += new->intf.intf[i].scollis;
tot->intf.intf[i].scarrier+= new->intf.intf[i].scarrier;
tot->intf.intf[i].scompr += new->intf.intf[i].scompr;
tot->intf.intf[i].type = new->intf.intf[i].type;
tot->intf.intf[i].speed = new->intf.intf[i].speed;
tot->intf.intf[i].duplex = new->intf.intf[i].duplex;
}
tot->intf.intf[i].name[0] = '\0';
tot->intf.nrintf = i;
#if HTTPSTATS
tot->www.accesses += new->www.accesses;
tot->www.totkbytes += new->www.totkbytes;
tot->www.bworkers = new->www.bworkers;
tot->www.iworkers = new->www.iworkers;
#endif
break;
case 'd': /* accumulate disk-related counters */
for (i=0; new->dsk.dsk[i].name[0]; i++)
{
strcpy(tot->dsk.dsk[i].name, new->dsk.dsk[i].name);
tot->dsk.dsk[i].nread += new->dsk.dsk[i].nread;
tot->dsk.dsk[i].nrsect += new->dsk.dsk[i].nrsect;
tot->dsk.dsk[i].nwrite += new->dsk.dsk[i].nwrite;
tot->dsk.dsk[i].nwsect += new->dsk.dsk[i].nwsect;
tot->dsk.dsk[i].io_ms += new->dsk.dsk[i].io_ms;
tot->dsk.dsk[i].avque += new->dsk.dsk[i].avque;
if (new->dsk.dsk[i].ndisc != -1) // discards?
{
tot->dsk.dsk[i].ndisc += new->dsk.dsk[i].ndisc;
tot->dsk.dsk[i].ndsect += new->dsk.dsk[i].ndsect;
}
}
tot->dsk.dsk[i].name[0] = '\0';
tot->dsk.ndsk = i;
for (i=0; new->dsk.lvm[i].name[0]; i++)
{
strcpy(tot->dsk.lvm[i].name, new->dsk.lvm[i].name);
tot->dsk.lvm[i].nread += new->dsk.lvm[i].nread;
tot->dsk.lvm[i].nrsect += new->dsk.lvm[i].nrsect;
tot->dsk.lvm[i].nwrite += new->dsk.lvm[i].nwrite;
tot->dsk.lvm[i].nwsect += new->dsk.lvm[i].nwsect;
tot->dsk.lvm[i].io_ms += new->dsk.lvm[i].io_ms;
tot->dsk.lvm[i].avque += new->dsk.lvm[i].avque;
if (new->dsk.lvm[i].ndisc != -1) // discards?
{
tot->dsk.lvm[i].ndisc += new->dsk.lvm[i].ndisc;
tot->dsk.lvm[i].ndsect += new->dsk.lvm[i].ndsect;
}
}
tot->dsk.lvm[i].name[0] = '\0';
tot->dsk.nlvm = i;
for (i=0; new->dsk.mdd[i].name[0]; i++)
{
strcpy(tot->dsk.mdd[i].name, new->dsk.mdd[i].name);
tot->dsk.mdd[i].nread += new->dsk.mdd[i].nread;
tot->dsk.mdd[i].nrsect += new->dsk.mdd[i].nrsect;
tot->dsk.mdd[i].nwrite += new->dsk.mdd[i].nwrite;
tot->dsk.mdd[i].nwsect += new->dsk.mdd[i].nwsect;
tot->dsk.mdd[i].io_ms += new->dsk.mdd[i].io_ms;
tot->dsk.mdd[i].avque += new->dsk.mdd[i].avque;
if (new->dsk.mdd[i].ndisc != -1) // discards?
{
tot->dsk.mdd[i].ndisc += new->dsk.lvm[i].ndisc;
tot->dsk.mdd[i].ndsect += new->dsk.lvm[i].ndsect;
}
}
tot->dsk.mdd[i].name[0] = '\0';
tot->dsk.nmdd = i;
break;
}
}
/*
** Generic function to subtract two counters taking into
** account the possibility that the counter is invalid
** (i.e. non-existing).
*/
static inline count_t
subcount(count_t newval, count_t oldval)
{
if (newval == -1) // invalid counter?
return -1;
if (newval >= oldval) // normal situation
return newval - oldval;
else // counter seems to be reset
return newval;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/mirrors/atop.git
git@gitee.com:mirrors/atop.git
mirrors
atop
atop
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891