One way to make it non-disruptive for 3.1 would be making this new behavior configurable (as I suggested in the bug) - is it worth the extra effort of adding a config option for this, or is 3.2 intended to be released in the new future?


There isn't a planned date for a 3.2 release so far.  I'm not sure we have any 
new functionality that is significant enough to call for a 3.2 release yet.

In that case, I've made the bug fix configurable - new patch attached

The default behavior preserves the existing bug, so people don't have to change anything until they are ready.

Furthermore, people can choose to keep the bug (i.e. disable the patch) in 3.2, although I've put warnings in the config file to say that the default behavior will change.

In this new form, are you happy for it to go in trunk and potentially 3.1.3?
Here's something that can be used as the basis for the helper script and/or the %post section of the spec file:

killall gmetad
cd $RRDROOT
find . -type d -name '*[A-Z]*' ! -name __SummaryInfo__ -mindepth 2
-maxdepth 2 | while read ;
do
  OLD_NAME=`echo "$REPLY" | cut -f3 -d/`
  NEW_NAME=`echo "$OLD_NAME" | tr [A-Z] [a-z]`
  CLUSTER_NAME=`echo "$REPLY" | cut -f2 -d/`
  echo mv "$REPLY" "${CLUSTER_NAME}/${NEW_NAME}"
  #mv "$REPLY" "${CLUSTER_NAME}/${NEW_NAME}"
done

Sounds good, add it to the patch.  :)


It's in the patch now - until a few people have tested it, it can stay out of the spec file
Index: contrib/ganglia-hosts-lowercase.sh
===================================================================
--- contrib/ganglia-hosts-lowercase.sh	(revision 0)
+++ contrib/ganglia-hosts-lowercase.sh	(revision 0)
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# This script renames all the host directory names to lowercase
+# It is part of a solution to the case-sensitive hostname problem,
+# bug 232, http://bugzilla.ganglia.info/cgi-bin/bugzilla/show_bug.cgi?id=232
+
+# RRDROOT must be set to the location where RRD files are kept
+
+#RRDROOT=/var/lib/ganglia/rrds
+
+if [ -z "${RRDROOT}" ];
+then
+  echo Please specify RRDROOT
+  exit 1
+fi
+
+killall gmetad
+cd $RRDROOT || exit 1
+find . -type d -name '*[A-Z]*' ! -name __SummaryInfo__ -mindepth 2 -maxdepth 2 | while read ;
+do
+  OLD_NAME=`echo "$REPLY" | cut -f3 -d/`
+  NEW_NAME=`echo "$OLD_NAME" | tr [A-Z] [a-z]`
+  CLUSTER_NAME=`echo "$REPLY" | cut -f2 -d/`
+  mv "$REPLY" "${CLUSTER_NAME}/${NEW_NAME}"
+done
+
+
Index: gmetad/process_xml.c
===================================================================
--- gmetad/process_xml.c	(revision 2002)
+++ gmetad/process_xml.c	(working copy)
@@ -313,6 +313,8 @@
                err_msg("Could not create hash table for cluster %s", name);
                return 1;
             }
+         if(gmetad_config.case_sensitive_hostnames == 0)
+            hash_set_flags(source->authority, HASH_FLAG_IGNORE_CASE);
 
          source->metric_summary = hash_create(DEFAULT_METRICSIZE);
          if (!source->metric_summary)
@@ -438,6 +440,14 @@
     */
    xmldata->hostname = realloc(xmldata->hostname, strlen(name)+1);
    strcpy(xmldata->hostname, name);
+
+   /* Convert name to lower case - host names can't be
+    * case sensitive
+    */
+   /*for(i = 0; name[i] != 0; i++)
+       xmldata->hostname[i] = tolower(name[i]);
+   xmldata->hostname[i] = 0; */
+
    hashkey.data = (void*) name;
    hashkey.size =  strlen(name) + 1;
 
