package daemon: Check volume package dependencies initially
Dumps the result (i.e. found problems and solutions) to the syslog. Eventually the user should be asked what to do when inconsistencies are encountered.
This commit is contained in:
parent
4b3ca457b6
commit
92b6d58598
@ -202,10 +202,43 @@ Root::_GetVolume(PackageFSMountType mountType)
|
||||
}
|
||||
|
||||
|
||||
Volume*
|
||||
Root::_NextVolumeFor(Volume* volume)
|
||||
{
|
||||
if (volume == NULL)
|
||||
return NULL;
|
||||
|
||||
PackageFSMountType mountType = volume->MountType();
|
||||
|
||||
do {
|
||||
switch (mountType) {
|
||||
case PACKAGE_FS_MOUNT_TYPE_HOME:
|
||||
mountType = PACKAGE_FS_MOUNT_TYPE_COMMON;
|
||||
break;
|
||||
case PACKAGE_FS_MOUNT_TYPE_COMMON:
|
||||
mountType = PACKAGE_FS_MOUNT_TYPE_SYSTEM;
|
||||
break;
|
||||
case PACKAGE_FS_MOUNT_TYPE_SYSTEM:
|
||||
case PACKAGE_FS_MOUNT_TYPE_CUSTOM:
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
volume = *_GetVolume(mountType);
|
||||
} while (volume == NULL);
|
||||
|
||||
return volume;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Root::_InitPackages(Volume* volume)
|
||||
{
|
||||
volume->InitPackages(this);
|
||||
if (volume->InitPackages(this) == B_OK) {
|
||||
Volume* nextVolume = _NextVolumeFor(volume);
|
||||
Volume* nextNextVolume = _NextVolumeFor(nextVolume);
|
||||
volume->InitialVerify(nextVolume, nextNextVolume);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,6 +52,7 @@ private:
|
||||
|
||||
private:
|
||||
Volume** _GetVolume(PackageFSMountType mountType);
|
||||
Volume* _NextVolumeFor(Volume* volume);
|
||||
|
||||
void _InitPackages(Volume* volume);
|
||||
void _DeleteVolume(Volume* volume);
|
||||
|
@ -20,6 +20,13 @@
|
||||
#include <NodeMonitor.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <package/solver/Solver.h>
|
||||
#include <package/solver/SolverPackage.h>
|
||||
#include <package/solver/SolverProblem.h>
|
||||
#include <package/solver/SolverProblemSolution.h>
|
||||
#include <package/solver/SolverRepository.h>
|
||||
#include <package/solver/SolverResult.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
#include <AutoLocker.h>
|
||||
|
||||
@ -205,6 +212,114 @@ Volume::InitPackages(Listener* listener)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Volume::AddPackagesToRepository(BSolverRepository& repository, bool activeOnly)
|
||||
{
|
||||
for (PackageFileNameHashTable::Iterator it
|
||||
= fPackagesByFileName.GetIterator(); it.HasNext();) {
|
||||
Package* package = it.Next();
|
||||
if (activeOnly && !package->IsActive())
|
||||
continue;
|
||||
|
||||
status_t error = repository.AddPackage(package->Info());
|
||||
if (error != B_OK) {
|
||||
ERROR("Volume::AddPackagesToRepository(): failed to add package %s "
|
||||
"to repository: %s\n", package->FileName().String(),
|
||||
strerror(error));
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Volume::InitialVerify(Volume* nextVolume, Volume* nextNextVolume)
|
||||
{
|
||||
INFORM("Volume::InitialVerify(%p, %p)\n", nextVolume, nextNextVolume);
|
||||
// create the solver
|
||||
BSolver* solver;
|
||||
status_t error = BSolver::Create(solver);
|
||||
if (error != B_OK) {
|
||||
ERROR("Volume::InitialVerify(): failed to create solver: %s\n",
|
||||
strerror(error));
|
||||
return;
|
||||
}
|
||||
ObjectDeleter<BSolver> solverDeleter(solver);
|
||||
|
||||
// add a repository with all active packages
|
||||
BSolverRepository repository;
|
||||
error = _AddRepository(solver, repository, true, true);
|
||||
if (error != B_OK) {
|
||||
ERROR("Volume::InitialVerify(): failed to add repository: %s\n",
|
||||
strerror(error));
|
||||
return;
|
||||
}
|
||||
|
||||
// add a repository for the next volume
|
||||
BSolverRepository nextRepository;
|
||||
if (nextVolume != NULL) {
|
||||
nextRepository.SetPriority(1);
|
||||
error = nextVolume->_AddRepository(solver, nextRepository, true, false);
|
||||
if (error != B_OK) {
|
||||
ERROR("Volume::InitialVerify(): failed to add repository: %s\n",
|
||||
strerror(error));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// add a repository for the next next volume
|
||||
BSolverRepository nextNextRepository;
|
||||
if (nextNextVolume != NULL) {
|
||||
nextNextRepository.SetPriority(2);
|
||||
error = nextNextVolume->_AddRepository(solver, nextNextRepository, true,
|
||||
false);
|
||||
if (error != B_OK) {
|
||||
ERROR("Volume::InitialVerify(): failed to add repository: %s\n",
|
||||
strerror(error));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// verify
|
||||
error = solver->VerifyInstallation();
|
||||
if (error != B_OK) {
|
||||
ERROR("Volume::InitialVerify(): failed to verify: %s\n",
|
||||
strerror(error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!solver->HasProblems()) {
|
||||
INFORM("Volume::InitialVerify(): volume at \"%s\" is consistent\n",
|
||||
Path().String());
|
||||
return;
|
||||
}
|
||||
|
||||
// print the problems
|
||||
// TODO: Notify the user ...
|
||||
INFORM("Volume::InitialVerify(): volume at \"%s\" has problems:\n",
|
||||
Path().String());
|
||||
|
||||
int32 problemCount = solver->CountProblems();
|
||||
for (int32 i = 0; i < problemCount; i++) {
|
||||
BSolverProblem* problem = solver->ProblemAt(i);
|
||||
INFORM(" %" B_PRId32 ": %s\n", i + 1, problem->ToString().String());
|
||||
int32 solutionCount = problem->CountSolutions();
|
||||
for (int32 k = 0; k < solutionCount; k++) {
|
||||
const BSolverProblemSolution* solution = problem->SolutionAt(k);
|
||||
INFORM(" solution %" B_PRId32 ":\n", k + 1);
|
||||
int32 elementCount = solution->CountElements();
|
||||
for (int32 l = 0; l < elementCount; l++) {
|
||||
const BSolverProblemSolutionElement* element
|
||||
= solution->ElementAt(l);
|
||||
INFORM(" - %s\n", element->ToString().String());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Volume::Unmounted()
|
||||
{
|
||||
@ -647,3 +762,34 @@ for (PackageNodeRefHashTable::Iterator it = fPackagesByNodeRef.GetIterator();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Volume::_AddRepository(BSolver* solver, BSolverRepository& repository,
|
||||
bool activeOnly, bool installed)
|
||||
{
|
||||
status_t error = repository.SetTo(Path());
|
||||
if (error != B_OK) {
|
||||
ERROR("Volume::_AddRepository(): failed to init repository: %s\n",
|
||||
strerror(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
repository.SetInstalled(installed);
|
||||
|
||||
error = AddPackagesToRepository(repository, true);
|
||||
if (error != B_OK) {
|
||||
ERROR("Volume::_AddRepository(): failed to add packages to "
|
||||
"repository: %s\n", strerror(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
error = solver->AddRepository(&repository);
|
||||
if (error != B_OK) {
|
||||
ERROR("Volume::_AddRepository(): failed to add repository to solver: "
|
||||
"%s\n", strerror(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -25,6 +25,11 @@ class BDirectory;
|
||||
|
||||
class Root;
|
||||
|
||||
namespace BPackageKit {
|
||||
class BSolver;
|
||||
class BSolverRepository;
|
||||
}
|
||||
|
||||
|
||||
class Volume : public BHandler {
|
||||
public:
|
||||
@ -38,6 +43,12 @@ public:
|
||||
node_ref& _packageRootRef);
|
||||
status_t InitPackages(Listener* listener);
|
||||
|
||||
status_t AddPackagesToRepository(
|
||||
BSolverRepository& repository,
|
||||
bool activeOnly);
|
||||
void InitialVerify(Volume* nextVolume,
|
||||
Volume* nextNextVolume);
|
||||
|
||||
void Unmounted();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
@ -98,6 +109,10 @@ private:
|
||||
status_t _ReadPackagesDirectory();
|
||||
status_t _GetActivePackages(int fd);
|
||||
|
||||
status_t _AddRepository(BSolver* solver,
|
||||
BSolverRepository& repository,
|
||||
bool activeOnly, bool installed);
|
||||
|
||||
private:
|
||||
BString fPath;
|
||||
PackageFSMountType fMountType;
|
||||
|
Loading…
Reference in New Issue
Block a user