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:
+33
-17
@@ -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,25 +249,37 @@ main(int argc, const char* const* argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (referencePath != NULL || resolvable != NULL) {
|
if (referencePath != NULL || resolvable != NULL) {
|
||||||
BPathFinder pathFinder;
|
try {
|
||||||
if (referencePath != NULL) {
|
BPathFinder pathFinder;
|
||||||
pathFinder.SetTo(referencePath, dependency);
|
if (referencePath != NULL) {
|
||||||
} else {
|
pathFinder.SetTo(referencePath, dependency);
|
||||||
pathFinder.SetTo(
|
} else {
|
||||||
BPackageKit::BPackageResolvableExpression(resolvable),
|
pathFinder.SetTo(
|
||||||
dependency);
|
BPackageKit::BPackageResolvableExpression(resolvable),
|
||||||
}
|
dependency);
|
||||||
|
}
|
||||||
|
|
||||||
BPath path;
|
BPath path;
|
||||||
status_t error = pathFinder.FindPath(architecture, baseDirectory,
|
status_t error = pathFinder.FindPath(architecture, baseDirectory,
|
||||||
subPath, existingOnly ? B_FIND_PATH_EXISTING_ONLY : 0, path);
|
subPath, existingOnly ? B_FIND_PATH_EXISTING_ONLY : 0, path);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
fprintf(stderr, "Error: Failed to find path: %s\n",
|
fprintf(stderr, "Error: Failed to find path: %s\n",
|
||||||
strerror(error));
|
strerror(error));
|
||||||
exit(1);
|
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 {
|
} else {
|
||||||
BStringList paths;
|
BStringList paths;
|
||||||
status_t error = BPathFinder::FindPaths(architecture, baseDirectory,
|
status_t error = BPathFinder::FindPaths(architecture, baseDirectory,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
if (!fSystemRepository->IsInstalled())
|
try {
|
||||||
_AddInstalledRepository(fHomeRepository);
|
if (!fSystemRepository->IsInstalled())
|
||||||
|
_AddInstalledRepository(fHomeRepository);
|
||||||
|
} catch(BFatalErrorException& exception) {
|
||||||
|
// No home repository found. This is ok for haikuporter chroots.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add other repositories
|
// add other repositories
|
||||||
@@ -787,11 +791,15 @@ BPackageManager::_AddLocalPackage(const char* fileName)
|
|||||||
bool
|
bool
|
||||||
BPackageManager::_NextSpecificInstallationLocation()
|
BPackageManager::_NextSpecificInstallationLocation()
|
||||||
{
|
{
|
||||||
if (fLocation == B_PACKAGE_INSTALLATION_LOCATION_SYSTEM) {
|
try {
|
||||||
fLocation = B_PACKAGE_INSTALLATION_LOCATION_HOME;
|
if (fLocation == B_PACKAGE_INSTALLATION_LOCATION_SYSTEM) {
|
||||||
fSystemRepository->SetInstalled(false);
|
fLocation = B_PACKAGE_INSTALLATION_LOCATION_HOME;
|
||||||
_AddInstalledRepository(fHomeRepository);
|
fSystemRepository->SetInstalled(false);
|
||||||
return true;
|
_AddInstalledRepository(fHomeRepository);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (BFatalErrorException& e) {
|
||||||
|
// No home repo. This is acceptable for example when we are in an haikuporter chroot.
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user