[haiku-commits] haiku: hrev46391 - in src: system/boot/loader/file_systems/packagefs add-ons/kernel/file_systems/packagefs/volume add-ons/kernel/file_systems/packagefs/package system/kernel/util system/libroot/os

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 19 Nov 2013 15:30:58 +0100 (CET)

hrev46391 adds 4 changesets to branch 'master'
old head: 7afd687f61a434215c3666570442736b66345b2b
new head: 3a7e0b00147f7a33bc52cb75a56bde8d9652d92a
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=3a7e0b0+%5E7afd687

----------------------------------------------------------------------------

cf09345: driver settings: Remove dead load_driver_settings_from_path()
  
  load_driver_settings() supports being passed an absolute path.

efe9df3: driver settings: Add load_driver_settings_file()
  
  Allows loading an already opened driver settings file (by FD).

2fdd1d9: khash: Move string hash functions to own header/source file
  
  Unlike khash they shouldn't be phased out (only renamed).

3a7e0b0: packagefs: Support blacklisting entries in packages
  
  In each installation location, it is now possible to create a settings
  file "packages" that allows to blacklist entries contained in packages.
  The format is:
  
  Package <package name> {
        EntryBlacklist {
                <entry path>
                ...
        }
  }
  ...
  
  <package name> is the base name (no version) of the respective package
  (e.g. "haiku"), <entry path> is an installation location relative path
  (e.g. "add-ons/Translators/FooTranslator").
  
  Blacklisted entries will be ignored by packagefs, i.e. they won't appear
  in the file system. This addresses the issue that it may be necessary to
  remove a problematic file (e.g. driver, add-on, or library), which would
  otherwise require editing the containing package file.
  
  The settings file is not not "live". Changes take effect only after
  reboot (respectively when remounting the concerned packagefs volume).

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

22 files changed, 1012 insertions(+), 97 deletions(-)
headers/os/drivers/driver_settings.h             |   1 +
headers/private/kernel/util/StringHash.h         |  29 +++
headers/private/kernel/util/khash.h              |   6 +-
headers/private/system/directories.h             |   2 +
.../kernel/file_systems/packagefs/Jamfile        |   1 +
.../file_systems/packagefs/package/Package.cpp   |  55 ++++-
.../file_systems/packagefs/package/Package.h     |   5 +-
.../packagefs/volume/PackageSettings.cpp         | 232 +++++++++++++++++++
.../packagefs/volume/PackageSettings.h           | 210 +++++++++++++++++
.../file_systems/packagefs/volume/Volume.cpp     |  10 +-
.../file_systems/packagefs/volume/Volume.h       |   2 +
src/system/boot/loader/Jamfile                   |   3 +-
.../boot/loader/file_systems/packagefs/Jamfile   |   1 +
.../packagefs/PackageSettingsItem.cpp            | 182 +++++++++++++++
.../file_systems/packagefs/PackageSettingsItem.h | 190 +++++++++++++++
.../loader/file_systems/packagefs/packagefs.cpp  |  50 +++-
.../loader/file_systems/packagefs/packagefs.h    |  11 +-
src/system/boot/loader/vfs.cpp                   |   3 +-
src/system/kernel/util/Jamfile                   |   1 +
src/system/kernel/util/StringHash.cpp            |  44 ++++
src/system/kernel/util/khash.cpp                 |  34 ---
src/system/libroot/os/driver_settings.cpp        |  37 +--

############################################################################

Commit:      cf09345cf599db2bfa9482211e6479ba8b2b1e6b
URL:         http://cgit.haiku-os.org/haiku/commit/?id=cf09345
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Nov 19 13:02:21 2013 UTC

driver settings: Remove dead load_driver_settings_from_path()

load_driver_settings() supports being passed an absolute path.

----------------------------------------------------------------------------

diff --git a/src/system/libroot/os/driver_settings.cpp 
b/src/system/libroot/os/driver_settings.cpp
index 4ac6356..56c4692 100644
--- a/src/system/libroot/os/driver_settings.cpp
+++ b/src/system/libroot/os/driver_settings.cpp
@@ -801,38 +801,6 @@ load_driver_settings(const char *driverName)
 }
 
 
-/** Loads a driver settings file using the full path, instead of
- *     only defining the leaf name (as load_driver_settings() does).
- *     I am not sure if this function is really necessary - I would
- *     probably prefer something like a search order (if it's not
- *     an absolute path):
- *             ~/config/settings/kernel/driver
- *             current directory
- *     That would render this function useless.
- */
-
-#if 0
-void *
-load_driver_settings_from_path(const char *path)
-{
-       settings_handle *handle;
-       int file;
-
-       if (path == NULL)
-               return NULL;
-
-       file = open(path, O_RDONLY);
-       if (file < B_OK)
-               return NULL;
-
-       handle = load_driver_settings_from_file(file);
-
-       close(file);
-       return (void *)handle;
-}
-#endif
-
-
 /*!
        Returns a new driver_settings handle that has the parsed contents
        of the passed string.

############################################################################

Commit:      efe9df37915b8fe394c273e13042681d7015e682
URL:         http://cgit.haiku-os.org/haiku/commit/?id=efe9df3
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Nov 19 14:06:30 2013 UTC

driver settings: Add load_driver_settings_file()

Allows loading an already opened driver settings file (by FD).

----------------------------------------------------------------------------

diff --git a/headers/os/drivers/driver_settings.h 
b/headers/os/drivers/driver_settings.h
index 69e8ea1..219d18f 100644
--- a/headers/os/drivers/driver_settings.h
+++ b/headers/os/drivers/driver_settings.h
@@ -24,6 +24,7 @@ extern "C" {
 #endif
 
 extern void                    *load_driver_settings(const char *driverName);
+extern void                    *load_driver_settings_file(int fd);
 extern status_t                unload_driver_settings(void *handle);
 
 extern void                    *parse_driver_settings_string(const char 
*settingsString);
diff --git a/src/system/libroot/os/driver_settings.cpp 
b/src/system/libroot/os/driver_settings.cpp
index 56c4692..5f7130d 100644
--- a/src/system/libroot/os/driver_settings.cpp
+++ b/src/system/libroot/os/driver_settings.cpp
@@ -409,8 +409,10 @@ new_settings(char *buffer, const char *driverName)
        handle->text = buffer;
 
 #ifdef _KERNEL_MODE
-       handle->ref_count = 1;
-       strlcpy(handle->name, driverName, sizeof(handle->name));
+       if (driverName != NULL) {
+               handle->ref_count = 1;
+               strlcpy(handle->name, driverName, sizeof(handle->name));
+       }
 #endif
 
        if (parse_settings(handle) == B_OK)
@@ -801,6 +803,13 @@ load_driver_settings(const char *driverName)
 }
 
 
+void*
+load_driver_settings_file(int fd)
+{
+       return load_driver_settings_from_file(fd, NULL);
+}
+
+
 /*!
        Returns a new driver_settings handle that has the parsed contents
        of the passed string.

############################################################################

Commit:      2fdd1d9ef18ba45b507e94c40ebc85510f830e00
URL:         http://cgit.haiku-os.org/haiku/commit/?id=2fdd1d9
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Nov 19 14:08:34 2013 UTC

khash: Move string hash functions to own header/source file

Unlike khash they shouldn't be phased out (only renamed).

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/util/StringHash.h 
b/headers/private/kernel/util/StringHash.h
new file mode 100644
index 0000000..29be9b3
--- /dev/null
+++ b/headers/private/kernel/util/StringHash.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2002-2013, Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
+ * Distributed under the terms of the NewOS License.
+ */
+#ifndef _KERNEL_UTIL_STRING_HASH_H
+#define _KERNEL_UTIL_STRING_HASH_H
+
+
+#include <SupportDefs.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+uint32 hash_hash_string(const char* string);
+uint32 hash_hash_string_part(const char* string, size_t maxLength);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _KERNEL_UTIL_STRING_HASH_H */
diff --git a/headers/private/kernel/util/khash.h 
b/headers/private/kernel/util/khash.h
index d1f5468..ae1b71f 100644
--- a/headers/private/kernel/util/khash.h
+++ b/headers/private/kernel/util/khash.h
@@ -9,7 +9,8 @@
 #define _KERNEL_UTIL_KHASH_H
 
 
