This is a patch which solves the bug 3118. Because it is not so small I am posting it here for comments.

Here is the patch description:

Currently we were updating [Icap|Ecap]::TheConfig even when [icap|ecap]_enable was false, which may lead to service activation for Icap or Ecap services that should be disabled. The patch removes such services from service groups before they are activated.

The patch also warns the user when an adaptation group loses some but not all of its services due to the new group cleanup code.


Regards,
  Christos
author: Measurement Factory
Bug 3118: ecap_enable on forces icap_enable on

We were updating [Icap|Ecap]::TheConfig even when [icap|ecap]_enable was false,
which may lead to service activation for Icap or Ecap services that should be
disabled. The patch removes such services from service groups before they are 
activated.

The patch also warns the user when an adaptation group loses some but not all
of its services due to the new group cleanup code.

=== modified file 'src/adaptation/Config.cc'
--- src/adaptation/Config.cc	2011-02-17 19:27:54 +0000
+++ src/adaptation/Config.cc	2011-07-29 13:06:49 +0000
@@ -59,6 +59,60 @@
 }
 
 void
+Adaptation::Config::removeService(const String& service)
+{
+    removeRule(service);
+    const Groups& groups = AllGroups();
+    for (unsigned int i = 0; i < groups.size(); ) {
+        const ServiceGroupPointer group = groups[i];
+        const ServiceGroup::Store& services = group->services;
+        typedef ServiceGroup::Store::const_iterator SGSI;
+        for (SGSI it = services.begin(); it != services.end(); ++it) {
+            if (*it == service) {
+                group->removedServices.push_back(service);
+                group->services.prune(service);
+                break;
+            }
+        }
+        if (services.empty()) {
+            removeRule(group->id);
+            AllGroups().prune(group);
+        } else {
+            ++i;
+        }
+    }
+}
+
+void
+Adaptation::Config::removeRule(const String& id)
+{
+    typedef AccessRules::const_iterator ARI;
+    const AccessRules& rules = AllRules();
+    for (ARI it = rules.begin(); it != rules.end(); ++it) {
+        AccessRule* rule = *it;
+        if (rule->groupId == id) {
+            AllRules().prune(rule);
+            delete (rule);
+            break;
+        }
+    }
+}
+
+void
+Adaptation::Config::clear()
+{
+    debugs(93, 3, HERE << "rules: " << AllRules().size() << ", groups: " <<
+           AllGroups().size() << ", services: " << serviceConfigs.size());
+    typedef ServiceConfigs::const_iterator SCI;
+    const ServiceConfigs& configs = serviceConfigs;
+    for (SCI cfg = configs.begin(); cfg != configs.end(); ++cfg)
+        removeService((*cfg)->key);
+    serviceConfigs.clean();
+    debugs(93, 3, HERE << "rules: " << AllRules().size() << ", groups: " <<
+           AllGroups().size() << ", services: " << serviceConfigs.size());
+}
+
+void
 Adaptation::Config::parseService()
 {
     ServiceConfigPointer cfg = newServiceConfig();
@@ -94,9 +148,14 @@
     }
 }
 
-void
+bool
 Adaptation::Config::finalize()
 {
+    if (!onoff) {
+        clear();
+        return false;
+    }
+
     // create service reps from service configs
     int created = 0;
 
@@ -120,6 +179,7 @@
 
     // services remember their configs; we do not have to
     serviceConfigs.clean();
+    return true;
 }
 
 // poor man for_each

=== modified file 'src/adaptation/Config.h'
--- src/adaptation/Config.h	2011-03-08 23:56:22 +0000
+++ src/adaptation/Config.h	2011-07-29 13:32:42 +0000
@@ -54,12 +54,27 @@
     void dumpService(StoreEntry *, const char *) const;
     ServicePointer findService(const String&);
 
-    virtual void finalize();
+    /**
+     * Creates and starts the adaptation services. In the case the adaptation
+     * mechanism is disabled then removes any reference to the services from
+     * access rules and service groups, and returns false.
+     * \return true if the services are ready and running, false otherwise
+     */
+    virtual bool finalize();
 
 protected:
+    /// Removes any reference to the services  from configuration
+    virtual void clear();
+
     /// creates service configuration object that will parse and keep cfg info
     virtual ServiceConfig *newServiceConfig() const;
 
+    /// Removes the given service from all service groups.
+    void removeService(const String& service);
+
+    /// Removes access rules of the given service or group
+    void removeRule(const String& id);
+
 private:
     Config(const Config &); // unsupported
     Config &operator =(const Config &); // unsupported

=== modified file 'src/adaptation/ServiceGroups.cc'
--- src/adaptation/ServiceGroups.cc	2011-03-30 17:43:55 +0000
+++ src/adaptation/ServiceGroups.cc	2011-07-29 13:06:49 +0000
@@ -39,6 +39,16 @@
     // 2) warn if all-same services have different bypass status
     // 3) warn if there are seemingly identical services in the group
     // TODO: optimize by remembering ServicePointers rather than IDs
+    if (!removedServices.empty()) {
+        String s;
+        for (Store::iterator it = removedServices.begin(); it != removedServices.end(); ++it) {
+            s.append(*it);
+            s.append(',');
+        }
+        s.cut(s.size() - 1);
+        debugs(93, DBG_IMPORTANT, "Adaptation group '" << id << "' contains disabled member(s) after reconfiguration: " << s);
+        removedServices.clean();
+    }
 
     String baselineKey;
     bool baselineBypass = false;

=== modified file 'src/adaptation/ServiceGroups.h'
--- src/adaptation/ServiceGroups.h	2011-03-30 17:43:55 +0000
+++ src/adaptation/ServiceGroups.h	2011-07-29 13:34:32 +0000
@@ -56,6 +56,7 @@
     String kind;
     Id id;
     Store services;
+    Store removedServices;///< the disabled services in the case ecap or icap is disabled
 
     Method method; /// based on the first added service
     VectPoint point; /// based on the first added service

=== modified file 'src/adaptation/ecap/Config.cc'
--- src/adaptation/ecap/Config.cc	2011-03-08 23:56:22 +0000
+++ src/adaptation/ecap/Config.cc	2011-07-29 13:06:49 +0000
@@ -18,12 +18,14 @@
 {
 }
 
-void
+bool
 Adaptation::Ecap::Config::finalize()
 {
-    Adaptation::Config::finalize();
+    if (!Adaptation::Config::finalize())
+        return false;
     Host::Register();
     CheckUnusedAdapterServices(AllServices());
+    return true;
 }
 
 Adaptation::ServiceConfig *

=== modified file 'src/adaptation/ecap/Config.h'
--- src/adaptation/ecap/Config.h	2011-03-10 01:12:44 +0000
+++ src/adaptation/ecap/Config.h	2011-07-29 13:06:49 +0000
@@ -38,7 +38,7 @@
     Config();
     ~Config();
 
-    virtual void finalize();
+    virtual bool finalize();
 
 protected:
     virtual Adaptation::ServiceConfig *newServiceConfig() const;

Reply via email to