pseudo - run a command in a virtual root environment
pseudo [-dflv] [ -x flags ] [
-P prefix ] [ -rR root ] [ -t
timeout ] [command]
pseudo -h
pseudo [-dflv] [ -x flags ] [
-P prefix ] [-BC] -i path
pseudo [-dflv] [ -x flags ] [
-P prefix ] [-BC]
-m from -M to
pseudo [-dflv] [ -x flags ] [
-P prefix ] -S
pseudo [-dflv] [ -x flags ] [
-P prefix ] -V
The pseudo utility provides a virtual root environment,
hereafter referred to as the pseudo environment, allowing the
creation of file system images and packages by users without root
privileges. The pseudo environment is implemented by pushing a special
library (libpseudo.so) into the LD_PRELOAD environment
variable. This library intercepts a large number of common filesystem
operations and some user-id related operations, and returns values that look
as though the operations had been performed by a root user. This is in turn
managed by a daemon program which keeps a list of virtualized file ownership
and permissions; this daemon program itself is pseudo.
The pseudo program itself can also be used as a program
launcher. The launcher is used to automatically configure a working
environment, then execute processes within that environment. Alternatively,
you can bypass this by setting up certain environment variables (see the
ENVIRONMENT section below). The pseudo client library
(libpseudo.so) can then start the server automatically.
The pseudo command can be invoked in one of several
possible modes:
- -B
- The -B option causes pseudo to scan its database, as with
the -C option, but instead of reporting mismatches, pseudo
attempts to repair them. Specifically, device and inode number mismatches
are corrected, and symlink or directory mismatches result in deletion of
database entries.
- -C
- The -C option causes pseudo to scan its database, comparing
against the filesystem, and reporting likely errors. This may be
unreliable when the server is actively running.
- -h
- The -h option causes pseudo to print a usage message and
exit.
- -i
- The -i option causes pseudo to attempt to correct device
number mismatches by checking inodes; if path has the same inode
number as recorded in the database, but a different device number, all
instances of the device number recorded in the database are updated to the
device number in the live filesystem for path. This is intended to
handle the mismatches that can occur when remounting an NFS filesystem.
The -i option implies the -C option. You can also specify
the -B option to request that the database be rebuilt.
- -m
- The -m and -M options cause pseudo to rename files,
replacing the string from with the string to. The -m
option pair implies the -C option. You can also specify the
-B option to request that the database be rebuilt.
- -V
- The -V option causes pseudo to print configuration
information and exit immediately.
- -S
- The -S option causes pseudo to try to find an existing
server, and if it finds one, instructs that server to shut down as soon as
all clients are detached from it. Note that the server will not shut down
while clients are connected to it; in this case, pseudo will print
a list of the remaining client PIDs.
- -d
- The -d option causes pseudo to immediately detach and run in the
background as a daemon. This is rarely useful except for debugging.
Finally, invoked without any of these options, pseudo sets
up an emulated root environment, then invokes command if it was
provided, otherwise a shell (using the SHELL environment variable if
it is set, or /bin/sh otherwise).
The following options modify the behavior of pseudo:
- -d (daemonize)
- Run as a daemon; pseudo detaches from the calling environment and
runs as a daemon. The command returns successfully if this appears to have
succeeded, otherwise it produces an error message and returns a failure
status.
- -f (foreground)
- Run in the foreground; pseudo runs as a server, and does not try to
start other commands. This mode is useful for debugging.
- -l (log)
- Enable logging. The pseudo daemon will log every filesystem
transaction in the log database.
- -r root
- -R root
- Set the PSEUDO_CHROOT environment variable, running as though the
program had called chroot(2) on the specified path. With -r,
this implies changing the working directory to the specified directory;
with -R, it does not.
- -t timeout
- Set the timeout of the pseudo daemon, in seconds. The default is
currently 30 seconds. After this long with no attached clients, the
pseudo daemon shuts down automatically. The server never shuts down
while it has attached clients. Note that this does not prevent continued
use; new clients can restart the daemon if they need it.
- -v (verbose)
- Increase the verbosity of the pseudo daemon, and the client library
for any programs started by this invocation of pseudo. This is
equivalent to the numeric form of the PSEUDO_DEBUG environment
variable; multiple -v options increase the debugging level.
- -x (debug)
- Set specific deugging flags (the pseudo utility's help message
lists them). This is equivalent to the string form of the
PSEUDO_DEBUG environment variable.
The two most common usages of pseudo are using it to run
specific commands, and setting up an environment manually for running
various other commands.
For the first case, the usage is reasonably simple:
$ /path/to/pseudo
# commands which require root privileges
You may have to use the -Pprefix option to tell
pseudo where to look for its database and server. If you specify a
full path, pseudo assumes that PSEUDO_PREFIX should be the
path to the directory containing the pseudo program, or to the
/bin directory containing the pseudo program.
The other way to use pseudo is by setting up an
environment. This is suitable for use in Makefiles or similar
environments, where you want to run a series of commands in the
pseudo environment, but not to keep invoking the pseudo
command. To do this, set up the
PSEUDO_PREFIX, LD_PRELOAD, and LD_LIBRARY_PATH
environment variables, then run programs normally. You do not need to
separately invoke the pseudo daemon; the client library starts it as
needed.
If you have moved a directory which pseudo was tracking,
you may be able to get the database reattached using the -m option. A
typical usage might be:
$ /path/to/pseudo -B -m oldpath -M
newpath
This requests that pseudo replace the string oldpath
with the string newpath at the beginnings of filenames, then
regenerate the database, correcting any device/inode numbers.
Depending on invocation, diagnostic messages usually go either to
standard error or to the file PSEUDO_PREFIX
/var/pseudo/pseudo.log. By default, pseudo daemon messages go
into the log file, but messages generated by the client code go to standard
error. These can be changed using the PSEUDO_DEBUG_FILE environment
variable, documented in ENVIRONMENT. At the default logging level,
only critical messages are displayed. If you have raised the logging level
(using the -v option or the PSEUDO_DEBUG environment
variable), additional messages are displayed. Levels higher than 2 are very
unlikely to be useful outside of pseudo development.
Diagnostic messages seen by default are those which are believed
to indicate either a serious internal flaw in pseudo or a completely
unexpected failure from the underlying operating system. In normal use, you
should see no diagnostic messages.
The most significant environment variables for pseudo are
LD_PRELOAD and LD_LIBRARY_PATH. However, these variables have
no special meaning to pseudo; rather, they are used in the standard
way to manipulate the dynamic linker into loading the libpseudo
library so that it can intercept calls into the underlying C library.
The following environment variables are used directly by
pseudo:
- PSEUDO_BINDIR
- This directory holds the path to the pseudo binary; by default, it
is the bin directory under PSEUDO_PREFIX.
- PSEUDO_CHROOT
- This variable holds the current emulated chroot(2) path. Paths that
are relative to this are treated as though they were instead relative to
the filesystem root.
- PSEUDO_DEBUG
- This variable holds either a numeric "debug level" for
pseudo to run at, or a set of specific debugging flags, generally
letters. Use pseudo -h to see the available flags. In general, this
is useful only for debugging pseudo itself.
- PSEUDO_DEBUG_FILE
- The name of a file to use for debugging messages from the pseudo client;
the default is to log to standard error. If the string contains a single
%s, that string is replaced with the short program name, and if it
contains a single %d, that string is replaced with the process ID.
Other format specifiers (other than '%%') are not allowed. By default, the
pseudo server logs to the file pseudo.log in the
var/pseudo directory, while clients log to standard error.
- PSEUDO_DISABLED
- If this variable is set to a value that doesn't look like f, F, n, N, s,
S, or a numeric zero, the pseudo client library does not modify the
behavior of called functions, though it continues to intercept them and
block signals while processing them. This variable is reevaluated on every
call to fork(2), clone(2) or related functions. If
the value starts with a lowercase or uppercase s , the pseudo
client disables all server spawning and communications, but still operates
locally. This means that no filesystem mode or permissions changes are
actually recorded or reported, but functions like chown() will
still report success, even though nothing happens. This function is
intended for debugging of issues which are complicated by the server's
involvement.
- PSEUDO_ALLOW_FSYNC
- If this variable is set, pseudo will allow fsync() and related
system calls, even it was configured with the --enable-force-async
option. Otherwise, that option results in all such calls being discarded
silently, even when PSEUDO_DISABLED is set. The value specified
doesn't matter.
- PSEUDO_ENOSYS_ABORT
- If this variable is set, the pseudo client library calls
abort() rather than setting errno to ENOSYS in the
event of a call to a missing underlying function. This variable has no
function outside of debugging pseudo itself.
- PSEUDO_LIBDIR
- This directory holds the path to the pseudo shared libraries; by
default, it is the lib directory under PSEUDO_PREFIX. (On
64-bit hosts, lib64 is also used.)
- PSEUDO_LOCALSTATEDIR
- This directory holds the pseudo database files and log files; by
default, it is the var/pseudo directory under
PSEUDO_PREFIX.
- PSEUDO_NOSYMLINKEXP
- By default, when chrooted, pseudo prepends the chroot directory to
the paths used for absolute symlinks; this behavior ensures that opening
symlinks produces expected results in most cases. In some cases you may
want to suppress this. If this variable is unset, or set to any value
other than 0, pseudo expands symlink paths like this. If this
variable is set to 0, the behavior is disabled.
- PSEUDO_OPTS
- This variable holds options to be passed to any new pseudo servers
started. Typically, when pseudo is used as a launcher, this will be
set automatically; however, you can also use it to pass options when using
LD_PRELOAD to manually run things in the pseudo
environment.
- PSEUDO_PASSWD
- This variable holds the path to a directory containing password and group
files to use for emulation of various password and group routines. It
should be the path to a directory containing the etc directory
containing files named passwd and group. When pseudo
is emulating a chroot environment, the chroot directory is used by
preference. The parallelism between these cases is why this variable
points at the parent directory of etc rather than the directory
containing the files. If there is no chroot environment, and this
variable is also unset, pseudo falls back to a directory specified
at configure time, with the default being the root directory. This is
controlled by the PSEUDO_PASSWD_FALLBACK definition.
- PSEUDO_PREFIX
- If set, the variable PSEUDO_PREFIX is used to determine the path to
use to find the pseudo server, in PSEUDO_PREFIX/bin, and the
pseudo data files, in PSEUDO_PREFIX/var/pseudo. This
variable is automatically set by the pseudo program when it is used
as a launcher.
- PSEUDO_PROFILE_PATH
- If pseudo was configured with profiling enabled, specifies a path
in which to write client profiling information for use with the
pseudo_profile utility (not built by default).
- PSEUDO_TAG
- If this variable is set in a client's environment, its value is
communicated to the server at the beginning of each client session, and
recorded in the log database if any logging occurs related to a specific
client. Note that different clients may have different tags associated
with them; the tag value is per-client, not per-server.
- PSEUDO_UIDS, PSEUDO_GIDS
- These variables are used internally to pass information about the current
emulated user and group identity from one process to another.
- PSEUDO_UNLOAD
- This variable is reevaluated on every call to
fork(2), exec(3) or related functions. If the variable
exists libpseudo.so will be removed from LD_PRELOAD and
PSEUDO_DISABLED behavior will also be triggered. For processes that
simply fork(2), the behavior will be the same as if
PSEUDO_DISABLED was set. For new processes, after a call to
exec(3) or system(3) pseudo will not be loaded in the
new process.
- SHELL
- If set, this will be used when pseudo is invoked without either a
command or one of the options which directs it to do something other than
run a command. Otherwise, pseudo defaults to /bin/sh .
The pseudo database is not particularly robust in the face
of whole directory trees being moved, or changes in the underlying device
and inode numbers. It has a reasonable chance of recovering if only the path
or the device numbers have changed, but it is not particularly designed to
address this. A future release is expected to have improved resilience in
these cases.
The filesystem on which pseudo keeps its database and files
must at a minimum support UNIX domain sockets and reasonable file locking
semantics. Note that pseudo relies on flock(2) locking
semantics; a lock has to persist into a child process. This should probably
eventually be fixed.
The pseudo client library is probably thread-safe, but has
not been adequately tested or debugged in that context.
Filesystem performance is noticably worse under pseudo than
it is otherwise. This is probably because nearly every operation (other than
reads and writes) involves at least one round-trip network communication
with the server, and probably some kind of database activity.
Documentation of the internals of pseudo may be found in
the doc subdirectory of the pseudo source tree.