-#include <SupportDefs.h>
+#include <util/StringHash.h>
+
 
 // The use of offsetof() on non-PODs is invalid. Since many structs use
 // templated members (i.e. DoublyLinkedList) which makes them non-PODs we
@@ -60,9 +61,6 @@ void hash_dump_table(struct hash_table* table);
  *             the key, returning 0 if equal, other if not
  */
 
-uint32 hash_hash_string(const char *string);
-uint32 hash_hash_string_part(const char *string, size_t maxLength);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/system/kernel/util/StringHash.cpp 
b/src/system/kernel/util/StringHash.cpp
new file mode 100644
index 0000000..ed8bd25
--- /dev/null
+++ b/src/system/kernel/util/StringHash.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2002-2013, Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Copyright 2001, Travis Geiselbrecht. All rights reserved.
+ * Distributed under the terms of the NewOS License.
+ */
+
+
+#include <util/StringHash.h>
+
+
+uint32
+hash_hash_string(const char* string)
+{
+       uint32 hash = 0;
+       char c;
+
+       // we assume hash to be at least 32 bits
+       while ((c = *string++) != 0) {
+               hash ^= hash >> 28;
+               hash <<= 4;
+               hash ^= c;
+       }
+
+       return hash;
+}
+
+
+uint32
+hash_hash_string_part(const char* string, size_t maxLength)
+{
+       uint32 hash = 0;
+       char c;
+
+       // we assume hash to be at least 32 bits
+       while (maxLength-- > 0 && (c = *string++) != 0) {
+               hash ^= hash >> 28;
+               hash <<= 4;
+               hash ^= c;
+       }
+
+       return hash;
+}
diff --git a/src/system/kernel/util/khash.cpp b/src/system/kernel/util/khash.cpp
index e52d88b..4b626ee 100644
--- a/src/system/kernel/util/khash.cpp
+++ b/src/system/kernel/util/khash.cpp
@@ -382,40 +382,6 @@ restart:
 
 
 uint32
