From e43e15284e3c91f9cdc2ba1e48b81f2c5ebe36fc Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Tue, 11 Aug 2009 09:53:14 +0100 Subject: [PATCH] Hostinfo day 6: RPM packaging, initscripts, hostinfo-status, hostinfo-test. --- .gitignore | 3 + COPYING | 339 +++++++++++++++++++++++++++++++++++++ Makefile.am | 2 + README | 3 +- conf/Makefile.am | 9 +- conf/guests.conf.in | 7 +- conf/hostinfo.init.in | 111 ++++++++++++ conf/hostinfod | 10 ++ configure.ac | 33 +++- hostinfo-set/hostinfo-set.pl | 13 ++ hostinfo-status/hostinfo-status.pl | 162 +++++++++++++++++- hostinfo-test/hostinfo-test.pl | 103 ++++++++++- hostinfod/Makefile.am | 6 +- hostinfod/apr12-compat.h | 30 ++++ hostinfod/commands.c | 2 + hostinfod/configuration.c | 32 ++-- hostinfod/hostinfo-protocol.pod | 9 + hostinfod/hostinfo.pod | 49 ++++-- hostinfod/main.c | 7 +- hostinfod/monitor_sockets.c | 4 +- virt-hostinfo.spec.in | 149 ++++++++++++++++ 21 files changed, 1030 insertions(+), 53 deletions(-) create mode 100644 COPYING create mode 100644 conf/hostinfo.init.in create mode 100644 conf/hostinfod create mode 100644 hostinfod/apr12-compat.h create mode 100644 virt-hostinfo.spec.in diff --git a/.gitignore b/.gitignore index 779429b..9b83c26 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ config.status configure conf/guests.conf conf/hostinfo.conf +conf/hostinfo depcomp hostinfod/hostinfo.8 hostinfod/hostinfo-protocol.5 @@ -30,3 +31,5 @@ local.sockets install-sh missing stamp-h1 +virt-hostinfo.spec +virt-hostinfo-*.tar.gz diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/Makefile.am b/Makefile.am index 859c7b9..a339492 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,4 +17,6 @@ ACLOCAL_AMFLAGS = -I m4 +EXTRA_DIST = virt-hostinfo.spec virt-hostinfo.spec.in + SUBDIRS = hostinfod conf hostinfo-status hostinfo-set hostinfo-test diff --git a/README b/README index 2deb984..00fab3e 100644 --- a/README +++ b/README @@ -14,7 +14,7 @@ Requirements - C compiler -- APR (Apache Portable Runtime) 1.3 +- APR (Apache Portable Runtime) 1.2.7 (1.3 preferred) - Perl @@ -25,6 +25,7 @@ Requirements - Perl module Sys::Virt +- Perl module XML::XPath Build diff --git a/conf/Makefile.am b/conf/Makefile.am index cd63e78..f11b399 100644 --- a/conf/Makefile.am +++ b/conf/Makefile.am @@ -15,6 +15,13 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -confdir = $(sysconfdir)/hostinfo +EXTRA_DIST = hostinfod +confdir = $(sysconfdir)/hostinfo conf_DATA = hostinfo.conf guests.conf + +initdir = $(sysconfdir)/init.d +init_SCRIPTS = hostinfo + +sysconfigdir = $(sysconfdir)/sysconfig +sysconfig_DATA = hostinfod diff --git a/conf/guests.conf.in b/conf/guests.conf.in index a822be2..cdd8392 100644 --- a/conf/guests.conf.in +++ b/conf/guests.conf.in @@ -13,17 +13,18 @@ # A rule for a specific qemu/KVM guest with the libvirt name 'dom'. #[qemu-dom] -#interval 60 +#interval 60 +#physcpus off # A rule that would apply to all qemu/KVM guests. #[qemu-*] -#interval 60 +#interval 60 # Catch-all default rule for guests. This rule MUST be last in the file. # This lists commands that are enabled. Any commands not listed here # will be disabled by default. [*] -interval 1 +interval 1 availcpus on corespersocket on memory on diff --git a/conf/hostinfo.init.in b/conf/hostinfo.init.in new file mode 100644 index 0000000..20b1ae0 --- /dev/null +++ b/conf/hostinfo.init.in @@ -0,0 +1,111 @@ +#!/bin/sh +# +# hostinfo: Access host information and statistics from virtual machines +# +# chkconfig: - 98 02 +# description: This daemon allows access to host information from guests. + +### BEGIN INIT INFO +# Provides: hostinfo +# Required-Start: libvirtd +# Required-Stop: libvirtd +# Default-Stop: +# Short-Description: Access host information and statistics from virtual machines +# Description: This daemon allows access to host information from guests. +### END INIT INFO + +# Source function library. +. /etc/rc.d/init.d/functions + +exec="/usr/sbin/hostinfod" +prog="hostinfod" +config="/etc/hostinfo/hostinfo.conf" + +[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog + +ARGS= +if [ -n "$HOSTINFO_VERBOSE" ]; then + ARGS="$ARGS -v" +fi +if [ -n "$HOSTINFO_CONFIG" ]; then + ARGS="$ARGS --config $HOSTINFO_CONFIG" +fi +if [ -n "$HOSTINFO_LIBVIRT_URI" ]; then + ARGS="$ARGS --connect $HOSTINFO_LIBVIRT_URI" +fi + +lockfile=/var/lock/subsys/$prog + +start() { + [ -x $exec ] || exit 5 + [ -f $config ] || exit 6 + echo -n $"Starting $prog: " + daemon $exec $ARGS + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile + return $retval +} + +stop() { + echo -n $"Stopping $prog: " + killproc $prog + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile + return $retval +} + +restart() { + stop + start +} + +reload() { + restart +} + +force_reload() { + restart +} + +rh_status() { + status $prog +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + + +case "$1" in + start) + rh_status_q && exit 0 + $1 + ;; + stop) + rh_status_q || exit 0 + $1 + ;; + restart) + $1 + ;; + reload) + rh_status_q || exit 7 + $1 + ;; + force-reload) + force_reload + ;; + status) + rh_status + ;; + condrestart|try-restart) + rh_status_q || exit 0 + restart + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" + exit 2 +esac +exit $? diff --git a/conf/hostinfod b/conf/hostinfod new file mode 100644 index 0000000..f2c11af --- /dev/null +++ b/conf/hostinfod @@ -0,0 +1,10 @@ +# Uncomment the following line to send verbose/debug messages to syslog. +# This is useful for tracking down configuration problems. +#HOSTINFO_VERBOSE=1 + +# Override the default configuration file path. +#HOSTINFO_CONFIG=/path/to/hostinfo.conf + +# Set the URI to use to connect to local libvirt daemon. +# See: http://libvirt.org/uri.html +#HOSTINFO_LIBVIRT_URI="xen:///" diff --git a/configure.ac b/configure.ac index 7a1377e..33dbad9 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -AC_INIT([virt-hostinfo],[0.1]) +AC_INIT([virt-hostinfo],[0.2.2]) AM_INIT_AUTOMAKE AC_CONFIG_MACRO_DIR([m4]) @@ -37,7 +37,7 @@ dnl C functions which may be missing on older systems. AC_CHECK_FUNCS([inotify_init1 clock_gettime]) dnl Check for required packages using pkg-config. -PKG_CHECK_MODULES([HOSTINFOD],[apr-1 >= 1.3 libvirt >= 0.2.1]) +PKG_CHECK_MODULES([HOSTINFOD],[apr-1 >= 1.2.7 libvirt >= 0.2.1]) dnl Check for Perl and POD. AC_CHECK_PROG([PERL],[perl],[perl],[no]) @@ -48,9 +48,26 @@ AC_CHECK_PROG([POD2TEXT],[pod2text],[pod2text],[no]) test "x$POD2TEXT" = "xno" && AC_MSG_ERROR([pod2text must be installed]) +dnl Check for required Perl modules. +missing_perl_modules=no +required="Pod::Usage Getopt::Long Sys::Virt XML::XPath XML::XPath::XMLParser" +for pm in $required; do + AC_MSG_CHECKING([for Perl module $pm]) + if ! perl -M$pm -e1 >/dev/null 2>&1; then + AC_MSG_RESULT([no]) + missing_perl_modules=yes + else + AC_MSG_RESULT([yes]) + fi +done +if test "x$missing_perl_modules" = "xyes"; then + AC_MSG_ERROR([some required Perl modules are missing]) +fi + dnl Produce output files. AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile + virt-hostinfo.spec hostinfod/Makefile conf/Makefile conf/hostinfo.conf @@ -58,10 +75,16 @@ AC_CONFIG_FILES([Makefile hostinfo-status/Makefile hostinfo-set/Makefile hostinfo-test/Makefile]) -AC_CONFIG_FILES([hostinfo-status/hostinfo-status:hostinfo-status/hostinfo-status.pl], +AC_CONFIG_FILES( + [hostinfo-status/hostinfo-status:hostinfo-status/hostinfo-status.pl], [chmod 0555 hostinfo-status/hostinfo-status]) -AC_CONFIG_FILES([hostinfo-set/hostinfo-set:hostinfo-set/hostinfo-set.pl], +AC_CONFIG_FILES( + [hostinfo-set/hostinfo-set:hostinfo-set/hostinfo-set.pl], [chmod 0555 hostinfo-set/hostinfo-set]) -AC_CONFIG_FILES([hostinfo-test/hostinfo-test:hostinfo-test/hostinfo-test.pl], +AC_CONFIG_FILES( + [hostinfo-test/hostinfo-test:hostinfo-test/hostinfo-test.pl], [chmod 0555 hostinfo-test/hostinfo-test]) +AC_CONFIG_FILES( + [conf/hostinfo:conf/hostinfo.init.in], + [chmod 0555 conf/hostinfo]) AC_OUTPUT diff --git a/hostinfo-set/hostinfo-set.pl b/hostinfo-set/hostinfo-set.pl index 8535cc6..b123a45 100755 --- a/hostinfo-set/hostinfo-set.pl +++ b/hostinfo-set/hostinfo-set.pl @@ -67,6 +67,19 @@ To enable hostinfo for every guest, you could do: =over 4 +=item B<--help> + +Display brief help. + +=item B<--version> + +Display version number and exit. + +=item B<--connect URI> | B<-c URI> + +Connect to libvirt using the given URI. If omitted then +we connect to the default libvirt hypervisor. + =item B<--enable> Enable hostinfo per-guest for each of the guests listed on the command diff --git a/hostinfo-status/hostinfo-status.pl b/hostinfo-status/hostinfo-status.pl index b367206..fed5c25 100755 --- a/hostinfo-status/hostinfo-status.pl +++ b/hostinfo-status/hostinfo-status.pl @@ -19,9 +19,11 @@ use strict; -#use Sys::Virt; - -=pod +use Pod::Usage; +use Getopt::Long; +use Sys::Virt; +use XML::XPath; +use XML::XPath::XMLParser; =head1 NAME @@ -39,7 +41,10 @@ particular guest. For example: # hostinfo-status myguest - myguest: hostinfo is enabled on serial port 1 (ttyS1/COM2) + myguest: hostinfo is enabled on serial port 1 (ttyS1, COM2) + + # hostinfo-status anotherguest + anotherguest: hostinfo is disabled If no guest names are listed on the command line, this command displays the status of all guests known to libvirt. @@ -51,12 +56,39 @@ host as a whole, you should use this command instead: (see L). -=cut - =head1 OPTIONS =over 4 +=cut + +my $help; + +=item B<--help> + +Display brief help. + +=cut + +my $version; + +=item B<--version> + +Display version number and exit. + +=cut + +my $uri; + +=item B<--connect URI> | B<-c URI> + +Connect to libvirt using the given URI. If omitted then +we connect to the default libvirt hypervisor. + +=cut + +my $quiet; + =item B<--quiet> Use this option from scripts to test if hostinfo is enabled @@ -72,8 +104,114 @@ for a single guest without the verbose messages: =cut - - +GetOptions ("help|?" => \$help, + "version" => \$version, + "connect|c=s" => \$uri, + "quiet" => \$quiet, + ) or pod2usage (2); +pod2usage (1) if $help; +if ($version) { + print "@VERSION@\n"; + exit +} + +sub main +{ + my $ret = 0; + + # Connect to libvirt. + my @libvirt_params = (readonly => 1); + push @libvirt_params, address => $uri if $uri; + my $conn = Sys::Virt->new (@libvirt_params); + die "could not connect to libvirt daemon" unless $conn; + + # Get domains we're going to examine. + my @names = @ARGV; + my @doms; + if (@names == 0) { + die "'--quiet' option given with no guest names" if $quiet; + @doms = $conn->list_domains (); + push @doms, $conn->list_defined_domains (); + } else { + die "'--quiet' option given with more than one guest name" + if $quiet && @names > 1; + @doms = map { $conn->get_domain_by_name ($_) } @names; + } + + # Examine each domain. + foreach my $dom (@doms) { + my $name = $dom->get_name; + my $xml = $dom->get_xml_description (); + my $path = XML::XPath->new (xml => $xml); + + # Get all devices. + my @serials = + $path->findnodes (q{//devices/serial[@type='unix']}); + + # Get the zero/one serial port which looks like a hostinfo device. + # It's an error if a domain has more than one of these. + my $errors = 0; + my $hostinfo_serial; + my $hostinfo_port; + + foreach my $serial (@serials) { + my $spath = + XML::XPath->new (xml => + XML::XPath::XMLParser::as_string ($serial)); + + # Check it's a hostinfo serial port. + my @srcs = + $spath->findnodes (q{//source[starts-with(@path,"@localstatedir@/lib/hostinfo")]}); + next if @srcs == 0; + + if (@srcs > 1) { + warn "error: $name: malformed domain XML: multiple elements\n"; + $errors++; + next; + } + + unless ($hostinfo_serial) { + $hostinfo_serial = $serial; + } else { + warn "error: $name: domain appears to have multiple hostinfo serial ports\n"; + $errors++; + next; + } + + # Get the target port. + my @targports = + $spath->findnodes (q{//target/@port}); + if (@targports == 0) { + warn "error: $name: malformed domain XML: no elements\n"; + $errors++; + next; + } + if (@targports > 1) { + warn "error: $name: malformed domain XML: multiple elements\n"; + $errors++; + next; + } + $hostinfo_port = $targports[0]->getData; + } + + if ($quiet) { + $ret = $errors ? 2 : defined ($hostinfo_serial) ? 0 : 1; + } else { + if ($hostinfo_serial) { + if (defined $hostinfo_port) { + my $windows_port = $hostinfo_port+1; + print "$name: hostinfo is enabled on serial port $hostinfo_port (ttyS$hostinfo_port, COM$windows_port)\n"; + } else { + print "$name: hostinfo is enabled on an undefined serial port\n"; + } + } else { + print "$name: hostinfo is disabled\n"; + } + } + } + + $ret; +} =head1 RETURN VALUE @@ -85,7 +223,13 @@ is enabled, 1 if hostinfo is disabled, or 2 if there was an error. =cut - +my $ret = eval { &main }; +if ($@) { + print STDERR "$@\n"; + exit 2; +} +exit $ret if $quiet; +exit 0; =head1 SEE ALSO diff --git a/hostinfo-test/hostinfo-test.pl b/hostinfo-test/hostinfo-test.pl index d265f74..fbc27d8 100755 --- a/hostinfo-test/hostinfo-test.pl +++ b/hostinfo-test/hostinfo-test.pl @@ -19,7 +19,8 @@ use strict; -#use Sys::Virt; +use Pod::Usage; +use Getopt::Long; =pod @@ -39,10 +40,6 @@ a guest (virtual machine). This command is used to make/test hostinfo requests. You can use this to test that the hostinfo system is working end-to-end. -On its own, the command will make a simple 'ping' request, just -to check that the path from the guest to the C (daemon) -inside the host is working: - # hostinfo-test or: @@ -50,16 +47,108 @@ or: # hostinfo-test error: no response ping request +=head1 OPTIONS + +=over 4 + +=cut + +my $help; + +=item B<--help> + +Display brief help. + +=cut + +my $version; + +=item B<--version> + +Display version number and exit. + +=cut + +my $serial = "/dev/ttyS1"; + +=item B<--serial /dev/ttyS?> | B<-s /dev/ttyS?> + +Select the serial device to use. The default is C. + +If you use the wrong serial device, you will get no response from +hostinfo commands, so choosing the correct device is important. To +find out which serial device to use, you should get the host system +administrator to run L on the host. + =cut +my $verbose; + +=item B<--verbose> | B<-v> + +Verbose messages. + +=cut + +GetOptions ("help|?" => \$help, + "version" => \$version, + "serial|s=s" => \$serial, + "verbose|v" => \$verbose, + ) or pod2usage (2); +pod2usage (1) if $help; +if ($version) { + print "@VERSION@\n"; + exit +} + +# Set the serial port to raw mode, no echo. +system ("stty raw -echo < $serial") == 0 or die "stty: $?"; + +open SERIAL, "+<$serial" or die "$serial: $!"; + +my $echodata; +my @chars = ('a'..'z', 'A'..'Z', '0'..'9'); +$echodata .= $chars[rand @chars] foreach (1..16); + +print qq{<<< PING "$echodata"\n} if $verbose; +print SERIAL qq{PING "$echodata"\r\n}; + +local $SIG{ALRM} = sub { die "error: no response from ping test\n" }; +alarm 3; + +my $input = ; +print ">>> $input" if $verbose; + +close SERIAL; + +if ($input !~ /^1\.\d+ 200 $echodata/) { + die "error: incorrect or unexpected response from ping test\n"; +} + +exit 0; + +=head1 TROUBLESHOOTING + +=over 4 + +=item * + +Use I<-v> option to get more verbose messages. + +=item * + +Look in the system log files on the host. +=item * +Follow the I section in L manpage. +=back =head1 RETURN VALUE -This command returns 0 if the test succeeded, or 1 if the test failed -or there was an error. +This command returns 0 if the test succeeded, or 1 if the command +failed or there was some other error. =head1 SEE ALSO diff --git a/hostinfod/Makefile.am b/hostinfod/Makefile.am index 63709db..e8aa621 100644 --- a/hostinfod/Makefile.am +++ b/hostinfod/Makefile.am @@ -15,13 +15,14 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -EXTRA_DIST = hostinfo.pod hostinfo-protocol.pod +EXTRA_DIST = hostinfo.pod hostinfo-protocol.pod hostinfod.8 CLEANFILES = hostinfo.8 hostinfo-protocol.5 sbin_PROGRAMS = hostinfod hostinfod_SOURCES = \ + apr12-compat.h \ commands.c \ configuration.c \ error.c \ @@ -56,3 +57,6 @@ hostinfo-protocol.5: hostinfo-protocol.pod -c "Virtualization Support" \ --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ $< > $@ + +install-data-hook: + mkdir -p $(DESTDIR)$(localstatedir)/lib/hostinfo diff --git a/hostinfod/apr12-compat.h b/hostinfod/apr12-compat.h new file mode 100644 index 0000000..8ce14be --- /dev/null +++ b/hostinfod/apr12-compat.h @@ -0,0 +1,30 @@ +/* virt-hostinfo + * Copyright (C) 2009 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef APR12_COMPAT_H +#define APR12_COMPAT_H + +/* These macros were not in APR 1.2 */ +#ifndef APR_ARRAY_PUSH +#define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary))) +#endif +#ifndef APR_ARRAY_IDX +#define APR_ARRAY_IDX(ary,i,type) (((type *)(ary)->elts)[i]) +#endif + +#endif /* APR12_COMPAT_H */ diff --git a/hostinfod/commands.c b/hostinfod/commands.c index d2a1d2d..8fd2246 100644 --- a/hostinfod/commands.c +++ b/hostinfod/commands.c @@ -37,9 +37,11 @@ #include #include #include +#include #include #include "hostinfod.h" +#include "apr12-compat.h" #define PROTOCOL_VERSION "1.0" #define CRLF "\r\n" diff --git a/hostinfod/configuration.c b/hostinfod/configuration.c index 86a43dc..7ff3afa 100644 --- a/hostinfod/configuration.c +++ b/hostinfod/configuration.c @@ -122,7 +122,9 @@ struct guests_data { const char *cmd; /* command being tested */ int in_section; /* currently processing the right section? */ double interval; /* interval for this guest (0 = any) */ + int interval_set; /* have we set interval yet? */ int enabled; /* is command enabled? */ + int enabled_set; /* have we set enabled flag yet? */ }; void @@ -135,7 +137,9 @@ check_guests_file (struct guest_description *hval, const char *cmd, data->cmd = cmd; data->in_section = 0; data->interval = 60.; /* default */ + data->interval_set = 0; data->enabled = 0; /* default */ + data->enabled_set = 0; process_conf_file (guests_file, 1, guests_process_line, guests_process_section, data); @@ -156,21 +160,27 @@ guests_process_line (const char *path, int lineno, return 0; if (strcasecmp (key, "interval") == 0) { - if (strcasecmp (value, "any") == 0) - data->interval = 0; - else { - if (sscanf (value, "%lg", &data->interval) != 1) { - error ("%s:%d: %s: not a valid decimal number", path, lineno, key); - return -1; + if (!data->interval_set) { + if (strcasecmp (value, "any") == 0) + data->interval = 0; + else { + if (sscanf (value, "%lg", &data->interval) != 1) { + error ("%s:%d: %s: not a valid decimal number", path, lineno, key); + return -1; + } } + data->interval_set = 1; } } else if (strcasecmp (key, data->cmd) == 0) { - bool = get_bool (value); - if (bool == -1) { - error ("%s:%d: %s: not a valid boolean - use 1 or 0", path, lineno, key); - return -1; + if (!data->enabled_set) { + bool = get_bool (value); + if (bool == -1) { + error ("%s:%d: %s: not a valid boolean - use 1 or 0", path, lineno, key); + return -1; + } + data->enabled = bool; + data->enabled_set = 1; } - data->enabled = bool; } return 0; diff --git a/hostinfod/hostinfo-protocol.pod b/hostinfod/hostinfo-protocol.pod index 036a856..f5b901c 100644 --- a/hostinfod/hostinfo-protocol.pod +++ b/hostinfod/hostinfo-protocol.pod @@ -53,6 +53,15 @@ to use any serial port, I it can try to determine the serial port dynamically (although this may be risky/undesirable depending on what the other serial ports are used for). +On Linux/Unix guests, you will need to disable echo and set the serial +port to raw mode. The easiest way to do this is to execute the +following command: + + stty raw -echo < /dev/ttyS1 + +although it can also be done using terminal ioctls (see L +and L). + =head2 REQUESTS AND REPLIES The basic protocol consists of sending a text-based command (the diff --git a/hostinfod/hostinfo.pod b/hostinfod/hostinfo.pod index 9bebced..6ddfe57 100644 --- a/hostinfod/hostinfo.pod +++ b/hostinfod/hostinfo.pod @@ -220,18 +220,27 @@ C<[*]>. A typical example would be: # Rule for specific qemu/KVM guest called 'guest1'. [qemu-guest1] - interval 60 - physcpus off + interval 60 + physcpus off # Rule that covers all other qemu/KVM guests. [qemu-*] - interval 60 + interval 60 # Catch-all default rule for guests. # This rule MUST be last in the file. [*] - interval 1 - physcpus on + interval 1 + availcpus on + corespersocket on + memory on + mhz on + model on + nodes on + physcpus on + ping on + socketspernode on + threadspercore on #etc. In the section header, C<[hypervisor-guestname]>, the C @@ -273,16 +282,12 @@ reboot the guest or restart the daemon. Setting this to C means there is no limit. Guests can flood the host with requests. -=item B - -Enable or disable requesting the number of physical CPUs available in -the host. - - - - +=item B BOOL> +Enable or disable the command named I. +The default for every command is disabled. You have to enable +each one that you want to allow. =back @@ -382,6 +387,24 @@ Is the guest using the correct serial port? Use the L program in the guest to test this. +=item 8. + +(Linux/Unix guests) Is getty attached to the serial port? + +On some operating systems, system daemons will attach themselves to +serial ports. Under Linux you can use the lsof command to check: + + /usr/sbin/lsof | grep ttyS + +=item 9. + +(Linux/Unix guests) Is serial device not in raw mode? + +Client software should set the serial device to raw mode and +disable echoing. The usual way to do this is: + + stty raw -echo < /dev/ttyS1 + =back Note that serial port settings like speed, parity etc. make no diff --git a/hostinfod/main.c b/hostinfod/main.c index 7c9601a..b27338e 100644 --- a/hostinfod/main.c +++ b/hostinfod/main.c @@ -367,7 +367,12 @@ do_reread_socket_dir (void) * been updated. */ for (hi = apr_hash_first (pool, guests); hi; hi = apr_hash_next (hi)) { - apr_hash_this(hi, NULL, NULL, (void **) &hval); + /* On RHEL 5 this gives: + * dereferencing type-punned pointer will break strict-aliasing rules + * XXX + */ + apr_hash_this (hi, NULL, NULL, (void **) &hval); + if (hval->counter != count) { /* This hash table implementation allows you to delete the * current entry safely. diff --git a/hostinfod/monitor_sockets.c b/hostinfod/monitor_sockets.c index 547a535..17c3cda 100644 --- a/hostinfod/monitor_sockets.c +++ b/hostinfod/monitor_sockets.c @@ -54,10 +54,12 @@ monitor_socket_dir (void) exit (1); } + debug ("creating inotify watch on '%s'", socket_dir); + #ifdef HAVE_INOTIFY_INIT1 sockets_inotify_fd = inotify_init1 (IN_NONBLOCK | IN_CLOEXEC); if (sockets_inotify_fd == -1) { - perrorf ("inotify_init"); + perrorf ("inotify_init1"); exit (1); } #else diff --git a/virt-hostinfo.spec.in b/virt-hostinfo.spec.in new file mode 100644 index 0000000..b209802 --- /dev/null +++ b/virt-hostinfo.spec.in @@ -0,0 +1,149 @@ +Summary: Access host information and statistics from virtual machines +Name: virt-hostinfo +Version: @VERSION@ +Release: 1%{?dist} +License: GPLv2+ +Group: System Environment/Daemons +URL: http://et.redhat.com/~rjones/hostinfo/ +Source0: http://et.redhat.com/~rjones/hostinfo/files/%{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + +BuildRequires: apr-devel >= 1.3 +BuildRequires: perl +BuildRequires: libvirt-devel >= 0.2.1 +BuildRequires: perl-Sys-Virt +BuildRequires: perl-XML-XPath + +Requires(post): chkconfig +Requires(preun): chkconfig +Requires(preun): initscripts +Requires(postun): initscripts + +Requires: %{name}-tools = %{version}-%{release} + + +%description +Allow a virtual machine to look at host information (such as number of +physical, not just virtual CPUs), and statistics like the load on the +host. Users have asked for this primarily as a diagnostic tool -- for +example, poor performance of a virtual machine might be caused by +excessive load on the host. + +Normally we try to isolate virtual machines from accessing any such +details from the host, and there are very good reasons for that too, +such as security of the host, commercial confidentiality, and the +privacy of other virtual machines running on the host. As a result, at +the moment there is no mechanism for accessing host information. + +Hostinfo allows the host administrator, at their discretion, and only +of limited data to limited virtual machines, to export host +information and statistics to virtual machines. + +Administrators have to: + + * explicitly enable this feature, + * select the virtual machines and/or data they wish to be seen in guests, + * select the frequency that guests can ask for data. + +Hostinfo runs a daemon on the host which collects the statistics. The +information will be exported to guests over a spare (virtual) serial +port. + +Guests request information by sending a plain text command to the +serial port, and receive information in the form of a simple, plain +text message. No special drivers or software are required by the +guest. + + +%package tools +Summary: Hostinfo server configuration tools +Group: Applications/System + + +%description tools +This package contains server configuration tools for +%{name}. + + +%package client +Summary: Hostinfo client and test tools +Group: Applications/System + + +%description client +This package contains client and test tools for testing +%{name}. + +It should be installed inside a virtual machine running on a +hostinfo-enabled host. + + +%prep +%setup -q + + +%build +%{configure} +make + + +%install +rm -rf $RPM_BUILD_ROOT +make DESTDIR=$RPM_BUILD_ROOT install + + +%clean +rm -rf $RPM_BUILD_ROOT + + +%post +/sbin/chkconfig --add hostinfo + + +%preun +if [ $1 = 0 ] ; then + /sbin/service hostinfo stop >/dev/null 2>&1 + /sbin/chkconfig --del hostinfo +fi + + +%postun +if [ "$1" -ge "1" ] ; then + /sbin/service hostinfo condrestart >/dev/null 2>&1 || : +fi + + +%files +%defattr(-,root,root,-) +%doc COPYING README +%dir %{_sysconfdir}/hostinfo +%config(noreplace) %{_sysconfdir}/hostinfo/guests.conf +%config(noreplace) %{_sysconfdir}/hostinfo/hostinfo.conf +%{_sysconfdir}/init.d/hostinfo +%config(noreplace) %{_sysconfdir}/sysconfig/hostinfod +%{_sbindir}/hostinfod +%{_mandir}/man5/hostinfo-protocol.5* +%{_mandir}/man8/hostinfo.8* +%{_mandir}/man8/hostinfod.8* +%dir %attr(0775,root,qemu) %{_localstatedir}/lib/hostinfo + + +%files tools +%defattr(-,root,root,-) +%doc COPYING +%{_bindir}/hostinfo-set +%{_bindir}/hostinfo-status +%{_mandir}/man8/hostinfo-set.8* +%{_mandir}/man8/hostinfo-status.8* + + +%files client +%defattr(-,root,root,-) +%doc COPYING +%{_bindir}/hostinfo-test +%{_mandir}/man1/hostinfo-test.1* + + +%changelog +* Tue Aug 11 2009 Richard W.M. Jones - @VERSION@-1 +- Initial RPM packaging. -- 1.8.3.1