Giter Site home page Giter Site logo

bedrocklinux / bedrocklinux-userland Goto Github PK

View Code? Open in Web Editor NEW
601.0 601.0 65.0 1.72 MB

This tracks development for the things such as scripts and (defaults for) config files for Bedrock Linux

Home Page: https://bedrocklinux.org

License: GNU General Public License v2.0

Shell 19.79% Makefile 27.29% C 52.92%

bedrocklinux-userland's People

Contributors

androw avatar camperboy1000 avatar cptpcrd avatar fermats-last-account avatar hardolaf avatar jfriedly avatar minibill avatar morgawr avatar n0toose avatar nicholas85 avatar nift4 avatar paradigm avatar paulschellin avatar person4268 avatar philantrop avatar runningnak3d avatar skirmisher avatar slackbyte avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bedrocklinux-userland's Issues

statoverride issue in Debian-based clients

A new Debian-based client, fresh from a debootstrap, will complain about
statoverride upon the first attempt to utilize its package manager. It is
possible to fix this issue by overwriting the statoverride file with a blank
file. brg could do this automatically when it is completed. However, more
research should be done to determine why this happens in case there is a good
reason debootstrap defaults to a non-empty statoverride file.

/etc/profile support for non-bourne shells

Bedrock Linux currently heavily depends on /etc/profile being sourced to set up various environment variables. However, that file is only sourced by bourne-compatible shells. The fish shell, for example, probably does not read it. Efforts should be made to ensure similar profile files are available for non-bourne shells.

Cannot install proprietary Nvidia drivers, probably bru's fault

The Nvidia proprietary Linux driver installer dies with SIGBUS on Bedrock Linux
1.0alpha4 Flopsie due, likely, to a bug in Bedrock Linux's bru utility.
Relevant strace output is below. Hopefully this is sufficient information to
hunt down the issue.

Various notes:

  • Note the installer seems to copy files via mmap()ing them.
  • There seems to be some kind of alignment issue that bru isn't happy about in one instance of mmap().
  • Note that if the ./nvidia.icd file is replaced with an empty file, the
    nvidia driver installs correctly; this issue is not triggered in that
    situation. No way to have an alignment issue if there is nothing to align.

The following lines starting with a # are my own comments added to help explain what is going on.

