ia64/xen-unstable
changeset 6339:f51fe43c5d1c
Merge libxenstat and xentop.
line diff
2.1 --- a/Config.mk Mon Aug 22 19:59:58 2005 +0000 2.2 +++ b/Config.mk Mon Aug 22 21:54:28 2005 +0000 2.3 @@ -14,6 +14,7 @@ LD = $(CROSS_COMPILE)ld 2.4 CC = $(CROSS_COMPILE)gcc 2.5 CPP = $(CROSS_COMPILE)gcc -E 2.6 AR = $(CROSS_COMPILE)ar 2.7 +RANLIB = $(CROSS_COMPILE)ranlib 2.8 NM = $(CROSS_COMPILE)nm 2.9 STRIP = $(CROSS_COMPILE)strip 2.10 OBJCOPY = $(CROSS_COMPILE)objcopy 2.11 @@ -43,3 +44,7 @@ KERNEL_REPO = http://www.kernel.org 2.12 # ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2.13 # ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY 2.14 ACM_USE_SECURITY_POLICY ?= ACM_NULL_POLICY 2.15 + 2.16 +# Optional components 2.17 +XENSTAT_XENTOP ?= y 2.18 +
105.1 --- a/tools/Makefile Mon Aug 22 19:59:58 2005 +0000 105.2 +++ b/tools/Makefile Mon Aug 22 21:54:28 2005 +0000 105.3 @@ -14,6 +14,7 @@ SUBDIRS += xcutils 105.4 SUBDIRS += firmware 105.5 SUBDIRS += security 105.6 SUBDIRS += console 105.7 +SUBDIRS += xenstat 105.8 105.9 .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean 105.10
106.1 --- a/tools/Rules.mk Mon Aug 22 19:59:58 2005 +0000 106.2 +++ b/tools/Rules.mk Mon Aug 22 21:54:28 2005 +0000 106.3 @@ -6,6 +6,7 @@ XEN_XC = $(XEN_ROOT)/tools/p 106.4 XEN_LIBXC = $(XEN_ROOT)/tools/libxc 106.5 XEN_XCS = $(XEN_ROOT)/tools/xcs 106.6 XEN_XENSTORE = $(XEN_ROOT)/tools/xenstore 106.7 +XEN_LIBXENSTAT = $(XEN_ROOT)/tools/xenstat/libxenstat/src 106.8 106.9 ifeq ($(XEN_TARGET_ARCH),x86_32) 106.10 CFLAGS += -m32 -march=i686
153.1 --- a/tools/python/xen/xm/main.py Mon Aug 22 19:59:58 2005 +0000 153.2 +++ b/tools/python/xen/xm/main.py Mon Aug 22 21:54:28 2005 +0000 153.3 @@ -49,6 +49,7 @@ xm common subcommands: 153.4 restore <File> create a domain from a saved state file 153.5 save <DomId> <File> save domain state (and config) to file 153.6 shutdown <DomId> shutdown a domain 153.7 + top monitor system and domains in real-time 153.8 unpause <DomId> unpause a paused domain 153.9 153.10 For a complete list of subcommands run 'xm help --long' 153.11 @@ -87,6 +88,7 @@ xm full list of subcommands: 153.12 dmesg [--clear] read or clear Xen's message buffer 153.13 info get information about the xen host 153.14 log print the xend log 153.15 + top monitor system and domains in real-time 153.16 153.17 Scheduler Commands: 153.18 bvt <options> set BVT scheduler parameters 153.19 @@ -457,6 +459,9 @@ def xm_console(args): 153.20 os.execvp('/usr/libexec/xen/xenconsole', cmd.split()) 153.21 console = sxp.child(info, "console") 153.22 153.23 +def xm_top(args): 153.24 + os.execv('/usr/sbin/xentop', ['/usr/sbin/xentop']) 153.25 + 153.26 def xm_dmesg(args): 153.27 153.28 gopts = Opts(use="""[-c|--clear] 153.29 @@ -545,6 +550,8 @@ def xm_block_destroy(args): 153.30 commands = { 153.31 # console commands 153.32 "console": xm_console, 153.33 + # xenstat commands 153.34 + "top": xm_top, 153.35 # domain commands 153.36 "domid": xm_domid, 153.37 "domname": xm_domname,
156.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 156.2 +++ b/tools/xenstat/Makefile Mon Aug 22 21:54:28 2005 +0000 156.3 @@ -0,0 +1,13 @@ 156.4 +XEN_ROOT = ../.. 156.5 +include $(XEN_ROOT)/tools/Rules.mk 156.6 + 156.7 +SUBDIRS := 156.8 +SUBDIRS += libxenstat 156.9 +SUBDIRS += xentop 156.10 + 156.11 +.PHONY: all install clean 156.12 + 156.13 +all install clean: 156.14 + @set -e; for subdir in $(SUBDIRS); do \ 156.15 + $(MAKE) -C $$subdir $@; \ 156.16 + done
157.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 157.2 +++ b/tools/xenstat/libxenstat/COPYING Mon Aug 22 21:54:28 2005 +0000 157.3 @@ -0,0 +1,510 @@ 157.4 + 157.5 + GNU LESSER GENERAL PUBLIC LICENSE 157.6 + Version 2.1, February 1999 157.7 + 157.8 + Copyright (C) 1991, 1999 Free Software Foundation, Inc. 157.9 + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 157.10 + Everyone is permitted to copy and distribute verbatim copies 157.11 + of this license document, but changing it is not allowed. 157.12 + 157.13 +[This is the first released version of the Lesser GPL. It also counts 157.14 + as the successor of the GNU Library Public License, version 2, hence 157.15 + the version number 2.1.] 157.16 + 157.17 + Preamble 157.18 + 157.19 + The licenses for most software are designed to take away your 157.20 +freedom to share and change it. By contrast, the GNU General Public 157.21 +Licenses are intended to guarantee your freedom to share and change 157.22 +free software--to make sure the software is free for all its users. 157.23 + 157.24 + This license, the Lesser General Public License, applies to some 157.25 +specially designated software packages--typically libraries--of the 157.26 +Free Software Foundation and other authors who decide to use it. You 157.27 +can use it too, but we suggest you first think carefully about whether 157.28 +this license or the ordinary General Public License is the better 157.29 +strategy to use in any particular case, based on the explanations 157.30 +below. 157.31 + 157.32 + When we speak of free software, we are referring to freedom of use, 157.33 +not price. Our General Public Licenses are designed to make sure that 157.34 +you have the freedom to distribute copies of free software (and charge 157.35 +for this service if you wish); that you receive source code or can get 157.36 +it if you want it; that you can change the software and use pieces of 157.37 +it in new free programs; and that you are informed that you can do 157.38 +these things. 157.39 + 157.40 + To protect your rights, we need to make restrictions that forbid 157.41 +distributors to deny you these rights or to ask you to surrender these 157.42 +rights. These restrictions translate to certain responsibilities for 157.43 +you if you distribute copies of the library or if you modify it. 157.44 + 157.45 + For example, if you distribute copies of the library, whether gratis 157.46 +or for a fee, you must give the recipients all the rights that we gave 157.47 +you. You must make sure that they, too, receive or can get the source 157.48 +code. If you link other code with the library, you must provide 157.49 +complete object files to the recipients, so that they can relink them 157.50 +with the library after making changes to the library and recompiling 157.51 +it. And you must show them these terms so they know their rights. 157.52 + 157.53 + We protect your rights with a two-step method: (1) we copyright the 157.54 +library, and (2) we offer you this license, which gives you legal 157.55 +permission to copy, distribute and/or modify the library. 157.56 + 157.57 + To protect each distributor, we want to make it very clear that 157.58 +there is no warranty for the free library. Also, if the library is 157.59 +modified by someone else and passed on, the recipients should know 157.60 +that what they have is not the original version, so that the original 157.61 +author's reputation will not be affected by problems that might be 157.62 +introduced by others. 157.63 + 157.64 + Finally, software patents pose a constant threat to the existence of 157.65 +any free program. We wish to make sure that a company cannot 157.66 +effectively restrict the users of a free program by obtaining a 157.67 +restrictive license from a patent holder. Therefore, we insist that 157.68 +any patent license obtained for a version of the library must be 157.69 +consistent with the full freedom of use specified in this license. 157.70 + 157.71 + Most GNU software, including some libraries, is covered by the 157.72 +ordinary GNU General Public License. This license, the GNU Lesser 157.73 +General Public License, applies to certain designated libraries, and 157.74 +is quite different from the ordinary General Public License. We use 157.75 +this license for certain libraries in order to permit linking those 157.76 +libraries into non-free programs. 157.77 + 157.78 + When a program is linked with a library, whether statically or using 157.79 +a shared library, the combination of the two is legally speaking a 157.80 +combined work, a derivative of the original library. The ordinary 157.81 +General Public License therefore permits such linking only if the 157.82 +entire combination fits its criteria of freedom. The Lesser General 157.83 +Public License permits more lax criteria for linking other code with 157.84 +the library. 157.85 + 157.86 + We call this license the "Lesser" General Public License because it 157.87 +does Less to protect the user's freedom than the ordinary General 157.88 +Public License. It also provides other free software developers Less 157.89 +of an advantage over competing non-free programs. These disadvantages 157.90 +are the reason we use the ordinary General Public License for many 157.91 +libraries. However, the Lesser license provides advantages in certain 157.92 +special circumstances. 157.93 + 157.94 + For example, on rare occasions, there may be a special need to 157.95 +encourage the widest possible use of a certain library, so that it 157.96 +becomes a de-facto standard. To achieve this, non-free programs must 157.97 +be allowed to use the library. A more frequent case is that a free 157.98 +library does the same job as widely used non-free libraries. In this 157.99 +case, there is little to gain by limiting the free library to free 157.100 +software only, so we use the Lesser General Public License. 157.101 + 157.102 + In other cases, permission to use a particular library in non-free 157.103 +programs enables a greater number of people to use a large body of 157.104 +free software. For example, permission to use the GNU C Library in 157.105 +non-free programs enables many more people to use the whole GNU 157.106 +operating system, as well as its variant, the GNU/Linux operating 157.107 +system. 157.108 + 157.109 + Although the Lesser General Public License is Less protective of the 157.110 +users' freedom, it does ensure that the user of a program that is 157.111 +linked with the Library has the freedom and the wherewithal to run 157.112 +that program using a modified version of the Library. 157.113 + 157.114 + The precise terms and conditions for copying, distribution and 157.115 +modification follow. Pay close attention to the difference between a 157.116 +"work based on the library" and a "work that uses the library". The 157.117 +former contains code derived from the library, whereas the latter must 157.118 +be combined with the library in order to run. 157.119 + 157.120 + GNU LESSER GENERAL PUBLIC LICENSE 157.121 + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 157.122 + 157.123 + 0. This License Agreement applies to any software library or other 157.124 +program which contains a notice placed by the copyright holder or 157.125 +other authorized party saying it may be distributed under the terms of 157.126 +this Lesser General Public License (also called "this License"). 157.127 +Each licensee is addressed as "you". 157.128 + 157.129 + A "library" means a collection of software functions and/or data 157.130 +prepared so as to be conveniently linked with application programs 157.131 +(which use some of those functions and data) to form executables. 157.132 + 157.133 + The "Library", below, refers to any such software library or work 157.134 +which has been distributed under these terms. A "work based on the 157.135 +Library" means either the Library or any derivative work under 157.136 +copyright law: that is to say, a work containing the Library or a 157.137 +portion of it, either verbatim or with modifications and/or translated 157.138 +straightforwardly into another language. (Hereinafter, translation is 157.139 +included without limitation in the term "modification".) 157.140 + 157.141 + "Source code" for a work means the preferred form of the work for 157.142 +making modifications to it. For a library, complete source code means 157.143 +all the source code for all modules it contains, plus any associated 157.144 +interface definition files, plus the scripts used to control 157.145 +compilation and installation of the library. 157.146 + 157.147 + Activities other than copying, distribution and modification are not 157.148 +covered by this License; they are outside its scope. The act of 157.149 +running a program using the Library is not restricted, and output from 157.150 +such a program is covered only if its contents constitute a work based 157.151 +on the Library (independent of the use of the Library in a tool for 157.152 +writing it). Whether that is true depends on what the Library does 157.153 +and what the program that uses the Library does. 157.154 + 157.155 + 1. You may copy and distribute verbatim copies of the Library's 157.156 +complete source code as you receive it, in any medium, provided that 157.157 +you conspicuously and appropriately publish on each copy an 157.158 +appropriate copyright notice and disclaimer of warranty; keep intact 157.159 +all the notices that refer to this License and to the absence of any 157.160 +warranty; and distribute a copy of this License along with the 157.161 +Library. 157.162 + 157.163 + You may charge a fee for the physical act of transferring a copy, 157.164 +and you may at your option offer warranty protection in exchange for a 157.165 +fee. 157.166 + 157.167 + 2. You may modify your copy or copies of the Library or any portion 157.168 +of it, thus forming a work based on the Library, and copy and 157.169 +distribute such modifications or work under the terms of Section 1 157.170 +above, provided that you also meet all of these conditions: 157.171 + 157.172 + a) The modified work must itself be a software library. 157.173 + 157.174 + b) You must cause the files modified to carry prominent notices 157.175 + stating that you changed the files and the date of any change. 157.176 + 157.177 + c) You must cause the whole of the work to be licensed at no 157.178 + charge to all third parties under the terms of this License. 157.179 + 157.180 + d) If a facility in the modified Library refers to a function or a 157.181 + table of data to be supplied by an application program that uses 157.182 + the facility, other than as an argument passed when the facility 157.183 + is invoked, then you must make a good faith effort to ensure that, 157.184 + in the event an application does not supply such function or 157.185 + table, the facility still operates, and performs whatever part of 157.186 + its purpose remains meaningful. 157.187 + 157.188 + (For example, a function in a library to compute square roots has 157.189 + a purpose that is entirely well-defined independent of the 157.190 + application. Therefore, Subsection 2d requires that any 157.191 + application-supplied function or table used by this function must 157.192 + be optional: if the application does not supply it, the square 157.193 + root function must still compute square roots.) 157.194 + 157.195 +These requirements apply to the modified work as a whole. If 157.196 +identifiable sections of that work are not derived from the Library, 157.197 +and can be reasonably considered independent and separate works in 157.198 +themselves, then this License, and its terms, do not apply to those 157.199 +sections when you distribute them as separate works. But when you 157.200 +distribute the same sections as part of a whole which is a work based 157.201 +on the Library, the distribution of the whole must be on the terms of 157.202 +this License, whose permissions for other licensees extend to the 157.203 +entire whole, and thus to each and every part regardless of who wrote 157.204 +it. 157.205 + 157.206 +Thus, it is not the intent of this section to claim rights or contest 157.207 +your rights to work written entirely by you; rather, the intent is to 157.208 +exercise the right to control the distribution of derivative or 157.209 +collective works based on the Library. 157.210 + 157.211 +In addition, mere aggregation of another work not based on the Library 157.212 +with the Library (or with a work based on the Library) on a volume of 157.213 +a storage or distribution medium does not bring the other work under 157.214 +the scope of this License. 157.215 + 157.216 + 3. You may opt to apply the terms of the ordinary GNU General Public 157.217 +License instead of this License to a given copy of the Library. To do 157.218 +this, you must alter all the notices that refer to this License, so 157.219 +that they refer to the ordinary GNU General Public License, version 2, 157.220 +instead of to this License. (If a newer version than version 2 of the 157.221 +ordinary GNU General Public License has appeared, then you can specify 157.222 +that version instead if you wish.) Do not make any other change in 157.223 +these notices. 157.224 + 157.225 + Once this change is made in a given copy, it is irreversible for 157.226 +that copy, so the ordinary GNU General Public License applies to all 157.227 +subsequent copies and derivative works made from that copy. 157.228 + 157.229 + This option is useful when you wish to copy part of the code of 157.230 +the Library into a program that is not a library. 157.231 + 157.232 + 4. You may copy and distribute the Library (or a portion or 157.233 +derivative of it, under Section 2) in object code or executable form 157.234 +under the terms of Sections 1 and 2 above provided that you accompany 157.235 +it with the complete corresponding machine-readable source code, which 157.236 +must be distributed under the terms of Sections 1 and 2 above on a 157.237 +medium customarily used for software interchange. 157.238 + 157.239 + If distribution of object code is made by offering access to copy 157.240 +from a designated place, then offering equivalent access to copy the 157.241 +source code from the same place satisfies the requirement to 157.242 +distribute the source code, even though third parties are not 157.243 +compelled to copy the source along with the object code. 157.244 + 157.245 + 5. A program that contains no derivative of any portion of the 157.246 +Library, but is designed to work with the Library by being compiled or 157.247 +linked with it, is called a "work that uses the Library". Such a 157.248 +work, in isolation, is not a derivative work of the Library, and 157.249 +therefore falls outside the scope of this License. 157.250 + 157.251 + However, linking a "work that uses the Library" with the Library 157.252 +creates an executable that is a derivative of the Library (because it 157.253 +contains portions of the Library), rather than a "work that uses the 157.254 +library". The executable is therefore covered by this License. 157.255 +Section 6 states terms for distribution of such executables. 157.256 + 157.257 + When a "work that uses the Library" uses material from a header file 157.258 +that is part of the Library, the object code for the work may be a 157.259 +derivative work of the Library even though the source code is not. 157.260 +Whether this is true is especially significant if the work can be 157.261 +linked without the Library, or if the work is itself a library. The 157.262 +threshold for this to be true is not precisely defined by law. 157.263 + 157.264 + If such an object file uses only numerical parameters, data 157.265 +structure layouts and accessors, and small macros and small inline 157.266 +functions (ten lines or less in length), then the use of the object 157.267 +file is unrestricted, regardless of whether it is legally a derivative 157.268 +work. (Executables containing this object code plus portions of the 157.269 +Library will still fall under Section 6.) 157.270 + 157.271 + Otherwise, if the work is a derivative of the Library, you may 157.272 +distribute the object code for the work under the terms of Section 6. 157.273 +Any executables containing that work also fall under Section 6, 157.274 +whether or not they are linked directly with the Library itself. 157.275 + 157.276 + 6. As an exception to the Sections above, you may also combine or 157.277 +link a "work that uses the Library" with the Library to produce a 157.278 +work containing portions of the Library, and distribute that work 157.279 +under terms of your choice, provided that the terms permit 157.280 +modification of the work for the customer's own use and reverse 157.281 +engineering for debugging such modifications. 157.282 + 157.283 + You must give prominent notice with each copy of the work that the 157.284 +Library is used in it and that the Library and its use are covered by 157.285 +this License. You must supply a copy of this License. If the work 157.286 +during execution displays copyright notices, you must include the 157.287 +copyright notice for the Library among them, as well as a reference 157.288 +directing the user to the copy of this License. Also, you must do one 157.289 +of these things: 157.290 + 157.291 + a) Accompany the work with the complete corresponding 157.292 + machine-readable source code for the Library including whatever 157.293 + changes were used in the work (which must be distributed under 157.294 + Sections 1 and 2 above); and, if the work is an executable linked 157.295 + with the Library, with the complete machine-readable "work that 157.296 + uses the Library", as object code and/or source code, so that the 157.297 + user can modify the Library and then relink to produce a modified 157.298 + executable containing the modified Library. (It is understood 157.299 + that the user who changes the contents of definitions files in the 157.300 + Library will not necessarily be able to recompile the application 157.301 + to use the modified definitions.) 157.302 + 157.303 + b) Use a suitable shared library mechanism for linking with the 157.304 + Library. A suitable mechanism is one that (1) uses at run time a 157.305 + copy of the library already present on the user's computer system, 157.306 + rather than copying library functions into the executable, and (2) 157.307 + will operate properly with a modified version of the library, if 157.308 + the user installs one, as long as the modified version is 157.309 + interface-compatible with the version that the work was made with. 157.310 + 157.311 + c) Accompany the work with a written offer, valid for at least 157.312 + three years, to give the same user the materials specified in 157.313 + Subsection 6a, above, for a charge no more than the cost of 157.314 + performing this distribution. 157.315 + 157.316 + d) If distribution of the work is made by offering access to copy 157.317 + from a designated place, offer equivalent access to copy the above 157.318 + specified materials from the same place. 157.319 + 157.320 + e) Verify that the user has already received a copy of these 157.321 + materials or that you have already sent this user a copy. 157.322 + 157.323 + For an executable, the required form of the "work that uses the 157.324 +Library" must include any data and utility programs needed for 157.325 +reproducing the executable from it. However, as a special exception, 157.326 +the materials to be distributed need not include anything that is 157.327 +normally distributed (in either source or binary form) with the major 157.328 +components (compiler, kernel, and so on) of the operating system on 157.329 +which the executable runs, unless that component itself accompanies 157.330 +the executable. 157.331 + 157.332 + It may happen that this requirement contradicts the license 157.333 +restrictions of other proprietary libraries that do not normally 157.334 +accompany the operating system. Such a contradiction means you cannot 157.335 +use both them and the Library together in an executable that you 157.336 +distribute. 157.337 + 157.338 + 7. You may place library facilities that are a work based on the 157.339 +Library side-by-side in a single library together with other library 157.340 +facilities not covered by this License, and distribute such a combined 157.341 +library, provided that the separate distribution of the work based on 157.342 +the Library and of the other library facilities is otherwise 157.343 +permitted, and provided that you do these two things: 157.344 + 157.345 + a) Accompany the combined library with a copy of the same work 157.346 + based on the Library, uncombined with any other library 157.347 + facilities. This must be distributed under the terms of the 157.348 + Sections above. 157.349 + 157.350 + b) Give prominent notice with the combined library of the fact 157.351 + that part of it is a work based on the Library, and explaining 157.352 + where to find the accompanying uncombined form of the same work. 157.353 + 157.354 + 8. You may not copy, modify, sublicense, link with, or distribute 157.355 +the Library except as expressly provided under this License. Any 157.356 +attempt otherwise to copy, modify, sublicense, link with, or 157.357 +distribute the Library is void, and will automatically terminate your 157.358 +rights under this License. However, parties who have received copies, 157.359 +or rights, from you under this License will not have their licenses 157.360 +terminated so long as such parties remain in full compliance. 157.361 + 157.362 + 9. You are not required to accept this License, since you have not 157.363 +signed it. However, nothing else grants you permission to modify or 157.364 +distribute the Library or its derivative works. These actions are 157.365 +prohibited by law if you do not accept this License. Therefore, by 157.366 +modifying or distributing the Library (or any work based on the 157.367 +Library), you indicate your acceptance of this License to do so, and 157.368 +all its terms and conditions for copying, distributing or modifying 157.369 +the Library or works based on it. 157.370 + 157.371 + 10. Each time you redistribute the Library (or any work based on the 157.372 +Library), the recipient automatically receives a license from the 157.373 +original licensor to copy, distribute, link with or modify the Library 157.374 +subject to these terms and conditions. You may not impose any further 157.375 +restrictions on the recipients' exercise of the rights granted herein. 157.376 +You are not responsible for enforcing compliance by third parties with 157.377 +this License. 157.378 + 157.379 + 11. If, as a consequence of a court judgment or allegation of patent 157.380 +infringement or for any other reason (not limited to patent issues), 157.381 +conditions are imposed on you (whether by court order, agreement or 157.382 +otherwise) that contradict the conditions of this License, they do not 157.383 +excuse you from the conditions of this License. If you cannot 157.384 +distribute so as to satisfy simultaneously your obligations under this 157.385 +License and any other pertinent obligations, then as a consequence you 157.386 +may not distribute the Library at all. For example, if a patent 157.387 +license would not permit royalty-free redistribution of the Library by 157.388 +all those who receive copies directly or indirectly through you, then 157.389 +the only way you could satisfy both it and this License would be to 157.390 +refrain entirely from distribution of the Library. 157.391 + 157.392 +If any portion of this section is held invalid or unenforceable under 157.393 +any particular circumstance, the balance of the section is intended to 157.394 +apply, and the section as a whole is intended to apply in other 157.395 +circumstances. 157.396 + 157.397 +It is not the purpose of this section to induce you to infringe any 157.398 +patents or other property right claims or to contest validity of any 157.399 +such claims; this section has the sole purpose of protecting the 157.400 +integrity of the free software distribution system which is 157.401 +implemented by public license practices. Many people have made 157.402 +generous contributions to the wide range of software distributed 157.403 +through that system in reliance on consistent application of that 157.404 +system; it is up to the author/donor to decide if he or she is willing 157.405 +to distribute software through any other system and a licensee cannot 157.406 +impose that choice. 157.407 + 157.408 +This section is intended to make thoroughly clear what is believed to 157.409 +be a consequence of the rest of this License. 157.410 + 157.411 + 12. If the distribution and/or use of the Library is restricted in 157.412 +certain countries either by patents or by copyrighted interfaces, the 157.413 +original copyright holder who places the Library under this License 157.414 +may add an explicit geographical distribution limitation excluding those 157.415 +countries, so that distribution is permitted only in or among 157.416 +countries not thus excluded. In such case, this License incorporates 157.417 +the limitation as if written in the body of this License. 157.418 + 157.419 + 13. The Free Software Foundation may publish revised and/or new 157.420 +versions of the Lesser General Public License from time to time. 157.421 +Such new versions will be similar in spirit to the present version, 157.422 +but may differ in detail to address new problems or concerns. 157.423 + 157.424 +Each version is given a distinguishing version number. If the Library 157.425 +specifies a version number of this License which applies to it and 157.426 +"any later version", you have the option of following the terms and 157.427 +conditions either of that version or of any later version published by 157.428 +the Free Software Foundation. If the Library does not specify a 157.429 +license version number, you may choose any version ever published by 157.430 +the Free Software Foundation. 157.431 + 157.432 + 14. If you wish to incorporate parts of the Library into other free 157.433 +programs whose distribution conditions are incompatible with these, 157.434 +write to the author to ask for permission. For software which is 157.435 +copyrighted by the Free Software Foundation, write to the Free 157.436 +Software Foundation; we sometimes make exceptions for this. Our 157.437 +decision will be guided by the two goals of preserving the free status 157.438 +of all derivatives of our free software and of promoting the sharing 157.439 +and reuse of software generally. 157.440 + 157.441 + NO WARRANTY 157.442 + 157.443 + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 157.444 +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 157.445 +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 157.446 +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 157.447 +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 157.448 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 157.449 +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 157.450 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 157.451 +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 157.452 + 157.453 + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 157.454 +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 157.455 +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 157.456 +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 157.457 +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 157.458 +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 157.459 +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 157.460 +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 157.461 +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 157.462 +DAMAGES. 157.463 + 157.464 + END OF TERMS AND CONDITIONS 157.465 + 157.466 + How to Apply These Terms to Your New Libraries 157.467 + 157.468 + If you develop a new library, and you want it to be of the greatest 157.469 +possible use to the public, we recommend making it free software that 157.470 +everyone can redistribute and change. You can do so by permitting 157.471 +redistribution under these terms (or, alternatively, under the terms 157.472 +of the ordinary General Public License). 157.473 + 157.474 + To apply these terms, attach the following notices to the library. 157.475 +It is safest to attach them to the start of each source file to most 157.476 +effectively convey the exclusion of warranty; and each file should 157.477 +have at least the "copyright" line and a pointer to where the full 157.478 +notice is found. 157.479 + 157.480 + 157.481 + <one line to give the library's name and a brief idea of what it does.> 157.482 + Copyright (C) <year> <name of author> 157.483 + 157.484 + This library is free software; you can redistribute it and/or 157.485 + modify it under the terms of the GNU Lesser General Public 157.486 + License as published by the Free Software Foundation; either 157.487 + version 2.1 of the License, or (at your option) any later version. 157.488 + 157.489 + This library is distributed in the hope that it will be useful, 157.490 + but WITHOUT ANY WARRANTY; without even the implied warranty of 157.491 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 157.492 + Lesser General Public License for more details. 157.493 + 157.494 + You should have received a copy of the GNU Lesser General Public 157.495 + License along with this library; if not, write to the Free Software 157.496 + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 157.497 + 157.498 +Also add information on how to contact you by electronic and paper mail. 157.499 + 157.500 +You should also get your employer (if you work as a programmer) or 157.501 +your school, if any, to sign a "copyright disclaimer" for the library, 157.502 +if necessary. Here is a sample; alter the names: 157.503 + 157.504 + Yoyodyne, Inc., hereby disclaims all copyright interest in the 157.505 + library `Frob' (a library for tweaking knobs) written by James 157.506 + Random Hacker. 157.507 + 157.508 + <signature of Ty Coon>, 1 April 1990 157.509 + Ty Coon, President of Vice 157.510 + 157.511 +That's all there is to it! 157.512 + 157.513 +
158.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 158.2 +++ b/tools/xenstat/libxenstat/Makefile Mon Aug 22 21:54:28 2005 +0000 158.3 @@ -0,0 +1,142 @@ 158.4 +# libxenstat: statistics-collection library for Xen 158.5 +# Copyright (C) International Business Machines Corp., 2005 158.6 +# Author: Josh Triplett <josht@us.ibm.com> 158.7 +# 158.8 +# This library is free software; you can redistribute it and/or 158.9 +# modify it under the terms of the GNU Lesser General Public 158.10 +# License as published by the Free Software Foundation; either 158.11 +# version 2.1 of the License, or (at your option) any later version. 158.12 +# 158.13 +# This library is distributed in the hope that it will be useful, 158.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 158.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 158.16 +# Lesser General Public License for more details. 158.17 + 158.18 +XEN_ROOT=../../.. 158.19 +include $(XEN_ROOT)/tools/Rules.mk 158.20 +LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse 158.21 + 158.22 +INSTALL = install 158.23 +INSTALL_PROG = $(INSTALL) -m0755 -D 158.24 +INSTALL_DATA = $(INSTALL) -m0644 -D 158.25 + 158.26 +prefix=/usr 158.27 +includedir=$(prefix)/include 158.28 +libdir=$(prefix)/lib 158.29 + 158.30 +LDCONFIG=ldconfig 158.31 +MAKE_LINK=ln -sf 158.32 + 158.33 +MAJOR=0 158.34 +MINOR=0 158.35 + 158.36 +LIB=src/libxenstat.a 158.37 +SHLIB=src/libxenstat.so.$(MAJOR).$(MINOR) 158.38 +SHLIB_LINKS=src/libxenstat.so.$(MAJOR) src/libxenstat.so 158.39 +OBJECTS=src/xenstat.o src/xen-interface.o 158.40 +SONAME_FLAGS=-Wl,-soname -Wl,libxenstat.so.$(MAJOR) 158.41 + 158.42 +WARN_FLAGS=-Wall -Werror 158.43 + 158.44 +CFLAGS+=-Isrc 158.45 +CFLAGS+=-I$(XEN_ROOT)/xen/include/public 158.46 +CFLAGS+=-I$(LINUX_ROOT)/include/asm-xen/linux-public/ 158.47 +LDFLAGS+=-Lsrc 158.48 + 158.49 +all: $(LIB) 158.50 + 158.51 +$(LIB): $(OBJECTS) 158.52 + $(AR) rc $@ $^ 158.53 + $(RANLIB) $@ 158.54 + 158.55 +$(SHLIB): $(OBJECTS) 158.56 + $(CC) $(LDFLAGS) $(SONAME_FLAGS) -shared -o $@ $(OBJECTS) 158.57 + 158.58 +src/xenstat.o: src/xenstat.c src/xenstat.h src/xen-interface.h 158.59 + $(CC) $(CFLAGS) $(WARN_FLAGS) -c -o $@ $< 158.60 + 158.61 +src/xen-interface.o: src/xen-interface.c src/xen-interface.h 158.62 + $(CC) $(CFLAGS) $(WARN_FLAGS) -c -o $@ $< 158.63 + 158.64 +src/libxenstat.so.$(MAJOR): $(LIB) 158.65 + $(MAKE_LINK) $(<F) $@ 158.66 + 158.67 +src/libxenstat.so: src/libxenstat.so.$(MAJOR) 158.68 + $(MAKE_LINK) $(<F) $@ 158.69 + 158.70 +install: all 158.71 +#install: all 158.72 +# $(INSTALL_DATA) src/xenstat.h $(DESTDIR)$(includedir)/xenstat.h 158.73 +# $(INSTALL_PROG) $(LIB) $(DESTDIR)$(libdir)/libxenstat.a 158.74 +# $(INSTALL_PROG) $(SHLIB) \ 158.75 +# $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR).$(MINOR) 158.76 +# $(MAKE_LINK) libxenstat.so.$(MAJOR).$(MINOR) \ 158.77 +# $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR) 158.78 +# $(MAKE_LINK) libxenstat.so.$(MAJOR) \ 158.79 +# $(DESTDIR)$(libdir)/libxenstat.so 158.80 +# -$(LDCONFIG) 158.81 + 158.82 +PYLIB=bindings/swig/python/_xenstat.so 158.83 +PYMOD=bindings/swig/python/xenstat.py 158.84 +PYSRC=bindings/swig/python/_xenstat.c 158.85 +PERLLIB=bindings/swig/perl/xenstat.so 158.86 +PERLMOD=bindings/swig/perl/xenstat.pm 158.87 +PERLSRC=bindings/swig/perl/xenstat.c 158.88 +BINDINGS=$(PYLIB) $(PYMOD) $(PERLLIB) $(PERLMOD) 158.89 +BINDINGSRC=$(PYSRC) $(PERLSRC) 158.90 + 158.91 +# The all-bindings target builds all the language bindings 158.92 +all-bindings: perl-bindings python-bindings 158.93 + 158.94 +# The install-bindings target installs all the language bindings 158.95 +install-bindings: install-perl-bindings install-python-bindings 158.96 + 158.97 +$(BINDINGS): $(SHLIB) $(SHLIB_LINKS) src/xenstat.h 158.98 + 158.99 +SWIG_FLAGS=-module xenstat -Isrc 158.100 + 158.101 +# Python bindings 158.102 +PYTHON_VERSION=2.3 158.103 +PYTHON_FLAGS=-I/usr/include/python$(PYTHON_VERSION) -lpython$(PYTHON_VERSION) 158.104 +$(PYSRC) $(PYMOD): bindings/swig/xenstat.i 158.105 + swig -python $(SWIG_FLAGS) -outdir $(@D) -o $(PYSRC) $< 158.106 + 158.107 +$(PYLIB): $(PYSRC) 158.108 + $(CC) $(CFLAGS) $(LDFLAGS) $(PYTHON_FLAGS) -shared -lxenstat -o $@ $< 158.109 + 158.110 +python-bindings: $(PYLIB) $(PYMOD) 158.111 + 158.112 +pythonlibdir=$(prefix)/lib/python$(PYTHON_VERSION)/site-packages 158.113 +install-python-bindings: $(PYLIB) $(PYMOD) 158.114 + $(INSTALL_PROG) $(PYLIB) $(DESTDIR)$(pythonlibdir)/_xenstat.so 158.115 + $(INSTALL_PROG) $(PYMOD) $(DESTDIR)$(pythonlibdir)/xenstat.py 158.116 + 158.117 +ifeq ($(XENSTAT_PYTHON_BINDINGS),y) 158.118 +all: python-bindings 158.119 +install: install-python-bindings 158.120 +endif 158.121 + 158.122 +# Perl bindings 158.123 +PERL_FLAGS=`perl -MConfig -e 'print "$$Config{ccflags} -I$$Config{archlib}/CORE";'` 158.124 +$(PERLSRC) $(PERLMOD): bindings/swig/xenstat.i 158.125 + swig -perl $(SWIG_FLAGS) -outdir $(@D) -o $(PERLSRC) $< 158.126 + 158.127 +$(PERLLIB): $(PERLSRC) 158.128 + $(CC) $(CFLAGS) $(LDFLAGS) $(PERL_FLAGS) -shared -lxenstat -o $@ $< 158.129 + 158.130 +perl-bindings: $(PERLLIB) $(PERLMOD) 158.131 + 158.132 +perllibdir=$(prefix)/lib/perl5 158.133 +perlmoddir=$(prefix)/share/perl5 158.134 +install-perl-bindings: $(PERLLIB) $(PERLMOD) 158.135 + $(INSTALL_PROG) $(PERLLIB) $(DESTDIR)$(perllibdir)/xenstat.so 158.136 + $(INSTALL_PROG) $(PERLMOD) $(DESTDIR)$(perlmoddir)/xenstat.pm 158.137 + 158.138 +ifeq ($(XENSTAT_PERL_BINDINGS),y) 158.139 +all: perl-bindings 158.140 +install: install-perl-bindings 158.141 +endif 158.142 + 158.143 +clean: 158.144 + rm -f $(LIB) $(SHLIB) $(SHLIB_LINKS) $(OBJECTS) \ 158.145 + $(BINDINGS) $(BINDINGSRC)
159.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 159.2 +++ b/tools/xenstat/libxenstat/bindings/swig/perl/.empty Mon Aug 22 21:54:28 2005 +0000 159.3 @@ -0,0 +1,1 @@ 159.4 +This directory is empty; this file is included to prevent version control systems from removing the directory.
160.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 160.2 +++ b/tools/xenstat/libxenstat/bindings/swig/python/.empty Mon Aug 22 21:54:28 2005 +0000 160.3 @@ -0,0 +1,1 @@ 160.4 +This directory is empty; this file is included to prevent version control systems from removing the directory.
161.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 161.2 +++ b/tools/xenstat/libxenstat/bindings/swig/xenstat.i Mon Aug 22 21:54:28 2005 +0000 161.3 @@ -0,0 +1,8 @@ 161.4 +%module xenstat_swig 161.5 +%{ 161.6 +/* Includes the header in the wrapper code */ 161.7 +#include "xenstat.h" 161.8 +%} 161.9 + 161.10 +/* Parse the header file to generate wrappers */ 161.11 +%include "xenstat.h"
162.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 162.2 +++ b/tools/xenstat/libxenstat/src/xen-interface.c Mon Aug 22 21:54:28 2005 +0000 162.3 @@ -0,0 +1,144 @@ 162.4 +/* xen-interface.c 162.5 + * 162.6 + * Copyright (C) International Business Machines Corp., 2005 162.7 + * Authors: Josh Triplett <josht@us.ibm.com> 162.8 + * Judy Fischbach <jfisch@us.ibm.com> 162.9 + * 162.10 + * This library is free software; you can redistribute it and/or 162.11 + * modify it under the terms of the GNU Lesser General Public 162.12 + * License as published by the Free Software Foundation; either 162.13 + * version 2.1 of the License, or (at your option) any later version. 162.14 + * 162.15 + * This library is distributed in the hope that it will be useful, 162.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 162.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 162.18 + * Lesser General Public License for more details. 162.19 + */ 162.20 + 162.21 +#include "xen-interface.h" 162.22 +#include <fcntl.h> 162.23 +#include <sys/ioctl.h> 162.24 +#include <sys/mman.h> 162.25 +#include <stdio.h> 162.26 +#include <stdlib.h> 162.27 +#include <unistd.h> 162.28 +#include "privcmd.h" 162.29 +#include "xen.h" 162.30 + 162.31 +struct xi_handle { 162.32 + int fd; 162.33 +}; 162.34 + 162.35 +/* Initialize for xen-interface. Returns a handle to be used with subsequent 162.36 + * calls to the xen-interface functions or NULL if an error occurs. */ 162.37 +xi_handle *xi_init() 162.38 +{ 162.39 + xi_handle *handle; 162.40 + 162.41 + handle = (xi_handle *)calloc(1, sizeof(xi_handle)); 162.42 + if (handle == NULL) 162.43 + return NULL; 162.44 + 162.45 + handle->fd = open("/proc/xen/privcmd", O_RDWR); 162.46 + if (handle->fd < 0) { 162.47 + perror("Couldn't open /proc/xen/privcmd"); 162.48 + free(handle); 162.49 + return NULL; 162.50 + } 162.51 + 162.52 + return handle; 162.53 +} 162.54 + 162.55 +/* Release the handle to libxc, free resources, etc. */ 162.56 +void xi_uninit(xi_handle *handle) 162.57 +{ 162.58 + close (handle->fd); 162.59 + free (handle); 162.60 +} 162.61 + 162.62 +/* Make Xen hypervisor call */ 162.63 +int xi_make_dom0_op(xi_handle *handle, dom0_op_t *op, int opcode) 162.64 +{ 162.65 + privcmd_hypercall_t privcmd; 162.66 + int ret = 0; 162.67 + 162.68 + /* set up for doing hypercall */ 162.69 + privcmd.op = __HYPERVISOR_dom0_op; 162.70 + privcmd.arg[0] = (unsigned long)op; 162.71 + op->cmd = opcode; 162.72 + op->interface_version = DOM0_INTERFACE_VERSION; 162.73 + 162.74 + if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) { 162.75 + perror("Failed to mlock privcmd structure"); 162.76 + return -1; 162.77 + } 162.78 + 162.79 + if (mlock( op, sizeof(dom0_op_t)) < 0) { 162.80 + perror("Failed to mlock dom0_op structure"); 162.81 + munlock( &privcmd, sizeof(privcmd_hypercall_t)); 162.82 + return -1; 162.83 + } 162.84 + 162.85 + if (ioctl( handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) { 162.86 + perror("Hypercall failed"); 162.87 + ret = -1; 162.88 + } 162.89 + 162.90 + munlock( &privcmd, sizeof(privcmd_hypercall_t)); 162.91 + munlock( op, sizeof(dom0_op_t)); 162.92 + 162.93 + return ret; 162.94 +} 162.95 + 162.96 +/* Obtain domain data from dom0 */ 162.97 +int xi_get_physinfo(xi_handle *handle, dom0_physinfo_t *physinfo) 162.98 +{ 162.99 + dom0_op_t op; 162.100 + 162.101 + if (xi_make_dom0_op(handle, &op, DOM0_PHYSINFO) < 0) { 162.102 + perror("DOM0_PHYSINFO Hypercall failed"); 162.103 + return -1; 162.104 + } 162.105 + 162.106 + *physinfo = op.u.physinfo; 162.107 + return 0; 162.108 +} 162.109 + 162.110 +/* Obtain domain data from dom0 */ 162.111 +int xi_get_domaininfolist(xi_handle *handle, dom0_getdomaininfo_t *info, 162.112 + unsigned int first_domain, unsigned int max_domains) 162.113 +{ 162.114 + dom0_op_t op; 162.115 + op.u.getdomaininfolist.first_domain = first_domain; 162.116 + op.u.getdomaininfolist.max_domains = max_domains; 162.117 + op.u.getdomaininfolist.buffer = info; 162.118 + 162.119 + if (mlock( info, max_domains * sizeof(dom0_getdomaininfo_t)) < 0) { 162.120 + perror("Failed to mlock domaininfo array"); 162.121 + return -1; 162.122 + } 162.123 + 162.124 + if (xi_make_dom0_op(handle, &op, DOM0_GETDOMAININFOLIST) < 0) { 162.125 + perror("DOM0_GETDOMAININFOLIST Hypercall failed"); 162.126 + return -1; 162.127 + } 162.128 + 162.129 + return op.u.getdomaininfolist.num_domains; 162.130 +} 162.131 + 162.132 +/* Returns cpu usage data from dom0 */ 162.133 +long long xi_get_vcpu_usage(xi_handle *handle, unsigned int domain, 162.134 + unsigned int vcpu) 162.135 +{ 162.136 + dom0_op_t op; 162.137 + op.u.getvcpucontext.domain = domain; 162.138 + op.u.getvcpucontext.vcpu = vcpu; 162.139 + op.u.getvcpucontext.ctxt = NULL; 162.140 + 162.141 + if (xi_make_dom0_op(handle, &op, DOM0_GETVCPUCONTEXT) < 0) { 162.142 + perror("DOM0_GETVCPUCONTEXT Hypercall failed"); 162.143 + return -1; 162.144 + } 162.145 + 162.146 + return op.u.getvcpucontext.cpu_time; 162.147 +}
163.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 163.2 +++ b/tools/xenstat/libxenstat/src/xen-interface.h Mon Aug 22 21:54:28 2005 +0000 163.3 @@ -0,0 +1,49 @@ 163.4 +/* xen-interface.h 163.5 + * 163.6 + * Copyright (C) International Business Machines Corp., 2005 163.7 + * Authors: Josh Triplett <josht@us.ibm.com> 163.8 + * Judy Fischbach <jfisch@us.ibm.com> 163.9 + * 163.10 + * This library is free software; you can redistribute it and/or 163.11 + * modify it under the terms of the GNU Lesser General Public 163.12 + * License as published by the Free Software Foundation; either 163.13 + * version 2.1 of the License, or (at your option) any later version. 163.14 + * 163.15 + * This library is distributed in the hope that it will be useful, 163.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 163.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 163.18 + * Lesser General Public License for more details. 163.19 + */ 163.20 + 163.21 +#include <stdint.h> 163.22 + 163.23 +typedef int8_t s8; 163.24 +typedef int16_t s16; 163.25 +typedef int32_t s32; 163.26 +typedef int64_t s64; 163.27 +typedef uint8_t u8; 163.28 +typedef uint16_t u16; 163.29 +typedef uint32_t u32; 163.30 +typedef uint64_t u64; 163.31 + 163.32 +#include "dom0_ops.h" 163.33 + 163.34 +/* Opaque handles */ 163.35 +typedef struct xi_handle xi_handle; 163.36 + 163.37 +/* Initialize for xen-interface. Returns a handle to be used with subsequent 163.38 + * calls to the xen-interface functions or NULL if an error occurs. */ 163.39 +xi_handle *xi_init(); 163.40 + 163.41 +/* Release the handle to libxc, free resources, etc. */ 163.42 +void xi_uninit(xi_handle *handle); 163.43 + 163.44 +/* Obtain physinfo data from dom0 */ 163.45 +int xi_get_physinfo(xi_handle *, dom0_physinfo_t *); 163.46 + 163.47 +/* Obtain domain data from dom0 */ 163.48 +int xi_get_domaininfolist(xi_handle *, dom0_getdomaininfo_t *, unsigned int, 163.49 + unsigned int); 163.50 + 163.51 +/* Returns cpu usage data from dom0 */ 163.52 +long long xi_get_vcpu_usage(xi_handle *, unsigned int, unsigned int);
164.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 164.2 +++ b/tools/xenstat/libxenstat/src/xenstat.c Mon Aug 22 21:54:28 2005 +0000 164.3 @@ -0,0 +1,620 @@ 164.4 +/* libxenstat: statistics-collection library for Xen 164.5 + * Copyright (C) International Business Machines Corp., 2005 164.6 + * Authors: Josh Triplett <josht@us.ibm.com> 164.7 + * Judy Fischbach <jfisch@us.ibm.com> 164.8 + * David Hendricks <dhendrix@us.ibm.com> 164.9 + * 164.10 + * This library is free software; you can redistribute it and/or 164.11 + * modify it under the terms of the GNU Lesser General Public 164.12 + * License as published by the Free Software Foundation; either 164.13 + * version 2.1 of the License, or (at your option) any later version. 164.14 + * 164.15 + * This library is distributed in the hope that it will be useful, 164.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 164.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 164.18 + * Lesser General Public License for more details. 164.19 + */ 164.20 + 164.21 +#include <limits.h> 164.22 +#include <stdlib.h> 164.23 +#include <stdio.h> 164.24 +#include <string.h> 164.25 +#include <unistd.h> 164.26 +#include <xen-interface.h> 164.27 +#include "xenstat.h" 164.28 + 164.29 +/* 164.30 + * Types 164.31 + */ 164.32 +struct xenstat_handle { 164.33 + xi_handle *xihandle; 164.34 + int page_size; 164.35 + FILE *procnetdev; 164.36 +}; 164.37 + 164.38 +struct xenstat_node { 164.39 + unsigned int flags; 164.40 + unsigned long long cpu_hz; 164.41 + unsigned int num_cpus; 164.42 + unsigned long long tot_mem; 164.43 + unsigned long long free_mem; 164.44 + unsigned int num_domains; 164.45 + xenstat_domain *domains; /* Array of length num_domains */ 164.46 +}; 164.47 + 164.48 +struct xenstat_domain { 164.49 + unsigned int id; 164.50 + unsigned int state; 164.51 + unsigned long long cpu_ns; 164.52 + unsigned int num_vcpus; 164.53 + xenstat_vcpu *vcpus; /* Array of length num_vcpus */ 164.54 + unsigned long long cur_mem; /* Current memory reservation */ 164.55 + unsigned long long max_mem; /* Total memory allowed */ 164.56 + unsigned int ssid; 164.57 + unsigned int num_networks; 164.58 + xenstat_network *networks; /* Array of length num_networks */ 164.59 +}; 164.60 + 164.61 +struct xenstat_vcpu { 164.62 + unsigned long long ns; 164.63 +}; 164.64 + 164.65 +struct xenstat_network { 164.66 + unsigned int id; 164.67 + /* Received */ 164.68 + unsigned long long rbytes; 164.69 + unsigned long long rpackets; 164.70 + unsigned long long rerrs; 164.71 + unsigned long long rdrop; 164.72 + /* Transmitted */ 164.73 + unsigned long long tbytes; 164.74 + unsigned long long tpackets; 164.75 + unsigned long long terrs; 164.76 + unsigned long long tdrop; 164.77 +}; 164.78 + 164.79 +/* 164.80 + * Data-collection types 164.81 + */ 164.82 +/* Called to collect the information for the node and all the domains on 164.83 + * it. When called, the domain information has already been collected. */ 164.84 +typedef int (*xenstat_collect_func)(xenstat_handle * handle, 164.85 + xenstat_node * node); 164.86 +/* Called to free the information collected by the collect function. The free 164.87 + * function will only be called on a xenstat_node if that node includes 164.88 + * information collected by the corresponding collector. */ 164.89 +typedef void (*xenstat_free_func)(xenstat_node * node); 164.90 +/* Called to free any information stored in the handle. Note the lack of a 164.91 + * matching init function; the collect functions should initialize on first 164.92 + * use. Also, the uninit function must handle the case that the collector has 164.93 + * never been initialized. */ 164.94 +typedef void (*xenstat_uninit_func)(xenstat_handle * handle); 164.95 +typedef struct xenstat_collector { 164.96 + unsigned int flag; 164.97 + xenstat_collect_func collect; 164.98 + xenstat_free_func free; 164.99 + xenstat_uninit_func uninit; 164.100 +} xenstat_collector; 164.101 + 164.102 +static int xenstat_collect_vcpus(xenstat_handle * handle, 164.103 + xenstat_node * node); 164.104 +static int xenstat_collect_networks(xenstat_handle * handle, 164.105 + xenstat_node * node); 164.106 +static void xenstat_free_vcpus(xenstat_node * node); 164.107 +static void xenstat_free_networks(xenstat_node * node); 164.108 +static void xenstat_uninit_vcpus(xenstat_handle * handle); 164.109 +static void xenstat_uninit_networks(xenstat_handle * handle); 164.110 + 164.111 +static xenstat_collector collectors[] = { 164.112 + { XENSTAT_VCPU, xenstat_collect_vcpus, 164.113 + xenstat_free_vcpus, xenstat_uninit_vcpus }, 164.114 + { XENSTAT_NETWORK, xenstat_collect_networks, 164.115 + xenstat_free_networks, xenstat_uninit_networks } 164.116 +}; 164.117 + 164.118 +#define NUM_COLLECTORS (sizeof(collectors)/sizeof(xenstat_collector)) 164.119 + 164.120 +/* 164.121 + * libxenstat API 164.122 + */ 164.123 +xenstat_handle *xenstat_init() 164.124 +{ 164.125 + xenstat_handle *handle; 164.126 + 164.127 + handle = (xenstat_handle *) calloc(1, sizeof(xenstat_handle)); 164.128 + if (handle == NULL) 164.129 + return NULL; 164.130 + 164.131 +#if defined(PAGESIZE) 164.132 + handle->page_size = PAGESIZE; 164.133 +#elif defined(PAGE_SIZE) 164.134 + handle->page_size = PAGE_SIZE; 164.135 +#else 164.136 + handle->page_size = sysconf(_SC_PAGE_SIZE); 164.137 + if (handle->page_size < 0) { 164.138 + perror("Failed to retrieve page size."); 164.139 + free(handle); 164.140 + return NULL; 164.141 + } 164.142 +#endif 164.143 + 164.144 + handle->xihandle = xi_init(); 164.145 + if (handle->xihandle == NULL) { 164.146 + perror("xi_init"); 164.147 + free(handle); 164.148 + return NULL; 164.149 + } 164.150 + 164.151 + return handle; 164.152 +} 164.153 + 164.154 +void xenstat_uninit(xenstat_handle * handle) 164.155 +{ 164.156 + unsigned int i; 164.157 + if (handle) { 164.158 + for (i = 0; i < NUM_COLLECTORS; i++) 164.159 + collectors[i].uninit(handle); 164.160 + xi_uninit(handle->xihandle); 164.161 + free(handle); 164.162 + } 164.163 +} 164.164 + 164.165 +xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags) 164.166 +{ 164.167 +#define DOMAIN_CHUNK_SIZE 256 164.168 + xenstat_node *node; 164.169 + dom0_physinfo_t physinfo; 164.170 + dom0_getdomaininfo_t domaininfo[DOMAIN_CHUNK_SIZE]; 164.171 + unsigned int num_domains, new_domains; 164.172 + unsigned int i; 164.173 + 164.174 + /* Create the node */ 164.175 + node = (xenstat_node *) calloc(1, sizeof(xenstat_node)); 164.176 + if (node == NULL) 164.177 + return NULL; 164.178 + 164.179 + /* Get information about the physical system */ 164.180 + if (xi_get_physinfo(handle->xihandle, &physinfo) < 0) { 164.181 + free(node); 164.182 + return NULL; 164.183 + } 164.184 + 164.185 + node->cpu_hz = ((unsigned long long)physinfo.cpu_khz) * 1000ULL; 164.186 + node->num_cpus = 164.187 + (physinfo.threads_per_core * physinfo.cores_per_socket * 164.188 + physinfo.sockets_per_node * physinfo.nr_nodes); 164.189 + node->tot_mem = ((unsigned long long)physinfo.total_pages) 164.190 + * handle->page_size; 164.191 + node->free_mem = ((unsigned long long)physinfo.free_pages) 164.192 + * handle->page_size; 164.193 + 164.194 + /* malloc(0) is not portable, so allocate a single domain. This will 164.195 + * be resized below. */ 164.196 + node->domains = malloc(sizeof(xenstat_domain)); 164.197 + if (node->domains == NULL) { 164.198 + free(node); 164.199 + return NULL; 164.200 + } 164.201 + 164.202 + num_domains = 0; 164.203 + do { 164.204 + xenstat_domain *domain; 164.205 + 164.206 + new_domains = xi_get_domaininfolist(handle->xihandle, 164.207 + domaininfo, num_domains, 164.208 + DOMAIN_CHUNK_SIZE); 164.209 + 164.210 + node->domains = realloc(node->domains, 164.211 + (num_domains + new_domains) 164.212 + * sizeof(xenstat_domain)); 164.213 + if (node->domains == NULL) { 164.214 + free(node); 164.215 + return NULL; 164.216 + } 164.217 + 164.218 + domain = node->domains + num_domains; 164.219 + 164.220 + for (i = 0; i < new_domains; i++) { 164.221 + /* Fill in domain using domaininfo[i] */ 164.222 + domain->id = domaininfo[i].domain; 164.223 + domain->state = domaininfo[i].flags; 164.224 + domain->cpu_ns = domaininfo[i].cpu_time; 164.225 + domain->num_vcpus = domaininfo[i].n_vcpu; 164.226 + domain->vcpus = NULL; 164.227 + domain->cur_mem = 164.228 + ((unsigned long long)domaininfo[i].tot_pages) 164.229 + * handle->page_size; 164.230 + domain->max_mem = 164.231 + domaininfo[i].max_pages == UINT_MAX 164.232 + ? (unsigned long long)-1 164.233 + : (unsigned long long)(domaininfo[i].max_pages 164.234 + * handle->page_size); 164.235 + domain->ssid = domaininfo[i].ssidref; 164.236 + domain->num_networks = 0; 164.237 + domain->networks = NULL; 164.238 + 164.239 + domain++; 164.240 + } 164.241 + num_domains += new_domains; 164.242 + } while (new_domains == DOMAIN_CHUNK_SIZE); 164.243 + node->num_domains = num_domains; 164.244 + 164.245 + /* Run all the extra data collectors requested */ 164.246 + node->flags = 0; 164.247 + for (i = 0; i < NUM_COLLECTORS; i++) { 164.248 + if ((flags & collectors[i].flag) == collectors[i].flag) { 164.249 + node->flags |= collectors[i].flag; 164.250 + if(collectors[i].collect(handle, node) == 0) { 164.251 + xenstat_free_node(node); 164.252 + return NULL; 164.253 + } 164.254 + } 164.255 + } 164.256 + 164.257 + return node; 164.258 +} 164.259 + 164.260 +void xenstat_free_node(xenstat_node * node) 164.261 +{ 164.262 + int i; 164.263 + 164.264 + if (node) { 164.265 + if (node->domains) { 164.266 + for (i = 0; i < NUM_COLLECTORS; i++) 164.267 + if((node->flags & collectors[i].flag) 164.268 + == collectors[i].flag) 164.269 + collectors[i].free(node); 164.270 + free(node->domains); 164.271 + } 164.272 + free(node); 164.273 + } 164.274 +} 164.275 + 164.276 +xenstat_domain *xenstat_node_domain(xenstat_node * node, unsigned int domid) 164.277 +{ 164.278 + unsigned int i; 164.279 + 164.280 + /* FIXME: binary search */ 164.281 + /* Find the appropriate domain entry in the node struct. */ 164.282 + for (i = 0; i < node->num_domains; i++) { 164.283 + if (node->domains[i].id == domid) 164.284 + return &(node->domains[i]); 164.285 + } 164.286 + return NULL; 164.287 +} 164.288 + 164.289 +xenstat_domain *xenstat_node_domain_by_index(xenstat_node * node, 164.290 + unsigned int index) 164.291 +{ 164.292 + if (0 <= index && index < node->num_domains) 164.293 + return &(node->domains[index]); 164.294 + return NULL; 164.295 +} 164.296 + 164.297 +unsigned long long xenstat_node_tot_mem(xenstat_node * node) 164.298 +{ 164.299 + return node->tot_mem; 164.300 +} 164.301 + 164.302 +unsigned long long xenstat_node_free_mem(xenstat_node * node) 164.303 +{ 164.304 + return node->free_mem; 164.305 +} 164.306 + 164.307 +unsigned int xenstat_node_num_domains(xenstat_node * node) 164.308 +{ 164.309 + return node->num_domains; 164.310 +} 164.311 + 164.312 +unsigned int xenstat_node_num_cpus(xenstat_node * node) 164.313 +{ 164.314 + return node->num_cpus; 164.315 +} 164.316 + 164.317 +/* Get information about the CPU speed */ 164.318 +unsigned long long xenstat_node_cpu_hz(xenstat_node * node) 164.319 +{ 164.320 + return node->cpu_hz; 164.321 +} 164.322 + 164.323 +/* Get the domain ID for this domain */ 164.324 +unsigned xenstat_domain_id(xenstat_domain * domain) 164.325 +{ 164.326 + return domain->id; 164.327 +} 164.328 + 164.329 +/* Get information about how much CPU time has been used */ 164.330 +unsigned long long xenstat_domain_cpu_ns(xenstat_domain * domain) 164.331 +{ 164.332 + return domain->cpu_ns; 164.333 +} 164.334 + 164.335 +/* Find the number of VCPUs allocated to a domain */ 164.336 +unsigned int xenstat_domain_num_vcpus(xenstat_domain * domain) 164.337 +{ 164.338 + return domain->num_vcpus; 164.339 +} 164.340 + 164.341 +xenstat_vcpu *xenstat_domain_vcpu(xenstat_domain * domain, unsigned int vcpu) 164.342 +{ 164.343 + if (0 <= vcpu && vcpu < domain->num_vcpus) 164.344 + return &(domain->vcpus[vcpu]); 164.345 + return NULL; 164.346 +} 164.347 + 164.348 +/* Find the current memory reservation for this domain */ 164.349 +unsigned long long xenstat_domain_cur_mem(xenstat_domain * domain) 164.350 +{ 164.351 + return domain->cur_mem; 164.352 +} 164.353 + 164.354 +/* Find the maximum memory reservation for this domain */ 164.355 +unsigned long long xenstat_domain_max_mem(xenstat_domain * domain) 164.356 +{ 164.357 + return domain->max_mem; 164.358 +} 164.359 + 164.360 +/* Find the domain's SSID */ 164.361 +unsigned int xenstat_domain_ssid(xenstat_domain * domain) 164.362 +{ 164.363 + return domain->ssid; 164.364 +} 164.365 + 164.366 +/* Get domain states */ 164.367 +unsigned int xenstat_domain_dying(xenstat_domain * domain) 164.368 +{ 164.369 + return (domain->state & DOMFLAGS_DYING) == DOMFLAGS_DYING; 164.370 +} 164.371 + 164.372 +unsigned int xenstat_domain_crashed(xenstat_domain * domain) 164.373 +{ 164.374 + return ((domain->state & DOMFLAGS_SHUTDOWN) == DOMFLAGS_SHUTDOWN) 164.375 + && (((domain->state >> DOMFLAGS_SHUTDOWNSHIFT) 164.376 + & DOMFLAGS_SHUTDOWNMASK) == SHUTDOWN_crash); 164.377 +} 164.378 + 164.379 +unsigned int xenstat_domain_shutdown(xenstat_domain * domain) 164.380 +{ 164.381 + return ((domain->state & DOMFLAGS_SHUTDOWN) == DOMFLAGS_SHUTDOWN) 164.382 + && (((domain->state >> DOMFLAGS_SHUTDOWNSHIFT) 164.383 + & DOMFLAGS_SHUTDOWNMASK) != SHUTDOWN_crash); 164.384 +} 164.385 + 164.386 +unsigned int xenstat_domain_paused(xenstat_domain * domain) 164.387 +{ 164.388 + return (domain->state & DOMFLAGS_PAUSED) == DOMFLAGS_PAUSED; 164.389 +} 164.390 + 164.391 +unsigned int xenstat_domain_blocked(xenstat_domain * domain) 164.392 +{ 164.393 + return (domain->state & DOMFLAGS_BLOCKED) == DOMFLAGS_BLOCKED; 164.394 +} 164.395 + 164.396 +unsigned int xenstat_domain_running(xenstat_domain * domain) 164.397 +{ 164.398 + return (domain->state & DOMFLAGS_RUNNING) == DOMFLAGS_RUNNING; 164.399 +} 164.400 + 164.401 +/* Get the number of networks for a given domain */ 164.402 +unsigned int xenstat_domain_num_networks(xenstat_domain * domain) 164.403 +{ 164.404 + return domain->num_networks; 164.405 +} 164.406 + 164.407 +/* Get the network handle to obtain network stats */ 164.408 +xenstat_network *xenstat_domain_network(xenstat_domain * domain, 164.409 + unsigned int network) 164.410 +{ 164.411 + if (domain->networks && 0 <= network && network < domain->num_networks) 164.412 + return &(domain->networks[network]); 164.413 + return NULL; 164.414 +} 164.415 + 164.416 +/* 164.417 + * VCPU functions 164.418 + */ 164.419 +/* Collect information about VCPUs */ 164.420 +static int xenstat_collect_vcpus(xenstat_handle * handle, xenstat_node * node) 164.421 +{ 164.422 + unsigned int i, vcpu; 164.423 + /* Fill in VCPU information */ 164.424 + for (i = 0; i < node->num_domains; i++) { 164.425 + node->domains[i].vcpus = malloc(node->domains[i].num_vcpus 164.426 + * sizeof(xenstat_vcpu)); 164.427 + if (node->domains[i].vcpus == NULL) 164.428 + return 0; 164.429 + 164.430 + for (vcpu = 0; vcpu < node->domains[i].num_vcpus; vcpu++) { 164.431 + /* FIXME: need to be using a more efficient mechanism*/ 164.432 + long long vcpu_time; 164.433 + vcpu_time = 164.434 + xi_get_vcpu_usage(handle->xihandle, 164.435 + node->domains[i].id, 164.436 + vcpu); 164.437 + if (vcpu_time < 0) 164.438 + return 0; 164.439 + node->domains[i].vcpus[vcpu].ns = vcpu_time; 164.440 + } 164.441 + } 164.442 + return 1; 164.443 +} 164.444 + 164.445 +/* Free VCPU information */ 164.446 +static void xenstat_free_vcpus(xenstat_node * node) 164.447 +{ 164.448 + unsigned int i; 164.449 + for (i = 0; i < node->num_domains; i++) 164.450 + free(node->domains[i].vcpus); 164.451 +} 164.452 + 164.453 +/* Free VCPU information in handle - nothing to do */ 164.454 +static void xenstat_uninit_vcpus(xenstat_handle * handle) 164.455 +{ 164.456 +} 164.457 + 164.458 +/* Get VCPU usage */ 164.459 +unsigned long long xenstat_vcpu_ns(xenstat_vcpu * vcpu) 164.460 +{ 164.461 + return vcpu->ns; 164.462 +} 164.463 + 164.464 +/* 164.465 + * Network functions 164.466 + */ 164.467 + 164.468 +/* Expected format of /proc/net/dev */ 164.469 +static const char PROCNETDEV_HEADER[] = 164.470 + "Inter-| Receive |" 164.471 + " Transmit\n" 164.472 + " face |bytes packets errs drop fifo frame compressed multicast|" 164.473 + "bytes packets errs drop fifo colls carrier compressed\n"; 164.474 + 164.475 +/* Collect information about networks */ 164.476 +static int xenstat_collect_networks(xenstat_handle * handle, 164.477 + xenstat_node * node) 164.478 +{ 164.479 + /* Open and validate /proc/net/dev if we haven't already */ 164.480 + if (handle->procnetdev == NULL) { 164.481 + char header[sizeof(PROCNETDEV_HEADER)]; 164.482 + handle->procnetdev = fopen("/proc/net/dev", "r"); 164.483 + if (handle->procnetdev == NULL) { 164.484 + perror("Error opening /proc/net/dev"); 164.485 + return 1; 164.486 + } 164.487 + 164.488 + /* Validate the format of /proc/net/dev */ 164.489 + if (fread(header, sizeof(PROCNETDEV_HEADER) - 1, 1, 164.490 + handle->procnetdev) != 1) { 164.491 + perror("Error reading /proc/net/dev header"); 164.492 + return 1; 164.493 + } 164.494 + header[sizeof(PROCNETDEV_HEADER) - 1] = '\0'; 164.495 + if (strcmp(header, PROCNETDEV_HEADER) != 0) { 164.496 + fprintf(stderr, 164.497 + "Unexpected /proc/net/dev format\n"); 164.498 + return 1; 164.499 + } 164.500 + } 164.501 + 164.502 + /* Fill in networks */ 164.503 + /* FIXME: optimize this */ 164.504 + fseek(handle->procnetdev, sizeof(PROCNETDEV_HEADER) - 1, SEEK_SET); 164.505 + while (1) { 164.506 + xenstat_domain *domain; 164.507 + xenstat_network net; 164.508 + unsigned int domid; 164.509 + int ret = fscanf(handle->procnetdev, 164.510 + "vif%u.%u:%llu%llu%llu%llu%*u%*u%*u%*u" 164.511 + "%llu%llu%llu%llu%*u%*u%*u%*u", 164.512 + &domid, &net.id, 164.513 + &net.tbytes, &net.tpackets, &net.terrs, 164.514 + &net.tdrop, 164.515 + &net.rbytes, &net.rpackets, &net.rerrs, 164.516 + &net.rdrop); 164.517 + if (ret == EOF) 164.518 + break; 164.519 + if (ret != 10) { 164.520 + unsigned int c; 164.521 + do { 164.522 + c = fgetc(handle->procnetdev); 164.523 + } while (c != '\n' && c != EOF); 164.524 + if (c == EOF) 164.525 + break; 164.526 + continue; 164.527 + } 164.528 + 164.529 + /* FIXME: this does a search for the domid */ 164.530 + domain = xenstat_node_domain(node, domid); 164.531 + if (domain == NULL) { 164.532 + fprintf(stderr, 164.533 + "Found interface vif%u.%u but domain %u" 164.534 + " does not exist.\n", domid, net.id, 164.535 + domid); 164.536 + continue; 164.537 + } 164.538 + if (domain->networks == NULL) { 164.539 + domain->num_networks = 1; 164.540 + domain->networks = malloc(sizeof(xenstat_network)); 164.541 + } else { 164.542 + domain->num_networks++; 164.543 + domain->networks = 164.544 + realloc(domain->networks, 164.545 + domain->num_networks * 164.546 + sizeof(xenstat_network)); 164.547 + } 164.548 + if (domain->networks == NULL) 164.549 + return 1; 164.550 + domain->networks[domain->num_networks - 1] = net; 164.551 + } 164.552 + 164.553 + return 1; 164.554 +} 164.555 + 164.556 +/* Free network information */ 164.557 +static void xenstat_free_networks(xenstat_node * node) 164.558 +{ 164.559 + unsigned int i; 164.560 + for (i = 0; i < node->num_domains; i++) 164.561 + free(node->domains[i].networks); 164.562 +} 164.563 + 164.564 +/* Free network information in handle */ 164.565 +static void xenstat_uninit_networks(xenstat_handle * handle) 164.566 +{ 164.567 + if(handle->procnetdev) 164.568 + fclose(handle->procnetdev); 164.569 +} 164.570 + 164.571 +/* Get the network ID */ 164.572 +unsigned int xenstat_network_id(xenstat_network * network) 164.573 +{ 164.574 + return network->id; 164.575 +} 164.576 + 164.577 +/* Get the number of receive bytes */ 164.578 +unsigned long long xenstat_network_rbytes(xenstat_network * network) 164.579 +{ 164.580 + return network->rbytes; 164.581 +} 164.582 + 164.583 +/* Get the number of receive packets */ 164.584 +unsigned long long xenstat_network_rpackets(xenstat_network * network) 164.585 +{ 164.586 + return network->rpackets; 164.587 +} 164.588 + 164.589 +/* Get the number of receive errors */ 164.590 +unsigned long long xenstat_network_rerrs(xenstat_network * network) 164.591 +{ 164.592 + return network->rerrs; 164.593 +} 164.594 + 164.595 +/* Get the number of receive drops */ 164.596 +unsigned long long xenstat_network_rdrop(xenstat_network * network) 164.597 +{ 164.598 + return network->rdrop; 164.599 +} 164.600 + 164.601 +/* Get the number of transmit bytes */ 164.602 +unsigned long long xenstat_network_tbytes(xenstat_network * network) 164.603 +{ 164.604 + return network->tbytes; 164.605 +} 164.606 + 164.607 +/* Get the number of transmit packets */ 164.608 +unsigned long long xenstat_network_tpackets(xenstat_network * network) 164.609 +{ 164.610 + return network->tpackets; 164.611 +} 164.612 + 164.613 +/* Get the number of transmit errors */ 164.614 +unsigned long long xenstat_network_terrs(xenstat_network * network) 164.615 +{ 164.616 + return network->terrs; 164.617 +} 164.618 + 164.619 +/* Get the number of transmit dropped packets */ 164.620 +unsigned long long xenstat_network_tdrop(xenstat_network * network) 164.621 +{ 164.622 + return network->tdrop; 164.623 +}
165.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 165.2 +++ b/tools/xenstat/libxenstat/src/xenstat.h Mon Aug 22 21:54:28 2005 +0000 165.3 @@ -0,0 +1,148 @@ 165.4 +/* libxenstat: statistics-collection library for Xen 165.5 + * Copyright (C) International Business Machines Corp., 2005 165.6 + * Authors: Josh Triplett <josht@us.ibm.com> 165.7 + * Judy Fischbach <jfisch@us.ibm.com> 165.8 + * David Hendricks <dhendrix@us.ibm.com> 165.9 + * 165.10 + * This library is free software; you can redistribute it and/or 165.11 + * modify it under the terms of the GNU Lesser General Public 165.12 + * License as published by the Free Software Foundation; either 165.13 + * version 2.1 of the License, or (at your option) any later version. 165.14 + * 165.15 + * This library is distributed in the hope that it will be useful, 165.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 165.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 165.18 + * Lesser General Public License for more details. 165.19 + */ 165.20 + 165.21 +/* libxenstat API */ 165.22 + 165.23 +/* Opaque handles */ 165.24 +typedef struct xenstat_handle xenstat_handle; 165.25 +typedef struct xenstat_domain xenstat_domain; 165.26 +typedef struct xenstat_node xenstat_node; 165.27 +typedef struct xenstat_vcpu xenstat_vcpu; 165.28 +typedef struct xenstat_network xenstat_network; 165.29 + 165.30 +/* Initialize the xenstat library. Returns a handle to be used with 165.31 + * subsequent calls to the xenstat library, or NULL if an error occurs. */ 165.32 +xenstat_handle *xenstat_init(); 165.33 + 165.34 +/* Release the handle to libxc, free resources, etc. */ 165.35 +void xenstat_uninit(xenstat_handle * handle); 165.36 + 165.37 +/* Get all available information about a node */ 165.38 +#define XENSTAT_VCPU 0x1 165.39 +#define XENSTAT_NETWORK 0x2 165.40 +#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK) 165.41 +xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags); 165.42 + 165.43 +/* Free the information */ 165.44 +void xenstat_free_node(xenstat_node * node); 165.45 + 165.46 +/* 165.47 + * Node functions - extract information from a xenstat_node 165.48 + */ 165.49 + 165.50 +/* Get information about the domain with the given domain ID */ 165.51 +xenstat_domain *xenstat_node_domain(xenstat_node * node, 165.52 + unsigned int domid); 165.53 + 165.54 +/* Get the domain with the given index; used to loop over all domains. */ 165.55 +xenstat_domain *xenstat_node_domain_by_index(xenstat_node * node, 165.56 + unsigned index); 165.57 + 165.58 +/* Get amount of total memory on a node */ 165.59 +unsigned long long xenstat_node_tot_mem(xenstat_node * node); 165.60 + 165.61 +/* Get amount of free memory on a node */ 165.62 +unsigned long long xenstat_node_free_mem(xenstat_node * node); 165.63 + 165.64 +/* Find the number of domains existing on a node */ 165.65 +unsigned int xenstat_node_num_domains(xenstat_node * node); 165.66 + 165.67 +/* Find the number of CPUs existing on a node */ 165.68 +unsigned int xenstat_node_num_cpus(xenstat_node * node); 165.69 + 165.70 +/* Get information about the CPU speed */ 165.71 +unsigned long long xenstat_node_cpu_hz(xenstat_node * node); 165.72 + 165.73 +/* 165.74 + * Domain functions - extract information from a xenstat_domain 165.75 + */ 165.76 + 165.77 +/* Get the domain ID for this domain */ 165.78 +unsigned xenstat_domain_id(xenstat_domain * domain); 165.79 + 165.80 +/* Get information about how much CPU time has been used */ 165.81 +unsigned long long xenstat_domain_cpu_ns(xenstat_domain * domain); 165.82 + 165.83 +/* Find the number of VCPUs allocated to a domain */ 165.84 +unsigned int xenstat_domain_num_vcpus(xenstat_domain * domain); 165.85 + 165.86 +/* Get the VCPU handle to obtain VCPU stats */ 165.87 +xenstat_vcpu *xenstat_domain_vcpu(xenstat_domain * domain, 165.88 + unsigned int vcpu); 165.89 + 165.90 +/* Find the current memory reservation for this domain */ 165.91 +unsigned long long xenstat_domain_cur_mem(xenstat_domain * domain); 165.92 + 165.93 +/* Find the maximum memory reservation for this domain */ 165.94 +unsigned long long xenstat_domain_max_mem(xenstat_domain * domain); 165.95 + 165.96 +/* Find the domain's SSID */ 165.97 +unsigned int xenstat_domain_ssid(xenstat_domain * domain); 165.98 + 165.99 +/* Get domain states */ 165.100 +unsigned int xenstat_domain_dying(xenstat_domain * domain); 165.101 +unsigned int xenstat_domain_crashed(xenstat_domain * domain); 165.102 +unsigned int xenstat_domain_shutdown(xenstat_domain * domain); 165.103 +unsigned int xenstat_domain_paused(xenstat_domain * domain); 165.104 +unsigned int xenstat_domain_blocked(xenstat_domain * domain); 165.105 +unsigned int xenstat_domain_running(xenstat_domain * domain); 165.106 + 165.107 +/* Get the number of networks for a given domain */ 165.108 +unsigned int xenstat_domain_num_networks(xenstat_domain *); 165.109 + 165.110 +/* Get the network handle to obtain network stats */ 165.111 +xenstat_network *xenstat_domain_network(xenstat_domain * domain, 165.112 + unsigned int network); 165.113 + 165.114 +/* 165.115 + * VCPU functions - extract information from a xenstat_vcpu 165.116 + */ 165.117 + 165.118 +/* Get VCPU usage */ 165.119 +unsigned long long xenstat_vcpu_ns(xenstat_vcpu * vcpu); 165.120 + 165.121 + 165.122 +/* 165.123 + * Network functions - extract information from a xenstat_network 165.124 + */ 165.125 + 165.126 +/* Get the ID for this network */ 165.127 +unsigned int xenstat_network_id(xenstat_network * network); 165.128 + 165.129 +/* Get the number of receive bytes for this network */ 165.130 +unsigned long long xenstat_network_rbytes(xenstat_network * network); 165.131 + 165.132 +/* Get the number of receive packets for this network */ 165.133 +unsigned long long xenstat_network_rpackets(xenstat_network * network); 165.134 + 165.135 +/* Get the number of receive errors for this network */ 165.136 +unsigned long long xenstat_network_rerrs(xenstat_network * network); 165.137 + 165.138 +/* Get the number of receive drops for this network */ 165.139 +unsigned long long xenstat_network_rdrop(xenstat_network * network); 165.140 + 165.141 +/* Get the number of transmit bytes for this network */ 165.142 +unsigned long long xenstat_network_tbytes(xenstat_network * network); 165.143 + 165.144 +/* Get the number of transmit packets for this network */ 165.145 +unsigned long long xenstat_network_tpackets(xenstat_network * network); 165.146 + 165.147 +/* Get the number of transmit errors for this network */ 165.148 +unsigned long long xenstat_network_terrs(xenstat_network * network); 165.149 + 165.150 +/* Get the number of transmit drops for this network */ 165.151 +unsigned long long xenstat_network_tdrop(xenstat_network * network);
166.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 166.2 +++ b/tools/xenstat/xentop/Makefile Mon Aug 22 21:54:28 2005 +0000 166.3 @@ -0,0 +1,44 @@ 166.4 +# Copyright (C) International Business Machines Corp., 2005 166.5 +# Author: Josh Triplett <josht@us.ibm.com> 166.6 +# 166.7 +# This program is free software; you can redistribute it and/or modify 166.8 +# it under the terms of the GNU General Public License as published by 166.9 +# the Free Software Foundation; under version 2 of the License. 166.10 +# 166.11 +# This program is distributed in the hope that it will be useful, 166.12 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 166.13 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 166.14 +# GNU General Public License for more details. 166.15 + 166.16 +XEN_ROOT=../../.. 166.17 +include $(XEN_ROOT)/tools/Rules.mk 166.18 + 166.19 +ifneq ($(XENSTAT_XENTOP),y) 166.20 +all install xentop: 166.21 +else 166.22 + 166.23 +INSTALL = install 166.24 +INSTALL_PROG = $(INSTALL) -m0755 -D 166.25 +INSTALL_DATA = $(INSTALL) -m0644 -D 166.26 + 166.27 +prefix=/usr 166.28 +mandir=$(prefix)/share/man 166.29 +man1dir=$(mandir)/man1 166.30 +sbindir=$(prefix)/sbin 166.31 + 166.32 +CFLAGS += -DGCC_PRINTF -Wall -Werror -I$(XEN_LIBXENSTAT) 166.33 +LDFLAGS += -L$(XEN_LIBXENSTAT) 166.34 +LDLIBS += -lxenstat -lcurses 166.35 + 166.36 +all: xentop 166.37 + 166.38 +xentop: xentop.o 166.39 + 166.40 +install: xentop xentop.1 166.41 + $(INSTALL_PROG) xentop $(DESTDIR)$(sbindir)/xentop 166.42 + $(INSTALL_DATA) xentop.1 $(DESTDIR)$(man1dir)/xentop.1 166.43 + 166.44 +endif 166.45 + 166.46 +clean: 166.47 + rm -f xentop xentop.o
167.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 167.2 +++ b/tools/xenstat/xentop/TODO Mon Aug 22 21:54:28 2005 +0000 167.3 @@ -0,0 +1,34 @@ 167.4 +Display error messages on the help line after bad input at a prompt. 167.5 +Fractional delay times 167.6 +Use prompting to search for domains 167.7 +Better line editing? 167.8 + 167.9 +* Make CPU in % more accurate 167.10 +* Domain total network TX % and RX % 167.11 + 167.12 +Like Top, f feature, field select of domain columns, toggle the display of 167.13 +field by typing the letter associated with field, if displayed it shows in 167.14 +bold and the letter is Capitalized along with a leading asterisk for the 167.15 +field, if not selected for display letter is lowercase, no leading asterisk 167.16 +and field is not bolded. 167.17 + 167.18 +Like Top, ordering of domain columns, o feature Capital letter shifts left, 167.19 +lowercase letter shifts right? 167.20 + 167.21 +Color 167.22 +Full management: pause, destroy, create domains 167.23 + 167.24 +Add support for Virtual Block Devices (vbd) 167.25 + 167.26 +To think about: 167.27 +Support for one than one node display (distributed monitoring 167.28 +from any node of all other nodes in a cluster) 167.29 +Bottom line option (Switch node, Search node [tab completion?]) 167.30 + 167.31 +Capture/Logging of resource information generated during a time interval. 167.32 +-b batch mode dump snapshots to standard output (used with -n) 167.33 +-n number of iterations to dump to standard output (unlimited if not specified) 167.34 +-d monitor DomIDs as -dD1,-dD2 or -dD1,D2... 167.35 + Monitor only domains with specified domain IDs 167.36 +-m monitor nodeIDs as -mN1,-mN2 or -mN1,N2... 167.37 + Monitor only domains with specified node IDs
168.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 168.2 +++ b/tools/xenstat/xentop/xentop.1 Mon Aug 22 21:54:28 2005 +0000 168.3 @@ -0,0 +1,88 @@ 168.4 +.\" Copyright (C) International Business Machines Corp., 2005 168.5 +.\" Author: Josh Triplett <josht@us.ibm.com> 168.6 +.\" 168.7 +.\" This program is free software; you can redistribute it and/or modify 168.8 +.\" it under the terms of the GNU General Public License as published by 168.9 +.\" the Free Software Foundation; under version 2 of the License. 168.10 +.\" 168.11 +.\" This program is distributed in the hope that it will be useful, 168.12 +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of 168.13 +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 168.14 +.\" GNU General Public License for more details. 168.15 +.\" 168.16 +.\" You should have received a copy of the GNU General Public License 168.17 +.\" along with this program; if not, write to the Free Software 168.18 +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 168.19 +.TH xentop 1 "August 2005" 168.20 +.SH NAME 168.21 +\fBxentop\fR \- displays real-time information about a Xen system and domains 168.22 + 168.23 +.SH SYNOPSIS 168.24 +.B xentop 168.25 +[\fB\-h\fR] 168.26 +[\fB\-V\fR] 168.27 +[\fB\-d\fRSECONDS] 168.28 +[\fB\-n\fR] 168.29 +[\fB\-r\fR] 168.30 +[\fB\-v\fR] 168.31 + 168.32 +.SH DESCRIPTION 168.33 +\fBxentop\fR displays information about the Xen system and domains, in a 168.34 +continually-updating manner. Command-line options and interactive commands 168.35 +can change the detail and format of the information displayed by \fBxentop\fR. 168.36 + 168.37 +.SH OPTIONS 168.38 +.TP 168.39 +\fB\-h\fR, \fB\-\-help\fR 168.40 +display help and exit 168.41 +.TP 168.42 +\fB\-V\fR, \fB\-\-version\fR 168.43 +output version information and exit 168.44 +.TP 168.45 +\fB\-d\fR, \fB\-\-delay\fR=\fISECONDS\fR 168.46 +seconds between updates (default 1) 168.47 +.TP 168.48 +\fB\-n\fR, \fB\-\-networks\fR 168.49 +output network information 168.50 +.TP 168.51 +\fB\-r\fR, \fB\-\-repeat\-header\fR 168.52 +repeat table header before each domain 168.53 +.TP 168.54 +\fB\-v\fR, \fB\-\-vcpus\fR 168.55 +output VCPU data 168.56 + 168.57 +.SH "INTERACTIVE COMMANDS" 168.58 +All interactive commands are case-insensitive. 168.59 +.TP 168.60 +.B D 168.61 +set delay between updates 168.62 +.TP 168.63 +.B N 168.64 +toggle display of network information 168.65 +.TP 168.66 +.B Q, Esc 168.67 +quit 168.68 +.TP 168.69 +.B R 168.70 +toggle table header before each domain 168.71 +.TP 168.72 +.B S 168.73 +cycle sort order 168.74 +.TP 168.75 +.B V 168.76 +toggle display of VCPU information 168.77 +.TP 168.78 +.B Arrows 168.79 +scroll domain display 168.80 + 168.81 +.SH AUTHORS 168.82 +Written by Judy Fischbach, David Hendricks, and Josh Triplett 168.83 + 168.84 +.SH "REPORTING BUGS" 168.85 +Report bugs to <dsteklof@us.ibm.com>. 168.86 + 168.87 +.SH COPYRIGHT 168.88 +Copyright \(co 2005 International Business Machines Corp 168.89 +.br 168.90 +This is free software; see the source for copying conditions. There is NO 168.91 +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
169.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 169.2 +++ b/tools/xenstat/xentop/xentop.c Mon Aug 22 21:54:28 2005 +0000 169.3 @@ -0,0 +1,876 @@ 169.4 +/* 169.5 + * Copyright (C) International Business Machines Corp., 2005 169.6 + * Author(s): Judy Fischbach <jfisch@us.ibm.com> 169.7 + * David Hendricks <dhendrix@us.ibm.com> 169.8 + * Josh Triplett <josht@us.ibm.com> 169.9 + * based on code from Anthony Liguori <aliguori@us.ibm.com> 169.10 + * 169.11 + * This program is free software; you can redistribute it and/or modify 169.12 + * it under the terms of the GNU General Public License as published by 169.13 + * the Free Software Foundation; under version 2 of the License. 169.14 + * 169.15 + * This program is distributed in the hope that it will be useful, 169.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 169.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 169.18 + * GNU General Public License for more details. 169.19 + * 169.20 + * You should have received a copy of the GNU General Public License 169.21 + * along with this program; if not, write to the Free Software 169.22 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 169.23 + */ 169.24 +#include <curses.h> 169.25 +#include <ctype.h> 169.26 +#include <errno.h> 169.27 +#include <stdio.h> 169.28 +#include <stdlib.h> 169.29 +#include <string.h> 169.30 +#include <sys/time.h> 169.31 +#include <time.h> 169.32 +#include <unistd.h> 169.33 + 169.34 +#include <xenstat.h> 169.35 + 169.36 +#define XENTOP_VERSION "1.0" 169.37 + 169.38 +#define XENTOP_DISCLAIMER \ 169.39 +"Copyright (C) 2005 International Business Machines Corp\n"\ 169.40 +"This is free software; see the source for copying conditions.There is NO\n"\ 169.41 +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" 169.42 +#define XENTOP_BUGSTO "Report bugs to <dsteklof@us.ibm.com>.\n" 169.43 + 169.44 +#define _GNU_SOURCE 169.45 +#include <getopt.h> 169.46 + 169.47 +#if !defined(__GNUC__) && !defined(__GNUG__) 169.48 +#define __attribute__(arg) /* empty */ 169.49 +#endif 169.50 + 169.51 +#define KEY_ESCAPE '\x1B' 169.52 + 169.53 +/* 169.54 + * Function prototypes 169.55 + */ 169.56 +/* Utility functions */ 169.57 +static void usage(const char *); 169.58 +static void version(void); 169.59 +static void cleanup(void); 169.60 +static void fail(const char *); 169.61 +static int current_row(void); 169.62 +static int lines(void); 169.63 +static void print(const char *, ...) __attribute__((format(printf,1,2))); 169.64 +static void attr_addstr(int attr, const char *str); 169.65 +static void set_delay(char *value); 169.66 +static void set_prompt(char *new_prompt, void (*func)(char *)); 169.67 +static int handle_key(int); 169.68 +static int compare(unsigned long long, unsigned long long); 169.69 +static int compare_domains(xenstat_domain **, xenstat_domain **); 169.70 +static unsigned long long tot_net_bytes( xenstat_domain *, int); 169.71 + 169.72 +/* Field functions */ 169.73 +static int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2); 169.74 +static void print_domid(xenstat_domain *domain); 169.75 +static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2); 169.76 +static void print_state(xenstat_domain *domain); 169.77 +static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2); 169.78 +static void print_cpu(xenstat_domain *domain); 169.79 +static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2); 169.80 +static void print_cpu_pct(xenstat_domain *domain); 169.81 +static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2); 169.82 +static void print_mem(xenstat_domain *domain); 169.83 +static void print_mem_pct(xenstat_domain *domain); 169.84 +static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2); 169.85 +static void print_maxmem(xenstat_domain *domain); 169.86 +static void print_max_pct(xenstat_domain *domain); 169.87 +static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2); 169.88 +static void print_vcpus(xenstat_domain *domain); 169.89 +static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2); 169.90 +static void print_nets(xenstat_domain *domain); 169.91 +static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2); 169.92 +static void print_net_tx(xenstat_domain *domain); 169.93 +static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2); 169.94 +static void print_net_rx(xenstat_domain *domain); 169.95 +static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2); 169.96 +static void print_ssid(xenstat_domain *domain); 169.97 + 169.98 +/* Section printing functions */ 169.99 +static void do_summary(void); 169.100 +static void do_header(void); 169.101 +static void do_bottom_line(void); 169.102 +static void do_domain(xenstat_domain *); 169.103 +static void do_vcpu(xenstat_domain *); 169.104 +static void do_network(xenstat_domain *); 169.105 +static void top(void); 169.106 + 169.107 +/* Field types */ 169.108 +typedef enum field_id { 169.109 + FIELD_DOMID, 169.110 + FIELD_STATE, 169.111 + FIELD_CPU, 169.112 + FIELD_CPU_PCT, 169.113 + FIELD_MEM, 169.114 + FIELD_MEM_PCT, 169.115 + FIELD_MAXMEM, 169.116 + FIELD_MAX_PCT, 169.117 + FIELD_VCPUS, 169.118 + FIELD_NETS, 169.119 + FIELD_NET_TX, 169.120 + FIELD_NET_RX, 169.121 + FIELD_SSID 169.122 +} field_id; 169.123 + 169.124 +typedef struct field { 169.125 + field_id num; 169.126 + const char *header; 169.127 + unsigned int default_width; 169.128 + int (*compare)(xenstat_domain *domain1, xenstat_domain *domain2); 169.129 + void (*print)(xenstat_domain *domain); 169.130 +} field; 169.131 + 169.132 +field fields[] = { 169.133 + { FIELD_DOMID, "DOMID", 5, compare_domid, print_domid }, 169.134 + { FIELD_STATE, "STATE", 6, compare_state, print_state }, 169.135 + { FIELD_CPU, "CPU(sec)", 10, compare_cpu, print_cpu }, 169.136 + { FIELD_CPU_PCT, "CPU(%)", 6, compare_cpu_pct, print_cpu_pct }, 169.137 + { FIELD_MEM, "MEM(k)", 10, compare_mem, print_mem }, 169.138 + { FIELD_MEM_PCT, "MEM(%)", 6, compare_mem, print_mem_pct }, 169.139 + { FIELD_MAXMEM, "MAXMEM(k)", 10, compare_maxmem, print_maxmem }, 169.140 + { FIELD_MAX_PCT, "MAXMEM(%)", 9, compare_maxmem, print_max_pct }, 169.141 + { FIELD_VCPUS, "VCPUS", 5, compare_vcpus, print_vcpus }, 169.142 + { FIELD_NETS, "NETS", 4, compare_nets, print_nets }, 169.143 + { FIELD_NET_TX, "NETTX(k)", 8, compare_net_tx, print_net_tx }, 169.144 + { FIELD_NET_RX, "NETRX(k)", 8, compare_net_rx, print_net_rx }, 169.145 + { FIELD_SSID, "SSID", 4, compare_ssid, print_ssid } 169.146 +}; 169.147 + 169.148 +const unsigned int NUM_FIELDS = sizeof(fields)/sizeof(field); 169.149 + 169.150 +/* Globals */ 169.151 +struct timeval curtime, oldtime; 169.152 +xenstat_handle *xhandle = NULL; 169.153 +xenstat_node *prev_node = NULL; 169.154 +xenstat_node *cur_node = NULL; 169.155 +field_id sort_field = FIELD_DOMID; 169.156 +unsigned int first_domain_index = 0; 169.157 +unsigned int delay = 1; 169.158 +int show_vcpus = 0; 169.159 +int show_networks = 0; 169.160 +int repeat_header = 0; 169.161 +#define PROMPT_VAL_LEN 80 169.162 +char *prompt = NULL; 169.163 +char prompt_val[PROMPT_VAL_LEN]; 169.164 +int prompt_val_len = 0; 169.165 +void (*prompt_complete_func)(char *); 169.166 + 169.167 +/* 169.168 + * Function definitions 169.169 + */ 169.170 + 169.171 +/* Utility functions */ 169.172 + 169.173 +/* Print usage message, using given program name */ 169.174 +static void usage(const char *program) 169.175 +{ 169.176 + printf("Usage: %s [OPTION]\n" 169.177 + "Displays ongoing information about xen vm resources \n\n" 169.178 + "-h, --help display this help and exit\n" 169.179 + "-V, --version output version information and exit\n" 169.180 + "-d, --delay=SECONDS seconds between updates (default 1)\n" 169.181 + "-n, --networks output vif network data\n" 169.182 + "-r, --repeat-header repeat table header before each domain\n" 169.183 + "-v, --vcpus output vcpu data\n" 169.184 + "\n" XENTOP_BUGSTO, 169.185 + program); 169.186 + return; 169.187 +} 169.188 + 169.189 +/* Print program version information */ 169.190 +static void version(void) 169.191 +{ 169.192 + printf("xentop " XENTOP_VERSION "\n" 169.193 + "Written by Judy Fischbach, David Hendricks, Josh Triplett\n" 169.194 + "\n" XENTOP_DISCLAIMER); 169.195 +} 169.196 + 169.197 +/* Clean up any open resources */ 169.198 +static void cleanup(void) 169.199 +{ 169.200 + if(!isendwin()) 169.201 + endwin(); 169.202 + if(prev_node != NULL) 169.203 + xenstat_free_node(prev_node); 169.204 + if(cur_node != NULL) 169.205 + xenstat_free_node(cur_node); 169.206 + if(xhandle != NULL) 169.207 + xenstat_uninit(xhandle); 169.208 +} 169.209 + 169.210 +/* Display the given message and gracefully exit */ 169.211 +static void fail(const char *str) 169.212 +{ 169.213 + if(!isendwin()) 169.214 + endwin(); 169.215 + fprintf(stderr, str); 169.216 + exit(1); 169.217 +} 169.218 + 169.219 +/* Return the row containing the cursor. */ 169.220 +static int current_row(void) 169.221 +{ 169.222 + int y, x; 169.223 + getyx(stdscr, y, x); 169.224 + return y; 169.225 +} 169.226 + 169.227 +/* Return the number of lines on the screen. */ 169.228 +static int lines(void) 169.229 +{ 169.230 + int y, x; 169.231 + getmaxyx(stdscr, y, x); 169.232 + return y; 169.233 +} 169.234 + 169.235 +/* printf-style print function which calls printw, but only if the cursor is 169.236 + * not on the last line. */ 169.237 +static void print(const char *fmt, ...) 169.238 +{ 169.239 + va_list args; 169.240 + 169.241 + if(current_row() < lines()-1) { 169.242 + va_start(args, fmt); 169.243 + vw_printw(stdscr, fmt, args); 169.244 + va_end(args); 169.245 + } 169.246 +} 169.247 + 169.248 +/* Print a string with the given attributes set. */ 169.249 +static void attr_addstr(int attr, const char *str) 169.250 +{ 169.251 + attron(attr); 169.252 + addstr(str); 169.253 + attroff(attr); 169.254 +} 169.255 + 169.256 +/* Handle setting the delay from the user-supplied value in prompt_val */ 169.257 +static void set_delay(char *value) 169.258 +{ 169.259 + int new_delay; 169.260 + new_delay = atoi(prompt_val); 169.261 + if(new_delay > 0) 169.262 + delay = new_delay; 169.263 +} 169.264 + 169.265 +/* Enable prompting mode with the given prompt string; call the given function 169.266 + * when a value is available. */ 169.267 +static void set_prompt(char *new_prompt, void (*func)(char *)) 169.268 +{ 169.269 + prompt = new_prompt; 169.270 + prompt_val[0] = '\0'; 169.271 + prompt_val_len = 0; 169.272 + prompt_complete_func = func; 169.273 +} 169.274 + 169.275 +/* Handle user input, return 0 if the program should quit, or 1 if not */ 169.276 +static int handle_key(int ch) 169.277 +{ 169.278 + if(prompt == NULL) { 169.279 + /* Not prompting for input; handle interactive commands */ 169.280 + switch(ch) { 169.281 + case 'n': case 'N': 169.282 + show_networks ^= 1; 169.283 + break; 169.284 + case 'r': case 'R': 169.285 + repeat_header ^= 1; 169.286 + break; 169.287 + case 's': case 'S': 169.288 + sort_field = (sort_field + 1) % NUM_FIELDS; 169.289 + break; 169.290 + case 'v': case 'V': 169.291 + show_vcpus ^= 1; 169.292 + break; 169.293 + case KEY_DOWN: 169.294 + first_domain_index++; 169.295 + break; 169.296 + case KEY_UP: 169.297 + if(first_domain_index > 0) 169.298 + first_domain_index--; 169.299 + break; 169.300 + case 'd': case 'D': 169.301 + set_prompt("Delay(sec)", set_delay); 169.302 + break; 169.303 + case 'q': case 'Q': case KEY_ESCAPE: 169.304 + return 0; 169.305 + } 169.306 + } else { 169.307 + /* Prompting for input; handle line editing */ 169.308 + switch(ch) { 169.309 + case '\r': 169.310 + prompt_complete_func(prompt_val); 169.311 + set_prompt(NULL, NULL); 169.312 + break; 169.313 + case KEY_ESCAPE: 169.314 + set_prompt(NULL, NULL); 169.315 + break; 169.316 + case KEY_BACKSPACE: 169.317 + if(prompt_val_len > 0) 169.318 + prompt_val[--prompt_val_len] = '\0'; 169.319 + default: 169.320 + if((prompt_val_len+1) < PROMPT_VAL_LEN 169.321 + && isprint(ch)) { 169.322 + prompt_val[prompt_val_len++] = (char)ch; 169.323 + prompt_val[prompt_val_len] = '\0'; 169.324 + } 169.325 + } 169.326 + } 169.327 + 169.328 + return 1; 169.329 +} 169.330 + 169.331 +/* Compares two integers, returning -1,0,1 for <,=,> */ 169.332 +static int compare(unsigned long long i1, unsigned long long i2) 169.333 +{ 169.334 + if(i1 < i2) 169.335 + return -1; 169.336 + if(i1 > i2) 169.337 + return 1; 169.338 + return 0; 169.339 +} 169.340 + 169.341 +/* Comparison function for use with qsort. Compares two domains using the 169.342 + * current sort field. */ 169.343 +static int compare_domains(xenstat_domain **domain1, xenstat_domain **domain2) 169.344 +{ 169.345 + return fields[sort_field].compare(*domain1, *domain2); 169.346 +} 169.347 + 169.348 +/* Field functions */ 169.349 + 169.350 +/* Compares domain ids of two domains, returning -1,0,1 for <,=,> */ 169.351 +int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2) 169.352 +{ 169.353 + return compare(xenstat_domain_id(domain1), xenstat_domain_id(domain2)); 169.354 +} 169.355 + 169.356 +/* Prints domain identification number */ 169.357 +void print_domid(xenstat_domain *domain) 169.358 +{ 169.359 + print("%5u", xenstat_domain_id(domain)); 169.360 +} 169.361 + 169.362 +struct { 169.363 + unsigned int (*get)(xenstat_domain *); 169.364 + char ch; 169.365 +} state_funcs[] = { 169.366 + { xenstat_domain_dying, 'd' }, 169.367 + { xenstat_domain_shutdown, 's' }, 169.368 + { xenstat_domain_blocked, 'b' }, 169.369 + { xenstat_domain_crashed, 'c' }, 169.370 + { xenstat_domain_paused, 'p' }, 169.371 + { xenstat_domain_running, 'r' } 169.372 +}; 169.373 +const unsigned int NUM_STATES = sizeof(state_funcs)/sizeof(*state_funcs); 169.374 + 169.375 +/* Compare states of two domains, returning -1,0,1 for <,=,> */ 169.376 +static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2) 169.377 +{ 169.378 + unsigned int i, d1s, d2s; 169.379 + for(i = 0; i < NUM_STATES; i++) { 169.380 + d1s = state_funcs[i].get(domain1); 169.381 + d2s = state_funcs[i].get(domain2); 169.382 + if(d1s && !d2s) 169.383 + return -1; 169.384 + if(d2s && !d1s) 169.385 + return 1; 169.386 + } 169.387 + return 0; 169.388 +} 169.389 + 169.390 +/* Prints domain state in abbreviated letter format */ 169.391 +static void print_state(xenstat_domain *domain) 169.392 +{ 169.393 + unsigned int i; 169.394 + for(i = 0; i < NUM_STATES; i++) 169.395 + print("%c", state_funcs[i].get(domain) ? state_funcs[i].ch 169.396 + : '-'); 169.397 +} 169.398 + 169.399 +/* Compares cpu usage of two domains, returning -1,0,1 for <,=,> */ 169.400 +static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2) 169.401 +{ 169.402 + return -compare(xenstat_domain_cpu_ns(domain1), 169.403 + xenstat_domain_cpu_ns(domain2)); 169.404 +} 169.405 + 169.406 +/* Prints domain cpu usage in seconds */ 169.407 +static void print_cpu(xenstat_domain *domain) 169.408 +{ 169.409 + print("%10llu", xenstat_domain_cpu_ns(domain)/1000000000); 169.410 +} 169.411 + 169.412 +/* Computes the CPU percentage used for a specified domain */ 169.413 +static double get_cpu_pct(xenstat_domain *domain) 169.414 +{ 169.415 + xenstat_domain *old_domain; 169.416 + double us_elapsed; 169.417 + 169.418 + /* Can't calculate CPU percentage without a previous sample. */ 169.419 + if(prev_node == NULL) 169.420 + return 0.0; 169.421 + 169.422 + old_domain = xenstat_node_domain(prev_node, xenstat_domain_id(domain)); 169.423 + if(old_domain == NULL) 169.424 + return 0.0; 169.425 + 169.426 + /* Calculate the time elapsed in microseconds */ 169.427 + us_elapsed = ((curtime.tv_sec-oldtime.tv_sec)*1000000.0 169.428 + +(curtime.tv_usec - oldtime.tv_usec)); 169.429 + 169.430 + /* In the following, nanoseconds must be multiplied by 1000.0 to 169.431 + * convert to microseconds, then divided by 100.0 to get a percentage, 169.432 + * resulting in a multiplication by 10.0 */ 169.433 + return ((xenstat_domain_cpu_ns(domain) 169.434 + -xenstat_domain_cpu_ns(old_domain))/10.0)/us_elapsed; 169.435 +} 169.436 + 169.437 +static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2) 169.438 +{ 169.439 + return -compare(get_cpu_pct(domain1), get_cpu_pct(domain2)); 169.440 +} 169.441 + 169.442 +/* Prints cpu percentage statistic */ 169.443 +static void print_cpu_pct(xenstat_domain *domain) 169.444 +{ 169.445 + print("%6.1f", get_cpu_pct(domain)); 169.446 +} 169.447 + 169.448 +/* Compares current memory of two domains, returning -1,0,1 for <,=,> */ 169.449 +static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2) 169.450 +{ 169.451 + return -compare(xenstat_domain_cur_mem(domain1), 169.452 + xenstat_domain_cur_mem(domain2)); 169.453 +} 169.454 + 169.455 +/* Prints current memory statistic */ 169.456 +static void print_mem(xenstat_domain *domain) 169.457 +{ 169.458 + print("%10llu", xenstat_domain_cur_mem(domain)/1024); 169.459 +} 169.460 + 169.461 +/* Prints memory percentage statistic, ratio of current domain memory to total 169.462 + * node memory */ 169.463 +static void print_mem_pct(xenstat_domain *domain) 169.464 +{ 169.465 + print("%6.1f", (double)xenstat_domain_cur_mem(domain) / 169.466 + (double)xenstat_node_tot_mem(cur_node) * 100); 169.467 +} 169.468 + 169.469 +/* Compares maximum memory of two domains, returning -1,0,1 for <,=,> */ 169.470 +static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2) 169.471 +{ 169.472 + return -compare(xenstat_domain_max_mem(domain1), 169.473 + xenstat_domain_max_mem(domain2)); 169.474 +} 169.475 + 169.476 +/* Prints maximum domain memory statistic in KB */ 169.477 +static void print_maxmem(xenstat_domain *domain) 169.478 +{ 169.479 + unsigned long long max_mem = xenstat_domain_max_mem(domain); 169.480 + if(max_mem == ((unsigned long long)-1)) 169.481 + print("%10s", "no limit"); 169.482 + else 169.483 + print("%10llu", max_mem/1024); 169.484 +} 169.485 + 169.486 +/* Prints memory percentage statistic, ratio of current domain memory to total 169.487 + * node memory */ 169.488 +static void print_max_pct(xenstat_domain *domain) 169.489 +{ 169.490 + if (xenstat_domain_max_mem(domain) == (unsigned long long)-1) 169.491 + print("%9s", "n/a"); 169.492 + else 169.493 + print("%9.1f", (double)xenstat_domain_max_mem(domain) / 169.494 + (double)xenstat_node_tot_mem(cur_node) * 100); 169.495 +} 169.496 + 169.497 +/* Compares number of virtual CPUs of two domains, returning -1,0,1 for 169.498 + * <,=,> */ 169.499 +static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2) 169.500 +{ 169.501 + return -compare(xenstat_domain_num_vcpus(domain1), 169.502 + xenstat_domain_num_vcpus(domain2)); 169.503 +} 169.504 + 169.505 +/* Prints number of virtual CPUs statistic */ 169.506 +static void print_vcpus(xenstat_domain *domain) 169.507 +{ 169.508 + print("%5u", xenstat_domain_num_vcpus(domain)); 169.509 +} 169.510 + 169.511 +/* Compares number of virtual networks of two domains, returning -1,0,1 for 169.512 + * <,=,> */ 169.513 +static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2) 169.514 +{ 169.515 + return -compare(xenstat_domain_num_networks(domain1), 169.516 + xenstat_domain_num_networks(domain2)); 169.517 +} 169.518 + 169.519 +/* Prints number of virtual networks statistic */ 169.520 +static void print_nets(xenstat_domain *domain) 169.521 +{ 169.522 + print("%4u", xenstat_domain_num_networks(domain)); 169.523 +} 169.524 + 169.525 +/* Compares number of total network tx bytes of two domains, returning -1,0,1 for 169.526 + * <,=,> */ 169.527 +static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2) 169.528 +{ 169.529 + return -compare(tot_net_bytes(domain1, FALSE), 169.530 + tot_net_bytes(domain2, FALSE)); 169.531 +} 169.532 + 169.533 +/* Prints number of total network tx bytes statistic */ 169.534 +static void print_net_tx(xenstat_domain *domain) 169.535 +{ 169.536 + print("%8llu", tot_net_bytes(domain, FALSE)/1024); 169.537 +} 169.538 + 169.539 +/* Compares number of total network rx bytes of two domains, returning -1,0,1 for 169.540 + * <,=,> */ 169.541 +static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2) 169.542 +{ 169.543 + return -compare(tot_net_bytes(domain1, TRUE), 169.544 + tot_net_bytes(domain2, TRUE)); 169.545 +} 169.546 + 169.547 +/* Prints number of total network rx bytes statistic */ 169.548 +static void print_net_rx(xenstat_domain *domain) 169.549 +{ 169.550 + print("%8llu", tot_net_bytes(domain, TRUE)/1024); 169.551 +} 169.552 + 169.553 +/* Gets number of total network bytes statistic, if rx true, then rx bytes 169.554 + * otherwise tx bytes 169.555 + */ 169.556 +static unsigned long long tot_net_bytes(xenstat_domain *domain, int rx_flag) 169.557 +{ 169.558 + int i = 0; 169.559 + xenstat_network *network; 169.560 + unsigned num_networks = 0; 169.561 + unsigned long long total = 0; 169.562 + 169.563 + /* How many networks? */ 169.564 + num_networks = xenstat_domain_num_networks(domain); 169.565 + 169.566 + /* Dump information for each network */ 169.567 + for (i=0; i < num_networks; i++) { 169.568 + /* Next get the network information */ 169.569 + network = xenstat_domain_network(domain,i); 169.570 + if (rx_flag) 169.571 + total += xenstat_network_rbytes(network); 169.572 + else 169.573 + total += xenstat_network_tbytes(network); 169.574 + } 169.575 + return (total); 169.576 +} 169.577 + 169.578 +/* Compares security id (ssid) of two domains, returning -1,0,1 for <,=,> */ 169.579 +static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2) 169.580 +{ 169.581 + return compare(xenstat_domain_ssid(domain1), 169.582 + xenstat_domain_ssid(domain2)); 169.583 +} 169.584 + 169.585 +/* Prints ssid statistic */ 169.586 +static void print_ssid(xenstat_domain *domain) 169.587 +{ 169.588 + print("%4u", xenstat_domain_ssid(domain)); 169.589 +} 169.590 + 169.591 +/* Section printing functions */ 169.592 +/* Prints the top summary, above the domain table */ 169.593 +void do_summary(void) 169.594 +{ 169.595 +#define TIME_STR_LEN 9 169.596 + const char *TIME_STR_FORMAT = "%H:%M:%S"; 169.597 + char time_str[TIME_STR_LEN]; 169.598 + unsigned run = 0, block = 0, pause = 0, 169.599 + crash = 0, dying = 0, shutdown = 0; 169.600 + unsigned i, num_domains = 0; 169.601 + unsigned long long used = 0; 169.602 + xenstat_domain *domain; 169.603 + 169.604 + /* Print program name, current time, and number of domains */ 169.605 + strftime(time_str, TIME_STR_LEN, TIME_STR_FORMAT, 169.606 + localtime(&curtime.tv_sec)); 169.607 + num_domains = xenstat_node_num_domains(cur_node); 169.608 + print("xentop - %s\n", time_str); 169.609 + 169.610 + /* Tabulate what states domains are in for summary */ 169.611 + for (i=0; i < num_domains; i++) { 169.612 + domain = xenstat_node_domain_by_index(cur_node,i); 169.613 + if (xenstat_domain_running(domain)) run++; 169.614 + else if (xenstat_domain_blocked(domain)) block++; 169.615 + else if (xenstat_domain_paused(domain)) pause++; 169.616 + else if (xenstat_domain_shutdown(domain)) shutdown++; 169.617 + else if (xenstat_domain_crashed(domain)) crash++; 169.618 + else if (xenstat_domain_dying(domain)) dying++; 169.619 + } 169.620 + 169.621 + print("%u domains: %u running, %u blocked, %u paused, " 169.622 + "%u crashed, %u dying, %u shutdown \n", 169.623 + num_domains, run, block, pause, crash, dying, shutdown); 169.624 + 169.625 + used = xenstat_node_tot_mem(cur_node)-xenstat_node_free_mem(cur_node); 169.626 + 169.627 + /* Dump node memory and cpu information */ 169.628 + print("Mem: %lluk total, %lluk used, %lluk free " 169.629 + "CPUs: %u @ %lluMHz\n", 169.630 + xenstat_node_tot_mem(cur_node)/1024, used/1024, 169.631 + xenstat_node_free_mem(cur_node)/1024, 169.632 + xenstat_node_num_cpus(cur_node), 169.633 + xenstat_node_cpu_hz(cur_node)/1000000); 169.634 +} 169.635 + 169.636 +/* Display the top header for the domain table */ 169.637 +void do_header(void) 169.638 +{ 169.639 + field_id i; 169.640 + 169.641 + /* Turn on REVERSE highlight attribute for headings */ 169.642 + attron(A_REVERSE); 169.643 + for(i = 0; i < NUM_FIELDS; i++) { 169.644 + if(i != 0) 169.645 + print(" "); 169.646 + /* The BOLD attribute is turned on for the sort column */ 169.647 + if(i == sort_field) 169.648 + attron(A_BOLD); 169.649 + print("%*s", fields[i].default_width, fields[i].header); 169.650 + if(i == sort_field) 169.651 + attroff(A_BOLD); 169.652 + } 169.653 + attroff(A_REVERSE); 169.654 + print("\n"); 169.655 +} 169.656 + 169.657 +/* Displays bottom status line or current prompt */ 169.658 +void do_bottom_line(void) 169.659 +{ 169.660 + move(lines()-1, 2); 169.661 + 169.662 + if (prompt != NULL) { 169.663 + printw("%s: %s", prompt, prompt_val); 169.664 + } else { 169.665 + addch(A_REVERSE | 'D'); addstr("elay "); 169.666 + 169.667 + /* network */ 169.668 + addch(A_REVERSE | 'N'); 169.669 + attr_addstr(show_networks ? COLOR_PAIR(1) : 0, "etworks"); 169.670 + addstr(" "); 169.671 + 169.672 + /* vcpus */ 169.673 + addch(A_REVERSE | 'V'); 169.674 + attr_addstr(show_vcpus ? COLOR_PAIR(1) : 0, "CPUs"); 169.675 + addstr(" "); 169.676 + 169.677 + /* repeat */ 169.678 + addch(A_REVERSE | 'R'); 169.679 + attr_addstr(repeat_header ? COLOR_PAIR(1) : 0, "epeat header"); 169.680 + addstr(" "); 169.681 + 169.682 + /* sort order */ 169.683 + addch(A_REVERSE | 'S'); addstr("ort order "); 169.684 + 169.685 + addch(A_REVERSE | 'Q'); addstr("uit "); 169.686 + } 169.687 +} 169.688 + 169.689 +/* Prints Domain information */ 169.690 +void do_domain(xenstat_domain *domain) 169.691 +{ 169.692 + unsigned int i; 169.693 + for(i = 0; i < NUM_FIELDS; i++) { 169.694 + if(i != 0) 169.695 + print(" "); 169.696 + if(i == sort_field) 169.697 + attron(A_BOLD); 169.698 + fields[i].print(domain); 169.699 + if(i == sort_field) 169.700 + attroff(A_BOLD); 169.701 + } 169.702 + print("\n"); 169.703 +} 169.704 + 169.705 +/* Output all vcpu information */ 169.706 +void do_vcpu(xenstat_domain *domain) 169.707 +{ 169.708 + int i = 0; 169.709 + unsigned num_vcpus = 0; 169.710 + xenstat_vcpu *vcpu; 169.711 + 169.712 + print("VCPUs(sec): "); 169.713 + 169.714 + num_vcpus = xenstat_domain_num_vcpus(domain); 169.715 + 169.716 + /* for all vcpus dump out values */ 169.717 + for (i=0; i< num_vcpus; i++) { 169.718 + vcpu = xenstat_domain_vcpu(domain,i); 169.719 + 169.720 + if (i != 0 && (i%5)==0) 169.721 + print("\n "); 169.722 + print(" %2u: %10llus", i, xenstat_vcpu_ns(vcpu)/1000000000); 169.723 + } 169.724 + print("\n"); 169.725 +} 169.726 + 169.727 +/* Output all network information */ 169.728 +void do_network(xenstat_domain *domain) 169.729 +{ 169.730 + int i = 0; 169.731 + xenstat_network *network; 169.732 + unsigned num_networks = 0; 169.733 + 169.734 + /* How many networks? */ 169.735 + num_networks = xenstat_domain_num_networks(domain); 169.736 + 169.737 + /* Dump information for each network */ 169.738 + for (i=0; i < num_networks; i++) { 169.739 + /* Next get the network information */ 169.740 + network = xenstat_domain_network(domain,i); 169.741 + 169.742 + print("Net%d RX: %8llubytes %8llupkts %8lluerr %8lludrop ", 169.743 + i, 169.744 + xenstat_network_rbytes(network), 169.745 + xenstat_network_rpackets(network), 169.746 + xenstat_network_rerrs(network), 169.747 + xenstat_network_rdrop(network)); 169.748 + 169.749 + print("TX: %8llubytes %8llupkts %8lluerr %8lludrop\n", 169.750 + xenstat_network_tbytes(network), 169.751 + xenstat_network_tpackets(network), 169.752 + xenstat_network_terrs(network), 169.753 + xenstat_network_tdrop(network)); 169.754 + } 169.755 +} 169.756 + 169.757 +static void top(void) 169.758 +{ 169.759 + xenstat_domain **domains; 169.760 + unsigned int i, num_domains = 0; 169.761 + 169.762 + /* Now get the node information */ 169.763 + if (prev_node != NULL) 169.764 + xenstat_free_node(prev_node); 169.765 + prev_node = cur_node; 169.766 + cur_node = xenstat_get_node(xhandle, XENSTAT_ALL); 169.767 + if (cur_node == NULL) 169.768 + fail("Failed to retrieve statistics from libxenstat\n"); 169.769 + 169.770 + /* dump summary top information */ 169.771 + do_summary(); 169.772 + 169.773 + /* Count the number of domains for which to report data */ 169.774 + num_domains = xenstat_node_num_domains(cur_node); 169.775 + 169.776 + domains = malloc(num_domains*sizeof(xenstat_domain *)); 169.777 + if(domains == NULL) 169.778 + fail("Failed to allocate memory\n"); 169.779 + 169.780 + for (i=0; i < num_domains; i++) 169.781 + domains[i] = xenstat_node_domain_by_index(cur_node, i); 169.782 + 169.783 + /* Sort */ 169.784 + qsort(domains, num_domains, sizeof(xenstat_domain *), 169.785 + (int(*)(const void *, const void *))compare_domains); 169.786 + 169.787 + if(first_domain_index >= num_domains) 169.788 + first_domain_index = num_domains-1; 169.789 + 169.790 + for (i = first_domain_index; i < num_domains; i++) { 169.791 + if(current_row() == lines()-1) 169.792 + break; 169.793 + if (i == first_domain_index || repeat_header) 169.794 + do_header(); 169.795 + do_domain(domains[i]); 169.796 + if (show_vcpus) 169.797 + do_vcpu(domains[i]); 169.798 + if (show_networks) 169.799 + do_network(domains[i]); 169.800 + } 169.801 + 169.802 + do_bottom_line(); 169.803 +} 169.804 + 169.805 +int main(int argc, char **argv) 169.806 +{ 169.807 + int opt, optind = 0; 169.808 + int ch = ERR; 169.809 + 169.810 + struct option lopts[] = { 169.811 + { "help", no_argument, NULL, 'h' }, 169.812 + { "version", no_argument, NULL, 'V' }, 169.813 + { "networks", no_argument, NULL, 'n' }, 169.814 + { "repeat-header", no_argument, NULL, 'r' }, 169.815 + { "vcpus", no_argument, NULL, 'v' }, 169.816 + { "delay", required_argument, NULL, 'd' }, 169.817 + { 0, 0, 0, 0 }, 169.818 + }; 169.819 + const char *sopts = "hVbnvd:"; 169.820 + 169.821 + if (atexit(cleanup) != 0) 169.822 + fail("Failed to install cleanup handler.\n"); 169.823 + 169.824 + while ((opt = getopt_long(argc, argv, sopts, lopts, &optind)) != -1) { 169.825 + switch (opt) { 169.826 + case 'h': 169.827 + case '?': 169.828 + default: 169.829 + usage(argv[0]); 169.830 + exit(0); 169.831 + case 'V': 169.832 + version(); 169.833 + exit(0); 169.834 + case 'n': 169.835 + show_networks = 1; 169.836 + break; 169.837 + case 'r': 169.838 + repeat_header = 1; 169.839 + break; 169.840 + case 'v': 169.841 + show_vcpus = 1; 169.842 + break; 169.843 + case 'd': 169.844 + delay = atoi(optarg); 169.845 + break; 169.846 + } 169.847 + } 169.848 + 169.849 + /* Get xenstat handle */ 169.850 + xhandle = xenstat_init(); 169.851 + if (xhandle == NULL) 169.852 + fail("Failed to initialize xenstat library\n"); 169.853 + 169.854 + /* Begin curses stuff */ 169.855 + initscr(); 169.856 + start_color(); 169.857 + cbreak(); 169.858 + noecho(); 169.859 + nonl(); 169.860 + keypad(stdscr, TRUE); 169.861 + halfdelay(5); 169.862 + use_default_colors(); 169.863 + init_pair(1, -1, COLOR_YELLOW); 169.864 + 169.865 + do { 169.866 + gettimeofday(&curtime, NULL); 169.867 + if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) { 169.868 + clear(); 169.869 + top(); 169.870 + oldtime = curtime; 169.871 + refresh(); 169.872 + } 169.873 + ch = getch(); 169.874 + } while (handle_key(ch)); 169.875 + 169.876 + /* Cleanup occurs in cleanup(), so no work to do here. */ 169.877 + 169.878 + return 0; 169.879 +}