Index: gmetad/rrd_helpers.c
===================================================================
--- gmetad/rrd_helpers.c	(revision 2002)
+++ gmetad/rrd_helpers.c	(working copy)
@@ -1,4 +1,5 @@
 /* $Id$ */
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -178,6 +179,7 @@
 {
    char rrd[ PATHSIZE ];
    char *summary_dir = "__SummaryInfo__";
+   int i;
 
    /* Build the path to our desired RRD file. Assume the rootdir exists. */
    strcpy(rrd, gmetad_config.rrd_rootdir);
@@ -190,7 +192,13 @@
 
    if (host) {
       strncat(rrd, "/", PATHSIZE);
+      i = strlen(rrd);
       strncat(rrd, host, PATHSIZE);
+      if(gmetad_config.case_sensitive_hostnames == 0) {
+         /* Convert the hostname to lowercase */
+         for( ; rrd[i] != 0; i++)
+            rrd[i] = tolower(rrd[i]);
+      }
       my_mkdir( rrd );
    }
    else {
Index: gmetad/gmetad.conf.in
===================================================================
--- gmetad/gmetad.conf.in	(revision 2002)
+++ gmetad/gmetad.conf.in	(working copy)
@@ -117,3 +117,14 @@
 # Where gmetad stores its round-robin databases
 # default: "@varstatedir@/ganglia/rrds"
 # rrd_rootdir "/some/other/place"
+#
+#-------------------------------------------------------------------------------
+# In earlier versions of gmetad, hostnames were handled in a case
+# sensitive manner
+# If your hostname directories have been renamed to lower case,
+# set this option to 0 to disable backward compatibility.
+# From version 3.2, backwards compatibility will be disabled by default.
+# default: 1   (for gmetad < 3.2)
+# default: 0   (for gmetad >= 3.2)
+case_sensitive_hostnames 1
+
Index: gmetad/conf.h
===================================================================
--- gmetad/conf.h	(revision 2002)
+++ gmetad/conf.h	(working copy)
@@ -21,6 +21,7 @@
       int all_trusted;
       int num_RRAs;
       char *RRAs[MAX_RRAS];
+      int case_sensitive_hostnames;
 } gmetad_config_t;
 
 int get_gmetad_config(char *conffile);
Index: gmetad/conf.c.in
===================================================================
--- gmetad/conf.c.in	(revision 2002)
+++ gmetad/conf.c.in	(working copy)
@@ -236,6 +236,13 @@
    return NULL;
 }
 
+static DOTCONF_CB(cb_case_sensitive_hostnames)
+{
+   gmetad_config_t *c = (gmetad_config_t*) cmd->option->info;
+   c->case_sensitive_hostnames = cmd->data.value;
+   return NULL;
+}
+
 static FUNC_ERRORHANDLER(errorhandler)
 {
    err_quit("gmetad config file error: %s\n", msg);
@@ -259,6 +266,7 @@
       {"setuid_username", ARG_STR, cb_setuid_username, &gmetad_config, 0},
       {"scalable", ARG_STR, cb_scalable, &gmetad_config, 0},
       {"RRAs", ARG_LIST, cb_RRAs, &gmetad_config, 0},
+      {"case_sensitive_hostnames", ARG_INT, cb_case_sensitive_hostnames, &gmetad_config, 0},
       LAST_OPTION
    };
 
@@ -284,6 +292,7 @@
    config->RRAs[2] = "RRA:AVERAGE:0.5:168:244";
    config->RRAs[3] = "RRA:AVERAGE:0.5:672:244";
    config->RRAs[4] = "RRA:AVERAGE:0.5:5760:374";
+   config->case_sensitive_hostnames = 1;
 }
 
 int
@@ -331,3 +340,4 @@
    dotconf_cleanup(configfile);
    return number_of_sources;
 }
+
Index: lib/hash.c
===================================================================
--- lib/hash.c	(revision 2002)
+++ lib/hash.c	(working copy)
@@ -1,4 +1,5 @@
 /* $Id$ */
+#include <ctype.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -171,6 +172,18 @@
    free( hash );
 }
 
+int
+hash_get_flags (hash_t *hash)
+{
+   return hash->flags;
+}
+
+void
+hash_set_flags (hash_t *hash, int flags)
+{
+   hash->flags = flags;
+}
+
 size_t
 hashval ( datum_t *key, hash_t *hash )
 {
@@ -181,13 +194,35 @@
    if ( hash == NULL || key == NULL || key->data == NULL || key->size <= 0 )
       return 0;
 
-   hash_val = ((unsigned char *)key->data)[0];
-   for ( i = 0; i < key->size ; i++ )
-      hash_val = ( hash_val * 32 + ((unsigned char *)key->data)[i]) % hash->size;
+   if(hash->flags & HASH_FLAG_IGNORE_CASE)
+   {
+      hash_val = tolower(((unsigned char *)key->data)[0]);
+      for ( i = 0; i < key->size ; i++ )
+         hash_val = ( hash_val * 32 + tolower(((unsigned char *)key->data)[i])) % hash->size; 
+   }
+   else
+   {
+      hash_val = ((unsigned char *)key->data)[0];
+      for ( i = 0; i < key->size ; i++ )
+         hash_val = ( hash_val * 32 + ((unsigned char *)key->data)[i]) % hash->size;
+   }
 
    return hash_val;
 }
 