-hash_hash_string(const char *string)
-{
-       uint32 hash = 0;
-       char c;
-
-       // we assume hash to be at least 32 bits
-       while ((c = *string++) != 0) {
-               hash ^= hash >> 28;
-               hash <<= 4;
-               hash ^= c;
-       }
-
-       return hash;
-}
-
-
-uint32
-hash_hash_string_part(const char *string, size_t maxLength)
-{
-       uint32 hash = 0;
-       char c;
-
-       // we assume hash to be at least 32 bits
-       while (maxLength-- > 0 && (c = *string++) != 0) {
-               hash ^= hash >> 28;
-               hash <<= 4;
-               hash ^= c;
-       }
-
-       return hash;
-}
-
-
-uint32
 hash_count_elements(struct hash_table *table)
 {
        return table->num_elements;

############################################################################

Revision:    hrev46391
Commit:      3a7e0b00147f7a33bc52cb75a56bde8d9652d92a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=3a7e0b0
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Nov 19 14:30:34 2013 UTC

packagefs: Support blacklisting entries in packages

In each installation location, it is now possible to create a settings
file "packages" that allows to blacklist entries contained in packages.
The format is:

Package <package name> {
        EntryBlacklist {
                <entry path>
                ...
        }
}
...

<package name> is the base name (no version) of the respective package
(e.g. "haiku"), <entry path> is an installation location relative path
(e.g. "add-ons/Translators/FooTranslator").

Blacklisted entries will be ignored by packagefs, i.e. they won't appear
in the file system. This addresses the issue that it may be necessary to
remove a problematic file (e.g. driver, add-on, or library), which would
otherwise require editing the containing package file.

The settings file is not not "live". Changes take effect only after
reboot (respectively when remounting the concerned packagefs volume).

----------------------------------------------------------------------------

diff --git a/headers/private/system/directories.h 
b/headers/private/system/directories.h
index d69bb68..050b173 100644
--- a/headers/private/system/directories.h
+++ b/headers/private/system/directories.h
@@ -38,6 +38,7 @@
 #define kSystemPackageLinksDirectory           "/boot/system/package-links"
 #define kSystemPreferencesDirectory    "/boot/system/preferences"
 #define kSystemServersDirectory                "/boot/system/servers"
+#define kSystemSettingsDirectory               "/boot/system/settings"
 
 #define kSystemEtcDirectory                    "/boot/system/settings/etc"
 #define kSystemTempDirectory                   "/boot/system/cache/tmp"
@@ -55,6 +56,7 @@
 #define kUserLibDirectory                              "/boot/home/config/lib"
 #define kUserPackagesDirectory                 "/boot/home/config/packages"
 #define kUserSettingsDirectory                         
"/boot/home/config/settings"
+#define kUserSettingsGlobalDirectory   "/boot/home/config/settings/global"
 #define kUserNonpackagedDirectory              "/boot/home/config/non-packaged"
 #define kUserNonpackagedAddonsDirectory 
"/boot/home/config/non-packaged/add-ons"
 #define kUserNonpackagedBinDirectory   "/boot/home/config/non-packaged/bin"
diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile 
b/src/add-ons/kernel/file_systems/packagefs/Jamfile
index d03b2a8..ee7f3f8 100644
--- a/src/add-ons/kernel/file_systems/packagefs/Jamfile
+++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile
@@ -50,6 +50,7 @@ HAIKU_PACKAGE_FS_SOURCES =
        PackageLinkSymlink.cpp
        PackageNode.cpp
        PackageNodeAttribute.cpp
+       PackageSettings.cpp
        PackageSymlink.cpp
        Resolvable.cpp
        ResolvableFamily.cpp
diff --git a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp 
b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
index 8f881c7..8d54f78 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
+++ b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
@@ -30,6 +30,7 @@
 #include "GlobalFactory.h"
 #include "PackageDirectory.h"
 #include "PackageFile.h"
+#include "PackageSettings.h"
 #include "PackageSymlink.h"
 #include "Version.h"
 #include "Volume.h"
@@ -93,9 +94,13 @@ private:
 
 
 struct Package::LoaderContentHandler : BPackageContentHandler {
-       LoaderContentHandler(Package* package)
+       LoaderContentHandler(Package* package, const PackageSettings& settings)
                :
                fPackage(package),
+               fSettings(settings),
+               fSettingsItem(NULL),
+               fLastSettingsEntry(NULL),
+               fLastSettingsEntryEntry(NULL),
                fErrorOccurred(false)
        {
        }
@@ -107,8 +112,11 @@ struct Package::LoaderContentHandler : 
BPackageContentHandler {
 
        virtual status_t HandleEntry(BPackageEntry* entry)
        {
-               if (fErrorOccurred)
+               if (fErrorOccurred
+                       || (fLastSettingsEntry != NULL
+                               && fLastSettingsEntry->IsBlackListed())) {
                        return B_OK;
+               }
 
                PackageDirectory* parentDir = NULL;
                if (entry->Parent() != NULL) {
@@ -118,6 +126,19 @@ struct Package::LoaderContentHandler : 
BPackageContentHandler {
                                RETURN_ERROR(B_BAD_DATA);
                }
 
+               if (fSettingsItem != NULL
+                       && (parentDir == NULL
+                               || entry->Parent() == fLastSettingsEntryEntry)) 
{
+                       PackageSettingsItem::Entry* settingsEntry
+                               = fSettingsItem->FindEntry(fLastSettingsEntry, 
entry->Name());
+                       if (settingsEntry != NULL) {
+                               fLastSettingsEntry = settingsEntry;
+                               fLastSettingsEntryEntry = entry;
+                               if (fLastSettingsEntry->IsBlackListed())
+                                       return B_OK;
+                       }
+               }
+
                // get the file mode -- filter out write permissions
                mode_t mode = entry->Mode() & ~(mode_t)(S_IWUSR | S_IWGRP | 
S_IWOTH);
 
@@ -174,8 +195,11 @@ struct Package::LoaderContentHandler : 
BPackageContentHandler {
        virtual status_t HandleEntryAttribute(BPackageEntry* entry,
                BPackageEntryAttribute* attribute)
        {
-               if (fErrorOccurred)
+               if (fErrorOccurred
+                       || (fLastSettingsEntry != NULL
+                               && fLastSettingsEntry->IsBlackListed())) {
                        return B_OK;
+               }
 
                PackageNode* node = (PackageNode*)entry->UserToken();
 
@@ -197,6 +221,11 @@ struct Package::LoaderContentHandler : 
BPackageContentHandler {
 
        virtual status_t HandleEntryDone(BPackageEntry* entry)
        {
+               if (entry == fLastSettingsEntryEntry) {
+                       fLastSettingsEntryEntry = entry->Parent();
+                       fLastSettingsEntry = fLastSettingsEntry->Parent();
+               }
+
                return B_OK;
        }
 
@@ -210,6 +239,9 @@ struct Package::LoaderContentHandler : 
BPackageContentHandler {
                                if (!name.SetTo(value.string))
                                        return B_NO_MEMORY;
                                fPackage->SetName(name);
+
+                               fSettingsItem = 
fSettings.PackageItemFor(fPackage->Name());
+
                                return B_OK;
                        }
 
@@ -232,7 +264,6 @@ struct Package::LoaderContentHandler : 
BPackageContentHandler {
                                        RETURN_ERROR(error);
 
                                fPackage->SetVersion(version);
-
                                break;
                        }
 
@@ -336,8 +367,12 @@ struct Package::LoaderContentHandler : 
BPackageContentHandler {
        }
 
 private:
-       Package*        fPackage;
-       bool            fErrorOccurred;
+       Package*                                        fPackage;
+       const PackageSettings&          fSettings;
+       const PackageSettingsItem*      fSettingsItem;
+       PackageSettingsItem::Entry*     fLastSettingsEntry;
+       const BPackageEntry*            fLastSettingsEntryEntry;
+       bool                                            fErrorOccurred;
 };
 
 
@@ -805,9 +840,9 @@ Package::Init(const char* fileName)
 
 
 status_t
-Package::Load()
+Package::Load(const PackageSettings& settings)
 {
-       status_t error = _Load();
+       status_t error = _Load(settings);
        if (error != B_OK)
                return error;
 
@@ -947,7 +982,7 @@ Package::CreateDataReader(const PackageData& data,
 
 
 status_t
-Package::_Load()
+Package::_Load(const PackageSettings& settings)
 {
        // open package file
        int fd = Open();
@@ -965,7 +1000,7 @@ Package::_Load()
                        
BHPKG::B_HPKG_READER_DONT_PRINT_VERSION_MISMATCH_MESSAGE);
                if (error == B_OK) {
                        // parse content
-                       LoaderContentHandler handler(this);
+                       LoaderContentHandler handler(this, settings);
                        error = handler.Init();
                        if (error != B_OK)
                                RETURN_ERROR(error);
diff --git a/src/add-ons/kernel/file_systems/packagefs/package/Package.h 
b/src/add-ons/kernel/file_systems/packagefs/package/Package.h
index 210264e..776ffd2 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/Package.h
+++ b/src/add-ons/kernel/file_systems/packagefs/package/Package.h
@@ -28,6 +28,7 @@ using BPackageKit::BHPKG::BAbstractBufferedDataReader;
 
 
 class PackageLinkDirectory;
+class PackageSettings;
 class Volume;
 class Version;
 
@@ -40,7 +41,7 @@ public:
                                                                ~Package();
 
                        status_t                        Init(const char* 
fileName);
-                       status_t                        Load();
+                       status_t                        Load(const 
PackageSettings& settings);
 
                        ::Volume*                       Volume() const          
{ return fVolume; }
                        const String&           FileName() const        { 
return fFileName; }
@@ -106,7 +107,7 @@ private:
                        struct CachingPackageReader;
 
 private:
-                       status_t                        _Load();
+                       status_t                        _Load(const 
PackageSettings& settings);
                        bool                            _InitVersionedName();
 
 private:
diff --git 
a/src/add-ons/kernel/file_systems/packagefs/volume/PackageSettings.cpp 
b/src/add-ons/kernel/file_systems/packagefs/volume/PackageSettings.cpp
new file mode 100644
index 0000000..1868b7b
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/packagefs/volume/PackageSettings.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "PackageSettings.h"
+
+#include <driver_settings.h>
+
+#include <AutoDeleter.h>
+#include <directories.h>
+#include <fs/KPath.h>
+#include <vfs.h>
+
+#include "DebugSupport.h"
+
+
+// #pragma mark - PackageSettingsItem
+
+
+PackageSettingsItem::PackageSettingsItem()
+       :
+       fName(),
+       fEntries()
+{
+}
+
+
+PackageSettingsItem::~PackageSettingsItem()
+{
+       Entry* entry = fEntries.Clear(true);
+       while (entry != NULL) {
+               Entry* next = entry->HashNext();
+               delete entry;
+               entry = next;
+       }
+}
+
+
+status_t
+PackageSettingsItem::Init(const driver_parameter& parameter)
+{
+       if (!fName.SetTo(parameter.values[0]) || fEntries.Init() != B_OK)
+               RETURN_ERROR(B_NO_MEMORY);
+
+       for (int i = 0; i < parameter.parameter_count; i++) {
+               const driver_parameter& subParameter = parameter.parameters[i];
+               if (strcmp(subParameter.name, "EntryBlacklist") != 0)
+                       continue;
+
+               status_t error = _AddBlackListedEntries(subParameter);
+               // abort only in case of serious issues (memory shortage)
+               if (error == B_NO_MEMORY)
+                       return error;
+       }
+
+       return B_OK;
+}
+
+
+void
+PackageSettingsItem::AddEntry(Entry* entry)
+{
+       fEntries.Insert(entry);
+}
+
+
+status_t
+PackageSettingsItem::AddEntry(const char* path, Entry*& _entry)
+{
+       Entry* parent = NULL;
+
+       while (*path != '\0') {
+               while (*path == '/') {
+                       path++;
+                       continue;
+               }
+
+               const char* componentEnd = strchr(path, '/');
+               if (componentEnd == NULL)
+                       componentEnd = path + strlen(path);
+
+               String name;
+               if (!name.SetTo(path, componentEnd - path))
+                       RETURN_ERROR(B_NO_MEMORY);
+
+               Entry* entry = FindEntry(parent, name);
+               if (entry == NULL) {
+                       entry = new(std::nothrow) Entry(parent, name);
+                       if (entry == NULL)
+                               RETURN_ERROR(B_NO_MEMORY);
+                       AddEntry(entry);
+               }
+
+               path = componentEnd;
+               parent = entry;
+       }
+
+       if (parent == NULL)
+               return B_BAD_VALUE;
+
+       _entry = parent;
+       return B_OK;
+}
+
+
+PackageSettingsItem::Entry*
+PackageSettingsItem::FindEntry(Entry* parent, const String& name) const
+{
+       return fEntries.Lookup(EntryKey(parent, name));
+}
+
+
+PackageSettingsItem::Entry*
+PackageSettingsItem::FindEntry(Entry* parent, const char* name) const
+{
+       return fEntries.Lookup(EntryKey(parent, name));
+}
+
+
+status_t
+PackageSettingsItem::_AddBlackListedEntries(const driver_parameter& parameter)
+{
+       for (int i = 0; i < parameter.parameter_count; i++) {
+               Entry* entry;
+               status_t error = AddEntry(parameter.parameters[i].name, entry);
+               // abort only in case of serious issues (memory shortage)
+               if (error == B_NO_MEMORY)
+                       return error;
+
+               entry->SetBlackListed(true);
+       }
+
+       return B_OK;
+}
+
+
+// #pragma mark - PackageSettings
+
+
+PackageSettings::PackageSettings()
+       :
+       fPackageItems()
+{
+}
+
+
+PackageSettings::~PackageSettings()
+{
+       PackageSettingsItem* item = fPackageItems.Clear(true);
+       while (item != NULL) {
+               PackageSettingsItem* next = item->HashNext();
+               delete item;
+               item = next;
+       }
+}
+
+
+status_t
+PackageSettings::Load(dev_t mountPointDeviceID, ino_t mountPointNodeID,
+       PackageFSMountType mountType)
+{
+       status_t error = fPackageItems.Init();
+       if (error != B_OK)
+               RETURN_ERROR(error);
+
+       // get the mount point relative settings file path
+       const char* settingsFilePath = mountType == PACKAGE_FS_MOUNT_TYPE_HOME
+               ? kUserSettingsGlobalDirectory "/packages"
+                       + strlen(kUserConfigDirectory) + 1
+               : kSystemSettingsDirectory "/packages" + 
strlen(kSystemDirectory) + 1;
+
+       // get an absolute path
+       KPath path;
+       if (path.InitCheck() != B_OK)
+               RETURN_ERROR(path.InitCheck());
+
+       error = vfs_entry_ref_to_path(mountPointDeviceID, mountPointNodeID,
+               NULL, true, path.LockBuffer(), path.BufferSize());
+       if (error != B_OK)
+               return error;
+       path.UnlockBuffer();
+
+       error = path.Append(settingsFilePath);
+       if (error != B_OK)
+               return error;
+
+       // load the driver settings
+       void* settingsHandle = load_driver_settings(path.Path());
+       if (settingsHandle == NULL)
+               return B_ENTRY_NOT_FOUND;
+       CObjectDeleter<void, status_t> settingsDeleter(settingsHandle,
+               &unload_driver_settings);
+
+       const driver_settings* settings = get_driver_settings(settingsHandle);
+       for (int i = 0; i < settings->parameter_count; i++) {
+               const driver_parameter& parameter = settings->parameters[i];
+               if (strcmp(parameter.name, "Package") != 0
+                       || parameter.value_count < 1) {
+                       continue;
+               }
+
+               error = _AddPackageSettingsItem(parameter);
+               // abort only in case of serious issues (memory shortage)
+               if (error == B_NO_MEMORY)
+                       return error;
+       }
+
+       return B_OK;
+}
+
+
+const PackageSettingsItem*
+PackageSettings::PackageItemFor(const String& name) const
+{
+       return fPackageItems.Lookup(name);
+}
+
+
+status_t
+PackageSettings::_AddPackageSettingsItem(const driver_parameter& parameter)
+{
+       PackageSettingsItem* packageItem = new(std::nothrow) 
PackageSettingsItem;
+       if (packageItem == NULL || packageItem->Init(parameter) != B_OK) {
+               delete packageItem;
+               RETURN_ERROR(B_NO_MEMORY);
+       }
+
+       fPackageItems.Insert(packageItem);
+       return B_OK;
+}
diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/PackageSettings.h 
b/src/add-ons/kernel/file_systems/packagefs/volume/PackageSettings.h
new file mode 100644
index 0000000..a1654e6
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/packagefs/volume/PackageSettings.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef PACKAGE_SETTINGS_H
+#define PACKAGE_SETTINGS_H
+
+
+#include <packagefs.h>
+#include <util/OpenHashTable.h>
+
+#include "String.h"
+
+
+struct driver_parameter;
+
+
+class PackageSettingsItem {
+public:
+                       class Entry {
+                       public:
+                               Entry(Entry* parent, const String& name)
+                                       :
+                                       fParent(parent),
+                                       fName(name),
+                                       fIsBlackListed(false)
+                               {
+                               }
+
+                               Entry* Parent() const
+                               {
+                                       return fParent;
+                               }
+
+                               const String& Name() const
+                               {
+                                       return fName;
+                               }
+
+                               bool IsBlackListed() const
+                               {
+                                       return fIsBlackListed;
+                               }
+
+                               void SetBlackListed(bool blackListed)
+                               {
+                                       fIsBlackListed = blackListed;
+                               }
+
+                               Entry*& HashNext()
+                               {
+                                       return fHashNext;
+                               }
+
+                       private:
+                               Entry*  fParent;
+                               String  fName;
+                               bool    fIsBlackListed;
+                               Entry*  fHashNext;
+                       };
+
+                       class EntryKey {
+                       public:
+                               EntryKey(Entry* parent, const char* name)
+                                       :
+                                       fParent(parent),
+                                       fName(name),
+                                       fHash((addr_t)parent / 8 ^ 
hash_hash_string(name))
+                               {
+                               }
+
+                               EntryKey(Entry* parent, const String& name)
+                                       :
+                                       fParent(parent),
+                                       fName(name),
+                                       fHash((addr_t)parent / 8 ^ name.Hash())
+                               {
+                               }
+
+                               Entry* Parent() const
+                               {
+                                       return fParent;
+                               }
+
+                               const char* Name() const
+                               {
+                                       return fName;
+                               }
+
+                               size_t Hash() const
+                               {
+                                       return fHash;
+                               }
+
+                       private:
+                               Entry*          fParent;
+                               const char*     fName;
+                               size_t          fHash;
+                       };
+
+public:
+                                                               
PackageSettingsItem();
+                                                               
~PackageSettingsItem();
+
+                       status_t                        Init(const 
driver_parameter& parameter);
+
+                       const String&           Name() const
+                                                                       { 
return fName; }
+
+                       void                            AddEntry(Entry* entry);
+                       status_t                        AddEntry(const char* 
path, Entry*& _entry);
+                       Entry*                          FindEntry(Entry* 
parent, const String& name)
+                                                                       const;
+                       Entry*                          FindEntry(Entry* 
parent, const char* name)
+                                                                       const;
+
+                       PackageSettingsItem*& HashNext()
+                                                                       { 
return fHashNext; }
+
+private:
+                       struct EntryHashDefinition {
+                               typedef EntryKey        KeyType;
+                               typedef Entry           ValueType;
+
+                               size_t HashKey(const EntryKey& key) const
+                               {
+                                       return key.Hash();
+                               }
+
+                               size_t Hash(const Entry* value) const
+                               {
+                                       return 
HashKey(EntryKey(value->Parent(), value->Name()));
+                               }
+
+                               bool Compare(const EntryKey& key, const Entry* 
value) const
+                               {
+                                       return key.Parent() == value->Parent()
+                                               && strcmp(key.Name(), 
value->Name()) == 0;
+                               }
+
+                               Entry*& GetLink(Entry* value) const
+                               {
+                                       return value->HashNext();
+                               }
+                       };
+
+                       typedef BOpenHashTable<EntryHashDefinition> EntryTable;
+
+private:
+                       status_t                        _AddBlackListedEntries(
+                                                                       const 
driver_parameter& parameter);
+
+private:
+                       String                          fName;
+                       EntryTable                      fEntries;
+                       PackageSettingsItem* fHashNext;
+};
+
+
+struct PackageSettingsItemHashDefinition {
+       typedef String                          KeyType;
+       typedef PackageSettingsItem     ValueType;
+
+       size_t HashKey(const String& key) const
+       {
+               return key.Hash();
+       }
+
+       size_t Hash(const PackageSettingsItem* value) const
+       {
+               return HashKey(value->Name());
+       }
+
+       bool Compare(const String& key, const PackageSettingsItem* value) const
+       {
+               return key == value->Name();
+       }
+
+       PackageSettingsItem*& GetLink(PackageSettingsItem* value) const
+       {
+               return value->HashNext();
+       }
+};
+
+
+class PackageSettings {
+public:
+                                                               
PackageSettings();
+                                                               
~PackageSettings();
+
+                       status_t                        Load(dev_t 
mountPointDeviceID,
+                                                                       ino_t 
mountPointNodeID,
+                                                                       
PackageFSMountType mountType);
+
+                       const PackageSettingsItem* PackageItemFor(const String& 
name) const;
+
+private:
+                       typedef 
BOpenHashTable<PackageSettingsItemHashDefinition>
+                               PackageItemTable;
+
+private:
+                       status_t                        _AddPackageSettingsItem(
+                                                                       const 
driver_parameter& parameter);
+
+private:
+                       PackageItemTable        fPackageItems;
+};
+
+
+#endif // PACKAGE_SETTINGS_H
diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp 
b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp
index 3e99ba6..0fcf1ad 100644
--- a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp
+++ b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp
@@ -275,6 +275,7 @@ Volume::Volume(fs_volume* fsVolume)
        fRootDirectory(NULL),
        fPackageFSRoot(NULL),
        fPackagesDirectory(NULL),
+       fPackageSettings(),
        fNextNodeID(kRootDirectoryID + 1)
 {
        rw_lock_init(&fLock, "packagefs volume");
@@ -450,6 +451,13 @@ Volume::Mount(const char* parameterString)
        if (error != B_OK)
                RETURN_ERROR(error);
 
+       // load package settings
+       error = fPackageSettings.Load(fMountPoint.deviceID, fMountPoint.nodeID,
+               fMountType);
+       // abort only in case of serious issues (memory shortage)
+       if (error == B_NO_MEMORY)
+               RETURN_ERROR(error);
+
        // create package domain
        fPackagesDirectory = new(std::nothrow) PackagesDirectory;
        if (fPackagesDirectory == NULL)
@@ -1434,7 +1442,7 @@ Volume::_LoadPackage(const char* name, Package*& _package)
        if (error != B_OK)
                return error;
 
-       error = package->Load();
+       error = package->Load(fPackageSettings);
        if (error != B_OK)
                return error;
 
diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h 
b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h
index 2e34a70..4df34f8 100644
--- a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h
+++ b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h
@@ -21,6 +21,7 @@
 #include "NodeListener.h"
 #include "Package.h"
 #include "PackageLinksListener.h"
+#include "PackageSettings.h"
 #include "Query.h"
 
 
@@ -179,6 +180,7 @@ private:
                        ::PackageFSRoot*        fPackageFSRoot;
                        ::MountType                     fMountType;
                        PackagesDirectory*      fPackagesDirectory;
+                       PackageSettings         fPackageSettings;
 
                        struct {
                                dev_t                   deviceID;
diff --git a/src/system/boot/loader/Jamfile b/src/system/boot/loader/Jamfile
index 5a21032..1b24a2e 100644
--- a/src/system/boot/loader/Jamfile
+++ b/src/system/boot/loader/Jamfile
@@ -79,6 +79,7 @@ BootStaticLibrary boot_loader :
        list.cpp
        ring_buffer.cpp
        safemode_settings.cpp
+       StringHash.cpp
 
        Referenceable.cpp
 
@@ -105,7 +106,7 @@ BootStaticLibrary boot_partitions :
        ;
 
 # Tell Jam where to find the utility sources
-SEARCH on [ FGristFiles kernel_cpp.cpp list.cpp ring_buffer.cpp ]
+SEARCH on [ FGristFiles kernel_cpp.cpp list.cpp ring_buffer.cpp StringHash.cpp 
]
     = [ FDirName $(HAIKU_TOP) src system kernel util ] ;
 
 SEARCH on [ FGristFiles KMessage.cpp ]
diff --git a/src/system/boot/loader/file_systems/packagefs/Jamfile 
b/src/system/boot/loader/file_systems/packagefs/Jamfile
index 07d8c03..2425fdf 100644
--- a/src/system/boot/loader/file_systems/packagefs/Jamfile
+++ b/src/system/boot/loader/file_systems/packagefs/Jamfile
@@ -17,6 +17,7 @@ SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package 
hpkg ] ;
 
 BootStaticLibrary boot_packagefs :
        packagefs.cpp
+       PackageSettingsItem.cpp
 
        # package kit
 
diff --git 
a/src/system/boot/loader/file_systems/packagefs/PackageSettingsItem.cpp 
b/src/system/boot/loader/file_systems/packagefs/PackageSettingsItem.cpp
new file mode 100644
index 0000000..d5d54c9
--- /dev/null
+++ b/src/system/boot/loader/file_systems/packagefs/PackageSettingsItem.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "PackageSettingsItem.h"
+
+#include <driver_settings.h>
+
+#include <AutoDeleter.h>
+#include <boot/vfs.h>
+#include <system/directories.h>
+
+
+namespace PackageFS {
+
+
+// #pragma mark - PackageSettingsItem
+
+
+PackageSettingsItem::PackageSettingsItem()
+       :
+       fEntries()
+{
+}
+
+
+PackageSettingsItem::~PackageSettingsItem()
+{
+       Entry* entry = fEntries.Clear(true);
+       while (entry != NULL) {
+               Entry* next = entry->HashNext();
+               delete entry;
+               entry = next;
+       }
+}
+
+
+/*static*/ PackageSettingsItem*
+PackageSettingsItem::Load(::Directory* systemDirectory, const char* name)
+{
+       // open the driver settings file
+       const char* settingsFilePath
+               = kSystemSettingsDirectory "/packages" + 
strlen(kSystemDirectory) + 1;
+
+       int fd = open_from(systemDirectory, settingsFilePath, B_READ_ONLY, 0);
+       if (fd < 0)
+               return NULL;
+       FileDescriptorCloser fdCloser(fd);
+
+       // load the driver settings
+       void* settingsHandle = load_driver_settings_file(fd);
+       if (settingsHandle == NULL)
+               return NULL;
+       CObjectDeleter<void, status_t> settingsDeleter(settingsHandle,
+               &unload_driver_settings);
+
+       const driver_settings* settings = get_driver_settings(settingsHandle);
+       for (int i = 0; i < settings->parameter_count; i++) {
+               const driver_parameter& parameter = settings->parameters[i];
+               if (strcmp(parameter.name, "Package") != 0
+                       || parameter.value_count < 1
+                       || strcmp(parameter.values[0], name) != 0) {
+                       continue;
+               }
+
+               PackageSettingsItem* settingsItem
+                       = new(std::nothrow) PackageSettingsItem;
+               if (settingsItem == NULL || settingsItem->Init(parameter) != 
B_OK) {
+                       delete settingsItem;
+                       return NULL;
+               }
+
+               return settingsItem;
+       }
+
+       return NULL;
+}
+
+
+status_t
+PackageSettingsItem::Init(const driver_parameter& parameter)
+{
+       if (fEntries.Init() != B_OK)
+               return B_NO_MEMORY;
+
+       for (int i = 0; i < parameter.parameter_count; i++) {
+               const driver_parameter& subParameter = parameter.parameters[i];
+               if (strcmp(subParameter.name, "EntryBlacklist") != 0)
+                       continue;
+
+               status_t error = _AddBlackListedEntries(subParameter);
+               // abort only in case of serious issues (memory shortage)
+               if (error == B_NO_MEMORY)
+                       return error;
+       }
+
+       return B_OK;
+}
+
+
+void
+PackageSettingsItem::AddEntry(Entry* entry)
+{
+       fEntries.Insert(entry);
+}
+
+
+status_t
+PackageSettingsItem::AddEntry(const char* path, Entry*& _entry)
+{
+       Entry* parent = NULL;
+
+       while (*path != '\0') {
+               while (*path == '/') {
+                       path++;
+                       continue;
+               }
+
+               const char* componentEnd = strchr(path, '/');
+               if (componentEnd == NULL)
+                       componentEnd = path + strlen(path);
+
+               const char* name = path;
+               size_t nameLength = componentEnd - path;
+
+               Entry* entry = FindEntry(parent, name, nameLength);
+               if (entry == NULL) {
+                       entry = new(std::nothrow) Entry(parent);
+                       if (entry == NULL || !entry->SetName(name, nameLength)) 
{
+                               delete entry;
+                               return B_NO_MEMORY;
+                       }
+                       AddEntry(entry);
+               }
+
+               path = componentEnd;
+               parent = entry;
+       }
+
+       if (parent == NULL)
+               return B_BAD_VALUE;
+
+       _entry = parent;
+       return B_OK;
+}
+
+
+PackageSettingsItem::Entry*
+PackageSettingsItem::FindEntry(Entry* parent, const char* name) const
+{
+       return fEntries.Lookup(EntryKey(parent, name));
+}
+
+
+PackageSettingsItem::Entry*
+PackageSettingsItem::FindEntry(Entry* parent, const char* name,
+       size_t nameLength) const
+{
+       return fEntries.Lookup(EntryKey(parent, name, nameLength));
+}
+
+
+status_t
+PackageSettingsItem::_AddBlackListedEntries(const driver_parameter& parameter)
+{
+       for (int i = 0; i < parameter.parameter_count; i++) {
+               Entry* entry;
+               status_t error = AddEntry(parameter.parameters[i].name, entry);
+               // abort only in case of serious issues (memory shortage)
+               if (error == B_NO_MEMORY)
+                       return error;
+
+               entry->SetBlackListed(true);
+       }
+
+       return B_OK;
+}
+
+
+}      // namespace PackageFS
diff --git 
a/src/system/boot/loader/file_systems/packagefs/PackageSettingsItem.h 
b/src/system/boot/loader/file_systems/packagefs/PackageSettingsItem.h
new file mode 100644
index 0000000..94f8b2d
--- /dev/null
+++ b/src/system/boot/loader/file_systems/packagefs/PackageSettingsItem.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef BOOT_LOADER_FILE_SYSTEMS_PACKAGEFS_PACKAGE_SETTINGS_ITEM_H
+#define BOOT_LOADER_FILE_SYSTEMS_PACKAGEFS_PACKAGE_SETTINGS_ITEM_H
+
+
+#include <string.h>
+
+#include <util/OpenHashTable.h>
+#include <util/StringHash.h>
+
+
+struct driver_parameter;
+class Directory;
+
+
+namespace PackageFS {
+
+
+class PackageSettingsItem {
+public:
+                       class Entry {
+                       public:
+                               Entry(Entry* parent)
+                                       :
+                                       fParent(parent),
+                                       fName(NULL),
+                                       fIsBlackListed(false)
+                               {
+                               }
+
+                               ~Entry()
+                               {
+                                       free(fName);
+                               }
+
+                               bool SetName(const char* name, size_t 
nameLength)
+                               {
+                                       fName = (char*)malloc(nameLength + 1);
+                                       if (fName == NULL)
+                                               return false;
+
+                                       memcpy(fName, name, nameLength);
+                                       fName[nameLength] = '\0';
+                                       return true;
+                               }
+
+                               Entry* Parent() const
+                               {
+                                       return fParent;
+                               }
+
+                               const char* Name() const
+                               {
+                                       return fName;
+                               }
+
+                               bool IsBlackListed() const
+                               {
+                                       return fIsBlackListed;
+                               }
+
+                               void SetBlackListed(bool blackListed)
+                               {
+                                       fIsBlackListed = blackListed;
+                               }
+
+                               Entry*& HashNext()
+                               {
+                                       return fHashNext;
+                               }
+
+                       private:
+                               Entry*  fParent;
+                               char*   fName;
+                               bool    fIsBlackListed;
+                               Entry*  fHashNext;
+                       };
+
+                       class EntryKey {
+                       public:
+                               EntryKey(Entry* parent, const char* name, 
size_t nameLength)
+                                       :
+                                       fParent(parent),
+                                       fName(name),
+                                       fNameLength(nameLength)
+                               {
+                               }
+
+                               EntryKey(Entry* parent, const char* name)
+                                       :
+                                       fParent(parent),
+                                       fName(name),
+                                       fNameLength(strlen(name))
+                               {
+                               }
+
+                               Entry* Parent() const
+                               {
+                                       return fParent;
+                               }
+
+                               const char* Name() const
+                               {
+                                       return fName;
+                               }
+
+                               size_t NameLength() const
+                               {
+                                       return fNameLength;
+                               }
+
+                               size_t Hash() const
+                               {
+                                       return (addr_t)fParent / 8
+                                               ^ hash_hash_string_part(fName, 
fNameLength);
+                               }
+
+                       private:
+                               Entry*          fParent;
+                               const char*     fName;
+                               size_t          fNameLength;
+                       };
+
+public:
+                                                               
PackageSettingsItem();
+                                                               
~PackageSettingsItem();
+
+       static  PackageSettingsItem* Load(::Directory* systemDirectory,
+                                                                       const 
char* name);
+
+                       status_t                        Init(const 
driver_parameter& parameter);
+
+                       void                            AddEntry(Entry* entry);
+                       status_t                        AddEntry(const char* 
path, Entry*& _entry);
+                       Entry*                          FindEntry(Entry* 
parent, const char* name)
+                                                                       const;
+                       Entry*                          FindEntry(Entry* 
parent, const char* name,
+                                                                       size_t 
nameLength) const;
+
+                       PackageSettingsItem*& HashNext()
+                                                                       { 
return fHashNext; }
+
+private:
+                       struct EntryHashDefinition {
+                               typedef EntryKey        KeyType;
+                               typedef Entry           ValueType;
+
+                               size_t HashKey(const EntryKey& key) const
+                               {
+                                       return key.Hash();
+                               }
+
+                               size_t Hash(const Entry* value) const
+                               {
+                                       return 
HashKey(EntryKey(value->Parent(), value->Name()));
+                               }
+
+                               bool Compare(const EntryKey& key, const Entry* 
value) const
+                               {
+                                       const char* name = value->Name();
+                                       return key.Parent() == value->Parent()
+                                               && strncmp(key.Name(), name, 
key.NameLength()) == 0
+                                               && name[key.NameLength()] == 
'\0';
+                               }
+
+                               Entry*& GetLink(Entry* value) const
+                               {
+                                       return value->HashNext();
+                               }
+                       };
+
+                       typedef BOpenHashTable<EntryHashDefinition> EntryTable;
+
+private:
+                       status_t                        _AddBlackListedEntries(
+                                                                       const 
driver_parameter& parameter);
+
+private:
+                       EntryTable                      fEntries;
+                       PackageSettingsItem* fHashNext;
+};
+
+
+}      // namespace PackageFS
+
+
+#endif // BOOT_LOADER_FILE_SYSTEMS_PACKAGEFS_PACKAGE_SETTINGS_ITEM_H
diff --git a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp 
b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp
index 1ab70be..53d75ad 100644
--- a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp
+++ b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp
@@ -25,6 +25,8 @@
 
 #include <boot/platform.h>
 
+#include "PackageSettingsItem.h"
+
 
 #if 0
 #      define RETURN_ERROR(error) return (error);
@@ -44,6 +46,8 @@ using namespace BPackageKit::BHPKG;
 using BPackageKit::BHPKG::BPrivate::PackageFileHeapReader;
 using BPackageKit::BHPKG::BPrivate::PackageReaderImpl;
 
+using PackageFS::PackageSettingsItem;
+
 
 namespace {
 
@@ -325,9 +329,13 @@ private:
 
 
 struct PackageLoaderContentHandler : BPackageContentHandler {
-       PackageLoaderContentHandler(PackageVolume* volume)
+       PackageLoaderContentHandler(PackageVolume* volume,
+               PackageSettingsItem* settingsItem)
                :
                fVolume(volume),
+               fSettingsItem(settingsItem),
+               fLastSettingsEntry(NULL),
+               fLastSettingsEntryEntry(NULL),
                fErrorOccurred(false)
        {
        }
@@ -339,8 +347,11 @@ struct PackageLoaderContentHandler : 
BPackageContentHandler {
 
        virtual status_t HandleEntry(BPackageEntry* entry)
        {
-               if (fErrorOccurred)
+               if (fErrorOccurred
+                       || (fLastSettingsEntry != NULL
+                               && fLastSettingsEntry->IsBlackListed())) {
                        return B_OK;
+               }
 
                PackageDirectory* parentDir = NULL;
                if (const BPackageEntry* parentEntry = entry->Parent()) {
@@ -351,6 +362,19 @@ struct PackageLoaderContentHandler : 
BPackageContentHandler {
                                (PackageNode*)parentEntry->UserToken());
                }
 
+               if (fSettingsItem != NULL
+                       && (parentDir == NULL
+                               || entry->Parent() == fLastSettingsEntryEntry)) 
{
+                       PackageSettingsItem::Entry* settingsEntry
+                               = fSettingsItem->FindEntry(fLastSettingsEntry, 
entry->Name());
+                       if (settingsEntry != NULL) {
+                               fLastSettingsEntry = settingsEntry;
+                               fLastSettingsEntryEntry = entry;
+                               if (fLastSettingsEntry->IsBlackListed())
+                                       return B_OK;
+                       }
+               }
+
                if (parentDir == NULL)
                        parentDir = fVolume->RootDirectory();
 
@@ -412,6 +436,11 @@ struct PackageLoaderContentHandler : 
BPackageContentHandler {
 
        virtual status_t HandleEntryDone(BPackageEntry* entry)
        {
+               if (entry == fLastSettingsEntryEntry) {
+                       fLastSettingsEntryEntry = entry->Parent();
+                       fLastSettingsEntry = fLastSettingsEntry->Parent();
+               }
+
                return B_OK;
        }
 
@@ -428,8 +457,11 @@ struct PackageLoaderContentHandler : 
BPackageContentHandler {
        }
 
 private:
-       PackageVolume*  fVolume;
-       bool                    fErrorOccurred;
+       PackageVolume*                          fVolume;
+       const PackageSettingsItem*      fSettingsItem;
+       PackageSettingsItem::Entry*     fLastSettingsEntry;
+       const BPackageEntry*            fLastSettingsEntryEntry;
+       bool                                            fErrorOccurred;
 };
 
 
@@ -761,7 +793,8 @@ create_node(PackageNode* packageNode, ::Node*& _node)
 
 
 status_t
-packagefs_mount_file(int fd, ::Directory*& _mountedDirectory)
+packagefs_mount_file(int fd, ::Directory* systemDirectory,
+       ::Directory*& _mountedDirectory)
 {
        PackageLoaderErrorOutput errorOutput;
        PackageReaderImpl packageReader(&errorOutput);
@@ -779,8 +812,13 @@ packagefs_mount_file(int fd, ::Directory*& 
_mountedDirectory)
        if (error != B_OK)
                RETURN_ERROR(error);
 
+       // load settings for the package
+       PackageSettingsItem* settings = 
PackageSettingsItem::Load(systemDirectory,
+               "haiku");
+       ObjectDeleter<PackageSettingsItem> settingsDeleter(settings);
+
        // parse content -- this constructs the entry/node tree
-       PackageLoaderContentHandler handler(volume);
+       PackageLoaderContentHandler handler(volume, settings);
        error = handler.Init();
        if (error != B_OK)
                RETURN_ERROR(error);
diff --git a/src/system/boot/loader/file_systems/packagefs/packagefs.h 
b/src/system/boot/loader/file_systems/packagefs/packagefs.h
index 1ae18a0..6c31dbd 100644
--- a/src/system/boot/loader/file_systems/packagefs/packagefs.h
+++ b/src/system/boot/loader/file_systems/packagefs/packagefs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2011-2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef BOOT_LOADER_FILE_SYSTEMS_PACKAGEFS_H
@@ -15,13 +15,8 @@ class Directory;
 class Node;
 
 
-__BEGIN_DECLS
-
-
-status_t packagefs_mount_file(int fd, Directory*& _mountedDirectory);
-
-
-__END_DECLS
+status_t packagefs_mount_file(int fd, Directory* systemDirectory,
+       Directory*& _mountedDirectory);
 
 
 #endif // BOOT_LOADER_FILE_SYSTEMS_PACKAGEFS_H
diff --git a/src/system/boot/loader/vfs.cpp b/src/system/boot/loader/vfs.cpp
index 2aa2ecc..bb7d5e0 100644
--- a/src/system/boot/loader/vfs.cpp
+++ b/src/system/boot/loader/vfs.cpp
@@ -445,7 +445,8 @@ BootVolume::SetTo(Directory* rootDirectory)
 
        // the system is packaged -- mount the packagefs
        Directory* packageRootDirectory;
-       status_t error = packagefs_mount_file(packageFD, packageRootDirectory);
+       status_t error = packagefs_mount_file(packageFD, fSystemDirectory,
+               packageRootDirectory);
        close(packageFD);
        if (error != B_OK) {
                Unset();
diff --git a/src/system/kernel/util/Jamfile b/src/system/kernel/util/Jamfile
index a8f49b9..cb8bf52 100644
--- a/src/system/kernel/util/Jamfile
+++ b/src/system/kernel/util/Jamfile
@@ -15,6 +15,7 @@ KernelMergeObject kernel_util.o :
        ring_buffer.cpp
        RadixBitmap.cpp
        Random.cpp
+       StringHash.cpp
 
        : $(TARGET_KERNEL_PIC_CCFLAGS) -DUSING_LIBGCC
 ;


Other related posts:

  • » [haiku-commits] haiku: hrev46391 - in src: system/boot/loader/file_systems/packagefs add-ons/kernel/file_systems/packagefs/volume add-ons/kernel/file_systems/packagefs/package system/kernel/util system/libroot/os - ingo_weinhold