# Logging that it is about to install /etc/OpenCL/vendors/nvidia.icd
write(1, "\33[34;16H\33[37m\33[44metc/OpenCL/vendors/nvidia.icd\n\33(B\33[0;7m\33[32m\33[40m \33[35;88H\33(B\33[0m\33[32m\33[40m5%\33(B\33[m\33[39;49m\33[37m\33[40m", 119) = 119
rt_sigaction(SIGTSTP, {0x7fc16c203bf0, [], SA_RESTORER|SA_RESTART, 0x7fc16c64e420}, NULL, 8) = 0
# stat()'ing directory structure in case the installer will have to create a directory (which it does not)
stat("/etc", {st_dev=makedev(0, 22), st_ino=1, st_mode=S_IFDIR|0755, st_nlink=52, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=2014/05/14-18:19:24, st_mtime=2014/05/14-18:20:02, st_ctime=2014/05/14-18:20:02}) = 0
stat("/etc/OpenCL", {st_dev=makedev(0, 22), st_ino=14, st_mode=S_IFDIR|0700, st_nlink=3, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=2014/05/14-18:20:02, st_mtime=2014/05/14-18:20:02, st_ctime=2014/05/14-18:20:02}) = 0
stat("/etc/OpenCL/vendors", {st_dev=makedev(0, 22), st_ino=21, st_mode=S_IFDIR|0700, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=2014/05/14-18:20:02, st_mtime=2014/05/14-18:21:13, st_ctime=2014/05/14-18:21:13}) = 0
# Here it opens the file to copy with fid=5
open("nvidia.icd", O_RDONLY) = 5
# Here it opens the file location to put the new file.  Note O_CREAT is used in case the file does not exist.  Note that this is in "/etc" on which is mounted bru.
open("/etc/OpenCL/vendors/nvidia.icd", O_RDWR|O_CREAT|O_TRUNC, 0444) = 6
# Here it gets the size of the nvidia.icd file to copy.  It does this in order to set the trailing NULL for the null-terminated string for the output file.
fstat(5, {st_dev=makedev(8, 17), st_ino=6275211, st_mode=S_IFREG|0644, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=22, st_atime=2014/05/14-18:20:25, st_mtime=2013/08/27-04:11:08, st_ctime=2014/05/14-18:20:28}) = 0
# Here it seeks to the relevant location based on the fstat() above to place the NULL
lseek(6, 21, SEEK_SET)   = 21
# Write the NULL in place
write(6, "\0", 1)        = 1
# Here it mmap()'s the input file
mmap(NULL, 22, PROT_READ, MAP_SHARED, 5, 0) = 0x7fc16cde2000
# Here it mmap()'s the output file, in the /etc directory in bru.  Which results in the SIGBUS below.
mmap(NULL, 22, PROT_READ|PROT_WRITE, MAP_SHARED, 6, 0) = 0x7fc16cde1000
--- SIGBUS (Bus error) @ 0 (0) ---
rt_sigaction(SIGTSTP, {SIG_IGN, [], SA_RESTORER|SA_RESTART, 0x7fc16c64e420}, {0x7fc16c203bf0, [], SA_RESTORER|SA_RESTART, 0x7fc16c64e420}, 8) = 0
write(1, "\33[39;49m\33[37m\33[40m\33[H\33[2J", 25) = 25
rt_sigaction(SIGTSTP, {0x7fc16c203bf0, [], SA_RESTORER|SA_RESTART, 0x7fc16c64e420}, NULL, 8) = 0
write(1, "\33[39;49m\33[98d\33[K\33[98;1H\33[?12l\33[?25h", 35) = 35
write(1, "\33[?1049l\r\33[?1l\33>", 16) = 16
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {c_iflags=0x4000, c_oflags=0x1, c_cflags=0xbf, c_lflags=0x8a31, c_line=0, c_cc[VMIN]=1, c_cc[VTIME]=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x00\x12\x0f\x17\x16\x00\x00\x00"}) = 0
ioctl(1, SNDCTL_TMR_STOP or TCSETSW, {c_iflags=0x4100, c_oflags=0x5, c_cflags=0xbf, c_lflags=0x8a3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x00\x12\x0f\x17\x16\x00\x00\x00"}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {c_iflags=0x4100, c_oflags=0x5, c_cflags=0xbf, c_lflags=0x8a3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x00\x12\x0f\x17\x16\x00\x00\x00"}) = 0
unlink("/tmp/nv-JbD2dG") = 0
write(2, "Received signal ", 16) = 16
write(2, "SIGBUS", 6)    = 6
write(2, "; aborting.\n", 12) = 12
exit_group(135)          = ?

Here's the same section of the strace output with bru unmounted (where it completes successfully)

25005 18:48:34 write(1, "\33[3G\33[37m\33[44mBacking up: /etc/OpenCL/vendors/nvidia.icd\n\33[3G\33(B\33[0;7m\33[32m\33[40m  \33[13;80H\33(B\33[0m\33[32m\33[40m1%\33(B\33[m\33[39;49m\33[37m\33[40m", 133) = 133
25005 18:48:34 rt_sigaction(SIGTSTP, {0x7fc39c56dbf0, [], SA_RESTORER|SA_RESTART, 0x7fc39c9b8420}, NULL, 8) = 0
25005 18:48:34 open("/var/lib/nvidia/log", O_WRONLY|O_CREAT|O_APPEND, 0666) = 5
25005 18:48:34 fstat(5, {st_dev=makedev(8, 17), st_ino=3515544, st_mode=S_IFREG|0600, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=71, st_atime=2014/05/14-18:48:34, st_mtime=2014/05/14-18:48:34, st_ctime=2014/05/14-18:48:34}) = 0
25005 18:48:34 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc39d14c000
25005 18:48:34 fstat(5, {st_dev=makedev(8, 17), st_ino=3515544, st_mode=S_IFREG|0600, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=71, st_atime=2014/05/14-18:48:34, st_mtime=2014/05/14-18:48:34, st_ctime=2014/05/14-18:48:34}) = 0
25005 18:48:34 lseek(5, 71, SEEK_SET)   = 71
25005 18:48:34 lstat("/etc/OpenCL/vendors/nvidia.icd", {st_dev=makedev(8, 17), st_ino=3515567, st_mode=S_IFREG|0400, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=22, st_atime=2014/05/14-18:48:26, st_mtime=2014/05/14-18:20:02, st_ctime=2014/05/14-18:48:26}) = 0
25005 18:48:34 open("/etc/OpenCL/vendors/nvidia.icd", O_RDONLY) = 6
25005 18:48:34 fstat(6, {st_dev=makedev(8, 17), st_ino=3515567, st_mode=S_IFREG|0400, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=22, st_atime=2014/05/14-18:48:26, st_mtime=2014/05/14-18:20:02, st_ctime=2014/05/14-18:48:26}) = 0
25005 18:48:34 mmap(NULL, 22, PROT_READ, MAP_SHARED, 6, 0) = 0x7fc39d14b000
25005 18:48:34 munmap(0x7fc39d14b000, 22) = 0
25005 18:48:34 close(6)                 = 0
25005 18:48:34 stat("/etc/OpenCL/vendors/nvidia.icd", {st_dev=makedev(8, 17), st_ino=3515567, st_mode=S_IFREG|0400, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=22, st_atime=2014/05/14-18:48:34, st_mtime=2014/05/14-18:20:02, st_ctime=2014/05/14-18:48:26}) = 0
25005 18:48:34 open("/etc/OpenCL/vendors/nvidia.icd", O_RDONLY) = 6
25005 18:48:34 open("/var/lib/nvidia/100", O_RDWR|O_CREAT|O_TRUNC, 0100400) = 7
25005 18:48:34 fstat(6, {st_dev=makedev(8, 17), st_ino=3515567, st_mode=S_IFREG|0400, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=22, st_atime=2014/05/14-18:48:34, st_mtime=2014/05/14-18:20:02, st_ctime=2014/05/14-18:48:26}) = 0
25005 18:48:34 lseek(7, 21, SEEK_SET)   = 21
25005 18:48:34 write(7, "\0", 1)        = 1
25005 18:48:34 mmap(NULL, 22, PROT_READ, MAP_SHARED, 6, 0) = 0x7fc39d14b000
25005 18:48:34 mmap(NULL, 22, PROT_READ|PROT_WRITE, MAP_SHARED, 7, 0) = 0x7fc39d147000
25005 18:48:34 munmap(0x7fc39d14b000, 22) = 0
25005 18:48:34 munmap(0x7fc39d147000, 22) = 0
25005 18:48:34 fchmod(7, 0100400)       = 0
25005 18:48:34 close(6)                 = 0
25005 18:48:34 close(7)                 = 0
25005 18:48:34 utime("/var/lib/nvidia/100", [2014/05/14-18:48:34, 2014/05/14-18:20:02]) = 0
25005 18:48:34 unlink("/etc/OpenCL/vendors/nvidia.icd") = 0
25005 18:48:34 write(5, "100: /etc/OpenCL/vendors/nvidia.icd\n4168248298 100400 0 0\n", 58) = 58
25005 18:48:34 close(5)                 = 0
25005 18:48:34 munmap(0x7fc39d14c000, 4096) = 0

There are work-arounds - the current documentation for installing proprietary Nvidia drivers has some hints - but they're all ugly. It'd be much easier if end users can just run sh NVIDIA-.... --no-kernel-module --no-x-check to install the drivers in a new client. Plus, whatever is causing this could pop up elsewhere.

To ease debugging, it may be useful to see if this can be repeated with a smaller/simpler program that repeats the relevant system calls rather than use the entire Nvidia driver installer.

dbus things should be global

Dbus is used for inter-process communication. Ideally, this should be
cross-client. However, as of Bedrock Linux 1.0alpha4 Flopsie, dbus does not
communicate across clients with the default settings. This is probably because
some things which are currently local should be global. These include:

  • /etc/machine-id
  • possibly some stuff in /etc/dbus-1
  • possibly some stuff in /var/run/dbus or /run/dbus

Investigation should be done and then the recommended defaults should be changed accordingly.

Debug flag/config for brp/bru

As of Nyla, both FUSE filesystems, brp or bru, require recompiling to enable
debug. This should be more readily accessible.

Have bru mount under source of bind mount

Currently if bru is restarted it is mounted over the source of the bind mounts that propogate it to the other clients. If there is some way to have it mount itself under the bind mounts that would be preferable.

SDL2 cannot configure joysticks if udev not from same client

As of Bedrock Linux 1.0alpha4, SDL2-based programs only recognize joysticks if
udevd is running and provided by the same client that provides the SDL2
program. This is problematic in that udevd is a singleton but multiple clients
could provide SDL2 commands.

Investigation should be done as to how SDL2 communicates with udevd in order
to remedy this.

Move hijack distro to its own stratum, off rootfs

As of Nyla, hijacking an install results in the hijacked distro as the rootfs.
This has a number of down sides:

  • While technically possible, it is non-trivial to remove the hijacked distro.
    The fact that such a thing is possible is a key marketing point for Bedrock
    Linux; it should be made trivial to demonstrate.
  • This requires changing the bootloader config, which has proven to be both
    error-prone when done manually and risky to do in an automated fashion.

Thus it should be changed.

Several points to consider:

  • This is not a limitation of the manual install method; it is only an issue
    with the hijack install method.
  • The process will likely involve moving rootfs files, global files, and the
    hijacked distro's files to separate stratum.
  • Copying the files is potentially problematic, as the user may have very large
    files which would be copied (e.g. global files in /home) and the disk usage
    could be unacceptable.
  • Moving the files/directories would be relatively swift, but only if
    everything is on the same partition. Automation/instructions here must be
    very careful about checking the partition setup in the hijacked distro. If this cannot be done consistently due to complexity here, ensure the merged hijacked/rootfs/global stratum option remains.
  • Moving the files needed while the system is running is risky. Instead,
    have the files moved around during the brn pre-boot period.
  • If it happens at brn, this largely requires the process to be automated, as
    users will not be able to do things such as check documentation or IRC at
    that point if limited to that machine.
  • To ensure brn is while the hijack process is incomplete, it should move/copy
    the current /sbin/init and/or /lib/systemd/systemd and place itself in those
    locations, then restore during hijack process after it has rebooted while it
    is running.
  • Aliases would be much less useful, as we could then ensure rootfs and global are stand-alone strata. However, aliases would still be useful for tracking which stratum provides init. Moreover, the local stratum alias has been found to be useful. The balance of complexity vs usefulness of aliases should be revisited once this is done.

support shutdown command

A number of commands talk to init to shutdown the system, such as poweroff,
halt and shutdown. These have to be init-specific, meaning clients versions of
these commands will not function properly. However, those from the core Bedrock
busybox do work. Thus, brc-wrapped version of halt and poweroff can be placed
at the beginning of the PATH to ensure function versions of these commands are
available from clients. However, busybox does not provide shutdown. Another
solution is needed to support the shutdown command.

Ability change bootloader, /boot directory

Ideally, the bootloader should be easily switched between reboots the same way kernels and init/pid1 are. If we allow each client to have its own /boot partition and its own package-manager-maintained bootloader it may be possible to pick which one to use by setting the bootable flag on the relevant partition and rebooting. Further investigation should be done.

Consider moving everything out of "real root"

As of 1.0beta1 Hawky, bedrock-as-a-client is in the "real root" and the other clients are all technically chroot()ed. This causes some confusion and may in fact be unnecessary. This issue has one potential solution to the confusion; namely, break bedrock-as-a-client up into two clients: global and fallback. While this may assist somewhat, global is still in the real root while the other clients are not.

An alternative layout would be to have no processes running in the real root. The root directory would simply be a collection of directories, one for each client, and possibly /bin/busybox and /sbin/init. (This would mean "sbin" is an illegal/reserved client name).

The only thing expected to run in the real root would be the pre-init process (and only for a short time), and mount commands. brc could support a special real-root option for these mount commands.

The primary down side to this strategy is that may make things more difficult to debug. The main advantage is that things would be "more pure" - no running process would be "special" in any way.

However, the downsides are plentiful:

  • Things will be more difficult to debug.
  • Mounting could be very confusing without being able to "see" what is going on directly.
  • Lots of catch-22s with things like /proc and /dev being mounted. Should they be mounted in the core? If so, the core is again special.

brt - installer/updater

The majority of Bedrock Linux's files are acquired from and maintained by other
distributions. Updating this software is done by the same means it is
typically done on the respective client distributions. However, a handful of
files will be specific to Bedrock Linux and, thus, Bedrock Linux's
responsibility to maintain. Hence, a new utility to manage this: brt, or
"BedRock insTaller/updaTer".

Bedrock Linux has a relatively small development team; there is no where near
enough manpower for a dedicated security team to watch for security issues and
push out updates in a timely manner. Considering this, the plan is to have the
updater:

  • Attempt to query version information for upstream core components, to make it
    easy for the end-user to know when an update is needed. This would be
    conceptually similar to commands such as apt-get update. For example, if
    the given Bedrock Linux system is using busybox 1.22.1 and 1.22.2 is pushed
    out, this would be able to detect this and notify the user.
  • Be able to automatically acquire the updated source, compile it and replace
    the relevant files with the updated versions. The current plan is to
    continue keeping the core relatively minimal, and thus some client must be
    able to provide commands such as gcc for this to work.
  • It is highly unlikely such a system will work reliably. Upstream core
    components could easily break something such that a human is required to
    remedy it. While this can be partially alleviated by having Bedrock Linux
    developers regularly update brt to reflect upstream changes, brt's entire
    design revolves around the fact that this may not happen sufficiently
    frequently to ensure end-users are secure. To minimize the chance brt may
    update something in a way that breaks it, brt should (optionally) run a
    test suite before actually installing the updated version of the file.
  • Since installation can be thought of as just updating multiple non-existent
    files with their existent equivalents, the same codebase will be used for the
    installer. Quite possibly the exact same file(s); the run-me-to-install
    executable in the root of the repository could be a symlink to wherever brt
    is placed (presumably /bedrock/bin/brt) This is preferable over
    distributing binaries when installing for the same reason it is preferable as
    an update mechanism: the limited development team may not be able to update
    things sufficiently frequently to ensure newly installed files have all of
    the latest bug fixes.
  • For a number of reasons, the majority of Bedrock Linux's core utilities are
    intended to be very portable and low on requirements. In general, they are only
    reliant on busybox (or, alternatively, GNU coreutils). However, brt may
    require a handful of items from clients / the installer host, such as gcc,
    make and git. When installing, attempting to acquire such items might
    result in a catch-22, as such items may be required to install them.
    It is not clear at this point if they will be included into the core so that
    brt can run independent of clients or if they will be required from the clients.

Build system fails in Alpine

It appears libattr is using the system gcc, not the constrainted musl-gcc, and
fails to build in a musl environment.

bru reference files under its own mount point

From a high level, what bru does is redirect any filesystem requires going
towards a specific list of files elsewhere (the "alternate" files). For
everything else (the "default" files), it should act as a pass-through,
delivering the same exact functionality that would be available if it was not
mounted.

For bru to do this, it needs:

  • to be mounted over a directory that will contain all of the relevant
    filepaths. For example, /etc.
  • access to the "default" files. For example, /etc.
  • access to the "alternate" files. For example,
    /bedrock/clients/global/etc/.

Note that the mount point and the default files root are both actually the same
location. This leads to a problem - bru cannot pass-through to the default
locations, as it would then be querying itself for what to do (which would then
be an infinite loop).

As of Hawky, bru resolves this by ensuring the "default" files are accessible
at another location it can reference. Specifically,
/bedrock/clients/<client-name>/<path-to-mount-point>. For example, a bru
mounted on /etc in client wheezy can see the file /etc/issue at
/bedrock/clients/wheezy/etc/issue.

The fact the files which bru will mount over are available elsewhere is a
side-effect of Hawky's design. It was, in some sense, "free" - those files
were going to be available there anyways. Nyla, however, will change things
such that that may no longer be the case. While we may be able to create
additional directories and mounts to resolve this, it is undesirable.

An alternative solution would be to alter bru so that it can see under its own
mount point and reference those files instead. This is preferable in that it
does not require we create more directories and more mounts, and is also
desirable in that bru will take fewer arguments and function more naturally
to how a user (who is not considering the technical, underlying details) would
expect it to.

Try this:

  • In terminal "A":

    mkdir -p /tmp/test
    cd /tmp/test
    touch foo bar baz

  • In terminal "B", as root:

    mount -t proc proc /tmp/test
    cd /tmp/test
    pwd
    ls
    ls /tmp/test

  • Back in terminal "A":

    pwd
    ls
    ls /tmp/test

  • Clean up with (in any terminal, as root):

    cd /
    umount /tmp/test
    rm -r /tmp/test

Both shells think they're in the same pwd, but actually see different things,
when they use a path relative to their pwd. When they use an absolute path,
they see the same thing. The plan is for bru to do this same technique so that
it can see under its own mount point.

Broadly, there are two strategies. In theory, we can mix-and-match components
from both, although it may be desirable to use as much as we can from one for
the sake of uniformity.

One strategy is to set the present working directory to the mount point
before it is mounted. Then, reference the "default" files via a relative
path. That is, do a chdir("/path/to/mount/point") in FUSE before calling
fuse_main(). Then, in all of the individual filesystem call functions,
reference the specified file via a relative path, e.g. stat("path/to/file")
not stat("/path/to/file"). The "alternate" files can be accessed via the
full path. This is effectively the same thing we did with the shell example
above.

Another strategy is to utilize a family of Linux filesystem calls which
reference, instead of the pwd, a file handler. With this strategy, bru would
open() the directory under its mount point and store the file handler before
calling fuse_main(). It would then reference this whenever it wants the
"default" file. One could also open() the "alternate" file directory root.
Then each filesystem call would simply have to choose which file handler to
reference.

The filesystem calls which operate relative to a file handler - instead of the
pwd - tend to have the same name as the "normal" filesystem call, but with "at"
appended at the end. For example, renameat() and unlinkat. There are
equivalents to these for many - but not quite all - of the filesystem calls.
For many of these exceptions, there is another family of calls that work on a
file handler directly instead of a file path; these tend to start with "f".
For example, fstat() and ftruncate(). One can, thus, use openat() -
giving it a reference file handler - and get back another file handler to pass
to fstat().

The pwd-based strategy is preferable in that it requires fewer changes to the
current bru code base, as we can use all of the same filesystem calls - just
ensure the path is relative if default, or use the full path if alternate.

The file handler-based strategy is preferable in that there is much less string
manipulation; no need to take an incoming absolute path and either drop the
leading "/" to make it relative or concatenate it to the alternate root.
However, it will require changing a fair number of lines of code to use the
*at() versions of the libraries.

In theory, we could implement some filesystem calls one way, and implement some
another; however, a uniform strategy would be preferable.

filename assumptions

Much of Bedrock Linux currently assumes file names do not contain characters such as whitespace, commas or colons. These assumptions should be removed.

brp.conf differentiation between directories and files in value

As of Nyla, brp.conf does not differentiate between directories and
non-directory files in the value side of the key-value pairs.

For example:

/bin/ = /usr/local/bin, /usr/bin, /bin, /sbin/initctl

brp is not aware of the fact that /sbin/initctl is a file and could be treated
differently from the directories.

shell tab-completion

Bedrock Linux has various utilities. Tab-completion for these utilities should be provided for major shells such as bash, zsh and possibly the less well known ones such as fish.

`bri -w` should indicate which client provides file (local vs global)

As of Hawky, bri -w will indicate which client will provide an executable via
the $PATH. For example:

$ bri -w vim
wheezy (direct)
$ bri -w pacman
arch (implicit)

If a slash is provided - indicating this is referring to a specific file on
disk and not from the $PATH - bri -w should indicate which client will
provide that file, and whether that file is local or global.

A loop over the equivalent path in all clients comparing stat output should
work for everything except bru files. If it is possible for bru to report
the underlying device to stat, this technique could be used everywhere.
Otherwise, some other strategy will need to be pursued.

sharing /var/run and /run

/var/run and/or /run should be shared. This is necessary to solve, for example, this issue.
Changing the default framework to include a bind = /run would appear to solve this and presumably other issues if it was not for the fact that some distros use /run while others use /var/run. This makes things tricky.

  • We cannot assume all client distros have moved to /run, as users may want to use older distros. Thus we cannot just share /run.
  • We cannot assume all software still uses /var/run (and just follows the symlink to /run). If /run exists as its own thing, people will use it.
  • We cannot put a symlink in the core from /var/run to /run (like many other newer distros do) and simply bind mount both /run and /var/run as a way to force older distros to act like the newer ones because the mount command appears to follow symlinks for both source and destination. There does not appear to be a flag to disable following symlinks in that situation.
  • We cannot bind mount /var/run over /run (or the other way around) and then share both of those, because, like the above item, mount follows symlinks.
  • We cannot share both directories as normal directories, as some distros may have programs use one and others may use the other.

Possible solutions:

  • Assume all clients have the symlink from /var/run to /run, and simply document this expectation.
  • We could hardcode brs to setup the /var/run to /run symlink in the clients or add some configuration option for specifically this, but I'd rather avoid that if we can. Ideally as much as possible should be generalized.
  • If we do have to add a new setting for this, perhaps it could be a setting to copy from the core/global over anything in that location on the client. This could then be used to blow away any existing /var/run and place a symlink over it. An accompanying bind setting on /run would then create /run in the core.
  • Testing should be done to confirm this, but bru should handle symlinks "correctly" such that we could union /var and simply set /run to be shared in it as a way to force symlinks to be shared. However, bru would be unnecessary overhead if we can think of alternatives.
  • Could add a new setting or config syntax to decouple the source and mount locations for bind mounts, so that one could ensure /run in some clients and /var/run in other clients are the same thing. However, this would require knowledge on when which is necessary; it would not "just work".
  • Could add a new setting to client.conf to copy something from the core on setup that would clobber anything from the client. However, this would result in unnecessary writes once it is done. The core's version could be touch'd to update timestamps to compare to avoid needlessly overwriting the same thing over and over.
  • Could add a new setting to client.conf to run a command on brs up. This would then have a default which checks if the client needs the symlink or not and create it accordingly.

brp rootfs

FUSE filesystems can't self-reference, as this results in an infinite loop which locks the system. brp needs to detect this scenario for the rootfs configuration item and handle it accordingly. For the time being, users can simply remove the rootfs configuration item from brp.conf.

Strategies for brp to detect this scenario:

  • Check if the fuse context indicates brp's pid.
    • Tests found this does not seem to work, despite the fact it feels like it should. More research necessary.
  • Check if the mount point for the given item is fuse.brp. This is potentially rather expensive as it has to be done quite a lot.
  • Check if the input path contains the mount point string (i.e. "/bedrock/brpath"). The problem with this is that there is no guarentee the user does not bind-mount the mount point into a completely different path.

Global mount propagation

As of Bedrock Linux 1.0alpha4 Flopsie, any mount points mounted at run time are
local to the client that mounts them. There should be a way to make these global.

Linux provides "share subtrees" which should function as a solution here.
Broadly, it works like this: Parts of the filesystem tree can be mirrored
elsewhere via bind-mounts. If these are set to be shared, then any time a
mount or unmount event occurs in any occurrence of this part of the tree, the
event is propagated to other parts of the tree.

brs should be tweaked to support this.

Various thoughts:

  • We cannot cleanly simply enable this everywhere, or otherwise any given local
    filepath would be replicated across all clients (defeating the entire point
    of local filepaths). Instead, we should only enable mount propagation on
    things that are explicitly set to be global.
  • We do not want mount propagation to occur in /bedrock/clients as everything
    in there is supposed to be local. Thus, we cannot simply make all global
    items propagate mount points. Moreover, the user may desire setting some
    mount point in only some clients for some unforeseen reason. Thus, a new
    clients.conf item should be added which acts like bind but propagates mount
    points so that the user can configure accordingly. This could be called
    shared. This would likely include all of the defaults except anything
    that falls in /bedrock to ensure explicit paths are not confused. Note
    that this would remove the need for a setting for /dev/pts and /dev/shm/
    as they would automatically be covered from a shared = /dev.
  • Note that this only effects mount points which occur while the subtree is
    mirrored. This can be solved by simply mounting shared items with --rbind
    rather than just bind so that any mount points at that point are included.
  • Note that when taking a client down, one must be careful not to propagate its
    umounts. Its mounts can be removed without propagating them by explicitly
    labeling them as not shared via mount --make-private.
  • Note that the mount points are made into shared subtrees, not directories.
    If the given directory is configured to be shared via clients.conf and it is
    not already a mount point, it must be made into one by bind mounting it to
    itself, then setting this mount point to --make-shared. The main problem
    here is that we have to be careful not to "leak" mount points by leaving them
    behind in the core after mounting all clients that use it.

simplify bind/union/share configuration

As of 1.0beta1 Hawky, Bedrock Linux provides multiple methods to specify which
files should be considered global. Different options have different
characteristics and implementations. As a result:

  • The user has to read and understand a fair bit of documentation
  • There are multiple separate chunks of code for each method.
  • Detecting which method is used can be tricky.

It may be possible to simplify things down to shared bind mounts in most
situations. To do this, the following changes will be needed:

  • What is now bind - namely, a private bind mount - may no longer be
    necessary. There is a limited to how much shared items propagate
    recursively; we may be able to leverage this to ensure that client's views of
    /bedrock/ - and, by extension, their self-view in /bedrock/clients/ -
    retain the desired properties without forcing them to be private mounts This
    has the added benefit of lessening the amount of configuration required. It
    is possible all of /bedrock will be properly shared with a single
    configuration item.
  • bru will have to be rewritten to function more like brp, so that it is
    mounted once in the core/global and is then propagated into the clients via
    bind mounts. This will require bru determine where to redirect by checking
    the pid and then, from that, determining the appropriate client. This can be
    done by readlink'ing /proc/<pid>/root. There are two catches to that
    technique - it only works as root, and it does not differentiate between
    current and real root - but neither of these will hamper us in this specific
    situation.
  • We will still have to differentiate between what are now union and share
    items in the configuration file. However, this can be done differently;
    perhaps more cleanly. There will be a single configuration item which
    indicates that a given item should be shared. This will include things like
    /proc and /home as it does now, but it will also include things such as
    /etc/passwd and /etc/shadow directly. As a result, the code which checks
    if a given share is in place can simply compare the outputs of busybox stat
    on the files (after filtering out the path to the files) to ensure they are
    the same. An additional configuration item will be used to indicate that
    everything shared in a given directory - namely, /etc - should be
    implemented via union rather than bind mounts. This part will be fed into
    bru. bru, like brp, may contain a "reparse_config" file to be notifed that a
    given client's config may have changed or that a client has been added or
    removed.

bru TODO items

bru still has unimplemented FUSE functions in its source, marked with TODOs. These should be implemented.

separate client configuration from client state

As of Hawky, Bedrock Linux convolves client configuration (e.g. framework = default) with client state (enabled vs disabled). It also retains the last
state on reboot, which may not be desirable.

This should be broken up into separate things. There should be configuration -
presumably a file at /bedrock/etc/clients.conf and a drop-file-in-dir at
/bedrock/etc/clients.conf.d. Then, separately, the current state would be
managed. Maybe touch/rm files in /bedrock/run. Moreover, which clients
should be enabled at boot should be its own configuration item, separate from
the clients enabled at shutdown. Separating this would allow a user to easily do
something like boot with a specific client as init, then disable all other clients (except global) to debug possible conflicts between clients, then upon reboot see all the expected clients. Or, alternatively, enable a client typically disabled without having to explicitly disable it again before shutting down.

brsh login shell, possibly drop brsh

Currently, brsh uses a very hacky solution for guessing whether or not it is
being launched as a login shell. Moreover, instead of properly passing the
this-is-a-login-shell information to the shell it calls, it simply sources
/etc/profile itself and passes everything as environmental variables.

Ideally, we should have brsh "correctly" detect that it is a login shell, and
then inform the calling shell in the same manner it was informed.

Even better would be dropping brsh completely, if we can make things work without it.

Support getting init from a client

Bedrock Linux should support getting an init from a client. There are a number
of things that make this tricky, but it does seem like it might be possible.

Various thoughts:

/sbin/init, the first process run, should be a Bedrock Linux program. It
will likely be a shell script. This will read some configuration to
determine which init the user desires from which client and then proceeds to
do setup work for that particular init. The setup work will do things such as:

  • Standardize existing mount points to be what the target init process expects
    the initrd to have created.
  • Do setup work the target init may not do, such as setup the core and/or other
    clients.

When Bedrock Linux's /sbin/init finishes setup, it will exec() to brc which
then exec()'s the target init. Using the exec()s for this is important
because some inits, most notably systemd, require being PID1. When performing
an exec() the PID does not change between the parent and new executable -
they're effectively the same process.

It may be necessary to have the target init call something to finalize
bedrock-specific setup when the target init's one-time setup is done, if that
type of thing could not be done by Bedrock's /sbin/init before hand without
messing up the target init.

It may be useful to have /sbin/init start a getty in an unusual place, such as
TTY9, as a fall back in case the client init fails. We may want to wrap this
getty in a loop so it automatically restarts.

Once implicit path pinning is setup, that should ensure the target init's
commands - such as systemctl - are provided by the exact same client providing
the init.

It may be wise to have brs refuse, or at least warn, about disabling the client
providing init, as that will likely crash the entire system.

Code to merge /etc files

In order to do things such as:

  • Copy a pre-existing distro install as a client which already have non-trivial users and groups
  • Dual booting with a client
  • Making Bedrock Linux into a live system which can pick up existing on-disk systems

Bedrock Linux needs to be able to (1) merge in the contents of some /etc files - particularly passwd and group - to the rest of the system when enabling the client and (2) sync the files back to the client when disabling (for dual-booting or live disks).

Hooks to do these operations at the right time are under way, but the scripts themselves should be written.

Various situations to consider:

  • If the only differences between the two versions of the files do not overlap in name or ID, should be easy to merge. When disabling a client, if Bedrock Linux added a new user or group, this will most likely be the situation.
  • If both versions include the same user/group name but different IDs, or the same ID, things get complicated. Possible solutions here include:
    • A script to run over the client and change the user/group names and IDs to things that do not overlap (which could take a rather long time to run)
    • Using UID/GID namespaces somehow so the UIDs and GIDs translate at runtime. This is problematic for things like the explicit path, however.

brg

There should be a tool to automate acquiring clients. Tools like debootstrap and pacman can make a client, but they largely depend on a similar client already existing due to dependencies. This tool should be very portable to avoid that limitation. The tentative name for the tool is "brg".

Separating bedrock-as-a-client into global and fallback

As of Bedrock Linux 1.0beta1 Hawky, a chunk of the system usually referred to
as "the core" or "bedrock-as-a-client" serves multiple purposes in a way that
is not immediately clear to new users.

  1. It serves as the location where the one copy of global files reside.
  2. It provides basic services, such commands like ls and sh, in case other clients fail to do so.

The core shows up in commands such as bri -l as "bedrock". This name does
not imply either of the services it provides. Moreover, it results in a bit of
a smurf-style filesystem. When installing Bedrock Linux, users will have a
/mnt/bedrock/bedrock/clients/bedrock path. The word "bedrock" loses meaning
in such situations. It also seems to encourage the idea that Bedrock Linux is
doing something similar to containers, as some of the system is chroot()'d
while some is, debatably, not; this results in a fair bit of confusion.

To remedy the above issues, bedrock-as-a-client should be broken up into two
clients: "global" and "fallback".

Global will only contain (1) global files, (2) the /bedrock directory (which
contains various Bedrock Linux subsystem related executables, the clients,
etc), (3) /boot, and (4) /sbin/init as is needed for this
issue
. Global
should not have a /etc/init.d/ or /bin/ directory in its root or anything
else that is typically local. /sbin/init will call /bedrock/bin/busybox to
get its required executables. It will be technically possible to run a shell
with global files as the local files it via brc global /bedrock/bin/busybox sh. The only processes that will be typically run in global are: /sbin/init
(and only for a short time to bootstrap another client's init) and brp (as
the filesystem it makes should be global). Global will not have a client.conf
file - its access will be hardcoded into the various Bedrock Linux utilities.

Fallback will be technically optional but recommended. Fallback will contain a
/bin and other things which are typically expected to be available on a Linux
system, albeit a minimal version. It will provide a minimal init - effectively
what is being used as of Hawky as the init. It will use a client.conf like
every other client; it can be disabled or removed entirely.

Convert existing, installed distro into Bedrock Linux

Ideas brought up in other issues, such as:

when taking together end up providing general framework for making Bedrock Linux installable "over" an existing distro.

The requirements would be:

  • Having everything Bedrock Linux needs at runtime to be in /bedrock. This should be quite do-able. The only thing that really has to be outside of it is the pre-init, in order to implement getting an init from a client. This could just be symlinked in place.
  • Have the client which client provides the global files be configurable. If installing onto a pre-existing distro, that install's global files can continue to be used.
  • Have the pre-init script read configuration in /bedrock and do the setup, including pivot_root'ing the client which will provide init into the real root.

With those things in place, what is the "real root" at boot time won't matter, as everything will be shifted around. Thus a pre-existing client could be real root. There won't be any need to worry about the global files, as we can just configure them to be the pre-existing distro. Users will be able to "uninstall" Bedrock Linux by just restoring /sbin/init and removing /bedrock.

We could distribute packages (e.g. .debs, .rpms, etc).

direct brc access should not use implicit

To specify which version of a local file is accessed, one can:

  • access it directly
  • access it implicitly
  • access it explicitly

For simply reading or writing a file, explicit access is just prepending a certain string to the front of the path to the file, e.g. vim /bedrock/clients/sid/etc/apt/sources.list will explicitly specify sid's /etc/apt/sources.list. However, this does not work for executables, because the executable will be confused if its local context does not change accordingly. In this situation we use brc, e.g. brc sid vim /etc/apt/sources.list will explicitly specify sid's vim (and change the local context as is needed).

Confusion arises when one uses brc to access something which is unavailable in the specified local context. Currently, in that situation, it falls through to implicit access. While this is completely managable if the user is on his/her toes, it is potentially confusing to people who are not accustomed to it. For example:

  • Only two clients, wheezy and sid.
  • wheezy has vim, sid does not
  • brc sid vim will launch wheezy's vim, not sid's, because sid doesn't have one and so it falls through to the implicit path.

Another example:

  • Only two clients, wheezy and sid.
  • Both clients have man, but only wheezy has the man page for vim.
  • brc sid man vim will get wheezy's vim man page, not sid's, because sid doesn't have such a man page and so it falls through to the implicit path.

This falling-through-to-implicit is an important part of how Bedrock Linux works and is generally a good thing to have. This way if any client provides something it will be be accessible no differently from how it is accessible natively. However, it is often only expected when not specifying something explicitly. When something is specified explicitly, people expect that version.

In these situations, it may be best to not use the implicit path for that one command. If something is not available directly, it should error out as thought it was never available at all. Implementing this may be tricky and/or require overly much resource overhead. In which case we could abandon this and simply require users understand what is happening in this situation.

There are two obvious ways to go about this: having brc detect and handle the situation, and having brp check and handle the situation.

  • brc could check if the given executable is in the $PATH without the implicit path items. However, this would not work for the man page situation above.

  • brp could (somehow) detect that the given command was just executed via brc and disable itself for any accesses by that exact PID. However, this would disable the implicit path for other situations wher it is desirable. For example:

    brc wheezy vimdiff /usr/share/applications/openbox.desktop /bedrock/brpath/applications/openbox.desktop

Would not work.

pre-brt installer

Plans/thoughts for/on the Bedrock Linux installer:

Bedrock Linux, as a project, is about leveraging pre-existing software. Philosophically, we try to avoid re-inventing the wheel if we can just use some other distro's solution instead. Installation is no exception: plenty of other distros already provide live system images which could be used to install Bedrock Linux; there is no need for Bedrock Linux to have its own branded live system image for an installer. Instead, we'll portable installation software that can run on some other distro (or another instance of Bedrock Linux), be it a live cd, an installation on another partition, or even changing an existing installation of another distro into Bedrock Linux.

Moreover, the project tries to maximize choice. If users want to install with some obscure live cd, that should be an option if we can make it one. The installation software should be as portable as we can make it. No relying on GNUisms - if a user wants to install with a busybox-based system, we should support it. Note that utilizing GNUisms for non-essential functionality is fine (e.g. GNU tar auto-detecting and auto-decompressing compressed tarballs, so long portable as alternatives exist for the essentials. Given the portability requirement, an installer cannot require a GUI. In general, smaller code bases are preferable; whether or not to allow an alternative GUI installer (maybe a wrapper around the CLI installer) has not yet been decided.

A long-term goal is to have an updater. Due to the design discussed there, it will need to be source-based. For the time being, the installer should also be source-based (i.e. we won't distribute binaries) in order to aid testing for what will eventually become a dual installer/updater.

In addition to being able to install a fresh system on newly formatted partitions, the installer should be able to convert an existing non-Bedrock install into Bedrock Linux. In addition to being able to do it in-place, we should investigate having the installer be able to kick out packages (.debs, .rpms, etc).

brc execvp error message

brc should give a better error message than "execvp" in contexts where it arises. This should be a trivial change - just replace the perror() line.

Notify application menu to refresh

Application menus do not seem to always refresh when a .desktop application is added. Investigate if they normally do without Bedrock Linux, and if so see if we can ensure they do with Bedrock Linux.

Note that Bedrock Linux does not, currently, have any hooks that run when a package is added via a package manager - updates to the .desktop file list happens on-the-fly when requested. We can't simply update the timestamp on a directory to trigger inotify, for example. At least not at the moment.

share xorg fonts

Like everything else, xorg fonts should "just work". Install a font
into one client, start xorg from another client, the font should show up
just like any other font.

To do this, we need to get the directories containing fonts into the xorg "font
path". Sadly, this is not as simple as adding them to a environment variable,
but it looks like it should still be doable.

Steps:

  • Create a global /etc/X11/xorg.conf.d/99-bedrock-xorg-fonts.conf which
    contains:

      Section "Files"
              FontPath "/bedrock/brpath/fonts/"
      EndSection
    
  • Add /etc/X11/xorg.conf.d/99-bedrock-xorg-fonts.conf to the default framework's /etc/ union

  • Add a new brp filter which will merge the contents of font.dir files. This
    shouldn't be to bad, as it is almost entirely just a bunch of lines which can
    be concatenated.

  • Add a new /font line to brp.conf which includes all of the common font
    directories, under the new font merge filter.

After that it should "just work". The only user configuration necessary will
be to add new font directories if a font is installed outside of the default
set. It should be possible to programatically query major repos for all of the
font directories they use to catch the big ones.

client aliases

Nyla will most likely add four aliases for clients:

  • "pid1" (or maybe "init") for the client that provides pid1
  • "rootfs" (or possibly something else, still open to suggestion) for the client that provides the bootloader / the client whose root directory is root at very early boot
  • "global" for the client that provides the global files
  • "local" as loop-back to the current client, roughly conceptually requivalent to something like "localhost".

Support for this should be generalized so that users can easily make their own client aliases. For example, if a user would like to alias "testing" to "jessie".

This will be implemented by having "client.alias" symlinks in /bedrock/etc/clients.d/ which point to the desired client. The various bedrock utilites will resolve the symlink accordingly. Moreover, symlinks will be required in /bedrock/clients/ to support explicit path calls.

Client enable/disable hooks

We should have hooks to run something before and after enabling and disabling a
client. This could have numerous uses:

  • This could be used to solve forcing the creation of symlinks in certain
    locations, which would solve these issues:
  • Be used to sync global files with the local ones in clients on enable/disable
    so Bedrock Linux could dual-boot with the client.
  • Be used by end-users for anything we forgot, rather than requiring them to
    make their own client.conf setting, which would require editing bri and brs.

The hooks could be added to client.conf files in order to utilize frameworks. These new client.conf settings could be called:

  • preenable
  • postenable
  • predisable
  • postdisable

There is no need to add a setting for whether or not these are blocking, as the
scripts they call could simply fork if they intended to be non-blocking.

Desktop environments should show up in Xorg login managers across strata

As of Nyla, Xorg login managers will only list Desktop Environments from the
same strata. They should list across strata.

Xorg GUI login managers look for .desktop files at /usr/share/xsessions/.
/usr/share is the default $XDG_DATA_DIRS value; it is possible Xorg GUI
login managers iterate over this variable, in which case we could
union/exec-filter /usr/share/xsessions via brpath. This would be ideal.
However, some some quick searches and tests with this in mind did not work out.

Attempt to handle grsec kernel chroot hardening

Grsec hardens chroot() in a fashion which breaks Bedrock Linux. It may be possible for Bedrock Linux to disable this functionality via writing to /proc. It may also require recommending changes to a grsec-specific config in the docs.

implicit path

Bedrock Linux's solution for the "implicit path" as of 1.0alpha4 Flopsie is insufficient.

Some background:

Bedrock Linux has four categories of file paths:

  • Any file accessed over a "local" path will appear to be the version unique to
    that client/distro. This includes things such as /usr to keep package
    managers from fighting with each other.
  • "global" files are ones which are the same irrelevant of which client
    provides the process looking at it. These include /home and /tmp
  • "explicit" file paths are used to let processes from one client access
    "local" files from another client. For example, to use a Debian client's vim
    to read an Arch Linux client's /etc/issue. As of Flopsie, these are accessible at /bedrock/clients/<CLIENTNAME>/<PATH_TO_FILE>
  • "implicit" paths are paths which need to be accessed globally in some
    automated fashion yet cannot be global or package managers will fight over
    them. Examples include:
    - Executables. Any process should be able to run any executable it has
    the permissions to run, irrelevant of which client provides which
    executable. However, these cannot be global or package managers will
    fight over them.
    - man and info pages. The man command should be able to pull up a man
    page provided by any client, irrelevant of which client provides either
    the man page or the man command. If these are local, then only the man
    command from one client will be able to utilize that client's man
    pages. If they are global, package managers will fight over them.
    - freedesktop.org icon/shortcut files. In order for a desktop
    environment's application menu to properly detect applications from
    other clients, it needs to see them, and so they cannot be local, but
    the package managers would conflict if they are global.

A few notable design limitations of the implicit path:

  • Like the explicit path, this cannot be a typical file path used in other
    distros. For example, one cannot make /usr/bin/ the implicit path or
    package managers will fight over them. Instead, it should be put in
    /bedrock like the explicit path. Thus, to be recognized by things like the
    man utility and the execvp system call there must be a way to inform
    these the relevant software about the new location. This is being done via
    environmental variables which should be set in the /etc/profile file so
    they are loaded at login shell. The relevant parts of the implicit path
    should be added to:
    - The PATH variable so executables are recognized there.
    - The MANPATH and INFOPATH variables so man and info recognize them.
    - The XDG_DATA_DIRS variable so freedesktop.org icons/shortcuts are picked up.
  • Multiple clients may provide the same item in the implicit path. For
    example, multiple clients will likely provide the sh executable. To ensure
    executable dependencies are correct (e.g. programs that assume sh is
    provided by bash get bash, and programs that assume sh is provided by
    dash get dash), the "typical" contents for the PATH variables should be
    before the new implicit path items. Only if the client does not provide
    the executable/manpage/etc should it be picked up from another client
    automatically. If the user wants a specific version that is not local,
    he/she can use brc to specify.
  • While the above priority rule is a sane default, there should also be a way
    to specify a given client always provides the given item. For example, if
    multiple clients provide the startx command but the user wants startx to
    always be provided by the same client, there should be a way to set this.
    This setting could simply populate items in the PATH variables before the
    "typical" ones.
    - This will mean if a user attempts to specify exactly which version
    via brc, such as using brc arch sh to run an Arch client's sh
    command rather than the set always-use-this version, it may not do
    what the user expects. Work-arounds for this have been proposed but
    are all ugly. They include having brc manually scan the PATH
    instead of calling execvp() in order skip the always-use-this items
    or having brp detect that brc is being called and disable the
    always-use-this items. Both of these only work for executables/PATH
    and not man pages or freedesktop.org icons.
  • Just as it should be possible to specify a client which always provides the
    given item, it should be possible to specify that the given client should
    always use the given item; i.e. for this item the implicit path should be
    effectively disabled. This is important for python, where various things
    have been found to be confused about python due to "viewing" multiple
    client's versions of python via python/python2/python3 executables.
  • Some of the implicit path items may need some alteration in the new implicit
    path location. For example, an executable cannot be directly run from
    another client as the local path items will not have changed. Instead, the
    implicit path executables should be wrapped in brc. Similarly, the
    freedesktop.org icons may include Exec= lines with full paths that will not
    work in another client; these must be filtered to either the correct full
    path in the new client or, perhaps preferably, have no path so the implicit
    system takes care of it, or include a brc. Other items like man and info
    pages can be used directly without alteration. In fact, instead of including
    their contents the implicit path items for man/info pages may be symlinks to
    the explicit path items for them.
  • Caching the implicit path contents (as is done in 1.0alpha4 Flopsie via the
    brp command, although only for executables) will have the best performance
    when the cache is up-to-date; however, failing to update it could be
    problematic. Having the user run brp every time one of the implicit path
    items changes should not be a requirement. Having a daemon automate calling
    brp would be problematic in case the user tries to do this mid-update.
    Proposed solutions include:
    - Having the implicit path be a fuse filesystem that always returns the
    right thing. If it needs to update something, it can block the
    filesystem request while doing this. This could figure out what is
    needed on-the-fly (which would be slow) or cache everything in RAM
    (which would use a lot of RAM) or on disk (which would write a lot to
    disk) and use inotify to watch for a need to update the cache.
    - Have the implicit path be a symlink that points to "real", on-disk
    content. A daemon would use inotify to watch for a need to change
    the on-disk content. When this occurs it would create a new
    directory and populate it accordingly, then adjust the symlink to
    point to the new directory. This symlink change should be
    effectively atomic to avoid any kind of race condition.

Currently, the implicit path items which are being considered are:

  • Executables / PATH
  • man pages / MANPATH
  • info pages / INFOPATH
  • freedesktop.org icons / XDG_DATA_DIRS

The following items should be considered:

  • Libraries / LD_PRELOAD
    - This is tricky because libraries could conflict with each other.
    Moreover, the use is limited because the client-specific package
    managers will likely take care of most library requirements locally.
  • Java / CLASSPATH
  • Python / PYTHONPATH

multi-thread FUSE filesystems

Both FUSE filesystems, brp and bru, currently run as single threaded. This can
significantly hamper performance as well as cause issues if a FUSE filesystem
tries to talk to itself. Investigate multithreading.

Too much mutexing will result in the same exact issues as the single threaded versions.

The Linux kernel apparently tracks IDs per task - and thus, per thread -
instead of per process as POSIX requires. This may be abusable to allow us to
seteuid()/setfsuid() each FUSE thread to ensure security stuff is properly
handled in the multithreaded environment without locks. Note that (1) glibc
goes out of its way to try to make seteuid() per process, POSIXy, and (2)
NTPL threading (which is standard now) similarly tries to ensure per-process
POSIXy ID handling (man 7 credentials). We'll have to try to bypass these.

kcheckpass not accepting password

KDE's password checker, kcheckpass - found at /usr/lib/kde4/libexec/kcheckpass - is used to check the password for the screen locker. This does not accept the correct password on Bedrock Linux.

Compile issues with busybox 1_24_stable

CC libbb/messages.o
libbb/messages.c:59:4: error: #error unknown path to wtmp file

error unknown path to wtmp file

^

libbb/messages.c:66:1: error: expected expression before β€˜char’
char bb_common_bufsiz1[COMMON_BUFSIZE] ALIGNED(sizeof(long long));
^
scripts/Makefile.build:197: recipe for target 'libbb/messages.o' failed
make[2]: *** [libbb/messages.o] Error 1
Makefile:741: recipe for target 'libbb' failed
make[1]: *** [libbb] Error 2
make[1]: Leaving directory '/tmp/bedrocklinux-userland/src/busybox'
Makefile:280: recipe for target 'build/bin/busybox' failed
make: *** [build/bin/busybox] Error 2

package manager manager

Currently, every client package must be managed from the package manager
corresponding to that client. This requires the end user regularly switch
package manager syntax (apt-get here, yum there, etc) which can be a bit
jarring. Moreover, these package managers do not intercommunicate and so
attempting to determine, for example, what client provides the latest version
of some package requires a non-trivial amount of work on the end-user's part.

All of this should be automated away by some tool which abstracts away the
client-specific package managers: a package manager manager (or "pmm").

Various thoughts:

The core of the package manager should be in POSIX-portable shell such that the
core's busybox can provide all of its dependencies. However, any client
package-manager specific functionality can rely on any tools those package
managers do. For example, since yum is written at least partially in python,
it is safe to assume python is available. Sticking with POSIX may be
preferable to avoid things such as the python 2->3 breakage, but is not
strictly necessary.

It is not strictly necessary that pmm be able to provide everything every
possible client package manager could provide. Attempting to translate
everything to closely may not be achievable in a sane manner. Instead, some
common subset of functionality should be targeted. If more functionality
appears strictly required by some package managers that is overly unique to
those package managers, some pass-through functionality could be provided to
"talk" directly to the package manager behind the scenes natively. Conversely,
not every client package manager must support every piece of functionality pmm
attempts to achieve. A fair bit of thought should be put into determining
exactly what the supported common functionality is before any actual coding
development starts for pmm.

Querying every client package manager for some things will likely end up to
slow. Instead, once the standard set of functionality is chosen it should be
possible to have pmm cache it locally.

It may be possible to have pmm cache information it gets online (mimicing, for
example, apt-get update) for distros which are not available locally as
clients. If a package is desired from one of these distros, pmm could call brg
to get the client.

add client.conf item for mount points which brs should not manage

A new client.conf item should be added for mount points brs will not manage.

When brs sees any of these mount items when enabling a client, it should not error out. Moreover, brs should not unmount these items. If the user does not want these to be mounted when the client is disabled, he/she must add the relevent code to the enable/disable hooks or otherwise manage them.

A recommended use of this would be for the root directory of the boot client for situation where the initrd mounts something unusual, e.g. FDE, lvm, or raid.

A tentative name for this setting is "unmanaged"

Utility to transfer global files

The plan for 1.0beta2/Nyla is to have the ability to configure which client carries the global files. While this adds substantial flexibility, it is still limited by the fact we can only have one client carrying the global files at a time. To help mitigate this, there should be a utility that can be used to transfer the global files (and possibly /bedrock) from whichever client carries them to another client.

The simplest way to do this would involve just copying the global files. Ideally, we could move mount points "live" so that what was the global client can be removed without rebooting the system.

/etc/init.d/rcK.clients brc command not found

I've added the following line to the end of my /etc/init.d/rcK.clients:

brc debian service networking start

and when the system is shutting down I get this message:

[ -- ]Running clients shutdown script... /etc/init.d/rK.clients: line 10: brc: not found

I've tried with

brc debian /etc/init.d/networking start

and got the same results.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.