Manpages - pacutils-sysroot.7
Table of Contents
NAME
pacutils-sysroot - managing a mounted guest system
DESCRIPTION
Managing Guests with –root
When a libalpm-based installation becomes broken to the point that the package manager itself can no longer be used, it must be fixed by loading a working environment and mounting the installation in need of repair as a guest. Typically this is done by setting the installation root to the guest with the –root option. Libalpm only uses the installation root to determine where to install and remove files during package transactions. It is completely independent of all other configuration options. This makes using –root unreliable for managing a mounted guest.
The first issue is that when changing the installation root, the host
system’s configuration is still used. Because the installation root is a
configuration option (RootDir
) it cannot be used to load an alternate
configuration file. Even if –config is added to load the guest
configuration, any Include
’d paths will still be resolved relative to
the host’s root. The only way to actually use the guest’s configuration
without using chroot
is to use –config and manually add the mount
path to all Include
paths.
Now the guest configuration files are being used, but all configured paths will still refer to paths under to the host’s root, not the guest’s. If an installation root is explicitly provided, pacman and pacutils will set defaults for some, but not all, configuration paths to be underneath it. This typically works, because those paths are rarely explicitly set, so the defaults generally do the correct thing. If they have been set, however, the configured values will be used without modification. In order to reliably operate on the guest, all configuration paths must be set relative to the installation root (except for the database and log file paths which will default to paths inside the installation root if unset).
Introducing the Sysroot
This is a significant amount of work just to run operate on a mounted
system. In order to allow reliable operating on a mounted guest, pacman
and pacutils have added the concept of a sysroot. The sysroot is what is
commonly intended when using the –root option; the program will
operate as if the sysroot were actually the filesystem root. This is
similar to using chroot
to enter the mounted system before running the
program, but still runs the host’s copy. There are two ways to do this:
chroot into the sysroot shortly after startup prior to reading any
configuration or prepend the sysroot to all paths.
Using chroot
directly can cause problems with libraries that use
delayed loading of configuration files or shared objects. Notably, glibc
delays loading certain objects until their functionality is actually
used. This can cause a mismatch between components loaded prior to the
chroot
and those loaded after. To avoid this problem, libalpm should
generally be configured to use paths under the sysroot without actually
calling chroot
.
Pacutils provides sysroot-aware versions of its configuration parsing functions to simplify the process. Note that the sysroot is prepended to all paths during config resolution. Programs using the sysroot configuration parsing routines should NOT prepend the sysroot to configuration paths provided on the command line.
EXAMPLES
#include <alpm.h> #include <getopt.h> #include <pacutils.h> enum { FLAG_CONFIG = 1, FLAG_SYSROOT, }; int main(int argc, char *argv[]) { const char *config_file = “/etc/pacman.conf”; const char *sysroot = NULL; alpm_handle_t *handle = NULL; pu_config_t *config = NULL; struct option long_opts[] = { { “config” , required_argument , NULL , FLAG_CONFIG } , { “sysroot” , required_argument , NULL , FLAG_SYSROOT } , { 0, 0, 0, 0 }, }; while((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { switch(c) { case FLAG_CONFIG: config_file = optarg; break; case FLAG_SYSROOT: sysroot = optarg; break; case ?: return 1; * getopt_long already printed an error message * } } if((config = pu_ui_config_load_sysroot(NULL, config_file, sysroot)) == NULL) { return 1; } * load_sysroot already printed an error message * if(!(handle = pu_initialize_handle_from_config(config))) { fprintf(stderr, “error: failed to initialize alpm.\n”); return 1; } puts(alpm_option_get_root(handle)); pu_config_free(config); alpm_release(handle); return 0; }