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:
parent
23a6a63e83
commit
6262ccbbe8
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user