Author: robert
Date: 2008-11-17 13:03:07 -0700 (Mon, 17 Nov 2008)
New Revision: 1093
Added:
trunk/ATTACHMENTS/pkg_unionfs/
trunk/ATTACHMENTS/pkg_unionfs/manager
trunk/ATTACHMENTS/pkg_unionfs/pkgs
trunk/pkg_unionfs.txt
Log:
Added pkg_unionfs hint and attachments.
Added: trunk/ATTACHMENTS/pkg_unionfs/manager
===================================================================
--- trunk/ATTACHMENTS/pkg_unionfs/manager (rev 0)
+++ trunk/ATTACHMENTS/pkg_unionfs/manager 2008-11-17 20:03:07 UTC (rev
1093)
@@ -0,0 +1,236 @@
+#!/bin/sh
+
+# The "pkg_dir" variable points to the directory containing the packages.
+# This path must be absolute.
+pkg_dir="/pkgs"
+
+# The "target_dir" variable points to the directory where the target
+# directories are located. This path must be absolute.
+target_dir="/"
+
+
+command="${1}"
+pkg_name="${2}"
+pkg_version="${3}"
+
+# Unfortunately, bash does not support map or dictionary data structures.
+# The goal of map_dir is to simulate this data structure. Given a source
+# directory, it will map it to a target directory.
+#
+# Input: ${1} - the path of the source directory; the path cannot be absolute
+# but must be relative to the package's directory.
+# Result: the target directory if the source directory has a target, otherwise
+# an empty string.
+function map_dir ()
+{
+ dir_entries ()
+ {
+ # target-point source-dir
+ echo "${target_dir}/bin bin"
+ echo "${target_dir}/bin jre/bin"
+ echo "${target_dir}/bin usr/bin"
+ echo "${target_dir}/bin usr/local/bin"
+
+ echo "${target_dir}/sbin sbin"
+ echo "${target_dir}/sbin usr/sbin"
+ echo "${target_dir}/sbin usr/local/sbin"
+
+ echo "${target_dir}/lib lib"
+ echo "${target_dir}/lib jre/lib"
+ echo "${target_dir}/lib usr/lib"
+ echo "${target_dir}/lib usr/local/lib"
+ echo "${target_dir}/lib lib64"
+ echo "${target_dir}/lib usr/lib64"
+ echo "${target_dir}/lib usr/local/lib64"
+
+ echo "${target_dir}/usr/include include"
+ echo "${target_dir}/usr/include usr/include"
+ echo "${target_dir}/usr/include usr/local/include"
+
+ echo "${target_dir}/usr/share share"
+ echo "${target_dir}/usr/share usr/share"
+ echo "${target_dir}/usr/share usr/local/share"
+
+ echo "${target_dir}/usr/man man"
+ echo "${target_dir}/usr/man usr/man"
+ echo "${target_dir}/usr/man usr/share/man"
+ echo "${target_dir}/usr/man usr/local/share/man"
+
+ echo "${target_dir}/etc etc"
+ echo "${target_dir}/var var"
+ }
+
+ ( dir_entries ) | while read mount_point source_dir; do
+ if [ "${source_dir}" == "${1}" ]; then
+ echo "${mount_point}"
+ exit 0
+ fi
+ done
+ echo
+}
+
+function print_usage()
+{
+ echo "Usage: ${0} <command> <parameters>"
+ echo "Commands:"
+ echo " list"
+ echo " list all packages"
+ echo " list package-name"
+ echo " list versions of specified package"
+ echo " load package-name [package-version]"
+ echo " load a package"
+ echo " unload package-name"
+ echo " unload a package"
+ echo " test package-name [package-version]"
+ echo " dump mount points of a package"
+}
+
+# Find all the sub-directories in a package directory. The prefix of ./ is
+# stripped off from all sub-directory paths returned by find.
+# Input: ${1} - the package name
+# ${2} - the package version
+# Result: all of the sub-directories
+function find_dirs()
+{
+ dir="${pkg_dir}/${1}/${2}/"
+ cd ${dir}
+ find . -maxdepth 3 -mindepth 1 -type d | sed 's/\.\///'
+}
+
+# Checks the variable ${pkg_name} to see if the package name exists.
+# It prints messages to standard error if the package is not found.
+# Input: ${pkg_name} - the name of the package.
+# Result: 0 if the package directory is found, 1 if not.
+function check_pkg_name()
+{
+ if [ "${pkg_name}" == "" ]; then
+ echo "No package was specified" >&2
+ exit 1
+ elif [ ! -d "${pkg_dir}/${pkg_name}" ]; then
+ echo "Package \`${pkg_name}' does not exist" >&2
+ potential_pkg_names=""
+ for potential_pkg_name in `${0} list`; do
+ matches=`echo ${potential_pkg_name} | grep ${pkg_name}`
+ if [ ! "${matches}" == "" ]; then
+ potential_pkg_names="${matches}
${potential_pkg_names}"
+ fi
+ done
+ if [ ! "${potential_pkg_names}" == "" ]; then
+ echo "Possible packages are: ${potential_pkg_names}" >&2
+ fi
+ exit 1
+ else
+ exit 0
+ fi
+}
+
+# Checks the package version in order to determine if it is valid.
+# If ${pkg_version} is empty, the default package version is used instead.
+# Input: ${pkg_version} - the package version to check
+# Result: the package version to use. This can be different from the supplied
+# ${pkg_version} if it is an empty string.
+function check_pkg_version()
+{
+ if [ "${pkg_version}" == "" ]; then
+ cd "${pkg_dir}/${pkg_name}"
+ for version in `ls -r`; do pkg_version=${version}; done
+ if [ "${pkg_version}" == "" ]; then
+ echo "No package versions are available for package
\`${pkg_name}'" >&2
+ exit 1
+ else
+ echo "No package version was specified for
\`${pkg_name}'; defaulting to \`${pkg_version}'" >&2
+ fi
+ else
+ if [ ! -d "${pkg_dir}/${pkg_name}/${pkg_version}" ]; then
+ echo "Version \`${pkg_version}' does not exist for
package \`${pkg_name}'" >&2
+ echo -n "Available versions are: " >&2
+ ${0} list ${pkg_name} >&2
+ exit 1
+ fi
+ fi
+ echo "${pkg_version}"
+ exit 0
+}
+
+# Performs a supplied function on each directory returned by map_dir.
+# On each directory returned, the function will be called with the parameters:
+# ${1} set to the absolute path to the source directory, and ${2} set to
+# the path to the target directory.
+# Input: ${1} - the function name to execute
+# ${2} - the package name
+# ${3} - the package version
+# Result: 0 if the supplied function succeeded for each directory, 1 otherwise.
+function for_each_mapped_dir ()
+{
+ for dir in `( find_dirs ${2} ${3} )`; do
+ dest=`( map_dir ${dir} )`
+ if [ "${dest}" != "" ]; then
+ ( "${1}" "${pkg_dir}/${2}/${3}/${dir}" "${dest}" )
+ if [ ! $? -eq 0 ]; then exit 1; fi
+ fi
+ done
+}
+
+case "${command}" in
+ list)
+ if [ "${pkg_name}" == "" ]; then
+ cd ${pkg_dir}
+ for pkg_name in *; do
+ if [ -d ${pkg_dir}/${pkg_name} ]; then
+ echo -n "${pkg_name} "
+ cd ${pkg_name}
+ for version in *; do
+ echo -n "${version} "
+ done
+ echo
+ cd ..
+ fi
+ done
+ echo
+ else
+ ( check_pkg_name ); if [ ! $? -eq 0 ]; then exit 1; fi
+ cd ${pkg_dir}/${pkg_name}
+ for version in *; do
+ echo -n "${version} "
+ done
+ echo
+ fi
+ ;;
+ load)
+ ( check_pkg_name ); if [ ! $? -eq 0 ]; then exit 1; fi
+ pkg_version=`( check_pkg_version )`; if [ ! $? -eq 0 ]; then
exit 1; fi
+ do_load ()
+ {
+ mount -n -t unionfs -o "remount,add=:${1}=rw" none
"${2}"
+ }
+ ( for_each_mapped_dir "do_load" ${pkg_name} ${pkg_version} )
+ exit ${?}
+ ;;
+ unload)
+ ( check_pkg_name ); if [ ! $? -eq 0 ]; then exit 1; fi
+ pkg_version=`( check_pkg_version )`; if [ ! $? -eq 0 ]; then
exit 1; fi
+ do_unload ()
+ {
+ mount -n -t unionfs -o "remount,del=${1}" none "${2}"
+ }
+ ( for_each_mapped_dir "do_unload" ${pkg_name} ${pkg_version} )
+ exit ${?}
+ ;;
+ test)
+ ( check_pkg_name ); if [ ! $? -eq 0 ]; then exit 1; fi
+ pkg_version=`( check_pkg_version )`; if [ ! $? -eq 0 ]; then
exit 1; fi
+ do_test ()
+ {
+ echo ${2} \<== ${1}
+ }
+ ( for_each_mapped_dir "do_test" ${pkg_name} ${pkg_version} )
+ exit $?
+ ;;
+ *)
+ if [ ! "${command}" == "" ]; then
+ echo "Command \`${command}' not understood"
+ fi
+ ( print_usage )
+ exit 1
+ ;;
+esac
Added: trunk/ATTACHMENTS/pkg_unionfs/pkgs
===================================================================
--- trunk/ATTACHMENTS/pkg_unionfs/pkgs (rev 0)
+++ trunk/ATTACHMENTS/pkg_unionfs/pkgs 2008-11-17 20:03:07 UTC (rev 1093)
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+CONFIG_FILE="/etc/sysconfig/pkgs_startup"
+PKG_LOADER="/pkgs/manager"
+
+case "${1}" in
+ start)
+ # setup the union mounts before loading any packages
+
+ echo -n "Setting up package management for directories:"
+ # mount read-only unions
+ for dir in /bin /sbin /lib /usr/include /usr/man /usr/share; do
+ echo -n " ${dir}"
+ mount -n -t unionfs -o "ro,dirs=$dir" none "$dir"
+ done
+
+ # mount read-write unions
+ for dir in /etc /var; do
+ echo -n " ${dir}"
+ mount -n -t unionfs -o "rw,dirs=$dir" none "$dir"
+ done
+ echo
+
+ # begin loading packages
+
+ echo -n "Loading packages:"
+ if [ ! -r "${CONFIG_FILE}" ]; then
+ echo " \`${CONFIG_FILE}' not found"
+ exit 1
+ fi
+
+ while read pkg version; do
+ # ignore comments
+ case "$pkg" in
+ ""|"#"*) continue ;;
+ esac
+
+ # load the package
+ ${PKG_LOADER} load ${pkg} ${version}
+
+ # check the result of the package loader
+ if [ $? -eq 0 ]; then
+ echo -n " ${pkg}"
+ else
+ failed="${failed} ${pkg}"
+ fi
+ done < ${CONFIG_FILE}
+ echo
+
+ if [ -n "${failed}" ]; then
+ echo "WARNING: Failed to load${failed}"
+ fi
+ ;;
+ not)
+ cd /pkgs
+ for pkg in *; do
+ result=`grep ${pkg} ${CONFIG_FILE}`
+ if [ "${result}" == "" ]; then
+ echo ${pkg}
+ fi
+ done
+ ;;
+ *)
+ echo "Usage: ${0} {start}"
+ exit 1
+ ;;
+esac
Added: trunk/pkg_unionfs.txt
===================================================================
--- trunk/pkg_unionfs.txt (rev 0)
+++ trunk/pkg_unionfs.txt 2008-11-17 20:03:07 UTC (rev 1093)
@@ -0,0 +1,612 @@
+AUTHOR: Samad Lotia
+
+DATE: 21 October, 2008
+
+LICENSE: GNU GPL 2
+(see http://www.linuxfromscratch.org/hints/downloads/files/LICENSES/gpl-2.txt)
+
+SYNOPSIS: A UnionFS-based package management system
+
+DESCRIPTION:
+ UnionFS is a kernel patch that allows one to merge the contents of many
+ disparate directories so they all appear as a single directory. This
+ functionality provides a basis for a minimal, yet effective,
+ package manager. This approach appeals to those who want a more rational
+ and organized directory structure.
+
+ATTACHMENTS:
+ 1)
http://www.linuxfromscratch.org/hints/downloads/files/ATTACHMENTS/pkg_unionfs/pkgs
+ 2)
http://www.linuxfromscratch.org/hints/downloads/files/ATTACHMENTS/pkg_unionfs/manager
+
+PREREQUISITES:
+ Completion of the "Constructing a Temporary System" chapter in the LFS book.
+
+HINT:
+
+Part I. Introduction
+
+UnionFS is a kernel patch that provides the ability to merge many directories
+such that their contents appear together in one directory. The package manager
+proposed here uses this ability to merge the contents of various packages so
+directories like /bin and /lib have the appearance of containing all loaded
+packages.
+
+This type of package management is inspired by GoboLinux's unique take
+on the archaic Unix directory structures*. Instead of installing all packages
+into the /usr directory whose contents can become quite unwieldy, packages
+are installed into their own directories. GoboLinux's package manager
+creates symbolic links in the necessary directories in order to give the
+appearance that the package is installed in traditional directories.
+A package can be removed by deleting the directory a package was
+installed in, causing the symbolic links pointing to that package to become
+invalidated. GoboLinux demonstrates that a fully-functional GNU/Linux system
+does not require packages to be installed in traditional directories.
+
+* http://www.gobolinux.org/?page=k5
+
+Section I.a. Advantages
+
+The primary benefit of this type of package manager is simplicity. It only
+requires a patched kernel, a startup script for setting up the UnionFS mount
+points, and a script for loading and unloading packages. This approach refrains
+from the canonical black-box style of package management where
+the user issues specialized commands to a complex package manager consisting of
+several tiers of programs and book-keeping files to install or
+uninstall a pacakge. Here, the user issues commands to a script that,
+in turn, merely issues mount commands to UnionFS.
+
+There are some possible benefits of a simpler directory structure:
+
+ * The contents of /bin, /sbin, and /lib merely contain a few files necessary
+ for init scripts.
+
+ * There is no chance an uninstalled package can leave behind stray files in
+ /etc or /usr/share.
+
+ * It is convenient to tuck away special libraries and files needed by a
+ specific package but need to be kept hidden from the rest of the system.
+
+ * It is easier to find configuration files for a package. Instead of hunting
+ down a configuration file in /etc or /usr/share that contains files from
+ all packages, one can browse through a package's directory to look for
+ a file.
+
+This approach is flexible in that determining what constitutes a package is
+up to the user. One can combine several different packages together
+into one super-package so their contents are loaded together. This is
+useful for packages like X.Org, which consists of hundreds subpackages.
+
+A secondary benefit of this approach is version management. In some cases it
+is useful to have multiple versions of the same package installed at the same
+time. One can try out a newer version of a package to see if it
+is satisfactory without affecting the installation of an older version.
+
+Section I.b. Disadvantages
+
+There are several disadvantages to this type of package management.
+
+First, this approach imposes a longer startup time. At system boot, necessary
+packages must be loaded before the system can be fully functional. This
+disadvantage is not a serious setback for most users, since loading one hundred
+and thirty packages takes about four seconds on a relatively new computer.
+
+Second, a package cannot be unloaded if its contents are in use. This
+limitation primarily affects packages consisting of libraries. Running programs
+must be terminated first in order to unload a package they depend on.
+
+Section I.c. How It Works
+
+Assume UnionFS is installed and is working. To demonstrate UnionFS, assume
there
+are the directories a, b, and c. a contains the file 1, b contains file 2, and
+c is empty.
+
+ $ ls
+ a b c
+ $ ls -a a
+ . .. 1
+ $ cat a/1
+ one
+ $ ls -a b
+ . .. 2
+ $ cat b/2
+ two
+ $ ls -a c
+ . ..
+
+The following command is then issued:
+ # mount -t unionfs -o "ro,dirs=a:b" none c
+This has the effect of performing a union operation on the contents of a and b
+and storing them in c.
+
+This produces the following result:
+ $ ls
+ a b c
+ $ ls -a a
+ . .. 1
+ $ cat a/1
+ one
+ $ ls -a b
+ . .. 2
+ $ cat b/2
+ two
+ $ ls -a c
+ . .. 1 2
+ $ cat c/1
+ one
+ $ cat c/2
+ two
+
+This functionality is the basis for the package manager. Assume there is a
+binary in directory /pkgs/sed/4.1.5/bin/sed. The package manager
+notices there is a bin directory at /pkgs/sed/4.1.5/bin. It determines that
this
+directory's contents should be mapped to the directory /bin.
+The package manager issues mount commands to UnionFS. After the package is
+loaded, /pkgs/sed/4.1.5/bin/sed appears as /bin/sed. A user of the system can
+use the sed program as if it exists in /bin/sed. When a package is unloaded,
+sed is no longer in /bin, yet remains as /pkgs/sed/4.1.5/bin/sed.
+
+Section I.d. Some Preliminary Jargon
+
+While jargon and specialized lexicon should be rigorously eschewed*, some
+preliminary terminology is presented here to reduce the verbosity of this
+document or to clarify potentially ambiguous phrases.
+
+ * Installing a package:
+ The programs, libraries, and configuration files are built and copied to
+ a designated directory for a package. This does not mean the package
+ is available and can be used by the system. Installation is not handled
+ in any way by the package manager proposed here.
+
+ * Loading a package:
+ The programs, libraries, and configurations of a package are made
+ available to the system. In other words, the package manager looks at a
+ package's contents and issues mounts to UnionFS so the appropriate files
+ will be presented in /bin, /lib, /etc, and so on. A package must be
+ installed before it can be loaded.
+
+ * Unloading a package:
+ The opposite of loading, where the contents of a package are made
+ unavailable to the system. A package's contents do not appear in /bin,
+ /lib, /etc, and so on, yet remain in its respective package directory.
+
+ * Uninstalling a package:
+ The opposite of installing, where the package's files are completely
+ removed from disk. A package, if it has been loaded, must be unloaded
+ first before it can be removed. Uninstalling is not handled by the
+ package manager, since rm is sufficient.
+
+ * Source directory:
+ This is a directory, like bin, share, or lib, in a package's
+ directory. Its contents, along with other packages' source directories,
+ are the source for directories that are a target for UnionFS, like
+ /bin, /usr/share, or /lib. In the example demonstrated in Section I.c,
+ /pkgs/sed/4.1.5/bin is a source directory.
+
+ * Target directory:
+ This is a directory, like /bin or /lib. Its contents are artificially
+ constructed by UnionFS. In the example demonstrated in Section I.c,
+ /bin is the target directory of the source directory /pkgs/sed/4.1.5/bin.
+
+* See Orwell, G. "Politics of the English Language." 1946.
+ http://www.mtholyoke.edu/acad/intrel/orwell46.htm
+
+Part II. Installation
+
+Setting up the package manager is discussed here and should be done
+after the chapter "Constructing a Temporary System" is completed.
+
+Section II.a. The Directory Structure
+
+The following directory structure is assumed in this
+document and provided scripts. It is perfectly reasonable to change this
+structure to one's tastes.
+
+ 1) The general directory containing all packages is stored in /pkgs.
+
+ 2) A package is installed in a subdirectory of /pkgs. For example, the
+ sed package is installed in /pkgs/sed.
+
+ 3) A package's version is a subdirectory in the package's directory. For
+ example, if sed has the version 4.1.5, it is installed in /pkgs/sed/4.1.5.
+ Since each package version has its own directory, multiple versions of
+ the same package can be installed.
+
+ 4) The target directories:
+ * /bin,
+ * /etc,
+ * /lib,
+ * /var,
+ * /usr/share,
+ * /usr/man,
+ * /usr/include,
+ * and /usr/info
+ should be created.
+
+ /usr/bin should link to /bin, and /usr/lib should link to /lib.
+ If one is using a 64-bit machine, the additional /lib64 and /usr/lib64
+ links should point to /lib.
+
+Section II.b. Installing Packages
+
+After the chapter "Constructing a Temporary System," the LFS book describes
+steps for the actual installation of packages in the chapter
+"Installing Basic System Software." The LFS book relies on a package's Makefile
+to determine the location--typically /usr--where the package is to be
+installed. Because packages are installed in non-standard locations, this
+default behavior must be superseded. One can install all packages in the LFS
+and BLFS books in their own directories, including fundamental packages like
+glibc and sysvinit.
+
+Many packages only require the DESTDIR parameter be passed to the Makefile
+when issuing the install command*. Here is an example of Bison-2.3 to
+illustrate the process of installing a typical package.
+
+ 1) Create the necessary directories:
+ mkdir -pv /pkgs/bison/2.3
+
+ 2) Follow the steps provided by LFS, except for "make install":
+ ./configure --prefix=/usr
+ echo '#define YYENABLE_NLS 1' >> config.h
+ make
+ make check
+
+ 3) Run "make install" with the DESTDIR parameter:
+ make DESTDIR=/pkgs/bison/2.3 install
+
+Most packages will follow this format. Unfortunately, not all packages
+use the DESTDIR parameter for installation. Some packages require
+the configure script's --prefix parameter to determine where the package is to
+be installed. One must look at the README or INSTALL files provided with a
+package to determine this.
+
+Typically, if a package does not have a configure script,
+the DESTDIR parameter will probably not work, and one must consult the
+provided documentation to determine how to install a package in a non-standard
+location.
+
+Some packages require the --sysconfdir parameter for the configure script.
+The LFS book specifies this should be /etc. Since the package is to be
+installed in a non-standard location, this should be set to
+/pkgs/name/version/etc.
+
+* See the section "Package Management" in the LFS book for further discussion.
+ http://www.linuxfromscratch.org/lfs/view/development/chapter06/pkgmgt.html
+
+Section II.c. Setting up the Kernel
+
+By now, all the packages specified in the chapter "Installing Basic System
+Software" should be installed in their own directories.
+
+In the chapter "Making the LFS System Bootable," the LFS book describes
+how to compile and install the kernel. In order to add the UnionFS capability
+to the Linux kernel, one must patch the kernel source code before compiling
+it. Here are the steps to setting up the patch.
+
+ 1) Download a kernel patch from:
+ http://www.filesystems.org/project-unionfs.html
+ Unpack the patch.
+
+ 2) Download the corresponding kernel version. The file name of the kernel
+ patch may be something like "unionfs-2.5_for_2.6.26.5.diff.gz". Therefore,
+ download the kernel version 2.6.26.5. Unpack the kernel source code.
+
+ 4) Apply the kernel patch by first entering the kernel source code directory
+ and then typing:
+ patch -Np1 -i /path/to/unionfs/patch.diff
+
+ 5) Follow the steps in the LFS book for setting up a menu configuration for
+ the kernel. While in the configuration program, ensure the UnionFS
+ module is built. The option can be found in
+ Drivers > Filesystems > Layered Filesystems. UnionFS can be built as a
+ module or can be statically linked with the kernel.
+
+ 6) Build and install the kernel as specified in the chapter "Making the LFS
+ System Bootable."
+
+Section II.d. Setting up the Scripts
+
+After finishing the "Setting up System Bootscripts" and "Making the LFS System
+Bootable" chapters, one must setup the necessary scripts for package
+management before restarting*. There are two attached scripts, pkgs and
manager.
+
+The manager script issues mount commands to UnionFS. This script can be
+copied into /pkgs. This script will be discussed in depth later.
+
+pkgs is an init script that (a) sets up all the mount points necessary for
+package management and (b) loads all the necessary packages for system startup.
+This script should be executed as early in the bootscripts as possible.
+If UnionFS is built as a module, the script should be
+executed after the module has been loaded. Otherwise, this script
+should be executed first. To install this script assuming one is using LFS's
+boot scripts, one should:
+
+ 1) Copy pkgs into /etc/rc.d/init.d.
+
+ 2) Make a link of pkgs to /etc/rc.sysinit:
+ a) If UnionFS was built as a module:
+
+ Have the script be executed after the necessary modules have been
+ loaded:
+ (i) ln -sv /etc/rc.d/init.d/pkgs /etc/rc.d/rc.sysinit/S06pkgs
+
+ Add UnionFS to /etc/sysconfig/modules in order to have the UnionFS
+ module be loaded at startup:
+ (ii) echo unionfs >> /etc/sysconfig/modules
+
+ b) If UnionFS was built into the kernel:
+
+ Lower the execution order of mountkernfs:
+ (i) mv -v /etc/rc.d/rc.sysinit/S00mountkernfs \
+ /etc/rc.d/rc.sysinit/S01mountkernfs
+
+ Have the pkgs script to be executed first:
+ (ii) ln -sv /etc/rc.d/init.d/pkgs /etc/rc.d/rc.sysinit/S00pkgs
+
+ 3) Create the pkgs_startup file:
+ This file is used by pkgs to determine what packages to load at
+ startup. This file is akin to /etc/sysconfig/modules. Each line in this
+ file has the following format:
+ package_name <SPACE> package_version
+
+ This file is typically located in /etc/sysconfig. If one wishes to use
+ another location, change the CONFIG_FILE variable in the pkgs script to
+ the location of this file.
+
+ This file should contain all the packages necessary for the init scripts
+ that follow the pkgs script, like sysklogd and udev, in order for
+ proper system startup. If one wishes to load all available packages
+ at system startup, type:
+ /pkgs/manager list > /etc/sysconfig/pkgs_startup
+
+If the manager script was not copied into /pkgs, open the pkgs script and
+look for the PKG_LOADER variable. This variable should be changed to the
+location of the manager script.
+
+* In fact, not setting up the package manager will produce a non-bootable
+ system because packages are installed in non-standard locations.
+
+Section II.e. Creating the Necessary Symbolic Links
+
+After the scripts have been installed, a few symbolic links must be created
+for proper system startup, since essential programs like init are not installed
+in standard locations.
+
+The general process for creating the symbolic links is as follows.
+All the programs (1) that are to be executed after the kernel has finished
+initializing and before the pkgs script can be executed and (2) the libraries
+these programs depend on must have symbolic links in the /bin, /sbin, or
+/lib directories. The pkgs script calls the manager script to load the
+packages, so all programs required by manager and the libraries they depend on
+must also have symbolic links.
+
+Subsection II.e.1. Program Symbolic Links
+
+Here is a list of programs whose symbolic links are typically required.
+Some systems may require additional programs. Those denoted by an
+asterisk are mandatory.
+
+ *1) init -- this program is executed by the kernel after initialization
+ The kernel expects init to be in /sbin/init.
+ *2) bash -- this is executed by init to run the init scripts
+ *3) echo -- this is used by all init scripts to display messages
+ *4) ls -- used by the manager script
+ *5) find -- used by the manager script
+ *6) sed -- used by the manager script
+ *7) mount -- this is used by the mountkernfs, pkgs, and manager scripts
+ 8) mountpoint -- this is used by the mountkernfs script
+ 9) modprobe -- this is used by the modules script
+ 10) dmesg -- this is used by the consolelog script
+
+To create the symbolic link for a program, one must locate the program first.
+This can be achieved by typing:
+ find /pkgs -name program_name
+
+Next, the symbolic link can be created:
+ ln -sv /path/to/program_name /bin
+ or
+ ln -sv /path/to/program_name /sbin
+
+For example, if one wants to create the symbolic link for init, one must first
+locate it by typing:
+ find /pkgs -name init
+
+If find produces the following result:
+ /pkgs/sysvinit/2.86/sbin/init
+
+The symbolic link can then be created by typing:
+ ln -sv /pkgs/sysvinit/2.86/sbin/init /sbin
+
+Subsection II.e.2. Library Symbolic Links
+
+All of the above programs depend on shared libraries. It is for this reason
+links to the required shared libraries must be in /lib. To determine the
+required libraries, type:
+ ldd /path/to/program
+
+Next, search for the location of the library by typing:
+ find /pkgs -name library_name
+
+Finally, create the symbolic link in /lib if one does not exist:
+ ln -sv /path/to/library /lib
+
+For example, if one wishes to create the symbolic links for bash, one must
+first determine the libraries it requires:
+ ldd /bin/bash
+
+The ldd program may produce the following output:
+ linux-vdso.so.1 => (0x00007ffff6bfe000)
+ libreadline.so.5 => /lib/libreadline.so.5 (0x00007fc8ee804000)
+ libhistory.so.5 => /lib/libhistory.so.5 (0x00007fc8ee6fc000)
+ libncursesw.so.5 => /lib/libncursesw.so.5 (0x00007fc8ee596000)
+ libdl.so.2 => /lib/libdl.so.2 (0x00007fc8ee492000)
+ libc.so.6 => /lib/libc.so.6 (0x00007fc8ee258000)
+ /lib64/ld-linux-x86-64.so.2 (0x00007fc8ee941000)
+
+For each of the files listed, a symbolic link should be created.
+"linux-vdso.so.1" is skipped because it does not point to an
+actual file. The library "libhistory.so.5" can be located by typing:
+ find /pkgs -name libhistory.so.5
+
+If find produces the result:
+ /pkgs/readline/5.2/lib/libhistory.so.5
+
+The symbolic link can be created by typing:
+ ln -sv /pkgs/readline/5.2/lib/libhistory.so.5 /lib
+
+Subsection II.e.3. Troubleshooting
+
+During system startup, if the kernel, init, or an init script reports it cannot
+find a certain program, there are two possible reasons: (a) a valid symbolic
+link to the program is not in /bin or /sbin, or (b) all the necessary libraries
+for the program do not have valid symbolic links in /lib.
+
+Part III. Using the Package Manager
+
+Now that installation is completed, one can boot into the LFS system. This
+section describes how to use the package manager.
+
+Section III.a. Loading and Unloading
+
+The manager script does the grunt work for setting up the target directories.
+It provides two functionalities: (1) loading a package and (2) unloading a
+package. Loading and unloading can be done as follows:
+
+ /pkgs/manager load package-name [package-version]
+
+For example, if one wishes to load the package sed, version 4.1.5, one types:
+
+ /pkgs/manager load sed 4.1.5
+
+Specifying the package version is optional. If it is omitted, the first version
+manager finds is used. Unloading the package follows the same format:
+
+ /pkgs/manager unload package-name [package-version]
+
+To unload sed, version 4.1.5, type:
+
+ /pkgs/manager unload sed 4.1.5
+
+The package version must match the same version used to load the package.
+
+Section III.b. Upgrading a package
+
+To upgrade a package, unload the package version that is already loaded, and
+load the new package version.
+
+Suppose there are two versions of the fluxbox package installed:
+ $ /pkgs/manager list fluxbox
+ 0.9.16 1.0.0
+
+To switch from 0.9.16 to 1.0.0, one types:
+ # /pkgs/manager unload fluxbox 0.9.16
+ # /pkgs/manager load fluxbox 1.0.0
+
+Section III.c. Diagnostics
+
+The manager script provides a few diagnostic tools:
+
+ * To list all of the packages available and their versions, type:
+ /pkgs/manager list
+
+ * To list all the available versions of a package, type:
+ /pkgs/manager list package-name
+
+ * To check that the correct directories are being unionized, type:
+ /pkgs/manager test package-name [package_version]
+
+Section III.d. Limitations
+
+One of the goals of the package manager is minimalism. Features
+found in most package managers are not available in the one presented here
+because of this choice. However, the limitations listed here can be overcome
+by extending the functionality of the package manager. The scripts are not
+designed to be a byzantine of code, and they contain comments to ease hacking.
+
+The manager script cannot determine what packages are loaded. There are
+no checks made when a package is loaded. Issuing a load command to a package
+already loaded has no effect. Unloading a package that is not loaded will
result
+in an error from UnionFS.
+
+If a package depends on another, it is up to the user to load that
+package. No dependency calculations are performed by the package manager.
+
+Section III.d. When to Reload a Package
+
+If a package's contents are modified, there are certain situations where
+reloading a package is necessary for changes to take effect.
+
+Adding files or directories to a source directory like etc or bin does not
+require a reload. Assume there is a package samba, version 2.10.13. There is
+the directory share in the package. If a file called mynotes.txt is added to
+the package's share directory, reloading the package will not be needed, since
+mynotes.txt will immediately appear in /usr/share.
+
+Adding a source directory where one did not exist before
+requires a reload. Assume there is the package gtk with version 2.10.13.
+This package only contains the directory usr; in other words, the directory
+/pkgs/gtk/2.10.13 only contains the directory usr.
+If an etc directory, which did not exist before, is created in
+/pkgs/gtk/2.10.13, a reload is necessary.
+
+Reloads can be accomplished by typing:
+ /pkgs/manager unload package-name package-version
+ /pkgs/manager load package-name package-version
+
+To reload the gtk package with version 2.10.13, one types:
+ /pkgs/manager unload gtk 2.10.13
+ /pkgs/manager load gtk 2.10.13
+
+Section III.e. Editing Files in a Package
+
+When editing a file in a package, one should open the file from
+the /pkgs directory, not from the target directory.
+
+Suppose there is a file in /pkgs/x.org/7.2/etc/X11/x.org,
+which also exists as /etc/X11/x.org. If one wishes to edit this file, it
+should be opened from /pkgs/x.org/7.2/etc/X11/x.org, not /etc/X11/x.org.
+Changes made to /pkgs/x.org/7.2/etc/X11/x.org will immediately become apparent
+in /etc/X11/x.org.
+
+Even though they are technically the same file, if
+/etc/X11/x.org is edited, UnionFS will physically create the directory
+/etc/X11, save the changes made to /etc/X11/x.org, and delete
+/pkgs/x.org/7.2/etc/X11/x.org. This behavior runs against the goal of
+keeping files in separate directories as much as possible.
+
+Section III.f. Uninstalling a package
+
+To uninstall a package, (a) unload the package, then (b) delete the package
+directory.
+
+Part IV. Concluding Remarks
+
+The goal of this document is to present an alternative package manager based
+on UnionFS to the de-facto standard of black-box style package managers.
+Users wishing for a higher degree of organization over files and directories
+may find this type of package manager useful.
+
+The ideas presented here can be extended, namely:
+
+ 1. Other operating systems, like the BSDs, can also take advantage of this
+ type of package management. In fact, the BSD kernels have supported
+ union directories for many years.
+
+ 2. The capabilities of the package manager can be improved by hacking the
+ manager script or write additional scripts that automate the
+ installation of packages.
+
+ Moreover, replacing the manager script with something in a different
+ scripting language may be better. Bash has been a difficult language for
+ the author, and rewriting the manager script in Python
+ would reduce the amount of code and make it cleaner. Adding functionality
+ to the package manager is probably much easier in Python than Bash.
+
+ 3. Users can have personal packages in their home directories and can
+ load and unload them. This can be achieved by: (a) allowing mounting to
+ non-root users, (b) copying the manager script to the user's home
+ directory, and (c) modifying the script's "pkg_dir" and "target_dir"
+ variables.
+
+CHANGELOG:
+ [2008-10-30]
+ * Hint created.
--
http://linuxfromscratch.org/mailman/listinfo/hints
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page