xref: /netbsd-src/external/bsd/top/dist/Porting (revision 10dd2532a5fc0a73e461275cb9fca28fc3013d32)
1*10dd2532SchristosInstructions for porting top to other architectures.
2*10dd2532Schristos
3*10dd2532SchristosThis is still a preliminary document.  Suggestions for improvement are
4*10dd2532Schristosmost welcome.
5*10dd2532Schristos
6*10dd2532SchristosBefore you embark on a port, please send me a mail message telling me
7*10dd2532Schristoswhat platform you are porting top to.  There are three reasons for
8*10dd2532Schristosthis: (1) I may already have a port, (2) module naming needs to be
9*10dd2532Schristoscentralized, (3) I want to loosely track the various porting efforts.
10*10dd2532SchristosYou do not need to wait for an "okay", but I do want to know that you
11*10dd2532Schristosare working on it.  And of course, once it is finished, please send me
12*10dd2532Schristosthe module files so that I can add them to the main distribution!
13*10dd2532Schristos
14*10dd2532Schristos----------
15*10dd2532Schristos
16*10dd2532SchristosThere is one set of functions which extract all the information that
17*10dd2532Schristostop needs for display.  These functions are collected in to one file.
18*10dd2532SchristosTo make top work on a different architecture simply requires a
19*10dd2532Schristosdifferent implementation of these functions.  The functions for a
20*10dd2532Schristosgiven architecture "foo" are stored in a file called "m_foo.c".  The
21*10dd2532SchristosConfigure script looks for these files and lets the configurer choose
22*10dd2532Schristosone of them.  This file is called a "module".  The idea is that making
23*10dd2532Schristostop work on a different machine only requires one additional file and
24*10dd2532Schristosdoes not require changes to any existing files.
25*10dd2532Schristos
26*10dd2532SchristosA module template is included in the distribution, called "m-template".
27*10dd2532SchristosTo write your own module, it is a good idea to start with this template.
28*10dd2532SchristosIf you architecture is similar to one for which a module already
29*10dd2532Schristosexists, then you can start with that module instead.  If you do so,
30*10dd2532Schristosremember to change the "AUTHOR" section at the top!
31*10dd2532Schristos
32*10dd2532SchristosThe first comment in a module contains information which is extracted
33*10dd2532Schristosand used by Configure.  This information is marked with words in all
34*10dd2532Schristoscapitals (such as "SYNOPSIS:" and "LIBS:").  Go look at m-template: it
35*10dd2532Schristosis fairly self-explanatory.  The text after "LIBS:" (on the same line)
36*10dd2532Schristosis extracted and included in the LIBS definition of the Makefile so
37*10dd2532Schristosthat extra libraries which may be necessary on some machines (such as
38*10dd2532Schristos"-lkvm") can be specified in the module.  The text after "CFLAGS:"
39*10dd2532Schristos(on the same line) is extracted and included as flags in the "CFLAGS"
40*10dd2532Schristosdefinition of the Makefile (thus in every compilation step).  This is
41*10dd2532Schristosused for rare circumstances only:  please don't abuse this hook.
42*10dd2532Schristos
43*10dd2532SchristosSome operating systems have idiosyncrasies which will affect the form
44*10dd2532Schristosand/or content of the information top displays.  You may wish to
45*10dd2532Schristosdocument such anomalies in the top man page.  This can be done by adding
46*10dd2532Schristosa file called m_{modulename}.man (where {modulename} is replaced with
47*10dd2532Schristosthe name of the module).  Configure will automatically add this file to
48*10dd2532Schristosthe end of the man page.  See m_sunos4.man for an example.
49*10dd2532Schristos
50*10dd2532SchristosA module is concerned with two structures:
51*10dd2532Schristos
52*10dd2532SchristosThe statics struct is filled in by machine_init.  Each item is a
53*10dd2532Schristospointer to a list of character pointers.  The list is terminated
54*10dd2532Schristoswith a null pointer.
55*10dd2532Schristos
56*10dd2532Schristosstruct statics
57*10dd2532Schristos{
58*10dd2532Schristos    char **procstate_names;	/* process state names */
59*10dd2532Schristos    char **cpustate_names;	/* cpu state names */
60*10dd2532Schristos    char **memory_names;	/* memory information names */
61*10dd2532Schristos};
62*10dd2532Schristos
63*10dd2532SchristosThe system_info struct is filled in by get_system_info and
64*10dd2532Schristosget_process_info.
65*10dd2532Schristos
66*10dd2532Schristosstruct system_info
67*10dd2532Schristos{
68*10dd2532Schristos    int    last_pid;     /* last pid assigned (0 means non-sequential assignment) */
69*10dd2532Schristos    double load_avg[NUM_AVERAGES];     /* see below */
70*10dd2532Schristos    int    p_total;      /* total number of processes */
71*10dd2532Schristos    int    p_active;     /* number of procs considered "active" */
72*10dd2532Schristos    int    *procstates;  /* array of process state counters */
73*10dd2532Schristos    int    *cpustates;   /* array of cpustate counters */
74*10dd2532Schristos    int    *memory;      /* memory information */
75*10dd2532Schristos};
76*10dd2532Schristos
77*10dd2532SchristosThe last three pointers each point to an array of integers.  The
78*10dd2532Schristoslength of the array is determined by the length of the corresponding
79*10dd2532Schristos_names array in the statics structure.  Furthermore, if an entry in a
80*10dd2532Schristos_names array is the empty string ("") then the corresponding value in
81*10dd2532Schristosthe value array will be skipped over.  The display routine displays,
82*10dd2532Schristosfor example, the string procstate_names[0] then the number
83*10dd2532Schristosprocstates[0], then procstate_names[1], procstates[1], etc. until
84*10dd2532Schristosprocstate_names[N] == NULL.  This allows for a tremendous amount of
85*10dd2532Schristosflexibility in labeling the displayed values.
86*10dd2532Schristos
87*10dd2532Schristos"procstates" and "memory" are displayed as straight integer values.
88*10dd2532SchristosValues in "cpustates" are displayed as a percentage * 10.  For
89*10dd2532Schristosexample, the (integer) value 105 is displayed as 10.5%.
90*10dd2532Schristos
91*10dd2532SchristosThese routines must be defined by the machine dependent module.
92*10dd2532Schristos
93*10dd2532Schristosint machine_init(struct statics *)
94*10dd2532Schristos
95*10dd2532Schristos	returns 0 on success and -1 on failure,
96*10dd2532Schristos	prints error messages
97*10dd2532Schristos
98*10dd2532Schristoschar *format_header(char *)
99*10dd2532Schristos
100*10dd2532Schristos	Returns a string which should be used as the header for the
101*10dd2532Schristos	process display area.  The argument is a string used to label
102*10dd2532Schristos	the username column (either "USERNAME" or "UID") and is always
103*10dd2532Schristos	8 characters in length.
104*10dd2532Schristos
105*10dd2532Schristosvoid get_system_info(struct system_info *)
106*10dd2532Schristos
107*10dd2532Schristoscaddr_t get_process_info(struct system_info *, int, int, int (*func)())
108*10dd2532Schristos
109*10dd2532Schristos	returns a handle to use with format_next_process
110*10dd2532Schristos
111*10dd2532Schristoschar *format_next_process(caddr_t, char *(*func)())
112*10dd2532Schristos
113*10dd2532Schristos	returns string which describes next process
114*10dd2532Schristos
115*10dd2532Schristosint proc_compare(caddr_t, caddr_t)
116*10dd2532Schristos
117*10dd2532Schristos	qsort comparison function
118*10dd2532Schristos
119*10dd2532Schristosuid_t proc_owner(pid_t)
120*10dd2532Schristos
121*10dd2532Schristos	Returns the uid owner of the process specified by the pid argument.
122*10dd2532Schristos	This function is VERY IMPORTANT.  If it fails to do its job, then
123*10dd2532Schristos	top may pose a security risk.
124*10dd2532Schristos
125*10dd2532Schristos
126*10dd2532Schristosget_process_info is called immediately after get_system_info.  In
127*10dd2532Schristosfact, the two functions could be rolled in to one.  The reason they
128*10dd2532Schristosare not is mostly historical.
129*10dd2532Schristos
130*10dd2532SchristosTop relies on the existence of a function called "setpriority" to
131*10dd2532Schristoschange a process's priority.  This exists as a kernel call on most 4.3
132*10dd2532SchristosBSD derived Unixes.  If neither your operating system nor your C
133*10dd2532Schristoslibrary supplies such a function, then you will need to add one to the
134*10dd2532Schristosmodule.  It is defined as follows:
135*10dd2532Schristos
136*10dd2532Schristos	int setpriority (int dummy, int who, int niceval)
137*10dd2532Schristos
138*10dd2532Schristos	For the purposes of top, the first argument is meaningless.
139*10dd2532Schristos	The second is the pid and the third is the new nice value.
140*10dd2532Schristos	This function should behave just like a kernel call, setting
141*10dd2532Schristos	errno and returning -1 in case of an error.  This function MUST
142*10dd2532Schristos	check to make sure that a non-root user does not specify a nice
143*10dd2532Schristos	value less than the process's current value.  If it detects such
144*10dd2532Schristos	a condition, it should set errno to EACCES and return -1.
145*10dd2532Schristos	Other possible ERRNO values:  ESRCH when pid "who" does not exist,
146*10dd2532Schristos	EPERM when the invoker is not root and not the same as the
147*10dd2532Schristos	process owner.
148*10dd2532Schristos
149*10dd2532SchristosNote that top checks process ownership and should never call setpriority
150*10dd2532Schristoswhen the invoker's uid is not root and not the same as the process's owner
151*10dd2532Schristosuid.
152*10dd2532Schristos
153*10dd2532Schristos
154*10dd2532SchristosThe file "machine.h" contains definitions which are useful to modules
155*10dd2532Schristosand to top.c (such as the structure definitions).  You SHOULD NOT need
156*10dd2532Schristosto change it when porting to a new platform.
157*10dd2532Schristos
158*10dd2532SchristosPorting to a new platform should NOT require any changes to existing
159*10dd2532Schristosfiles.  You should only need to add m_ files.  If you feel you need a
160*10dd2532Schristoschange in one of the existing files, please contact me so that we can
161*10dd2532Schristosdiscuss the details.  I want to keep such changes as general as
162*10dd2532Schristospossible.
163*10dd2532Schristos
164*10dd2532Schristos--------
165*10dd2532Schristos
166*10dd2532SchristosChanges were made to the module interface between 3.5 and 3.6.  Here are
167*10dd2532Schristosthe changes that need to be made to port a 3.5 module to 3.6:
168*10dd2532Schristos
169*10dd2532SchristosThe array that stores memory statistics and is passed back in the system
170*10dd2532Schristosinformation structure as "memory" must now be an array of (signed) longs.
171*10dd2532SchristosThis was done to more easily accomodate systems that have gigabytes of
172*10dd2532Schristosmemory.  Since the numbers are supposed to be kilobytes, a long can still
173*10dd2532Schristosrepresent up to 2 terabytes.  Look for "int memory_stats[X]" (where "X"
174*10dd2532Schristosis some arbitrary number) and change it to "long memory_stats[X]".  If
175*10dd2532Schristosthe module support reporting swap information on a separate line, then
176*10dd2532Schristosits "swap_stats" array also needs to be an array of longs.
177*10dd2532Schristos
178*10dd2532SchristosThe argument to proc_owner should be an int, as in "int pid".  When it is
179*10dd2532Schristosused in proc_owner it should be cast as necessary.  Many operating systems
180*10dd2532Schristoswill require it to be cast to a pid_t before being compared to the appropriate
181*10dd2532Schristoselement in the proc structure.
182*10dd2532Schristos
183*10dd2532SchristosIn the function format_next_process, the last argument in the main call
184*10dd2532Schristosto sprintf is the string that contains the command for the process.
185*10dd2532SchristosMake sure that this last argument is enclosed in a call to "printable".
186*10dd2532SchristosFor example:  "printable(MPP(pp, p_comm))".
187*10dd2532Schristos
188*10dd2532SchristosThe third argument to "get_process_info" needs to be changed to an integer,
189*10dd2532Schristostypically "int compare_index".  The call to qsort in get_process_info may
190*10dd2532Schristosbe guarded by "if (compare != NULL)".  If it is, remove the if statement.
191*10dd2532Schristos
192*10dd2532SchristosThe other changes to get_process_info depends on whether or not the module
193*10dd2532Schristossupports multiple sort orders.
194*10dd2532Schristos
195*10dd2532SchristosTo support multiple keys:
196*10dd2532Schristos
197*10dd2532SchristosCreate an array int (*proc_compares[])() and assign to it the list of
198*10dd2532Schristoscomparison functions, NULL terminated.  For example:
199*10dd2532Schristos
200*10dd2532Schristosint (*proc_compares[])() = {
201*10dd2532Schristos    compare_cpu,
202*10dd2532Schristos    compare_size,
203*10dd2532Schristos    compare_res,
204*10dd2532Schristos    compare_time,
205*10dd2532Schristos    NULL };
206*10dd2532Schristos
207*10dd2532SchristosIn get_process_info there is a call to qsort which uses one of the
208*10dd2532Schristosfunctions in proc_compares.  It should be changed so that its fourth
209*10dd2532Schristosargument is "proc_compares[compare_index]".
210*10dd2532Schristos
211*10dd2532SchristosIf the module contains the function "proc_compare", it should be removed.
212*10dd2532Schristos
213*10dd2532SchristosThere should also be a NULL-terminated array of strings which list the names
214*10dd2532Schristosfor the sort keys, for example:
215*10dd2532Schristos
216*10dd2532Schristoschar *ordernames[] =
217*10dd2532Schristos{"cpu", "size", "res", "time", NULL};
218*10dd2532Schristos
219*10dd2532SchristosTo indicate that this module supports multiple sort keys, add the following
220*10dd2532Schristosline in machine_init:
221*10dd2532Schristos
222*10dd2532Schristos	statics->order_names = ordernames;
223*10dd2532Schristos
224*10dd2532SchristosIf there is no support for multiple keys:
225*10dd2532Schristos
226*10dd2532SchristosLeave statics->order_names alone and call the comparison function of
227*10dd2532Schristosyour choice in get_process_info, ignoring the third argument.
228*10dd2532Schristos
229*10dd2532Schristos
230