1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-atop

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
atopsar.c 73 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Gerlof Langeveld Отправлено 17.02.2024 15:33 d2a10ef
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910
/*
** ATOP - System & Process Monitor
**
** The program 'atop'/'atopsar' offers the possibility to view the activity of
** the system on system-level as well as process-level.
**
** This source-file contains the 'atopsar'-functionality, that makes use
** of the 'atop'-framework.
** ==========================================================================
** Author: Gerlof Langeveld
** E-mail: gerlof.langeveld@atoptool.nl
** Initial: July 2007
** --------------------------------------------------------------------------
** Copyright (C) 2007-2010 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/mman.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/utsname.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <regex.h>
#include <sys/ioctl.h>
#include "atop.h"
#include "ifprop.h"
#include "photosyst.h"
#include "photoproc.h"
#include "cgroups.h"
#include "gpucom.h"
#define MAXFL 64 /* maximum number of command-line flags */
/*
** color definitions
*/
#define COLSETHEAD "\033[30;43m" /* black on yellow */
#define COLSETMED "\033[36m" /* cyan */
#define COLSETHIGH "\033[31m" /* red */
#define COLRESET "\033[00m" /* reset any color */
/*
** miscellaneous values
*/
static unsigned int nsamples = 9999999;
static char stampalways;
static char usemarkers;
static char allresources;
static int numreports;
static time_t saved_begintime;
static unsigned int repeathead = 9999999;
static unsigned int summarycnt = 1;
static char *datemsg = "-------------------------- analysis "
"date: %s --------------------------\n";
/*
** structure definition for print-functions
*/
struct pridef {
char wanted; /* selected option (boolean) */
char *cntcat; /* used categories of counters */
char flag; /* flag on command line */
void (*prihead)(int, int, int); /* print header of list */
int (*priline)(struct sstat *, struct tstat *, struct tstat **,
int, time_t, time_t, time_t,
int, int, int, char *,
int, int, int, int, int, int, int);
/* print counters per line (excl. time) */
char *about; /* statistics about what */
};
extern struct pridef pridef[]; /* table of print-functions */
extern int pricnt; /* total number of print-functions */
static time_t daylim; /* last second of day in epoch */
static int prinow; /* current selection */
static char coloron; /* boolean: colors active now */
/*
** local prototypes
*/
static void engine(void);
static void pratopsaruse(char *);
static void reportlive(time_t, int, struct sstat *);
static char reportraw (time_t, int,
struct devtstat *, struct sstat *,
struct cgchainer *, int, int,
int, unsigned int, char);
static void reportheader(struct utsname *, time_t);
static time_t daylimit(time_t);
int
atopsar(int argc, char *argv[])
{
register int i, c;
struct rlimit rlim;
char *p, *flaglist;
usecolors = 't';
/*
** interpret command-line arguments & flags
*/
if (argc > 1)
{
/*
** gather all flags for the print-functions
*/
flaglist = malloc(pricnt+32);
if (!flaglist)
ptrverify(flaglist, "Malloc failed for %d flags\n", pricnt+32);
for (i=0; i < pricnt; i++)
flaglist[i] = pridef[i].flag;
flaglist[i] = 0;
/*
** add generic flags
*/
strcat(flaglist, "b:e:SxCMHr:R:aA");
while ((c=getopt(argc, argv, flaglist)) != EOF)
{
switch (c)
{
case '?': /* usage wanted ? */
pratopsaruse(argv[0]);
break;
case 'b': /* begin time ? */
if ( !getbranchtime(optarg, &begintime) )
pratopsaruse(argv[0]);
saved_begintime = begintime;
break;
case 'e': /* end time ? */
if ( !getbranchtime(optarg, &endtime) )
pratopsaruse(argv[0]);
break;
case 'r': /* reading of file data ? */
strncpy(rawname, optarg, RAWNAMESZ-1);
if (strcmp(rawname, "-") == 0)
strcpy(rawname, "/dev/stdin");
rawreadflag++;
break;
case 'R': /* summarize samples */
if (!numeric(optarg))
pratopsaruse(argv[0]);
summarycnt = atoi(optarg);
if (summarycnt < 1)
pratopsaruse(argv[0]);
break;
case 'S': /* timestamp on every line */
stampalways = 1;
break;
case 'x': /* never use colors */
usecolors = 0;
break;
case 'C': /* always use colors */
usecolors = 'a';
break;
case 'M': /* markers for overload */
usemarkers = 1;
break;
case 'H': /* repeat headers */
repeathead = 23; /* define default */
if (isatty(fileno(stdout)))
{
struct winsize wsz;
if ( ioctl(1, TIOCGWINSZ, &wsz) != -1)
repeathead = wsz.ws_row - 1;
}
break;
case 'a': /* every interval all units */
allresources = 1;
break;
case 'A': /* all reports wanted ? */
for (i=0; i < pricnt; i++)
pridef[i].wanted = 1;
numreports = pricnt;
break;
default: /* gather report-flags */
for (i=0; i < pricnt; i++)
{
if (pridef[i].flag == c &&
pridef[i].wanted == 0 )
{
pridef[i].wanted = 1;
numreports++;
break;
}
}
if (i == pricnt)
pratopsaruse(argv[0]);
}
}
free(flaglist);
/*
** get optional interval-value and
** optional number of samples
*/
if (optind < argc && optind < MAXFL)
{
if (rawreadflag)
pratopsaruse(argv[0]);
if (!numeric(argv[optind]))
pratopsaruse(argv[0]);
interval = atoi(argv[optind]);
optind++;
if (optind < argc)
{
if (!numeric(argv[optind]) )
pratopsaruse(argv[0]);
if ( (nsamples = atoi(argv[optind])) < 1)
pratopsaruse(argv[0]);
}
}
else /* if no interval specified, read from logfile */
{
rawreadflag++;
}
}
else /* if no flags specified at all, read from logfile */
{
rawreadflag++;
}
/*
** if no report-flags have been specified, take the first
** option in the print-list as default
*/
if (numreports == 0)
{
pridef[0].wanted = 1;
numreports = 1;
}
/*
** set stdout output on line-basis
*/
setvbuf(stdout, (char *)0, _IOLBF, BUFSIZ);
/*
** if only use colors when the output is directed to a tty,
** be sure that output is directed to a tty
*/
if (usecolors == 't')
{
if (! isatty(fileno(stdout)) )
usecolors = 0;
}
/*
** check if raw data from a file must be viewed
*/
if (rawreadflag)
{
/*
** select own reportraw-function to be called
** by the rawread function
*/
vis.show_samp = reportraw;
for (i=0; i < pricnt; i++)
{
if ( pridef[i].wanted )
{
prinow = i;
daylim = 0;
begintime = saved_begintime;
if (!rawread()) // reading from named pipe
break; // can only be done once
printf("\n");
}
}
cleanstop(0);
}
/*
** live data must be gathered
**
** determine the name of this node (without domain-name)
** and the kernel-version
*/
(void) uname(&utsname);
if ( (p = strchr(utsname.nodename, '.')) )
*p = '\0';
sscanf(utsname.release, "%d.%d.%d", &osrel, &osvers, &ossub);
/*
** determine the clock rate and memory page size for this machine
*/
hertz = sysconf(_SC_CLK_TCK);
pagesize = sysconf(_SC_PAGESIZE);
/*
** determine start-time for gathering current statistics
*/
curtime = time(0);
/*
** regain the root-privileges that we dropped at the beginning
** to do some privileged work now
*/
regainrootprivs();
/*
** lock in memory to get reliable samples (also when
** memory is low);
** ignored if not running under superuser privileges!
*/
rlim.rlim_cur = RLIM_INFINITY;
rlim.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_MEMLOCK, &rlim) == 0)
(void) mlockall(MCL_CURRENT|MCL_FUTURE);
/*
** increment CPU scheduling-priority to get reliable samples (also
** during heavy CPU load);
** ignored if not running under superuser privileges!
*/
if ( nice(-20) == -1)
;
/*
** determine properties (like speed) of all interfaces
*/
initifprop();
/*
** since privileged activities are finished now, there is no
** need to keep running under root-privileges, so switch
** effective user-id to real user-id
*/
if (! droprootprivs() )
mcleanstop(42, "failed to drop root privs\n");
/*
** start live reporting
*/
engine();
return 0;
}
/*
** engine() that drives the main-loop for atopsar
*/
static void
engine(void)
{
struct sigaction sigact;
int nrgpus; /* number of GPUs */
int nrgpuproc, /* number of GPU procs */
gpustats=0; /* boolean: request sent */
/*
** reserve space for system-level statistics
*/
static struct sstat *cursstat; /* current */
static struct sstat *presstat; /* previous */
static struct sstat *devsstat; /* deviation */
static struct sstat *hlpsstat;
/*
** initialization: allocate required memory dynamically
*/
cursstat = calloc(1, sizeof(struct sstat));
presstat = calloc(1, sizeof(struct sstat));
devsstat = calloc(1, sizeof(struct sstat));
ptrverify(cursstat, "Malloc failed for current sysstats\n");
ptrverify(presstat, "Malloc failed for prev sysstats\n");
ptrverify(devsstat, "Malloc failed for deviate sysstats\n");
/*
** install the signal-handler for ALARM and SIGUSR1 (both triggers
** for the next sample)
*/
memset(&sigact, 0, sizeof sigact);
sigact.sa_handler = getusr1;
sigaction(SIGUSR1, &sigact, (struct sigaction *)0);
memset(&sigact, 0, sizeof sigact);
sigact.sa_handler = getalarm;
sigaction(SIGALRM, &sigact, (struct sigaction *)0);
if (interval > 0)
alarm(interval);
/*
** print overall report header
*/
reportheader(&utsname, time(0));
/*
** open socket to the atopgpud daemon for GPU statistics
*/
nrgpus = gpud_init();
/*
** MAIN-LOOP:
** - Wait for the requested number of seconds or for other trigger
**
** - System-level counters
** get current counters
** calculate the differences with the previous sample
**
** - Call the print-function to visualize the differences
*/
for (sampcnt=0; sampcnt < nsamples+1; sampcnt++)
{
/*
** wait for alarm-signal to arrive or
** wait for SIGUSR1 in case of an interval of 0.
*/
if (sampcnt > 0)
pause();
/*
** gather time info for this sample
*/
pretime = curtime;
curtime = time(0); /* seconds since 1-1-1970 */
/*
** send request for statistics to atopgpud
*/
if (nrgpus)
gpustats = gpud_statrequest();
/*
** take a snapshot of the current system-level statistics
** and calculate the deviations (i.e. calculate the activity
** during the last sample)
*/
hlpsstat = cursstat; /* swap current/prev. stats */
cursstat = presstat;
presstat = hlpsstat;
photosyst(cursstat); /* obtain new counters */
/*
** receive and parse response from atopgpud
*/
if (nrgpus && gpustats)
{
nrgpuproc = gpud_statresponse(nrgpus, cursstat->gpu.gpu, NULL);
// connection lost or timeout on receive?
if (nrgpuproc == -1)
{
int ng;
// try to reconnect
ng = gpud_init();
if (ng != nrgpus) // no success
nrgpus = 0;
if (nrgpus)
{
// request for stats again
if (gpud_statrequest())
{
// receive stats response
nrgpuproc = gpud_statresponse(nrgpus,
cursstat->gpu.gpu, NULL);
// persistent failure?
if (nrgpuproc == -1)
nrgpus = 0;
}
}
}
cursstat->gpu.nrgpus = nrgpus;
}
/*
** calculate deviations, i.e. activity during interval
*/
deviatsyst(cursstat, presstat, devsstat,
curtime-pretime > 0 ? curtime-pretime : 1);
/*
** activate the report-function to visualize the deviations
*/
reportlive(curtime,
curtime-pretime > 0 ? curtime-pretime : 1, devsstat);
} /* end of main-loop */
}
/*
** report function to print a new sample in case of live measurements
*/
static void
reportlive(time_t curtime, int numsecs, struct sstat *ss)
{
char timebuf[16], datebuf[16];
int i, nr = numreports, rv;
static unsigned int curline, headline;
/*
** printing more reports needs another way of handling compared
** to printing one report
*/
if (numreports > 1)
{
/*
** skip first sample
*/
if (sampcnt == 0)
return;
printf(datemsg, convdate(curtime, datebuf));
for (i=0; i < pricnt && nr > 0; i++)
{
if ( !pridef[i].wanted )
continue;
nr--;
/*
** print header-line
*/
printf("\n");
if (usecolors)
printf(COLSETHEAD);
printf("%s ", convtime(curtime-numsecs, timebuf));
(pridef[i].prihead)(osvers, osrel, ossub);
if (usecolors)
printf(COLRESET);
printf("\n");
/*
** print line with statistical counters
*/
printf("%s ", convtime(curtime, timebuf));
if ( !(pridef[i].priline)(ss, (struct tstat *)0, 0, 0,
numsecs, numsecs*hertz, hertz,
osvers, osrel, ossub,
stampalways ? timebuf : " ",
0, 0, 0, 0, 0, 0, 0) )
{
/*
** print line has failed;
** do not call function again
*/
pridef[i].wanted = 0;
if (--numreports == 0)
cleanstop(1);
}
}
printf("\n");
}
else /* just one report to be printed */
{
/*
** search required report
*/
for (i=0; i < pricnt; i++)
if ( pridef[i].wanted )
break;
/*
** verify if we have passed midnight of some day
*/
if (curtime > daylim)
{
printf(datemsg, convdate(curtime, datebuf));
daylim = daylimit(curtime);
curline++;
}
/*
** print first header
*/
if (sampcnt == 0)
{
/*
** print header-line
*/
printf("\n");
if (usecolors)
printf(COLSETHEAD);
printf("%s ", convtime(curtime, timebuf));
(pridef[i].prihead)(osvers, osrel, ossub);
if (usecolors)
printf(COLRESET);
printf("\n");
curline+=2;
headline = repeathead;
return;
}
/*
** print line with statistical counters
*/
printf("%s ", convtime(curtime, timebuf));
if ( !(rv = (pridef[i].priline)(ss, (struct tstat *)0, 0, 0,
numsecs, numsecs*hertz, hertz,
osvers, osrel, ossub,
stampalways ? timebuf : " ",
0, 0, 0, 0, 0, 0, 0) ) )
{
/*
** print line has failed;
** do not call function again
*/
cleanstop(1);
}
curline+=rv;
if (curline >= headline)
{
headline = curline + repeathead;
/*
** print header-line
*/
printf("\n");
if (usecolors)
printf(COLSETHEAD);
printf("%s ", convtime(curtime, timebuf));
(pridef[i].prihead)(osvers, osrel, ossub);
if (usecolors)
printf(COLRESET);
printf("\n");
curline+=2;
}
}
}
/*
** report function to print a new sample in case of logged measurements
*/
static char
reportraw(time_t curtime, int numsecs,
struct devtstat *devtstat, struct sstat *sstat,
struct cgchainer *devchain, int ncgroups, int npids,
int nexit, unsigned int noverflow, char flags)
{
static char firstcall = 1;
char timebuf[16], datebuf[16];
unsigned int rv;
static unsigned int curline, headline, sampsum,
totalsec, totalexit, lastnpres,
lastntrun, lastntslpi, lastntslpu,
lastntidle, lastnzomb;
static time_t lasttime;
static struct sstat totsyst;
/*
** is this function still wanted?
*/
if ( ! pridef[prinow].wanted )
return '\0';
/*
** when this is first call to this function,
** print overall header with system information
*/
if (firstcall)
{
reportheader(&utsname, time(0));
firstcall = 0;
}
/*
** verify if we have passed midnight
*/
if (curtime > daylim)
{
printf(datemsg, convdate(curtime, datebuf));
daylim = daylimit(curtime);
curline++;
}
/*
** when this is the first record for a new report,
** initialize various variables
*/
if (sampcnt == 1)
{
/*
** initialize variables for new report
*/
pretime = curtime;
curline = 1;
headline = 0;
sampsum = summarycnt + 1;
totalsec = 0;
totalexit = 0;
memset(&totsyst, 0, sizeof totsyst);
return '\0';
}
/*
** check if a (new) report header needs to be printed
*/
if (curline >= headline)
{
headline = curline + repeathead;
/*
** print header-line
*/
printf("\n");
if (usecolors)
printf(COLSETHEAD);
printf("%s ", convtime(pretime, timebuf));
(pridef[prinow].prihead)(osvers, osrel, ossub);
if (usecolors)
printf(COLRESET);
printf("\n");
curline+=2;
}
/*
** when current record contains log-restart indicator,
** print message and reinitialize variables
*/
if (flags & RRBOOT)
{
/*
** when accumulating counters, print results upto
** the *previous* record
*/
if (summarycnt > 1 && sampcnt <= sampsum && totalsec)
{
printf("%s ", convtime(lasttime, timebuf));
rv = (pridef[prinow].priline)(&totsyst,
(struct tstat *)0, 0, 0,
totalsec, totalsec*hertz, hertz,
osvers, osrel, ossub,
stampalways ? timebuf : " ",
lastnpres, lastntrun, lastntslpi,
lastntslpu, lastntidle,
totalexit, lastnzomb);
if (rv == 0)
{
curline++;
pridef[prinow].wanted = 0; /* not call again */
if (--numreports == 0)
cleanstop(1);
}
else
{
curline += rv;
}
}
/*
** print restart-line in case of logging restarted
*/
printf("%s ", convtime(curtime, timebuf));
printf("......................... logging restarted "
".........................\n");
pretime = curtime;
curline++;
/*
** reinitialize variables
*/
sampsum = summarycnt + sampcnt;
totalsec = 0;
totalexit = 0;
memset(&totsyst, 0, sizeof totsyst);
return '\0';
}
/*
** when no accumulation is required,
** just print current sample
*/
if (summarycnt == 1)
{
printf("%s ", convtime(curtime, timebuf));
rv = (pridef[prinow].priline) (sstat, devtstat->taskall,
devtstat->procall, devtstat->nprocall,
numsecs, numsecs*hertz, hertz,
osvers, osrel, ossub,
stampalways ? timebuf : " ",
devtstat->ntaskall, devtstat->totrun,
devtstat->totslpi, devtstat->totslpu,
devtstat->totidle,
nexit, devtstat->totzombie);
if (rv == 0)
{
curline++;
pridef[prinow].wanted = 0; /* not call again */
if (--numreports == 0)
cleanstop(1);
}
else
{
curline += rv;
}
}
else /* accumulation is required */
{
char *cp = pridef[prinow].cntcat;
/*
** maintain totals per category
*/
while (*cp)
{
totalsyst(*cp, sstat, &totsyst);
cp++;
}
totalsec += numsecs;
totalexit += nexit;
/*
** remember some values in case the next record
** contains the log-restart indicator
*/
lasttime = curtime;
lastnpres = devtstat->nprocall;
lastntrun = devtstat->totrun;
lastntslpi = devtstat->totslpi;
lastntslpu = devtstat->totslpu;
lastntidle = devtstat->totidle;
lastnzomb = devtstat->totzombie;
/*
** print line only if needed
*/
if (sampcnt >= sampsum || ( (flags&RRLAST) && totalsec) )
{
/*
** print output line for required report
*/
printf("%s ", convtime(curtime, timebuf));
rv = (pridef[prinow].priline) (&totsyst,
(struct tstat *)0, 0, 0,
totalsec, totalsec*hertz, hertz,
osvers, osrel, ossub,
stampalways ? timebuf : " ",
devtstat->ntaskall, devtstat->totrun,
devtstat->totslpi, devtstat->totslpu,
devtstat->totidle,
totalexit, devtstat->totzombie);
if (rv == 0)
{
curline++;
pridef[prinow].wanted = 0; /* not call again */
if (--numreports == 0)
cleanstop(1);
}
else
{
curline += rv;
}
sampsum = summarycnt + sampcnt;
totalsec = 0;
totalexit = 0;
memset(&totsyst, 0, sizeof totsyst);
}
else
{
rv = 1;
}
}
if (!rv)
{
/*
** print for line has failed;
** never call this function again
*/
pridef[prinow].wanted = 0;
if (--numreports == 0)
cleanstop(1);
}
pretime = curtime;
return '\0';
}
/*
** print overall header
*/
static void
reportheader(struct utsname *uname, time_t mtime)
{
char cdate[16];
printf("\n%s %s %s %s %s\n\n",
uname->nodename,
uname->release,
uname->version,
uname->machine,
convdate(mtime, cdate));
}
/*
** print usage of atopsar command
*/
void
pratopsaruse(char *myname)
{
int i;
fprintf(stderr,
"Usage: %s [-flags] [-r file|-|date|y...] [-R cnt] [-b time] [-e time]\n",
myname);
fprintf(stderr, "\t\tor\n");
fprintf(stderr,
"Usage: %s [-flags] interval [samples]\n", myname);
fprintf(stderr, "\n");
fprintf(stderr,
"\tToday's atop logfile is used by default!\n");
fprintf(stderr, "\n");
fprintf(stderr,
"\tGeneric flags:\n");
fprintf(stderr,
"\t -r read statistical data from specific atop logfile\n");
fprintf(stderr,
"\t (pathname, - for stdin, date in format YYYYMMDD, or y[y..])\n");
fprintf(stderr,
"\t -R summarize <cnt> samples into one sample\n");
fprintf(stderr,
"\t -b begin showing data from specified time as [YYYYMMDD]hhmm[ss]\n");
fprintf(stderr,
"\t -e finish showing data after specified time as [YYYYMMDD]hhmm[ss]\n");
fprintf(stderr,
"\t -S print timestamp on every line in case of more "
"resources\n");
fprintf(stderr,
"\t -x never use colors to indicate overload"
" (default: only if tty)\n");
fprintf(stderr,
"\t -C always use colors to indicate overload"
" (default: only if tty)\n");
fprintf(stderr,
"\t -M use markers to indicate overload "
"(* = critical, + = almost)\n");
fprintf(stderr,
"\t -H repeat report headers "
"(in case of tty: depending on screen lines)\n");
fprintf(stderr,
"\t -a print all resources, even when inactive\n");
fprintf(stderr, "\n");
fprintf(stderr,
"\tSpecific flags to select reports:\n");
fprintf(stderr,
"\t -A print all available reports\n");
for (i=0; i < pricnt; i++)
fprintf(stderr,
"\t -%c %s\n", pridef[i].flag, pridef[i].about);
fprintf(stderr, "\n");
fprintf(stderr,
"Please refer to the man-page of 'atopsar' "
"for more details.\n");
cleanstop(1);
}
/*
** calculate the epoch-value for the last second
** of the day given a certain epoch
*/
static time_t
daylimit(time_t timval)
{
struct tm *tp = localtime(&timval);
tp->tm_hour = 23;
tp->tm_min = 59;
tp->tm_sec = 59;
return mktime(tp);
}
/*
** function to be called before printing a statistics line
** to switch on colors when necessary
*/
static void
preprint(unsigned int badness)
{
if (usecolors)
{
if (badness >= 100)
{
coloron = 1;
printf(COLSETHIGH);
}
else
{
if (almostcrit && badness >= almostcrit)
{
coloron = 1;
printf(COLSETMED);
}
}
}
}
/*
** function to be called after printing a statistics line
** to switch off colors when necessary and print a line feed
*/
static void
postprint(unsigned int badness)
{
if (coloron)
{
coloron = 0;
printf(COLRESET);
}
if (usemarkers)
{
if (badness >= 100)
{
printf(" *");
}
else
{
if (almostcrit && badness >= almostcrit)
printf(" +");
}
}
printf("\n");
}
/*
** function to handle the default flags for atopsar as
** read from the files ~/.atoprc and /etc/atoprc
*/
void
do_atopsarflags(char *name, char *val)
{
int i, j;
for (i=0; val[i]; i++)
{
switch (val[i])
{
case '-':
break;
case 'S': /* timestamp on every line */
stampalways = 1;
break;
case 'x': /* always colors for overload */
usecolors = 0;
break;
case 'C': /* always colors for overload */
usecolors = 'a';
break;
case 'M': /* markers for overload */
usemarkers = 1;
break;
case 'H': /* repeat headers */
repeathead = 23; /* define default */
if (isatty(fileno(stdout)))
{
struct winsize wsz;
if ( ioctl(1, TIOCGWINSZ, &wsz) != -1)
repeathead = wsz.ws_row - 1;
}
break;
case 'a': /* every interval all units */
allresources = 1;
break;
case 'A': /* all reports wanted ? */
for (j=0; j < pricnt; j++)
pridef[j].wanted = 1;
numreports = pricnt;
break;
default: /* gather report-flags */
for (j=0; j < pricnt; j++)
{
if (pridef[j].flag == val[i] &&
pridef[j].wanted == 0 )
{
pridef[j].wanted = 1;
numreports++;
break;
}
}
}
}
}
/**************************************************************************/
/* Functions to print statistics */
/**************************************************************************/
/*
** CPU statistics
*/
static void
cpuhead(int osvers, int osrel, int ossub)
{
printf("cpu %%usr %%nice %%sys %%irq %%softirq %%steal %%guest "
" %%wait %%idle _cpu_");
}
static int
cpuline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
register int i, nlines = 1;
count_t cputot;
unsigned int badness;
/*
** print overall statistics
*/
cputot = ss->cpu.all.stime + ss->cpu.all.utime +
ss->cpu.all.ntime + ss->cpu.all.itime +
ss->cpu.all.wtime + ss->cpu.all.Itime +
ss->cpu.all.Stime + ss->cpu.all.steal;
if (cputot == 0)
cputot = 1; /* avoid divide-by-zero */
if (cpubadness)
badness = ((cputot - ss->cpu.all.itime - ss->cpu.all.wtime) *
100.0 / cputot) * 100 / cpubadness;
else
badness = 0;
preprint(badness);
printf("all %5.0lf %5.0lf %4.0lf %4.0lf %8.0lf %7.0f %6.0f %6.0lf %5.0lf",
(double) (ss->cpu.all.utime * 100.0) / cputot * ss->cpu.nrcpu,
(double) (ss->cpu.all.ntime * 100.0) / cputot * ss->cpu.nrcpu,
(double) (ss->cpu.all.stime * 100.0) / cputot * ss->cpu.nrcpu,
(double) (ss->cpu.all.Itime * 100.0) / cputot * ss->cpu.nrcpu,
(double) (ss->cpu.all.Stime * 100.0) / cputot * ss->cpu.nrcpu,
(double) (ss->cpu.all.steal * 100.0) / cputot * ss->cpu.nrcpu,
(double) (ss->cpu.all.guest * 100.0) / cputot * ss->cpu.nrcpu,
(double) (ss->cpu.all.wtime * 100.0) / cputot * ss->cpu.nrcpu,
(double) (ss->cpu.all.itime * 100.0) / cputot * ss->cpu.nrcpu);
postprint(badness);
/*
** print per-cpu statistics
*/
if (ss->cpu.nrcpu > 1)
{
for (i=0; i < ss->cpu.nrcpu; i++)
{
cputot = ss->cpu.cpu[i].stime + ss->cpu.cpu[i].utime +
ss->cpu.cpu[i].ntime + ss->cpu.cpu[i].itime +
ss->cpu.cpu[i].wtime + ss->cpu.cpu[i].Itime +
ss->cpu.cpu[i].Stime + ss->cpu.cpu[i].steal;
if (cputot == 0)
cputot = 1; /* avoid divide-by-zero */
if (cpubadness)
badness = ((cputot - ss->cpu.cpu[i].itime -
ss->cpu.cpu[i].wtime) * 100.0 /
cputot) * 100 / cpubadness;
else
badness = 0;
printf("%s ", tstamp);
preprint(badness);
printf("%4d %5.0lf %5.0lf %4.0lf %4.0lf %8.0lf "
"%7.0f %6.0lf %6.0lf %5.0lf",
i,
(double)(ss->cpu.cpu[i].utime * 100.0) / cputot,
(double)(ss->cpu.cpu[i].ntime * 100.0) / cputot,
(double)(ss->cpu.cpu[i].stime * 100.0) / cputot,
(double)(ss->cpu.cpu[i].Itime * 100.0) / cputot,
(double)(ss->cpu.cpu[i].Stime * 100.0) / cputot,
(double)(ss->cpu.cpu[i].steal * 100.0) / cputot,
(double)(ss->cpu.cpu[i].guest * 100.0) / cputot,
(double)(ss->cpu.cpu[i].wtime * 100.0) / cputot,
(double)(ss->cpu.cpu[i].itime * 100.0) / cputot);
postprint(badness);
nlines++;
}
}
return nlines;
}
/*
** GPU statistics
*/
static void
gpuhead(int osvers, int osrel, int ossub)
{
printf(" busaddr gpubusy membusy memocc memtot memuse gputype"
" _gpu_");
}
static int
gpuline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
static char firstcall = 1;
register long i, nlines = 0;
char fmt1[16], fmt2[16];
count_t avgmemuse;
for (i=0; i < ss->gpu.nrgpus; i++) /* per GPU */
{
/*
** determine whether or not the GPU has been active
** during interval
*/
int wasactive;
wasactive = ss->gpu.gpu[i].gpuperccum +
ss->gpu.gpu[i].memperccum;
if (wasactive == -2) // metrics not available?
wasactive = 0;
if (ss->gpu.gpu[i].samples == 0)
avgmemuse = ss->gpu.gpu[i].memusenow;
else
avgmemuse = ss->gpu.gpu[i].memusecum /
ss->gpu.gpu[i].samples;
// memusage > 512 MiB (rather arbitrary)?
//
if (avgmemuse > 512*1024)
wasactive = 1;
/*
** print for the first sample all GPUs that are found;
** afterwards print only info about the GPUs
** that were really active during the interval
*/
if (!firstcall && !allresources && !wasactive)
continue;
if (nlines++)
printf("%s ", tstamp);
if (ss->gpu.gpu[i].samples == 0)
ss->gpu.gpu[i].samples = 1;
if (ss->gpu.gpu[i].gpuperccum == -1)
strcpy(fmt1, "N/A");
else
snprintf(fmt1, sizeof fmt1, "%lld%%",
ss->gpu.gpu[i].gpuperccum / ss->gpu.gpu[i].samples);
if (ss->gpu.gpu[i].memperccum == -1)
strcpy(fmt2, "N/A");
else
snprintf(fmt2, sizeof fmt2, "%lld%%",
ss->gpu.gpu[i].memperccum / ss->gpu.gpu[i].samples);
if (ss->gpu.gpu[i].memtotnow == 0)
ss->gpu.gpu[i].memtotnow = 1;
printf("%2ld/%9.9s %7s %7s %5lld%% %5lldM %5lldM %s\n",
i, ss->gpu.gpu[i].busid,
fmt1, fmt2,
ss->gpu.gpu[i].memusenow*100/ss->gpu.gpu[i].memtotnow,
ss->gpu.gpu[i].memtotnow / 1024,
ss->gpu.gpu[i].memusenow / 1024,
ss->gpu.gpu[i].type);
}
if (nlines == 0)
{
printf("\n");
nlines++;
}
firstcall = 0;
return nlines;
}
/*
** other processor statistics
*/
static void
prochead(int osvers, int osrel, int ossub)
{
printf("pswch/s devintr/s clones/s loadavg1 loadavg5 loadavg15 "
" _load_");
}
static int
procline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%7.0lf %9.0lf %9.2lf %8.2lf %8.2lf %8.2lf\n",
(double)ss->cpu.csw / deltasec,
(double)ss->cpu.devint / deltasec,
(double)ss->cpu.nprocs / deltasec,
ss->cpu.lavg1, ss->cpu.lavg5, ss->cpu.lavg15);
return 1;
}
/*
** process statistics
*/
static void
taskhead(int osvers, int osrel, int ossub)
{
printf("clones/s pexit/s curproc curzomb trun tslpi tslpu tidle "
"_procthr_");
}
static int
taskline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
if (ppres == 0)
{
printf("report not available for live measurements.....\n");
return 0;
}
if (ts) /* process statistics available */
{
printf("%8.2lf %7.2lf %7d %7d %6d %6d %5d %5d\n",
(double)ss->cpu.nprocs / deltasec,
(double)pexit / deltasec,
nactproc-pexit, pzombie,
ntrun, ntslpi, ntslpu, ntidle);
}
else
{
printf("%8.2lf %7.2lf %7d %7d\n",
(double)ss->cpu.nprocs / deltasec,
(double)pexit / deltasec,
nactproc-pexit, pzombie);
}
return 1;
}
/*
** memory- & swap-usage
*/
static void
memhead(int osvers, int osrel, int ossub)
{
printf("memtotal memfree buffers cached dirty slabmem"
" swptotal swpfree _mem_" );
}
static int
memline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
unsigned int mbadness, sbadness;
if (membadness)
mbadness = ((ss->mem.physmem - ss->mem.freemem
- ss->mem.cachemem - ss->mem.buffermem
+ ss->mem.shmem) * 100.0 / ss->mem.physmem)
* 100 / membadness;
else
mbadness = 0;
if (swpbadness)
sbadness = ((ss->mem.totswap - ss->mem.freeswap)
* 100.0 / ss->mem.totswap)
* 100 / swpbadness;
else
sbadness = 0;
preprint(mbadness >= sbadness ? mbadness : sbadness);
printf("%7lldM %6lldM %6lldM %5lldM %4lldM %6lldM %7lldM %6lldM",
ss->mem.physmem * (pagesize / 1024) /1024,
ss->mem.freemem * (pagesize / 1024) /1024,
ss->mem.buffermem * (pagesize / 1024) /1024,
ss->mem.cachemem * (pagesize / 1024) /1024,
ss->mem.cachedrt * (pagesize / 1024) /1024,
ss->mem.slabmem * (pagesize / 1024) /1024,
ss->mem.totswap * (pagesize / 1024) /1024,
ss->mem.freeswap * (pagesize / 1024) /1024);
postprint(mbadness >= sbadness ? mbadness : sbadness);
return 1;
}
/*
** swapping statistics
*/
static void
swaphead(int osvers, int osrel, int ossub)
{
printf("pagescan/s swapin/s swapout/s oomkill"
" commitspc commitlim _swap_");
}
static int
swapline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
unsigned int badness;
if (membadness)
badness = (ss->mem.swouts / deltasec * pagbadness)
* 100 / membadness;
else
badness = 0;
/*
** take care that this line is anyhow colored for
** 'almost critical' in case of swapouts > 1 per second
*/
if (ss->mem.swouts / deltasec > 0 &&
pagbadness && almostcrit && badness < almostcrit)
badness = almostcrit;
if (ss->mem.commitlim && ss->mem.committed > ss->mem.commitlim)
badness = 100; /* force colored output */
preprint(badness);
printf("%10.2lf %9.2lf %9.2lf %7lld %9lluM %9lluM",
(double)ss->mem.pgscans / deltasec,
(double)ss->mem.swins / deltasec,
(double)ss->mem.swouts / deltasec,
ss->mem.oomkills,
ss->mem.committed * (pagesize / 1024) / 1024,
ss->mem.commitlim * (pagesize / 1024) / 1024);
postprint(badness);
return 1;
}
/*
** PSI statistics
*/
static void
psihead(int osvers, int osrel, int ossub)
{
printf("cpusome memsome memfull iosome iofull");
}
static int
psiline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
// calculate pressure percentages for entire interval
unsigned int csperc = ss->psi.cpusome.total/(deltatic*10000/hz);
unsigned int msperc = ss->psi.memsome.total/(deltatic*10000/hz);
unsigned int mfperc = ss->psi.memfull.total/(deltatic*10000/hz);
unsigned int isperc = ss->psi.iosome.total /(deltatic*10000/hz);
unsigned int ifperc = ss->psi.iofull.total /(deltatic*10000/hz);
unsigned int badness = 0;
if (!ss->psi.present)
{
printf("no PSI stats available for this interval...\n");
return 1;
}
// correct percentages if needed
if (csperc > 100)
csperc = 100;
if (msperc > 100)
msperc = 100;
if (mfperc > 100)
mfperc = 100;
if (isperc > 100)
isperc = 100;
if (ifperc > 100)
ifperc = 100;
// consider a 'some' percentage > 0 as almost critical
// (I/O full tends to increase rapidly as well)
if (csperc || msperc || isperc || ifperc)
badness = 80;
// consider a memory 'full' percentage > 0 as critical
if (mfperc)
badness = 100;
// show results
preprint(badness);
printf(" %3u%% %3u%% %3u%% %3u%% %3u%%",
csperc, msperc, mfperc, isperc, ifperc);
postprint(badness);
return 1;
}
/*
** disk statistics
*/
static void
lvmhead(int osvers, int osrel, int ossub)
{
printf("disk busy read/s KB/read "
"writ/s KB/writ avque avserv _lvm_");
}
static void
mddhead(int osvers, int osrel, int ossub)
{
printf("disk busy read/s KB/read "
"writ/s KB/writ avque avserv _mdd_");
}
static void
dskhead(int osvers, int osrel, int ossub)
{
printf("disk busy read/s KB/read "
"writ/s KB/writ avque avserv _dsk_");
}
static int
gendskline(struct sstat *ss, char *tstamp, char selector)
{
static char firstcall = 1;
register int i, nlines = 0, nunit = 0;
count_t mstot, iotot;
struct perdsk *dp;
unsigned int badness;
switch (selector)
{
case 'l':
dp = ss->dsk.lvm;
nunit = ss->dsk.nlvm;
break;
case 'm':
dp = ss->dsk.mdd;
nunit = ss->dsk.nmdd;
break;
case 'd':
dp = ss->dsk.dsk;
nunit = ss->dsk.ndsk;
break;
default:
return 0;
}
mstot = (ss->cpu.all.stime + ss->cpu.all.utime +
ss->cpu.all.ntime + ss->cpu.all.itime +
ss->cpu.all.wtime + ss->cpu.all.Itime +
ss->cpu.all.Stime + ss->cpu.all.steal )
* (count_t)1000 / hertz / ss->cpu.nrcpu;
for (i=0; i < nunit; i++, dp++)
{
char *pn;
int len;
iotot = dp->nread + dp->nwrite +
(dp->ndisc != -1 ? dp->ndisc : 0);
if (iotot == 0 && !firstcall && !allresources)
continue; /* no activity on this disk */
/*
** disk was active during last interval; print info
*/
if (nlines++)
printf("%s ", tstamp);
if (dskbadness)
badness = (dp->io_ms * 100.0 / mstot) * 100/dskbadness;
else
badness = 0;
preprint(badness);
if ( (len = strlen(dp->name)) > 14)
pn = dp->name + len - 14;
else
pn = dp->name;
printf("%-14s %3.0lf%% %6.1lf %7.1lf %7.1lf %7.1lf "
"%5.1lf %9.5lf ms",
pn,
mstot ? (double)dp->io_ms * 100.0 / mstot : 0.0,
mstot ? (double)dp->nread * 1000.0 / mstot : 0.0,
dp->nread ?
(double)dp->nrsect / dp->nread / 2.0 : 0.0,
mstot ? (double)dp->nwrite * 1000.0 / mstot : 0.0,
dp->nwrite ?
(double)dp->nwsect / dp->nwrite / 2.0 : 0.0,
dp->io_ms ? (double)dp->avque / dp->io_ms : 0.0,
iotot ? (double)dp->io_ms / iotot : 0.0);
postprint(badness);
}
if (nlines == 0)
{
printf("\n");
nlines++;
}
firstcall = 0;
return nlines;
}
static int
lvmline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
return gendskline(ss, tstamp, 'l');
}
static int
mddline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
return gendskline(ss, tstamp, 'm');
}
static int
dskline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
return gendskline(ss, tstamp, 'd');
}
/*
** NFS client statistics
*/
static void
nfmhead(int osvers, int osrel, int ossub)
{
printf("mounted_device physread/s physwrit/s"
" _nfm_");
}
static int
nfmline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
static char firstcall = 1;
register long i, nlines = 0;
char *pn, state;
int len;
for (i=0; i < ss->nfs.nfsmounts.nrmounts; i++) /* per NFS mount */
{
/*
** print for the first sample all mounts that
** are found; afterwards print only the mounts
** that were really active during the interval
*/
if (firstcall ||
allresources ||
ss->nfs.nfsmounts.nfsmnt[i].age < deltasec ||
ss->nfs.nfsmounts.nfsmnt[i].bytestotread ||
ss->nfs.nfsmounts.nfsmnt[i].bytestotwrite )
{
if (nlines++)
printf("%s ", tstamp);
if ( (len = strlen(ss->nfs.nfsmounts.nfsmnt[i].mountdev)) > 38)
pn = ss->nfs.nfsmounts.nfsmnt[i].mountdev + len - 38;
else
pn = ss->nfs.nfsmounts.nfsmnt[i].mountdev;
if (ss->nfs.nfsmounts.nfsmnt[i].age < deltasec)
state = 'M';
else
state = ' ';
printf("%-38s %10.3lfK %10.3lfK %c\n",
pn,
(double)ss->nfs.nfsmounts.nfsmnt[i].bytestotread /
1024 / deltasec,
(double)ss->nfs.nfsmounts.nfsmnt[i].bytestotwrite /
1024 / deltasec,
state);
}
}
if (nlines == 0)
{
printf("\n");
nlines++;
}
firstcall= 0;
return nlines;
}
static void
nfchead(int osvers, int osrel, int ossub)
{
printf(" rpc/s rpcread/s rpcwrite/s retrans/s autrefresh/s "
" _nfc_");
}
static int
nfcline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%10.2lf %10.2lf %10.2lf %10.2lf %12.2lf\n",
(double)ss->nfs.client.rpccnt / deltasec,
(double)ss->nfs.client.rpcread / deltasec,
(double)ss->nfs.client.rpcwrite / deltasec,
(double)ss->nfs.client.rpcretrans / deltasec,
(double)ss->nfs.client.rpcautrefresh / deltasec);
return 1;
}
static void
nfshead(int osvers, int osrel, int ossub)
{
printf(" rpc/s rpcread/s rpcwrite/s MBcr/s MBcw/s "
"nettcp/s netudp/s _nfs_");
}
static int
nfsline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%7.2lf %10.2lf %10.2lf %6.2lf %7.2lf %9.2lf %8.2lf\n",
(double)ss->nfs.server.rpccnt / deltasec,
(double)ss->nfs.server.rpcread / deltasec,
(double)ss->nfs.server.rpcwrite / deltasec,
(double)ss->nfs.server.nrbytes / 1024.0 / 1024.0 / deltasec,
(double)ss->nfs.server.nwbytes / 1024.0 / 1024.0 / deltasec,
(double)ss->nfs.server.nettcpcnt / deltasec,
(double)ss->nfs.server.netudpcnt / deltasec);
return 1;
}
/*
** network-interface statistics
*/
static void
ibhead(int osvers, int osrel, int ossub)
{
printf("controller port busy ipack/s opack/s "
"igbps ogbps maxgbps lanes _ib_");
}
static int
ibline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
static char firstcall = 1;
register long i, nlines = 0;
double busy;
unsigned int badness;
for (i=0; i < ss->ifb.nrports; i++) /* per interface */
{
count_t ival, oval;
/*
** print for the first sample all ports that
** are found; afterwards print only the ports
** that were really active during the interval
*/
if (!firstcall && !allresources &&
!ss->ifb.ifb[i].rcvb && !ss->ifb.ifb[i].sndb)
continue;
/*
** convert byte-transfers to bit-transfers (* 8)
** convert bit-transfers to gigabit-transfers (/ 1000000000)
** per second
*/
ival = ss->ifb.ifb[i].rcvb*ss->ifb.ifb[i].lanes/125000000/deltasec;
oval = ss->ifb.ifb[i].sndb*ss->ifb.ifb[i].lanes/125000000/deltasec;
/*
** calculate busy-percentage for port
*/
busy = (ival > oval ? ival*100 : oval*100)/ss->ifb.ifb[i].rate;
if (nlines++)
printf("%s ", tstamp);
if (netbadness)
badness = busy * 100 / netbadness;
else
badness = 0;
preprint(badness);
printf("%-10s %4hd %4.0f%% %7.1lf %7.1lf %5lld %5lld %7lld %5d",
ss->ifb.ifb[i].ibname,
ss->ifb.ifb[i].portnr,
busy,
(double)ss->ifb.ifb[i].rcvp / deltasec,
(double)ss->ifb.ifb[i].sndp / deltasec,
ival, oval,
ss->ifb.ifb[i].rate / 1000,
ss->ifb.ifb[i].lanes);
postprint(badness);
}
if (nlines == 0)
{
printf("\n");
nlines++;
}
firstcall = 0;
return nlines;
}
/*
** network-interface statistics
*/
static void
ifhead(int osvers, int osrel, int ossub)
{
printf("interf busy ipack/s opack/s iKbyte/s oKbyte/s "
"imbps ombps maxmbps_if_");
}
static int
ifline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
static char firstcall = 1;
register long i, nlines = 0;
double busy;
char busyval[16], dupval;
unsigned int badness;
char *pn;
int len;
for (i=0; i < ss->intf.nrintf; i++) /* per interface */
{
count_t ival, oval;
/*
** print for the first sample all interfaces which
** are found; afterwards print only the interfaces
** which were really active during the interval
*/
if (!firstcall && !allresources &&
!ss->intf.intf[i].rpack && !ss->intf.intf[i].spack)
continue;
/*
** convert byte-transfers to bit-transfers (* 8)
** convert bit-transfers to megabit-transfers (/ 1000000)
** per second
*/
ival = ss->intf.intf[i].rbyte/125000/deltasec;
oval = ss->intf.intf[i].sbyte/125000/deltasec;
/*
** calculate busy-percentage for interface
*/
if (ss->intf.intf[i].speed) /* speed known? */
{
if (ss->intf.intf[i].duplex)
busy = (ival > oval ? ival*100 : oval*100) /
ss->intf.intf[i].speed;
else
busy = (ival + oval) * 100 /
ss->intf.intf[i].speed;
// especially with wireless, the speed might have
// dropped temporarily to a very low value (snapshot)
// it might be better to take the speed of the
// previous sample
if (busy > 100 && ss->intf.intf[i].speed <
ss->intf.intf[i].speedp )
{
ss->intf.intf[i].speed =
ss->intf.intf[i].speedp;
if (ss->intf.intf[i].duplex)
busy = (ival > oval ?
ival*100 : oval*100) /
ss->intf.intf[i].speed;
else
busy = (ival + oval) * 100 /
ss->intf.intf[i].speed;
}
snprintf(busyval, sizeof busyval,
"%3.0lf%%", busy);
}
else
{
strcpy(busyval, "?"); /* speed unknown */
busy = 0;
}
if (nlines++)
printf("%s ", tstamp);
if (ss->intf.intf[i].speed)
{
if (ss->intf.intf[i].duplex)
dupval = 'f';
else
dupval = 'h';
}
else
{
dupval = ' ';
}
if (netbadness)
badness = busy * 100 / netbadness;
else
badness = 0;
if ( (len = strlen(ss->intf.intf[i].name)) > 6)
pn = ss->intf.intf[i].name + len - 6;
else
pn = ss->intf.intf[i].name;
preprint(badness);
printf("%-6s %4s %7.1lf %7.1lf %8.0lf %8.0lf "
"%5lld %5lld %7ld %c",
pn, busyval,
(double)ss->intf.intf[i].rpack / deltasec,
(double)ss->intf.intf[i].spack / deltasec,
(double)ss->intf.intf[i].rbyte / 1024 / deltasec,
(double)ss->intf.intf[i].sbyte / 1024 / deltasec,
ival, oval,
ss->intf.intf[i].speed, dupval);
postprint(badness);
}
if (nlines == 0)
{
printf("\n");
nlines++;
}
firstcall = 0;
return nlines;
}
static void
IFhead(int osvers, int osrel, int ossub)
{
printf("interf ierr/s oerr/s coll/s idrop/s odrop/s "
"iframe/s ocarrier/s _if_");
}
static int
IFline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
static char firstcall = 1;
register long i, nlines = 0;
char *pn;
int len;
for (i=0; i < ss->intf.nrintf; i++) /* per interface */
{
/*
** print for the first sample all interfaces which
** are found; afterwards print only the interfaces
** which were really active during the interval
*/
if (!firstcall && !allresources &&
!ss->intf.intf[i].rpack && !ss->intf.intf[i].spack)
continue;
if (nlines++)
printf("%s ", tstamp);
if ( (len = strlen(ss->intf.intf[i].name)) > 6)
pn = ss->intf.intf[i].name + len - 6;
else
pn = ss->intf.intf[i].name;
printf("%-6s %6.2lf %6.2lf %6.2lf %7.2lf %7.2lf "
"%8.2lf %10.2lf\n",
pn,
(double)ss->intf.intf[i].rerrs / deltasec,
(double)ss->intf.intf[i].serrs / deltasec,
(double)ss->intf.intf[i].scollis / deltasec,
(double)ss->intf.intf[i].rdrop / deltasec,
(double)ss->intf.intf[i].sdrop / deltasec,
(double)ss->intf.intf[i].rframe / deltasec,
(double)ss->intf.intf[i].scarrier / deltasec);
}
if (nlines == 0)
{
printf("\n");
nlines++;
}
firstcall= 0;
return nlines;
}
/*
** IP version 4 statistics
*/
static void
ipv4head(int osvers, int osrel, int ossub)
{
printf("inrecv/s outreq/s indeliver/s forward/s "
"reasmok/s fragcreat/s _ipv4_");
}
static int
ipv4line(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%8.1lf %8.1lf %11.1lf %9.1lf %9.1lf %11.1lf\n",
(double)ss->net.ipv4.InReceives / deltasec,
(double)ss->net.ipv4.OutRequests / deltasec,
(double)ss->net.ipv4.InDelivers / deltasec,
(double)ss->net.ipv4.Forwarding / deltasec,
(double)ss->net.ipv4.ReasmOKs / deltasec,
(double)ss->net.ipv4.FragCreates / deltasec);
return 1;
}
static void
IPv4head(int osvers, int osrel, int ossub)
{
printf("in: dsc/s hder/s ader/s unkp/s ratim/s rfail/s "
"out: dsc/s nrt/s_ipv4_");
}
static int
IPv4line(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf(" %5.1lf %6.1lf %6.1lf %6.1lf %7.1lf %7.1lf "
" %5.1lf %5.1lf\n",
(double)ss->net.ipv4.InDiscards / deltasec,
(double)ss->net.ipv4.InHdrErrors / deltasec,
(double)ss->net.ipv4.InAddrErrors / deltasec,
(double)ss->net.ipv4.InUnknownProtos / deltasec,
(double)ss->net.ipv4.ReasmTimeout / deltasec,
(double)ss->net.ipv4.ReasmFails / deltasec,
(double)ss->net.ipv4.OutDiscards / deltasec,
(double)ss->net.ipv4.OutNoRoutes / deltasec);
return 1;
}
/*
** ICMP version 4 statistics
*/
static void
icmpv4head(int osvers, int osrel, int ossub)
{
printf("intot/s outtot/s inecho/s inerep/s "
"otecho/s oterep/s _icmpv4_" );
}
static int
icmpv4line(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%7.1lf %8.1lf %8.2lf %8.2lf %8.2lf %8.2lf\n",
(double)ss->net.icmpv4.InMsgs / deltasec,
(double)ss->net.icmpv4.OutMsgs / deltasec,
(double)ss->net.icmpv4.InEchos / deltasec,
(double)ss->net.icmpv4.OutEchos / deltasec,
(double)ss->net.icmpv4.InEchoReps / deltasec,
(double)ss->net.icmpv4.OutEchoReps / deltasec);
return 1;
}
static void
ICMPv4head(int osvers, int osrel, int ossub)
{
printf("ierr/s isq/s ird/s idu/s ite/s "
"oerr/s osq/s ord/s odu/s ote/s_icmpv4_");
}
static int
ICMPv4line(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%6.2lf %5.2lf %5.2lf %5.2lf %5.2lf "
"%6.2lf %5.2lf %5.2lf %5.2lf %5.2lf\n",
(double)ss->net.icmpv4.InErrors / deltasec,
(double)ss->net.icmpv4.InSrcQuenchs / deltasec,
(double)ss->net.icmpv4.InRedirects / deltasec,
(double)ss->net.icmpv4.InDestUnreachs / deltasec,
(double)ss->net.icmpv4.InTimeExcds / deltasec,
(double)ss->net.icmpv4.OutErrors / deltasec,
(double)ss->net.icmpv4.OutSrcQuenchs / deltasec,
(double)ss->net.icmpv4.OutRedirects / deltasec,
(double)ss->net.icmpv4.OutDestUnreachs / deltasec,
(double)ss->net.icmpv4.OutTimeExcds / deltasec);
return 1;
}
/*
** UDP version 4 statistics
*/
static void
udpv4head(int osvers, int osrel, int ossub)
{
printf("indgram/s outdgram/s inerr/s noport/s "
" _udpv4_");
}
static int
udpv4line(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%9.1lf %10.1lf %7.2lf %9.2lf\n",
(double)ss->net.udpv4.InDatagrams / deltasec,
(double)ss->net.udpv4.OutDatagrams / deltasec,
(double)ss->net.udpv4.InErrors / deltasec,
(double)ss->net.udpv4.NoPorts / deltasec);
return 1;
}
/*
** IP version 6 statistics
*/
static void
ipv6head(int osvers, int osrel, int ossub)
{
printf("inrecv/s outreq/s inmc/s outmc/s indeliv/s "
"reasmok/s fragcre/s _ipv6_");
}
static int
ipv6line(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%8.1lf %8.1lf %6.1lf %7.1lf %9.1lf %9.1lf %9.1lf\n",
(double)ss->net.ipv6.Ip6InReceives / deltasec,
(double)ss->net.ipv6.Ip6OutRequests / deltasec,
(double)ss->net.ipv6.Ip6InMcastPkts / deltasec,
(double)ss->net.ipv6.Ip6OutMcastPkts / deltasec,
(double)ss->net.ipv6.Ip6InDelivers / deltasec,
(double)ss->net.ipv6.Ip6ReasmOKs / deltasec,
(double)ss->net.ipv6.Ip6FragCreates / deltasec);
return 1;
}
static void
IPv6head(int osvers, int osrel, int ossub)
{
printf("in: dsc/s hder/s ader/s unkp/s ratim/s rfail/s "
"out: dsc/s nrt/s_ipv6_");
}
static int
IPv6line(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf(" %5.1lf %6.1lf %6.1lf %6.1lf %7.1lf %7.1lf "
" %5.1lf %5.1lf\n",
(double)ss->net.ipv6.Ip6InDiscards / deltasec,
(double)ss->net.ipv6.Ip6InHdrErrors / deltasec,
(double)ss->net.ipv6.Ip6InAddrErrors / deltasec,
(double)ss->net.ipv6.Ip6InUnknownProtos / deltasec,
(double)ss->net.ipv6.Ip6ReasmTimeout / deltasec,
(double)ss->net.ipv6.Ip6ReasmFails / deltasec,
(double)ss->net.ipv6.Ip6OutDiscards / deltasec,
(double)ss->net.ipv6.Ip6OutNoRoutes / deltasec);
return 1;
}
/*
** ICMP version 6 statistics
*/
static void
icmpv6head(int osvers, int osrel, int ossub)
{
printf("intot/s outtot/s inerr/s innsol/s innadv/s "
"otnsol/s otnadv/s _icmp6_" );
}
static int
icmpv6line(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%7.1lf %8.1lf %7.2lf %8.2lf %8.2lf %8.2lf %8.2lf\n",
(double)ss->net.icmpv6.Icmp6InMsgs / deltasec,
(double)ss->net.icmpv6.Icmp6OutMsgs / deltasec,
(double)ss->net.icmpv6.Icmp6InErrors / deltasec,
(double)ss->net.icmpv6.Icmp6InNeighborSolicits / deltasec,
(double)ss->net.icmpv6.Icmp6InNeighborAdvertisements/ deltasec,
(double)ss->net.icmpv6.Icmp6OutNeighborSolicits / deltasec,
(double)ss->net.icmpv6.Icmp6OutNeighborAdvertisements
/deltasec);
return 1;
}
static void
ICMPv6head(int osvers, int osrel, int ossub)
{
printf("iecho/s ierep/s oerep/s idu/s odu/s ird/s ord/s ite/s "
"ote/s _icmpv6_");
}
static int
ICMPv6line(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%7.2lf %7.2lf %7.2lf %5.2lf %5.2lf "
"%5.2lf %5.2lf %5.2lf %5.2lf\n",
(double)ss->net.icmpv6.Icmp6InEchos / deltasec,
(double)ss->net.icmpv6.Icmp6InEchoReplies / deltasec,
(double)ss->net.icmpv6.Icmp6OutEchoReplies / deltasec,
(double)ss->net.icmpv6.Icmp6InDestUnreachs / deltasec,
(double)ss->net.icmpv6.Icmp6OutDestUnreachs / deltasec,
(double)ss->net.icmpv6.Icmp6InRedirects / deltasec,
(double)ss->net.icmpv6.Icmp6OutRedirects / deltasec,
(double)ss->net.icmpv6.Icmp6InTimeExcds / deltasec,
(double)ss->net.icmpv6.Icmp6OutTimeExcds / deltasec);
return 1;
}
/*
** UDP version 6 statistics
*/
static void
udpv6head(int osvers, int osrel, int ossub)
{
printf("indgram/s outdgram/s inerr/s noport/s "
" _udpv6_");
}
static int
udpv6line(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%9.1lf %10.1lf %7.2lf %9.2lf\n",
(double)ss->net.udpv6.Udp6InDatagrams / deltasec,
(double)ss->net.udpv6.Udp6OutDatagrams / deltasec,
(double)ss->net.udpv6.Udp6InErrors / deltasec,
(double)ss->net.udpv6.Udp6NoPorts / deltasec);
return 1;
}
/*
** TCP statistics
*/
static void
tcphead(int osvers, int osrel, int ossub)
{
printf("insegs/s outsegs/s actopen/s pasopen/s "
"nowopen _tcp_");
}
static int
tcpline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%8.1lf %9.1lf %9.1lf %9.1lf %7lld\n",
(double)ss->net.tcp.InSegs / deltasec,
(double)ss->net.tcp.OutSegs / deltasec,
(double)ss->net.tcp.ActiveOpens / deltasec,
(double)ss->net.tcp.PassiveOpens / deltasec,
ss->net.tcp.CurrEstab);
return 1;
}
static void
TCPhead(int osvers, int osrel, int ossub)
{
printf("inerr/s retrans/s attfail/s "
"estabreset/s outreset/s _tcp_");
}
static int
TCPline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%7.1lf %9.1lf %9.1lf %12.1lf %10.1lf\n",
(double)ss->net.tcp.InErrs / deltasec,
(double)ss->net.tcp.RetransSegs / deltasec,
(double)ss->net.tcp.AttemptFails / deltasec,
(double)ss->net.tcp.EstabResets / deltasec,
(double)ss->net.tcp.OutRsts / deltasec);
return 1;
}
#if HTTPSTATS
static void
httphead(int osvers, int osrel, int ossub)
{
printf("requests/s Kbytes/s bytes/req "
"idleworkers busyworkers _http_");
}
static int
httpline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
printf("%10.2lf %8.2lf %9.2lf %11d %11d\n",
(double)ss->www.accesses / deltasec,
(double)ss->www.totkbytes / deltasec,
ss->www.accesses ?
(double)ss->www.totkbytes*1024/ss->www.accesses : 0,
ss->www.iworkers,
ss->www.bworkers);
return 1;
}
#endif
/*
** per-process statistics: top-3 processor consumers
*/
static void
topchead(int osvers, int osrel, int ossub)
{
printf(" pid command cpu%% | pid command cpu%% | "
" pid command cpu%%_top3_");
}
static int
topcline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
count_t availcpu;
if (!ts)
{
printf("report not available.....\n");
return 0;
}
/*
** sort process list in cpu order
*/
qsort(ps, nactproc, sizeof(struct tstat *), compcpu);
availcpu = ss->cpu.all.stime + ss->cpu.all.utime +
ss->cpu.all.ntime + ss->cpu.all.itime +
ss->cpu.all.wtime + ss->cpu.all.Itime +
ss->cpu.all.Stime + ss->cpu.all.steal;
availcpu /= ss->cpu.nrcpu;
if (availcpu == 0)
availcpu = 1; /* avoid divide-by-zero */
if (nactproc >= 1 && (ps[0])->cpu.stime + (ps[0])->cpu.utime > 0)
printf("%5d %-8.8s %3.0lf%% | ",
(ps[0])->gen.pid, (ps[0])->gen.name,
(double)((ps[0])->cpu.stime + (ps[0])->cpu.utime)*100.0/availcpu);
else
printf("%19s | ", " ");
if (nactproc >= 2 && (ps[1])->cpu.stime + (ps[1])->cpu.utime > 0)
printf("%5d %-8.8s %3.0lf%% | ",
(ps[1])->gen.pid, (ps[1])->gen.name,
(double)((ps[1])->cpu.stime + (ps[1])->cpu.utime)*100.0/availcpu);
else
printf("%19s | ", " ");
if (nactproc >= 3 && (ps[2])->cpu.stime + (ps[2])->cpu.utime > 0)
printf("%5d %-8.8s %3.0lf%%\n",
(ps[2])->gen.pid, (ps[2])->gen.name,
(double)((ps[2])->cpu.stime + (ps[2])->cpu.utime)*100.0/availcpu);
else
printf("%19s\n", " ");
return 1;
}
/*
** per-process statistics: top-3 memory consumers
*/
static void
topmhead(int osvers, int osrel, int ossub)
{
printf(" pid command mem%% | pid command mem%% | "
" pid command mem%%_top3_");
}
static int
topmline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
count_t availmem;
if (!ts)
{
printf("report not available.....\n");
return 0;
}
/*
** sort process list in memory order
*/
qsort(ps, nactproc, sizeof(struct tstat *), compmem);
availmem = ss->mem.physmem * pagesize/1024;
if (nactproc >= 1)
printf("%5d %-8.8s %3.0lf%% | ",
(ps[0])->gen.pid, (ps[0])->gen.name,
(double)(ps[0])->mem.rmem * 100.0 / availmem);
else
printf("%19s | ", " ");
if (nactproc >= 2)
printf("%5d %-8.8s %3.0lf%% | ",
(ps[1])->gen.pid, (ps[1])->gen.name,
(double)(ps[1])->mem.rmem * 100.0 / availmem);
else
printf("%19s | ", " ");
if (nactproc >= 3)
printf("%5d %-8.8s %3.0lf%%\n",
(ps[2])->gen.pid, (ps[2])->gen.name,
(double)(ps[2])->mem.rmem * 100.0 / availmem);
else
printf("%19s\n", " ");
return 1;
}
/*
** per-process statistics: top-3 disk consumers
*/
static void
topdhead(int osvers, int osrel, int ossub)
{
printf(" pid command dsk%% | pid command dsk%% | "
" pid command dsk%%_top3_");
}
static int
topdline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
int i;
count_t availdsk;
if (!ts)
{
printf("report not available.....\n");
return 0;
}
if ( !(supportflags & IOSTAT) )
{
printf("no per-process disk counters available.....\n");
return 0;
}
/*
** determine total disk accesses for all processes
*/
for (i=0, availdsk=0; i < nactproc; i++)
{
availdsk += (ps[i])->dsk.rio + (ps[i])->dsk.wio;
}
if (availdsk == 0)
availdsk = 1;
/*
** sort process list in disk order
*/
qsort(ps, nactproc, sizeof(struct tstat *), compdsk);
if (nactproc >= 1 && (ps[0])->dsk.rio + (ps[0])->dsk.wio > 0)
printf("%5d %-8.8s %3.0lf%% | ",
(ps[0])->gen.pid, (ps[0])->gen.name,
(double)((ps[0])->dsk.rio+(ps[0])->dsk.wio) *100.0/availdsk);
else
printf("%19s | ", " ");
if (nactproc >= 2 && (ps[1])->dsk.rio + (ps[1])->dsk.wio > 0)
printf("%5d %-8.8s %3.0lf%% | ",
(ps[1])->gen.pid, (ps[1])->gen.name,
(double)((ps[1])->dsk.rio+(ps[1])->dsk.wio) *100.0/availdsk);
else
printf("%19s | ", " ");
if (nactproc >= 3 && (ps[2])->dsk.rio + (ps[2])->dsk.wio > 0)
printf("%5d %-8.8s %3.0lf%%\n",
(ps[2])->gen.pid, (ps[2])->gen.name,
(double)((ps[2])->dsk.rio+(ps[2])->dsk.wio) *100.0/availdsk);
else
printf("%19s\n", " ");
return 1;
}
/*
** per-process statistics: top-3 network consumers
*/
static void
topnhead(int osvers, int osrel, int ossub)
{
printf(" pid command net%% | pid command net%% | "
" pid command net%%_top3_");
}
static int
topnline(struct sstat *ss, struct tstat *ts, struct tstat **ps, int nactproc,
time_t deltasec, time_t deltatic, time_t hz,
int osvers, int osrel, int ossub, char *tstamp,
int ppres, int ntrun, int ntslpi, int ntslpu, int ntidle,
int pexit, int pzombie)
{
int i;
count_t availnet;
count_t totbytes;
if (!ts)
{
printf("report not available.....\n");
return 0;
}
if ( !(supportflags & NETATOP) )
{
printf("no per-process network counters available.....\n");
return 0;
}
/*
** determine total network accesses for all processes
*/
for (i=0, availnet=0; i < nactproc; i++)
{
availnet += (*(ps+i))->net.tcpssz + (*(ps+i))->net.tcprsz +
(*(ps+i))->net.udpssz + (*(ps+i))->net.udprsz;
}
if (availnet == 0)
availnet = 1;
/*
** sort process list in network order
*/
qsort(ps, nactproc, sizeof(struct tstat *), compnet);
if (nactproc >= 1)
{
totbytes = (ps[0])->net.tcpssz + (ps[0])->net.tcprsz +
(ps[0])->net.udpssz + (ps[0])->net.udprsz;
if (totbytes > 0)
printf("%5d %-8.8s %3.0lf%% | ",
(ps[0])->gen.pid, (ps[0])->gen.name,
(double)totbytes * 100.0 / availnet);
else
printf("%19s | ", " ");
}
else
printf("%19s | ", " ");
if (nactproc >= 2)
{
totbytes = (ps[1])->net.tcpssz + (ps[1])->net.tcprsz +
(ps[1])->net.udpssz + (ps[1])->net.udprsz;
if (totbytes > 0)
printf("%5d %-8.8s %3.0lf%% | ",
(ps[1])->gen.pid, (ps[1])->gen.name,
(double)totbytes * 100.0 / availnet);
else
printf("%19s | ", " ");
}
else
printf("%19s | ", " ");
if (nactproc >= 3)
{
totbytes = (ps[2])->net.tcpssz + (ps[2])->net.tcprsz +
(ps[2])->net.udpssz + (ps[2])->net.udprsz;
if (totbytes > 0)
printf("%5d %-8.8s %3.0lf%%\n",
(ps[2])->gen.pid, (ps[2])->gen.name,
(double)totbytes * 100.0 / availnet);
else
printf("%19s\n", " ");
}
else
printf("%19s\n", " ");
return 1;
}
/*********************************************************************/
/* Function definition table. */
/* */
/* The layout of this table is as follows: */
/* Column 1: */
/* Boolean which indicates if the specified function is */
/* active during a run of 'atopsar'. When started, */
/* this boolean will be defined 'true' for all entries for */
/* which the command-line flag has been specified. Initially */
/* this column should contain 0 (false), unless this function */
/* is always required. */
/* If no flags are specified for 'atopsar', the first entry */
/* in this table is defined active (default flag). */
/* */
/* Column 2: */
/* Categories of counters used by this function. */
/* c = cpu counters, m = memory counters, */
/* d = disk counters, n = network counters */
/* */
/* Column 3: */
/* Flag which can be used as command-line argument to */
/* select the function defined in this table-entry. Be sure */
/* that a unique character is choosen. */
/* Notice that certain flags are reserved! */
/* */
/* Column 4: */
/* Entry-point of the 'printhead' function. */
/* */
/* Column 5: */
/* Entry-point of the 'printline' function. */
/* */
/* Column 6: */
/* Information about the statistics shown by the function */
/* specified by the table-entry. This text is printed as */
/* command-usage. */
/*********************************************************************/
struct pridef pridef[] =
{
{0, "c", 'c', cpuhead, cpuline, "cpu utilization", },
{0, "c", 'p', prochead, procline, "process(or) load", },
{0, "c", 'P', taskhead, taskline, "processes & threads", },
{0, "c", 'g', gpuhead, gpuline, "gpu utilization", },
{0, "m", 'm', memhead, memline, "memory & swapspace", },
{0, "m", 's', swaphead, swapline, "swap rate", },
{0, "cmd",'B', psihead, psiline, "pressure stall info (PSI)",},
{0, "cd", 'l', lvmhead, lvmline, "logical volume activity", },
{0, "cd", 'f', mddhead, mddline, "multiple device activity",},
{0, "cd", 'd', dskhead, dskline, "disk activity", },
{0, "n", 'h', ibhead, ibline, "infiniband utilization", },
{0, "n", 'n', nfmhead, nfmline, "NFS client mounts", },
{0, "n", 'j', nfchead, nfcline, "NFS client activity", },
{0, "n", 'J', nfshead, nfsline, "NFS server activity", },
{0, "n", 'i', ifhead, ifline, "net-interf (general)", },
{0, "n", 'I', IFhead, IFline, "net-interf (errors)", },
{0, "n", 'w', ipv4head, ipv4line, "ip v4 (general)", },
{0, "n", 'W', IPv4head, IPv4line, "ip v4 (errors)", },
{0, "n", 'y', icmpv4head, icmpv4line, "icmp v4 (general)", },
{0, "n", 'Y', ICMPv4head, ICMPv4line, "icmp v4 (per type)", },
{0, "n", 'u', udpv4head, udpv4line, "udp v4", },
{0, "n", 'z', ipv6head, ipv6line, "ip v6 (general)", },
{0, "n", 'Z', IPv6head, IPv6line, "ip v6 (errors)", },
{0, "n", 'k', icmpv6head, icmpv6line, "icmp v6 (general)", },
{0, "n", 'K', ICMPv6head, ICMPv6line, "icmp v6 (per type)", },
{0, "n", 'U', udpv6head, udpv6line, "udp v6", },
{0, "n", 't', tcphead, tcpline, "tcp (general)", },
{0, "n", 'T', TCPhead, TCPline, "tcp (errors)", },
#if HTTPSTATS
{0, "n", 'o', httphead, httpline, "HTTP activity", },
#endif
{0, "", 'O', topchead, topcline, "top-3 processes cpu", },
{0, "", 'G', topmhead, topmline, "top-3 processes memory", },
{0, "", 'D', topdhead, topdline, "top-3 processes disk", },
{0, "", 'N', topnhead, topnline, "top-3 processes network",},
};
int pricnt = sizeof(pridef)/sizeof(struct pridef);

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-atop.git
git@api.gitlife.ru:oschina-mirror/mirrors-atop.git
oschina-mirror
mirrors-atop
mirrors-atop
master