Fix use of findpaths from inside chroot

The package kit needs to provide the package daemon with the node_ref of
the root directory, so the package daemon gives the correct results when
the request comes from inside a chroot.

Moreover, the package kit must be able to handle a root with a system
but no home package dir, as is the case inside the chroot environment
created by haikuporter.

Fixes #12602.
This commit is contained in:
Adrien Destugues
2016-08-20 07:57:52 +02:00
parent 23a6a63e83
commit 6262ccbbe8
4 changed files with 78 additions and 26 deletions
+16
View File
@@ -10,11 +10,15 @@
#include <string.h> #include <string.h>
#include <package/PackageResolvableExpression.h> #include <package/PackageResolvableExpression.h>
#include <package/manager/Exceptions.h>
#include <Path.h> #include <Path.h>
#include <PathFinder.h> #include <PathFinder.h>
#include <StringList.h> #include <StringList.h>
using namespace BPackageKit::BManager::BPrivate;
extern const char* __progname; extern const char* __progname;
const char* kCommandName = __progname; const char* kCommandName = __progname;
@@ -245,6 +249,7 @@ main(int argc, const char* const* argv)
} }
if (referencePath != NULL || resolvable != NULL) { if (referencePath != NULL || resolvable != NULL) {
try {
BPathFinder pathFinder; BPathFinder pathFinder;
if (referencePath != NULL) { if (referencePath != NULL) {
pathFinder.SetTo(referencePath, dependency); pathFinder.SetTo(referencePath, dependency);
@@ -264,6 +269,17 @@ main(int argc, const char* const* argv)
} }
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 { } else {
BStringList paths; BStringList paths;
status_t error = BPathFinder::FindPaths(architecture, baseDirectory, status_t error = BPathFinder::FindPaths(architecture, baseDirectory,
+14 -1
View File
@@ -45,12 +45,25 @@ BDaemonClient::GetInstallationLocationInfo(
if (error != B_OK) if (error != B_OK)
return error; return error;
// send the request
BMessage request(B_MESSAGE_GET_INSTALLATION_LOCATION_INFO); BMessage request(B_MESSAGE_GET_INSTALLATION_LOCATION_INFO);
error = request.AddInt32("location", location); error = request.AddInt32("location", location);
if (error != B_OK) if (error != B_OK)
return error; 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; BMessage reply;
fDaemonMessenger.SendMessage(&request, &reply); fDaemonMessenger.SendMessage(&request, &reply);
if (reply.what != B_MESSAGE_GET_INSTALLATION_LOCATION_INFO_REPLY) if (reply.what != B_MESSAGE_GET_INSTALLATION_LOCATION_INFO_REPLY)
@@ -110,8 +110,12 @@ BPackageManager::Init(uint32 flags)
// well. But we can easily filter those out. // well. But we can easily filter those out.
_AddInstalledRepository(fSystemRepository); _AddInstalledRepository(fSystemRepository);
try {
if (!fSystemRepository->IsInstalled()) if (!fSystemRepository->IsInstalled())
_AddInstalledRepository(fHomeRepository); _AddInstalledRepository(fHomeRepository);
} catch(BFatalErrorException& exception) {
// No home repository found. This is ok for haikuporter chroots.
}
} }
// add other repositories // add other repositories
@@ -787,12 +791,16 @@ BPackageManager::_AddLocalPackage(const char* fileName)
bool bool
BPackageManager::_NextSpecificInstallationLocation() BPackageManager::_NextSpecificInstallationLocation()
{ {
try {
if (fLocation == B_PACKAGE_INSTALLATION_LOCATION_SYSTEM) { if (fLocation == B_PACKAGE_INSTALLATION_LOCATION_SYSTEM) {
fLocation = B_PACKAGE_INSTALLATION_LOCATION_HOME; fLocation = B_PACKAGE_INSTALLATION_LOCATION_HOME;
fSystemRepository->SetInstalled(false); fSystemRepository->SetInstalled(false);
_AddInstalledRepository(fHomeRepository); _AddInstalledRepository(fHomeRepository);
return true; return true;
} }
} catch (BFatalErrorException& e) {
// No home repo. This is acceptable for example when we are in an haikuporter chroot.
}
return false; return false;
} }
+16 -1
View File
@@ -83,8 +83,23 @@ PackageDaemon::MessageReceived(BMessage* message)
case B_MESSAGE_GET_INSTALLATION_LOCATION_INFO: case B_MESSAGE_GET_INSTALLATION_LOCATION_INFO:
case B_MESSAGE_COMMIT_TRANSACTION: 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()); fSystemRoot->HandleRequest(DetachCurrentMessage());
else {
Root* root = _FindRoot(nodeRef);
if (root != NULL) {
root->HandleRequest(DetachCurrentMessage());
}
}
break; break;
} }