+int
+hash_keycmp(hash_t *hash, datum_t *key1, datum_t *key2)
+{
+   if(hash->flags & HASH_FLAG_IGNORE_CASE)
+   {
+      return strncasecmp(key1->data, key2->data, key1->size);
+   }
+   else
+   {
+      return strncmp(key1->data, key2->data, key1->size);
+   }
+}
+
 datum_t *
 hash_insert (datum_t *key, datum_t *val, hash_t *hash)
 {
@@ -241,7 +276,7 @@
          if( bucket->key->size != key->size )
             continue;
 
-         if(! strncmp(bucket->key->data, key->data, key->size) )
+         if(! hash_keycmp(hash, bucket->key, key) )
             {
                /* New data for an existing key */
 
@@ -316,7 +351,7 @@
       if ( key->size != bucket->key->size )
          continue;
  
-      if (! memcmp( key->data, bucket->key->data, key->size ))
+      if (! hash_keycmp( hash, key, bucket->key))
          {
             val =  datum_dup( bucket->val );
             READ_UNLOCK(hash, i);
@@ -349,7 +384,7 @@
        bucket != NULL; last = bucket, bucket = bucket->next)
     {
       if (bucket->key->size == key->size 
-          && !strncmp (key->data, bucket->key->data, key->size))
+          && !hash_keycmp(hash, key, bucket->key))
         {
           if (last != NULL)
             {
Index: lib/hash.h
===================================================================
--- lib/hash.h	(revision 2002)
+++ lib/hash.h	(working copy)
@@ -13,6 +13,8 @@
 #define WRITE_UNLOCK(__hash, __nodeval) \
 pthread_rdwr_wunlock_np( &(__hash->node[__nodeval]->rwlock))
 
+#define HASH_FLAG_IGNORE_CASE 1
+
 typedef struct 
 {
    void        *data;
@@ -39,12 +41,16 @@
 {
   size_t size;
   node_t **node;
+  int flags;
 }
 hash_t;
 
 hash_t  *hash_create (size_t size);
 void     hash_destroy(hash_t *hash);
 
+int      hash_get_flags(hash_t *hash);
+void     hash_set_flags(hash_t *hash, int flags);
+
 datum_t *hash_insert (datum_t *key, datum_t *val, hash_t *hash);
 datum_t *hash_delete (datum_t *key, hash_t *hash);
 
Index: web/conf.php.in
===================================================================
--- web/conf.php.in	(revision 2002)
+++ web/conf.php.in	(working copy)
@@ -188,4 +188,13 @@
 );
 $default_graph_size = 'default';
 $graph_sizes_keys = array_keys( $graph_sizes );
+
+# In earlier versions of gmetad, hostnames were handled in a case
+# sensitive manner
+# If your hostname directories have been renamed to lower case,
+# set this option to 0 to disable backward compatibility.
+# From version 3.2, backwards compatibility will be disabled by default.
+# default: 1   (for gmetad < 3.2)
+# default: 0   (for gmetad >= 3.2)
+$case_sensitive_hostnames = true;
 ?>
Index: web/get_context.php
===================================================================
--- web/get_context.php	(revision 2002)
+++ web/get_context.php	(working copy)
@@ -11,8 +11,13 @@
     escapeshellcmd( clean_string( rawurldecode($_GET["c"]) ) ) : NULL;
 $gridname = isset($_GET["G"]) ?
     escapeshellcmd( clean_string( rawurldecode($_GET["G"]) ) ) : NULL;
-$hostname = isset($_GET["h"]) ?
-    escapeshellcmd( clean_string( rawurldecode($_GET["h"]) ) ) : NULL;
+if($case_sensitive_hostnames == 1) {
+    $hostname = isset($_GET["h"]) ?
+        escapeshellcmd( clean_string( rawurldecode($_GET["h"]) ) ) : NULL;
+} else {
+    $hostname = isset($_GET["h"]) ?
+        strtolower( escapeshellcmd( clean_string( rawurldecode($_GET["h"]) ) ) ) : NULL;
+}
 $range = isset( $_GET["r"] ) && in_array($_GET["r"], array_keys( $time_ranges ) ) ?
     escapeshellcmd( rawurldecode($_GET["r"])) : NULL;
 $metricname = isset($_GET["m"]) ?
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Ganglia-developers mailing list
Ganglia-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ganglia-developers

Reply via email to