[haiku-development] Re: chroot and package daemon bug

  • From: Ingo Weinhold <ingo_weinhold@xxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Wed, 17 Aug 2016 20:21:58 +0200

On 08/16/2016 10:46 PM, Adrien Destugues wrote:

On Fri, Aug 12, 2016 at 09:02:32PM +0200, Ingo Weinhold wrote:
On 08/11/2016 10:38 PM, Adrien Destugues wrote:
You can just

   struct stat st;
   stat("/", &st);

and use (st.st_dev, st.st_ino) (a node_ref).

2) The vnode (or most likely, the dev and inode numbers) are sent to the
     package daemon in GetInstallLocationInfo
3) The package daemon uses the given node as a root, instead of using
     the default fSystemRoot (PackageDaemon.cpp:87)
4) The correct package dirs are returned, the code works as expected.

Sounds good.

Attached is what I have so far.

In case you intended to attach a patch to the mail, it didn't get here.

It turned out a bit more complex on
package daemon side:
- I tried to create a Root and a Volume on the fly when the request is
   sent.

That doesn't sound right.

As far as I can see, the Root being a chroot, there is no mount
   notification when it is created. I'm not sure if the package daemon
   can infer the root when it sees a volume being created.

A Root object in the package daemon represents the base directory of a standard directory layout that contains a mounted system and/or a home packagefs volume. Whenever the package daemon encounters a packagefs volume (initial scan on startup or when it gets a B_DEVICE_MOUNTED notification), a Volume object is created for it and, if the volume is of type "system" or "home", that Volume is either added to the matching preexisting Root object or a new Root object is created.

So there's initially a Root object for "/" and as soon as a packagefs for a (future or already existing) chroot is mounted a Root object for the chroot base directory will be created. So you don't have to create it; it should already exist.

- I tried passing the request to the Volume directly, but 1) this is not
   allowed as per comments in Root and Volume (operations on the Volume
   should always run in the Root's job worker thread)

The thread/locking policy is documented in Volume.h. Only write operations need to be performed by the Root's thread. Not sure, if there's a stray obsolete comment somewhere. IIRC initially it did indeed work differently, but having "get location info" requests wait for pending write operations (which could block indefinitely due to possibly required user interaction) wasn't a good idea.

, and 2) it doesn't
   work anyway because populating the volume with the list of packages is
   done in the job queue, and there is no way to wait for that operation
   to complete.
- So, I changed the Root class to process the request asynchronously by
   posting it to the job queue. This serializes things as designed and
   possibly fixes other concurrency problems.

I'm afraid, I don't understand, why you trying that. Maybe I'm missing something, but the approach you proposed in your previous mail sounded good. If you've implemented step 2) (adding the node_ref to the client's message), implementing step 3) should be fairly simple: In the B_MESSAGE_GET_INSTALLATION_LOCATION_INFO/B_MESSAGE_COMMIT_TRANSACTION case in PackageDaemon::MessageReceived() extract the node_ref from the message, use _FindRoot() to get the corresponding Root object and call HandleRequest() on it (instead of on fSystemRoot).

CU, Ingo


Other related posts: