[haiku-development] Re: chroot and package daemon bug
- From: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
- To: haiku-development@xxxxxxxxxxxxx
- Date: Thu, 18 Aug 2016 07:18:04 +0200
On Wed, Aug 17, 2016 at 08:21:58PM +0200, Ingo Weinhold wrote:
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'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).
Thanks, I somehow missed that I could use _FindRoot directly.
So, I have a first version of this working. There was, however, one
extra problem. In the chroot, there is no package volume mounted in
/home/config. The package kit does not expect that, and throws an
exception. I have added try/catch blocks to get it working, but I don't
know if they are at the right place. If that is the right thing to do,
I'll commit the changes.
Attached (and online at
http://pulkomandy.tk/drop/packages_chroot.diff)
is the new version of the patch.
--
Adrien.
diff --git a/src/bin/findpaths.cpp b/src/bin/findpaths.cpp
index e2beb59..0bf7950 100644
--- a/src/bin/findpaths.cpp
+++ b/src/bin/findpaths.cpp
@@ -10,11 +10,15 @@
#include <string.h>
#include <package/PackageResolvableExpression.h>
+#include <package/manager/Exceptions.h>
#include <Path.h>
#include <PathFinder.h>
#include <StringList.h>
+using namespace BPackageKit::BManager::BPrivate;
+
+
extern const char* __progname;
const char* kCommandName = __progname;
@@ -245,25 +249,37 @@ main(int argc, const char* const* argv)
}
if (referencePath != NULL || resolvable != NULL) {
- BPathFinder pathFinder;
- if (referencePath != NULL) {
- pathFinder.SetTo(referencePath, dependency);
- } else {
- pathFinder.SetTo(
-
BPackageKit::BPackageResolvableExpression(resolvable),
- dependency);
- }
+ try {
+ BPathFinder pathFinder;
+ if (referencePath != NULL) {
+ pathFinder.SetTo(referencePath, dependency);
+ } else {
+ pathFinder.SetTo(
+
BPackageKit::BPackageResolvableExpression(resolvable),
+ dependency);
+ }
- BPath path;
- status_t error = pathFinder.FindPath(architecture,
baseDirectory,
- subPath, existingOnly ? B_FIND_PATH_EXISTING_ONLY : 0,
path);
- if (error != B_OK) {
- fprintf(stderr, "Error: Failed to find path: %s\n",
- strerror(error));
- exit(1);
- }
+ BPath path;
+ status_t error = pathFinder.FindPath(architecture,
baseDirectory,
+ subPath, existingOnly ?
B_FIND_PATH_EXISTING_ONLY : 0, path);
+ if (error != B_OK) {
+ fprintf(stderr, "Error: Failed to find path:
%s\n",
+ strerror(error));
+ exit(1);
+ }
- printf("%s\n", path.Path());
+ printf("%s\n", path.Path());
+ } catch(BFatalErrorException& exception) {
+ if (!exception.Details().IsEmpty())
+ fprintf(stderr, "%s",
exception.Details().String());
+ if (exception.Error() == B_OK) {
+ fprintf(stderr, "Error: %s\n",
exception.Message().String());
+ } else {
+ fprintf(stderr, "Error: %s: %s\n",
exception.Message().String(),
+ strerror(exception.Error()));
+ }
+ return 1;
+ }
} else {
BStringList paths;
status_t error = BPathFinder::FindPaths(architecture,
baseDirectory,
diff --git a/src/kits/package/DaemonClient.cpp
b/src/kits/package/DaemonClient.cpp
index ee0e7c2..7a9ca03 100644
--- a/src/kits/package/DaemonClient.cpp
+++ b/src/kits/package/DaemonClient.cpp
@@ -45,12 +45,25 @@ BDaemonClient::GetInstallationLocationInfo(
if (error != B_OK)
return error;
- // send the request
BMessage request(B_MESSAGE_GET_INSTALLATION_LOCATION_INFO);
error = request.AddInt32("location", location);
if (error != B_OK)
return error;
+ // Get our filesystem root node. If we are in a chroot this is not the
same
+ // as the package_daemon root node, so we must provide it.
+ struct stat st;
+ if (stat("/boot", &st) == 0)
+ {
+ error = request.AddInt32("volume", st.st_dev);
+ if (error != B_OK)
+ return error;
+ error = request.AddInt64("root", st.st_ino);
+ if (error != B_OK)
+ return error;
+ }
+
+ // send the request
BMessage reply;
fDaemonMessenger.SendMessage(&request, &reply);
if (reply.what != B_MESSAGE_GET_INSTALLATION_LOCATION_INFO_REPLY)
diff --git a/src/kits/package/manager/PackageManager.cpp
b/src/kits/package/manager/PackageManager.cpp
index 901b856..6d9ccd8 100644
--- a/src/kits/package/manager/PackageManager.cpp
+++ b/src/kits/package/manager/PackageManager.cpp
@@ -110,8 +110,12 @@ BPackageManager::Init(uint32 flags)
// well. But we can easily filter those out.
_AddInstalledRepository(fSystemRepository);
- if (!fSystemRepository->IsInstalled())
- _AddInstalledRepository(fHomeRepository);
+ try {
+ if (!fSystemRepository->IsInstalled())
+ _AddInstalledRepository(fHomeRepository);
+ } catch(BFatalErrorException& exception) {
+ // No home repository found. This is ok for haikuporter
chroots.
+ }
}
// add other repositories
@@ -787,11 +791,15 @@ BPackageManager::_AddLocalPackage(const char* fileName)
bool
BPackageManager::_NextSpecificInstallationLocation()
{
- if (fLocation == B_PACKAGE_INSTALLATION_LOCATION_SYSTEM) {
- fLocation = B_PACKAGE_INSTALLATION_LOCATION_HOME;
- fSystemRepository->SetInstalled(false);
- _AddInstalledRepository(fHomeRepository);
- return true;
+ try {
+ if (fLocation == B_PACKAGE_INSTALLATION_LOCATION_SYSTEM) {
+ fLocation = B_PACKAGE_INSTALLATION_LOCATION_HOME;
+ fSystemRepository->SetInstalled(false);
+ _AddInstalledRepository(fHomeRepository);
+ return true;
+ }
+ } catch (BFatalErrorException& e) {
+ // No home repo. This is acceptable for example when we are in
an haikuporter chroot.
}
return false;
diff --git a/src/servers/package/PackageDaemon.cpp
b/src/servers/package/PackageDaemon.cpp
index 0c05213..4b35cb1 100644
--- a/src/servers/package/PackageDaemon.cpp
+++ b/src/servers/package/PackageDaemon.cpp
@@ -83,8 +83,23 @@ PackageDaemon::MessageReceived(BMessage* message)
case B_MESSAGE_GET_INSTALLATION_LOCATION_INFO:
case B_MESSAGE_COMMIT_TRANSACTION:
{
- if (fSystemRoot != NULL)
+ status_t error;
+ node_ref nodeRef;
+
+ // Get the node_ref of the filesystem root to see which
one it is
+ error = message->FindInt32("volume", &nodeRef.device);
+ if (error == B_OK)
+ error = message->FindInt64("root",
&nodeRef.node);
+
+ if (fSystemRoot != NULL && (error != B_OK
+ || fSystemRoot->NodeRef() == nodeRef))
fSystemRoot->HandleRequest(DetachCurrentMessage());
+ else {
+ Root* root = _FindRoot(nodeRef);
+ if (root != NULL) {
+
root->HandleRequest(DetachCurrentMessage());
+ }
+ }
break;
}
Other related posts: