From: Balbir Singh Date: Sat, 24 May 2008 11:23:08 +0000 (+0000) Subject: Merged with balbir, all part of build automation X-Git-Tag: v0.34~289^2~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9190c1241a381f610d52eb6413f793cfc8435ef2;p=thirdparty%2Flibcgroup.git Merged with balbir, all part of build automation Signed-off-by: Balbir Singh git-svn-id: https://libcg.svn.sourceforge.net/svnroot/libcg/tags/v0.1b@52 4f4bb910-9a46-0410-90c8-c897d4f1cd53 --- diff --git a/balbir/COPYING b/balbir/COPYING deleted file mode 100644 index 2d2d780e..00000000 --- a/balbir/COPYING +++ /dev/null @@ -1,510 +0,0 @@ - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, 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. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations -below. - - When we speak of free software, we are referring to freedom of use, -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 and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it -becomes a de-facto standard. To achieve this, non-free programs must -be allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, 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 library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete 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 distribute a copy of this License along with the -Library. - - 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 Library or any portion -of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -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 Library, 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 Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you 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. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at least - three years, to give the same user the materials specified in - Subsection 6a, above, for a charge no more than the cost of - performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be 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. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library 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. - - 9. 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 Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -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 with -this License. - - 11. 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 Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library 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 Library. - -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. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library 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. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser 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 Library -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 Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -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 - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. 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 LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms -of the ordinary General Public License). - - To apply these terms, attach the following notices to the library. -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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or -your school, if any, to sign a "copyright disclaimer" for the library, -if necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James - Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/balbir/INSTALL b/balbir/INSTALL deleted file mode 100644 index d3c5b40a..00000000 --- a/balbir/INSTALL +++ /dev/null @@ -1,237 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007 Free Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - -Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 6. Often, you can also type `make uninstall' to remove the installed - files again. - -Compilers and Options -===================== - -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - -You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - -Installation Names -================== - -By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - -Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: - - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - -`configure' recognizes the following options to control how it operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/balbir/Makefile b/balbir/Makefile deleted file mode 100644 index b9f4591a..00000000 --- a/balbir/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -# -# Copyright IBM Corporation. 2007 -# -# Authors: Balbir Singh -# This program is free software; you can redistribute it and/or modify it -# under the terms of version 2.1 of the GNU Lesser General Public License -# as published by the Free Software Foundation. -# -# This program is distributed in the hope that it would be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -YACC_DEBUG=-t -DEBUG=-DDEBUG -INC=-I. -LIBS= -lcgroup -LDFLAGS= -YACC=byacc -LEX=flex -bindir=${exec_prefix}/bin -libdir=${exec_prefix}/lib -includedir=${prefix}/include -prefix=/usr -exec_prefix=${prefix} -INSTALL=install -INSTALL_DATA=${INSTALL} -m 644 -PACKAGE_VERSION=0.1b -CFLAGS=-g -O2 $(INC) -DPACKAGE_VERSION=$(PACKAGE_VERSION) -VERSION=1 - -all: libcgroup.so - -cgconfig: libcgroup.so config.c y.tab.c lex.yy.c libcgroup.h file-ops.c - $(CC) $(CFLAGS) -o $@ y.tab.c lex.yy.c config.c file-ops.c $(LDFLAGS) $(LIBS) - -y.tab.c: parse.y lex.yy.c - $(YACC) -v -d parse.y - -lex.yy.c: lex.l - $(LEX) lex.l - -libcgroup.so: api.c libcgroup.h - $(CXX) $(CFLAGS) -shared -fPIC -o $@ api.c - ln -sf $@ $@.$(VERSION) - -install: libcgroup.so - $(INSTALL_DATA) -D libcgroup.h $(DESTDIR)$(includedir)/libcgroup.h - $(INSTALL) -D libcgroup.so $(DESTDIR)$(libdir)/libcgroup-$(PACKAGE_VERSION).so - ln -sf libcgroup-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libcgroup.so.$(VERSION) - ln -sf libcgroup.so.$(VERSION) $(DESTDIR)$(libdir)/libcgroup.so - -uninstall: libcgroup.so - rm -f $(DESTDIR)$(includedir)/libcgroup.h - rm -f $(DESTDIR)$(libdir)/libcgroup.so - rm -f $(DESTDIR)$(libdir)/libcgroup.so.$(VERSION) - rm -f $(DESTDIR)$(libdir)/libcgroup-$(PACKAGE_VERSION).so - -clean: - \rm -f y.tab.c y.tab.h lex.yy.c y.output cgconfig libcgroup.so diff --git a/balbir/Makefile.in b/balbir/Makefile.in deleted file mode 100644 index 99b7ab6d..00000000 --- a/balbir/Makefile.in +++ /dev/null @@ -1,59 +0,0 @@ -# -# Copyright IBM Corporation. 2007 -# -# Authors: Balbir Singh -# This program is free software; you can redistribute it and/or modify it -# under the terms of version 2.1 of the GNU Lesser General Public License -# as published by the Free Software Foundation. -# -# This program is distributed in the hope that it would be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -YACC_DEBUG=-t -DEBUG=-DDEBUG -INC=-I. -LIBS= -lcgroup -LDFLAGS=@LDFLAGS@ -YACC=@YACC@ -LEX=@LEX@ -bindir=@bindir@ -libdir=@libdir@ -includedir=@includedir@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -INSTALL=@INSTALL@ -INSTALL_DATA=@INSTALL_DATA@ -PACKAGE_VERSION=@PACKAGE_VERSION@ -CFLAGS=@CFLAGS@ $(INC) -DPACKAGE_VERSION=$(PACKAGE_VERSION) -VERSION=1 - -all: libcgroup.so - -cgconfig: libcgroup.so config.c y.tab.c lex.yy.c libcgroup.h file-ops.c - $(CC) $(CFLAGS) -o $@ y.tab.c lex.yy.c config.c file-ops.c $(LDFLAGS) $(LIBS) - -y.tab.c: parse.y lex.yy.c - $(YACC) -v -d parse.y - -lex.yy.c: lex.l - $(LEX) lex.l - -libcgroup.so: api.c libcgroup.h - $(CXX) $(CFLAGS) -shared -fPIC -o $@ api.c - ln -sf $@ $@.$(VERSION) - -install: libcgroup.so - $(INSTALL_DATA) -D libcgroup.h $(DESTDIR)$(includedir)/libcgroup.h - $(INSTALL) -D libcgroup.so $(DESTDIR)$(libdir)/libcgroup-$(PACKAGE_VERSION).so - ln -sf libcgroup-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libcgroup.so.$(VERSION) - ln -sf libcgroup.so.$(VERSION) $(DESTDIR)$(libdir)/libcgroup.so - -uninstall: libcgroup.so - rm -f $(DESTDIR)$(includedir)/libcgroup.h - rm -f $(DESTDIR)$(libdir)/libcgroup.so - rm -f $(DESTDIR)$(libdir)/libcgroup.so.$(VERSION) - rm -f $(DESTDIR)$(libdir)/libcgroup-$(PACKAGE_VERSION).so - -clean: - \rm -f y.tab.c y.tab.h lex.yy.c y.output cgconfig libcgroup.so diff --git a/balbir/api.c b/balbir/api.c deleted file mode 100644 index fce70a7b..00000000 --- a/balbir/api.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Copyright IBM Corporation. 2007 - * - * Author: Dhaval Giani - * Author: Balbir Singh - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2.1 of the GNU Lesser General Public License - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * TODOs: - * 1. Convert comments to Docbook style. - * 2. Add more APIs for the control groups. - * 3. Handle the configuration related APIs. - * 4. Error handling. - * - * Code initiated and designed by Dhaval Giani. All faults are most likely - * his mistake. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef PACKAGE_VERSION -#define PACKAGE_VERSION 0.01 -#endif - -#define VERSION(ver) #ver - -/* - * Remember to bump this up for major API changes. - */ -const static char cg_version[] = VERSION(PACKAGE_VERSION); - -struct cg_mount_table_s cg_mount_table[CG_CONTROLLER_MAX]; - -static int cg_chown_file(FTS *fts, FTSENT *ent, uid_t owner, gid_t group) -{ - int ret = 0; - const char *filename = fts->fts_path; - dbg("seeing file %s\n", filename); - switch (ent->fts_info) { - case FTS_ERR: - errno = ent->fts_errno; - break; - case FTS_D: - case FTS_DC: - case FTS_NSOK: - case FTS_NS: - case FTS_DNR: - case FTS_DP: - case FTS_F: - case FTS_DEFAULT: - ret = chown(filename, owner, group); - break; - } - return ret; -} - -/* - * TODO: Need to decide a better place to put this function. - */ -static int cg_chown_recursive(char **path, uid_t owner, gid_t group) -{ - int ret = 0; - dbg("path is %s\n", *path); - FTS *fts = fts_open(path, FTS_PHYSICAL | FTS_NOCHDIR | - FTS_NOSTAT, NULL); - while (1) { - FTSENT *ent; - ent = fts_read(fts); - if (!ent) { - dbg("fts_read failed\n"); - break; - } - ret = cg_chown_file(fts, ent, owner, group); - } - fts_close(fts); - return ret; -} - -/** - * cgroup_init(), initializes the MOUNT_POINT. - * This code is not currently thread safe (hint: getmntent is not thread safe). - * This API is likely to change in the future to push state back to the caller - * to achieve thread safety. The code currently supports just one mount point. - * Complain if the cgroup filesystem controllers are bound to different mount - * points. - */ -int cgroup_init() -{ - FILE *proc_mount; - struct mntent *ent, *found_ent = NULL; - int found_mnt = 0; - int ret = 0; - char *mntent_tok; - static char *controllers[CG_CONTROLLER_MAX]; - FILE *proc_cgroup; - char subsys_name[FILENAME_MAX]; - int hierarchy, num_cgroups, enabled; - int i=0; - char *mntopt; - int err; - - proc_cgroup = fopen("/proc/cgroups", "r"); - - if (!proc_cgroup) - return EIO; - - /* - * The first line of the file has stuff we are not interested in. - * So just read it and discard the information. - * - * XX: fix the size for fgets - */ - fgets(subsys_name, FILENAME_MAX, proc_cgroup); - while (!feof(proc_cgroup)) { - err = fscanf(proc_cgroup, "%s %d %d %d", subsys_name, - &hierarchy, &num_cgroups, &enabled); - if (err < 0) - break; - controllers[i] = (char *)malloc(strlen(subsys_name)); - strcpy(controllers[i], subsys_name); - i++; - } - controllers[i] = NULL; - fclose(proc_cgroup); - - proc_mount = fopen("/proc/mounts", "r"); - if (proc_mount == NULL) { - return EIO; - } - - while ((ent = getmntent(proc_mount)) != NULL) { - if (!strncmp(ent->mnt_type, "cgroup", strlen("cgroup"))) { - for (i = 0; controllers[i] != NULL; i++) { - mntopt = hasmntopt(ent, controllers[i]); - if (mntopt && - strcmp(mntopt, controllers[i]) == 0) { - dbg("matched %s:%s\n", mntopt, - controllers[i]); - strcpy(cg_mount_table[found_mnt].name, - controllers[i]); - strcpy(cg_mount_table[found_mnt].path, - ent->mnt_dir); - dbg("Found cgroup option %s, " - " count %d\n", - ent->mnt_opts, found_mnt); - found_mnt++; - } - } - } - } - - if (!found_mnt) { - cg_mount_table[0].name[0] = '\0'; - return ECGROUPNOTMOUNTED; - } - - found_mnt++; - cg_mount_table[found_mnt].name[0] = '\0'; - - - fclose(proc_mount); - return ret; -} - -static char **get_mounted_controllers(char *mountpoint) -{ - char **controllers; - int i, j; - - i = 0; - j = 0; - - controllers = (char **) malloc(sizeof(char *) * CG_CONTROLLER_MAX); - - for (i = 0; i < CG_CONTROLLER_MAX && cg_mount_table[i].name != NULL; - i++) { - if (strcmp(cg_mount_table[i].name, mountpoint) == 0) { - controllers[j] = (char *)malloc(sizeof(char) * - FILENAME_MAX); - strcpy(controllers[j], cg_mount_table[i].name); - j++; - } - } - controllers[j] = (char *)malloc(sizeof(char) * FILENAME_MAX); - controllers[j][0] = '\0'; - - return controllers; -} - -static int cg_test_mounted_fs() -{ - FILE *proc_mount; - struct mntent *ent; - - proc_mount = fopen("/proc/mounts", "r"); - if (proc_mount == NULL) { - return -1; - } - ent = getmntent(proc_mount); - - while (strcmp(ent->mnt_type, "cgroup") !=0) { - ent = getmntent(proc_mount); - if (ent == NULL) - return 0; - } - fclose(proc_mount); - return 1; -} - -static inline pid_t cg_gettid() -{ - return syscall(__NR_gettid); -} - -static char* cg_build_path(char *name, char *path, char *type) -{ - int i; - for (i = 0; cg_mount_table[i].name[0] != '\0'; i++) { - if (strcmp(cg_mount_table[i].name, type) == 0) { - strcpy(path, cg_mount_table[i].path); - strcat(path, "/"); - strcat(path, name); - strcat(path, "/"); - return path; - } - } - return NULL; -} - -/** cgroup_attach_task_pid is used to assign tasks to a cgroup. - * struct cgroup *cgroup: The cgroup to assign the thread to. - * pid_t tid: The thread to be assigned to the cgroup. - * - * returns 0 on success. - * returns ECGROUPNOTOWNER if the caller does not have access to the cgroup. - * returns ECGROUPNOTALLOWED for other causes of failure. - */ -int cgroup_attach_task_pid(struct cgroup *cgroup, pid_t tid) -{ - char path[FILENAME_MAX]; - FILE *tasks; - int i; - - if(!cgroup) - { - for(i = 0; i < CG_CONTROLLER_MAX && - cg_mount_table[i].name[0]!='\0'; i++) { - if (!cg_build_path(cgroup->name, path, NULL)) - continue; - strcat(path, "/tasks"); - - tasks = fopen(path, "w"); - if (!tasks) { - switch (errno) { - case EPERM: - return ECGROUPNOTOWNER; - default: - return ECGROUPNOTALLOWED; - } - } - fprintf(tasks, "%d", tid); - fclose(tasks); - } - } else { - for( i = 0; i <= CG_CONTROLLER_MAX && - cgroup->controller[i] != NULL ; i++) { - if (!cg_build_path(cgroup->name, path, - cgroup->controller[i]->name)) - continue; - - strcat(path, "/tasks"); - - tasks = fopen(path, "w"); - if (!tasks) { - switch (errno) { - case EPERM: - return ECGROUPNOTOWNER; - default: - return ECGROUPNOTALLOWED; - } - } - fprintf(tasks, "%d", tid); - fclose(tasks); - } - } - return 0; - -} - -/** cgroup_attach_task is used to attach the current thread to a cgroup. - * struct cgroup *cgroup: The cgroup to assign the current thread to. - * - * See cg_attach_task_pid for return values. - */ -int cgroup_attach_task(struct cgroup *cgroup) -{ - pid_t tid = cg_gettid(); - int error; - - error = cgroup_attach_task_pid(cgroup, tid); - - return error; -} - -/* - * create_control_group() - * This is the basic function used to create the control group. This function - * just makes the group. It does not set any permissions, or any control values. - * The argument path is the fully qualified path name to make it generic. - */ -static int cg_create_control_group(char *path) -{ - int error; - if (!cg_test_mounted_fs()) - return ECGROUPNOTMOUNTED; - error = mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - if (error) { - switch(errno) { - case EPERM: - return ECGROUPNOTOWNER; - default: - return ECGROUPNOTALLOWED; - } - } - return error; -} - -/* - * set_control_value() - * This is the low level function for putting in a value in a control file. - * This function takes in the complete path and sets the value in val in that - * file. - */ -static int cg_set_control_value(char *path, char *val) -{ - int error; - FILE *control_file; - if (!cg_test_mounted_fs()) - return ECGROUPNOTMOUNTED; - - control_file = fopen(path, "a"); - - if (!control_file) { - if (errno == EPERM) { - /* - * We need to set the correct error value, does the - * group exist but we don't have the subsystem - * mounted at that point, or is it that the group - * does not exist. So we check if the tasks file - * exist. Before that, we need to extract the path. - */ - int len = strlen(path); - - while (*(path+len) != '/') - len--; - *(path+len+1) = '\0'; - strcat(path, "tasks"); - control_file = fopen(path, "r"); - if (!control_file) { - if (errno == ENOENT) - return ECGROUPSUBSYSNOTMOUNTED; - } - fclose(control_file); - return ECGROUPNOTALLOWED; - } - return errno; - } - - fprintf(control_file, "%s", val); - fclose(control_file); - return 0; -} - -/** cgroup_modify_cgroup modifies the cgroup control files. - * struct cgroup *cgroup: The name will be the cgroup to be modified. - * The values will be the values to be modified, those not mentioned - * in the structure will not be modified. - * - * The uids cannot be modified yet. - * - * returns 0 on success. - * - */ - -int cgroup_modify_cgroup(struct cgroup *cgroup) -{ - char path[FILENAME_MAX], base[FILENAME_MAX]; - int i; - int error; - - for (i = 0; i < CG_CONTROLLER_MAX && cgroup->controller[i]; - i++, strcpy(path, base)) { - int j; - if (!cg_build_path(cgroup->name, base, - cgroup->controller[i]->name)) - continue; - for(j = 0; j < CG_NV_MAX && - cgroup->controller[i]->values[j]; - j++, strcpy(path, base)) { - strcat(path, cgroup->controller[i]->values[j]->name); - error = cg_set_control_value(path, - cgroup->controller[i]->values[j]->value); - if (error) - goto err; - } - } - return 0; -err: - return error; - -} - -/** cgroup_create_cgroup creates a new control group. - * struct cgroup *cgroup: The control group to be created - * - * returns 0 on success. We recommend calling cg_delete_cgroup - * if this routine fails. That should do the cleanup operation. - */ -int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership) -{ - char *fts_path[2], base[FILENAME_MAX], *path; - int i, j, k; - int error = 0; - - fts_path[0] = (char *)malloc(FILENAME_MAX); - if (!fts_path[0]) - return ENOMEM; - fts_path[1] = NULL; - path = fts_path[0]; - - /* - * XX: One important test to be done is to check, if you have multiple - * subsystems mounted at one point, all of them *have* be on the cgroup - * data structure. If not, we fail. - */ - for (k = 0; k < CG_CONTROLLER_MAX && cgroup->controller[k]; k++) { - path[0] = '\0'; - - if (!cg_build_path(cgroup->name, path, - cgroup->controller[k]->name)) - continue; - - dbg("path is %s\n", path); - error = cg_create_control_group(path); - if (error) - goto err; - - strcpy(base, path); - - if (!ignore_ownership) - error = cg_chown_recursive(fts_path, - cgroup->control_uid, cgroup->control_gid); - - if (error) - goto err; - - for (j = 0; j < CG_NV_MAX && cgroup->controller[k]->values[j]; - j++, strcpy(path, base)) { - strcat(path, cgroup->controller[k]->values[j]->name); - error = cg_set_control_value(path, - cgroup->controller[k]->values[j]->value); - /* - * Should we undo, what we've done in the loops above? - */ - if (error) - goto err; - } - - if (!ignore_ownership) { - strcpy(path, base); - strcat(path, "/tasks"); - chown(path, cgroup->tasks_uid, cgroup->tasks_gid); - } - } - -err: - free(path); - return error; -} - -/** cgroup_delete cgroup deletes a control group. - * struct cgroup *cgroup takes the group which is to be deleted. - * - * returns 0 on success. - */ -int cgroup_delete_cgroup(struct cgroup *cgroup, int ignore_migration) -{ - FILE *delete_tasks, *base_tasks = NULL; - int tids; - char path[FILENAME_MAX]; - int error = ECGROUPNOTALLOWED; - int i; - - for (i = 0; i < CG_CONTROLLER_MAX && cgroup->controller; i++) { - if (!cg_build_path(cgroup->name, path, - cgroup->controller[i]->name)) - continue; - strcat(path, "../tasks"); - - base_tasks = fopen(path, "w"); - if (!base_tasks) - goto base_open_err; - - if (!cg_build_path(cgroup->name, path, - cgroup->controller[i]->name)) - continue; - - strcat(path, "tasks"); - - delete_tasks = fopen(path, "r"); - if (!delete_tasks) - goto del_open_err; - - while (!feof(delete_tasks)) { - fscanf(delete_tasks, "%d", &tids); - fprintf(base_tasks, "%d", tids); - } - - if (!cg_build_path(cgroup->name, path, - cgroup->controller[i]->name)) - continue; - error = rmdir(path); - - fclose(delete_tasks); - } -del_open_err: - if (base_tasks) - fclose(base_tasks); -base_open_err: - if (ignore_migration) { - for (i = 0; cgroup->controller[i] != NULL; i++) { - if (!cg_build_path(cgroup->name, path, - cgroup->controller[i]->name)) - continue; - error = rmdir(path); - } - } - return error; -} diff --git a/balbir/config.c b/balbir/config.c deleted file mode 100644 index bed45ce7..00000000 --- a/balbir/config.c +++ /dev/null @@ -1,704 +0,0 @@ -/* - * Copyright IBM Corporation. 2007 - * - * Authors: Balbir Singh - * Dhaval Giani - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2.1 of the GNU Lesser General Public License - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * TODOs: - * 1. Implement our own hashing scheme - * 2. Add namespace support - * 3. Add support for parsing cgroup filesystem and creating a - * config out of it. - * - * Code initiated and designed by Balbir Singh. All faults are most likely - * his mistake. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -extern FILE *yyin; -extern int yyparse(void); -extern int yydebug; -extern int line_no; -extern int verbose; - -struct hsearch_data group_hash; -struct list_of_names *group_list; -struct mount_table *mount_table; - -const char library_ver[] = "0.01"; -const char cg_filesystem[] = "cgroup"; - -struct cg_group *current_group; - -const char *cg_controller_names[] = { - "cpu", - NULL, -}; - -/* - * File traversal routines require the maximum number of open file - * descriptors to be specified - */ -const int cg_max_openfd = 20; - -/* - * Insert the group into the list of group names we maintain. This helps - * us cleanup nicely - */ -int cg_insert_into_group_list(const char *name) -{ - struct list_of_names *tmp, *curr; - - tmp = malloc(sizeof(*tmp)); - if (!tmp) - return 0; - tmp->next = NULL; - tmp->name = (char *)name; - - if (!group_list) { - group_list = tmp; - return 1; - } - curr = group_list; - while (curr->next) - curr = curr->next; - - curr->next = tmp; - return 1; -} - -/* - * Cleanup the group list. We walk the group list and free the entries in the - * hash tables and controller specific entries. - */ -int cg_cleanup_group_list(void) -{ - struct list_of_names *curr = group_list, *tmp; - ENTRY item, *found_item; - int ret; - struct cg_group *cg_group; - - while (curr) { - tmp = curr; - curr = curr->next; - item.key = tmp->name; - ret = hsearch_r(item, FIND, &found_item, &group_hash); - if (!ret) { - printf("Most likely a bug in the code\n"); - continue; - } - /* - * Free the name and it's value - */ - free(tmp->name); - cg_group = (struct cg_group *)found_item->data; - /* - * Controller specific cleanup - */ - if (cg_group->cpu_config.shares) - free(cg_group->cpu_config.shares); - - free(found_item->data); - } - - return 1; -} - -/* - * Find and walk the mount_table structures to find the specified controller - * name. This routine is *NOT* thread safe. - */ -struct mount_table *cg_find_mount_info(const char *controller_name) -{ - struct mount_table *curr = mount_table; - char *str; - - while (curr) { - str = curr->options; - if (!str) - return NULL; - - str = strtok(curr->options, ","); - do { - if (!strncmp(str, controller_name, strlen(str))) - return curr; - str = strtok(NULL, ","); - } while(str); - curr = curr->next; - } - return NULL; -} - -int cg_cpu_controller_settings(struct cg_group *cg_group, - const char *group_path) -{ - int ret = 1; - char *shares_file; - - shares_file = malloc(strlen(group_path) + strlen("/cpu.shares") + 1); - if (!shares_file) - return 0; - - strncpy(shares_file, group_path, strlen(group_path)); - shares_file = strncat(shares_file, "/cpu.shares", - strlen("/cpu.shares")); - dbg("shares file is %s\n", shares_file); - if (cg_group->cpu_config.shares) { - FILE *fd = fopen(shares_file, "rw+"); - if (!fd) - goto cleanup_shares; - /* - * Assume that one write will do it for us - */ - fwrite(cg_group->cpu_config.shares, - strlen(cg_group->cpu_config.shares), 1, fd); - fclose(fd); - } -cleanup_shares: - free(shares_file); - return ret; -} - -int cg_controller_handle_option(struct cg_group *cg_group, - const char *cg_controller_name, - const char *group_path) -{ - int ret = 0; - if (!strncmp(cg_controller_name, "cpu", strlen("cpu"))) { - ret = cg_cpu_controller_settings(cg_group, group_path); - } else - assert(0); - return ret; -} - -int cg_create_group(struct cg_group *cg_group) -{ - int i, ret; - struct mount_table *mount_info; - char *group_path, *tasks_file, *shares_file; - - dbg("found group %s\n", cg_group->name); - - for (i = 0; cg_controller_names[i]; i++) { - - /* - * Find the mount point related information - */ - mount_info = cg_find_mount_info(cg_controller_names[i]); - dbg("mount_info for controller %s:%s\n", - mount_info->mount_point, cg_controller_names[i]); - if (!mount_info) - return 0; - - /* - * TODO: Namespace support is most likely going to be - * plugged in here - */ - - /* - * Find the path to the group directory - */ - group_path = cg_build_group_path(cg_group, mount_info); - if (!group_path) - goto cleanup_group; - - /* - * Create the specified directory. Errors are ignored. - * If the directory already exists, we are most likely - * OK - */ - ret = cg_make_directory(cg_group, group_path); - if (!ret && (errno != EEXIST)) - goto cleanup_dir; - - /* - * Find the tasks file, should probably be encapsulated - * like we encapsulate cg_build_group_path - */ - tasks_file = malloc(strlen(group_path) + strlen("/tasks") + 1); - if (!tasks_file) - goto cleanup_dir; - strncpy(tasks_file, group_path, strlen(group_path)); - tasks_file = strncat(tasks_file, "/tasks", strlen("/tasks")); - dbg("tasks file is %s\n", tasks_file); - - /* - * Assign task file ownership - */ - ret = chown(tasks_file, cg_group->tasks_uid, - cg_group->tasks_gid); - if (ret < 0) - goto cleanup_perm; - - /* - * Controller specific work, errors are not fatal. - */ - cg_controller_handle_option(cg_group, cg_controller_names[i], - group_path); - free(tasks_file); - free(group_path); - } - return 1; -cleanup_perm: - rmdir(group_path); -cleanup_dir: - free(group_path); -cleanup_group: - return 0; -} - -/* - * Go ahead and create the groups in the filesystem. This routine will need - * to be revisited everytime new controllers are added. - */ -int cg_create_groups(void) -{ - struct list_of_names *curr = group_list, *tmp; - ENTRY item, *found_item; - struct cg_group *cg_group; - int ret = 1; - - while (curr) { - tmp = curr; - curr = curr->next; - item.key = tmp->name; - ret = hsearch_r(item, FIND, &found_item, &group_hash); - if (!ret) - return 0; - cg_group = (struct cg_group *)found_item->data; - ret = cg_create_group(cg_group); - if (!ret) - break; - } - - return ret; -} - -/* - * Go ahead and create the groups in the filesystem. This routine will need - * to be revisited everytime new controllers are added. - */ -int cg_destroy_groups(void) -{ - struct list_of_names *curr = group_list, *tmp; - ENTRY item, *found_item; - struct cg_group *cg_group; - int ret; - struct mount_table *mount_info; - char *group_path; - - while (curr) { - tmp = curr; - curr = curr->next; - item.key = tmp->name; - ret = hsearch_r(item, FIND, &found_item, &group_hash); - if (!ret) - return 0; - cg_group = (struct cg_group *)found_item->data; - mount_info = cg_find_mount_info("cpu"); - dbg("mount_info for cpu %s\n", mount_info->mount_point); - if (!mount_info) - return 0; - group_path = malloc(strlen(mount_info->mount_point) + - strlen(cg_group->name) + 2); - if (!group_path) - return 0; - strncpy(group_path, mount_info->mount_point, - strlen(mount_info->mount_point) + 1); - dbg("group_path is %s\n", group_path); - strncat(group_path, "/", strlen("/")); - strncat(group_path, cg_group->name, strlen(cg_group->name)); - dbg("group_path is %s\n", group_path); - /* - * We might strategically add migrate tasks here, so that - * rmdir is successful. TODO: Later - */ - ret = rmdir(group_path); - if (ret < 0) - goto err; - } - - return 1; -err: - free(group_path); - return 0; -} -/* - * The cg_get_current_group routine is used by the parser to figure out - * the current group that is being built and fill it in with the information - * as it parses through the configuration file - */ -struct cg_group *cg_get_current_group(void) -{ - if (!current_group) - current_group = calloc(1, sizeof(*current_group)); - - return current_group; -} - -/* - * This routine should be invoked when the current group being parsed is - * completely parsed - */ -void cg_put_current_group(void) -{ - /* - * NOTE: we do not free the group, the group is installed into the - * hash table, the cleanup routine will do the freeing of the group - */ - current_group = NULL; -} - -int cg_insert_group(const char *group_name) -{ - struct cg_group *cg_group = cg_get_current_group(); - ENTRY item, *found_item; - int ret; - - if (!cg_group) - return 0; - /* - * Dont' copy the name over, just point to it - */ - cg_group->name = (char *)group_name; - item.key = (char *)group_name; - item.data = cg_group; - dbg("Inserting %s into hash table\n", group_name); - ret = hsearch_r(item, ENTER, &found_item, &group_hash); - if (!ret) { - if (found_item) - errno = EEXIST; - errno = ENOMEM; - goto err; - } - ret = cg_insert_into_group_list(group_name); - if (!ret) - goto err; - dbg("Inserted %s into hash and list\n", group_name); - cg_put_current_group(); - return 1; -err: - cg_cleanup_group_list(); - return 0; -} - -/* - * Because of the way parsing works (bottom-up, shift-reduce), we don't - * know the name of the controller yet. Compilers build an AST and use - * a symbol table to deal with this problem. This code does simple things - * like concatinating strings and passing them upwards. This routine is - * *NOT* thread safe. - * - * This code will need modification everytime new controller support is - * added. - */ -int cg_parse_controller_options(char *controller, char *name_value) -{ - struct cg_group *cg_group = cg_get_current_group(); - char *name, *value; - - if (!cg_group) - return 0; - - if (!strncmp(controller, "cpu", strlen("cpu"))) { - name = strtok(name_value, " "); - value = strtok(NULL, " "); - if (!strncmp(name, "cpu.shares", strlen("cpu.shares"))) - cg_group->cpu_config.shares = strdup(value); - else { - free(controller); - free(name_value); - return 0; - } - dbg("cpu name %s value %s\n", name, value); - } else { - return 0; - } - free(controller); - free(name_value); - return 1; -} - -/* - * Convert the uid/gid field and supplied value to appropriate task - * permissions. This routine is *NOT* thread safe. - */ -int cg_group_task_perm(char *perm_type, char *value) -{ - struct cg_group *cg_group = cg_get_current_group(); - struct passwd *pw; - struct group *group; - long val = atoi(value); - if (!strncmp(perm_type, "uid", strlen("uid"))) { - if (!val) { /* We got the identifier as a name */ - pw = getpwnam(value); - if (!pw) { - free(perm_type); - free(value); - return 0; - } else { - cg_group->tasks_uid = pw->pw_uid; - } - } else { - cg_group->tasks_uid = val; - } - dbg("TASKS %s: %d\n", perm_type, cg_group->tasks_uid); - } - if (!strncmp(perm_type, "gid", strlen("gid"))) { - if (!val) { /* We got the identifier as a name */ - group = getgrnam(value); - if (!group) { - free(perm_type); - free(value); - return 0; - } else { - cg_group->tasks_gid = group->gr_gid; - } - } else { - cg_group->tasks_gid = val; - } - dbg("TASKS %s: %d\n", perm_type, cg_group->tasks_gid); - } - free(perm_type); - free(value); - return 1; -} - -int cg_group_admin_perm(char *perm_type, char *value) -{ - struct cg_group *cg_group = cg_get_current_group(); - struct passwd *pw; - struct group *group; - long val = atoi(value); - if (!strncmp(perm_type, "uid", strlen("uid"))) { - if (!val) { /* We got the identifier as a name */ - pw = getpwnam(value); - if (!pw) { - free(perm_type); - free(value); - return 0; - } else { - cg_group->admin_uid = pw->pw_uid; - } - } else { - cg_group->admin_uid = val; - } - dbg("ADMIN %s: %d\n", perm_type, cg_group->admin_uid); - } - if (!strncmp(perm_type, "gid", strlen("gid"))) { - if (!val) { /* We got the identifier as a name */ - group = getgrnam(value); - if (!group) { - free(perm_type); - free(value); - return 0; - } else { - cg_group->admin_gid = group->gr_gid; - } - } else { - cg_group->admin_gid = val; - } - dbg("ADMIN %s: %d\n", perm_type, - cg_group->admin_gid); - } - free(perm_type); - free(value); - return 1; -} - -/* - * We maintain a hash table. The group hash table maintains the parameters for - * each group, including the parameters for each controller - * - * TODO: Make the initialization a run time configuration parameter - */ -int cg_init_group_and_mount_info(void) -{ - int ret; - - group_list = NULL; - mount_table = NULL; - current_group = NULL; - - ret = hcreate_r(MAX_GROUP_ELEMENTS, &group_hash); - if (!ret) - return 0; - return 1; -} - -/* - * This routine should be called only once all elements of the hash table have - * been freed. Otherwise, we'll end up with a memory leak. - */ -void cg_destroy_group_and_mount_info(void) -{ - hdestroy_r(&group_hash); - group_list = NULL; - mount_table = NULL; - current_group = NULL; -} - -/* - * Insert a name, mount_point pair into the mount_table data structure - * TODO: Validate names and mount points - */ -int cg_insert_into_mount_table(const char *name, const char *mount_point) -{ - struct mount_table *tmp, *prev = mount_table; - - while (prev && prev->next != NULL && - (strncmp(mount_point, prev->mount_point, strlen(mount_point)))) - prev = prev->next; - - if (prev && - !(strncmp(mount_point, prev->mount_point, strlen(mount_point)))) { - prev->options = realloc(prev->options, strlen(prev->options) - + strlen(name) + 2); - if (!prev->options) - return 0; - strncat(prev->options, ",", strlen(",")); - strncat(prev->options, name, strlen(name)); - dbg("options %s: mount_point %s\n", prev->options, - prev->mount_point); - return 1; - } - - tmp = malloc(sizeof(*tmp)); - if (!tmp) - return 0; - - tmp->next = NULL; - tmp->mount_point = (char *)mount_point; - tmp->options = (char *)name; - dbg("options %s: mount_point %s\n", tmp->options, tmp->mount_point); - - if (!prev) { - mount_table = tmp; - return 1; - } else { - prev->next = tmp; - } - - return 1; -} - -void cg_cleanup_mount_table(void) -{ - struct mount_table *curr = mount_table, *tmp; - - while (curr) { - tmp = curr; - curr = curr->next; - tmp->next = NULL; - - /* - * Some of this data might have been allocated by the lexer - * while parsing tokens - */ - free(tmp->mount_point); - free(tmp->options); - - free(tmp); - } -} - -int cg_load_config(const char *pathname) -{ - yyin = fopen(pathname, "rw"); - if (!yyin) { - dbg("Failed to open file %s\n", pathname); - return 0; - } - - if (!cg_init_group_and_mount_info()) - return 0; - - if (yyparse() != 0) { - dbg("Failed to parse file %s\n", pathname); - return 0; - } - - if (!cg_mount_controllers()) - goto err_mnt; - if (!cg_create_groups()) - goto err_grp; - - fclose(yyin); - return 1; -err_grp: - cg_destroy_groups(); - cg_cleanup_group_list(); -err_mnt: - cg_unmount_controllers(); - cg_cleanup_mount_table(); - fclose(yyin); - return 0; -} - -void cg_unload_current_config(void) -{ - cg_destroy_groups(); - cg_cleanup_group_list(); - cg_unmount_controllers(); - cg_cleanup_mount_table(); - cg_destroy_group_and_mount_info(); -} - -int main(int argc, char *argv[]) -{ - int c; - char filename[PATH_MAX]; - int ret; - - if (argc < 2) { - fprintf(stderr, "usage is %s