Volume::_AddInitialPackagesFromDirectory(): Use openat() instead of
dup() to get a FD for the packages directory. Currently our fdopendir()
implementation doesn't use it directly anyway, but in theory it could
and would then change the state of the original FD.
If the file exists load only the packages specified in it. If it doesn't
exist or any kind of error occurs, fall back to loading all packages in
the packages directory.
Dumps the result (i.e. found problems and solutions) to the syslog.
Eventually the user should be asked what to do when inconsistencies are
encountered.
* We first process the node monitoring events, collecting the required
package activation changes, then apply all changes together.
* Change the PackageFSActivationChangeItem/-Request structs. The former
is no longer variable in size, which makes it easier to work with.
There's now a worker thread per Root that does all the work that can
take time. Node monitoring notifications received in the main thread are
just pushed into the worker's job queue, so the application looper
remains responsive.
* packagefs: Disable (comment out) node monitoring of the packages
directory.
* package daemon:
- When a packagefs volume is added load the respective packages
directory and get from the volume which of the packages are
activated.
- Add node monitoring for the packages directory and
activate/deactivate packages as packages are added/removed.
* Add PACKAGE_FS_OPERATION_GET_PACKAGE_INFOS which returns the node refs
of all packages activated.
* Add PACKAGE_FS_OPERATION_CHANGE_ACTIVATION to activate/deactivate
multiple packages.
* The package directory path specified when mounting must be interpreted
in the caller's I/O context. We did always interpret it in the
kernel's I/O context, so that a relative path or a path in a chroot
environment wouldn't work correctly. Now opening the directory is done
in PackageDomain::Init() where we can at least guess the path's
origin.
* We also normalize the path, though merely to get more conclusive debug
output, since after opening the directory the path isn't used for
anything else anymore.
* Make the "packages" mount parameter optional. If not specified, use
the "packages" folder at our mount point.
B_ALREADY_WIRED, which was erroneously passed for the area protection
parameter to map_backing_store(), has the value 7 which implies user
readable and writable. Hence the address ranges around 0xdeadbeef and
0xcccccccc could actually be read and written from anywhere.
The tree comparisons didn't allow for different Nodes having the same
attribute value. Therefore only the first node would be added and later
we would try to remove a node not actually in the tree, leading to a
crash.
packagefs seems to finally unmount cleanly, now.
* Volume::_RemovePackageLinksDirectory(): We don't want to call
_RemovePackageLinksNode(). Besides that the ID hash table has already
been emptied before and we would thus release a reference to the node
erroneously, the method doesn't do anything we want anyway. We don't
want any children to be removed, since we have unregistered the
volume's packages already (which removes the respective package link
directories); the remaining ones are from other volumes and not ours
to remove.
* PackageFSRoot: Release a reference to the package links directory in
the destructor. We create the directory in Init() after all and no one
else takes over ownership.
Since we publish shine-through directories directly to the VFS, we need
to acquire an additional reference, because we release a reference when
a node is put.
PackageLinkDirectory::NotifyDirectoryAdded() first notified the listener
(Volume) about the directory itself, then about the links it contained.
Since Volume adds the nodes recursively, the latter were added twice,
resulting in a corrupted ID hash table.
* Make sure that the computed dependencies don't themselves depend on
the specified package.
* Print only the actual dependencies, not the specified package.