static int ex_metric_init (apr_pool_t *p)
{
    int i;
    Ganglia_25metric *gmi;

    /* Allocate a pool that will be used by this module */
    apr_pool_create(&pool, p);

    /* Initialize each metric */
    scan_mounts(pool);

    /* Add a terminator to the array and replace the empty static metric definition 
        array with the dynamic array that we just created 
    */
    gmi = apr_array_push(metric_info);
    memset (gmi, 0, sizeof(*gmi));

    fs_module.metrics_info = (Ganglia_25metric *)metric_info->elts;

    for (i = 0; fs_module.metrics_info[i].name != NULL; i++) {
        /* Initialize the metadata storage for each of the metrics and then
         *  store one or more key/value pairs.  The define MGROUPS defines
         *  the key for the grouping attribute. */
        MMETRIC_INIT_METADATA(&(fs_module.metrics_info[i]),p);
        MMETRIC_ADD_METADATA(&(fs_module.metrics_info[i]),MGROUP,"disk");
    }

    return 0;
}
int main(int argc, char *argv[])
{
	opt_type opts;
	int sig_number;
#ifdef WITH_IPV6
	int ipv4_only, ipv6_only;
#endif
	unsigned char default_namespace = NAMESPACE_FILE;
	struct device_list *match_devices = NULL;
	struct unixsocket_list *unixsockets = NULL;
	struct mount_list *mounts = NULL;

	dev_t netdev;
	struct ip_connections *tcp_connection_list = NULL;
	struct ip_connections *udp_connection_list = NULL;
#ifdef WITH_IPV6
	struct ip6_connections *tcp6_connection_list = NULL;
	struct ip6_connections *udp6_connection_list = NULL;
#endif
	struct inode_list *match_inodes = NULL;
	struct names *names_head, *this_name, *names_tail;
	int argc_cnt;
    char *current_argv, *option;
    char option_buf[3];
    struct option *optr;
	char *nsptr;
  int skip_argv;

	struct option options[] = {
		{"all", 0, NULL, 'a'},
		{"kill", 0, NULL, 'k'},
		{"interactive", 0, NULL, 'i'},
		{"list-signals", 0, NULL, 'l'},
		{"mount", 0, NULL, 'm'},
		{"ismountpoint", 0, NULL, 'M'},
		{"namespace", 1, NULL, 'n'},
		{"silent", 0, NULL, 's'},
		{"user", 0, NULL, 'u'},
		{"verbose", 0, NULL, 'v'},
		{"version", 0, NULL, 'V'},
#ifdef WITH_IPV6
		{"ipv4", 0, NULL, '4'},
		{"ipv6", 0, NULL, '6'},
#endif
		{ 0, 0, 0, 0 }
	};

#ifdef WITH_IPV6
	ipv4_only = ipv6_only = 0;
#endif
	names_head = this_name = names_tail = NULL;
	opts = 0;
	sig_number = SIGKILL;

#ifdef ENABLE_NLS
	/* Set up the i18n */
	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
#endif

	netdev = find_net_dev();
	fill_unix_cache(&unixsockets);

    for (argc_cnt = 1; argc_cnt < argc; argc_cnt++) {
      current_argv = argv[argc_cnt];
      if (current_argv[0] == '-') { /* its an option */
        if (current_argv[1] == '-') { /* its a long option */
          if (current_argv[2] == '\0')  /* -- */
            break;
          /* Parse the long options */
          option = option_buf;
          for (optr = options; optr->name != NULL; optr++) {
            if (strcmp(current_argv+2,optr->name) == 0) {
              sprintf(option_buf, "-%c", (char)optr->val);
              break;
            }
          }
          if (optr->name == NULL) {
			fprintf(stderr, _("%s: Invalid option %s\n"), argv[0],
				current_argv);
			usage(NULL);
          }
        } else {
          option = current_argv;
        }
        skip_argv=0;
        while (*(++option) != '\0' && !skip_argv) { /* skips over the - */
		  switch (*option) {
#ifdef WITH_IPV6
		  case '4':
			ipv4_only = 1;
			break;
		  case '6':
			ipv6_only = 1;
			break;
#endif /* WITH_IPV6 */
		  case 'a':
			opts |= OPT_ALLFILES;
			break;
		  case 'c':
			opts |= OPT_MOUNTS;
			break;
		  case 'f':
			/* ignored */
			break;
		  case 'h':
			usage(NULL);
			break;
		  case 'i':
			opts |= OPT_INTERACTIVE;
			break;
		  case 'k':
			opts |= OPT_KILL;
			break;
		  case 'l':
			list_signals();
			return 0;
		  case 'm':
			opts |= OPT_MOUNTS;
			break;
		  case 'M':
			opts |= OPT_ISMOUNTPOINT;
		    read_proc_mounts(&mounts);
			break;
		  case 'n':
            argc_cnt++;
            if (argc_cnt >= argc) {
              usage(_ ("Namespace option requires an argument."));
              exit(1);;
            }
            skip_argv=1;
            //while(option != '\0') option++;
			if (strcmp(argv[argc_cnt], "tcp") == 0)
				default_namespace = NAMESPACE_TCP;
			else if (strcmp(argv[argc_cnt], "udp") == 0)
				default_namespace = NAMESPACE_UDP;
			else if (strcmp(argv[argc_cnt], "file") == 0)
				default_namespace = NAMESPACE_FILE;
			else
				usage(_("Invalid namespace name"));
			break;
		  case 's':
			opts |= OPT_SILENT;
			break;
		  case 'u':
			opts |= OPT_USER;
			break;
		  case 'v':
			opts |= OPT_VERBOSE;
			break;
		  case 'V':
			print_version();
			return 0;
          default:
            if (isupper(*option) || isdigit(*option)) {
              sig_number = get_signal(current_argv+1, argv[0]);
            skip_argv=1;
              break;
            }
			fprintf(stderr, "%s: Invalid option %c\n", argv[0],
				*option);
			usage(NULL);
			exit(1);
			break;
		  }		/* switch */
	    }			/* while option */
        continue;
      } /* an option */
      /* Not an option, must be a file specification */

		if ((this_name = malloc(sizeof(struct names))) == NULL)
			continue;
		this_name->next = NULL;
		/* try to find namespace spec */
		this_name->name_space = default_namespace;
		if (((nsptr = strchr(current_argv, '/')) != NULL)
		    && (nsptr != current_argv)) {
			if (strcmp(nsptr + 1, "tcp") == 0) {
				this_name->name_space = NAMESPACE_TCP;
				*nsptr = '\0';
			} else if (strcmp(nsptr + 1, "udp") == 0) {
				this_name->name_space = NAMESPACE_UDP;
				*nsptr = '\0';
			} else if (strcmp(nsptr + 1, "file") == 0) {
				this_name->name_space = NAMESPACE_FILE;
				*nsptr = '\0';
			}
		}
		this_name->matched_procs = NULL;
		if (opts & (OPT_MOUNTS|OPT_ISMOUNTPOINT)
		    && this_name->name_space != NAMESPACE_FILE)
			usage(_
			      ("You can only use files with mountpoint options"));
		if (opts & OPT_ISMOUNTPOINT &&
		    !is_mountpoint(&mounts, current_argv)) {
			free(this_name);
			continue;
		}
		switch (this_name->name_space) {
		case NAMESPACE_TCP:
			if (asprintf(&(this_name->filename), "%s/tcp", current_argv) > 0) {
#ifdef WITH_IPV6
			  parse_inet(this_name, ipv4_only, ipv6_only,
				   &tcp_connection_list, &tcp6_connection_list);
#else
			  parse_inet(this_name, &tcp_connection_list);
#endif
			}
			break;
		case NAMESPACE_UDP:
			if (asprintf(&(this_name->filename), "%s/udp", current_argv) > 0) {
#ifdef WITH_IPV6
			  parse_inet(this_name, ipv4_only, ipv6_only,
				   &udp_connection_list, &udp6_connection_list);
#else
			  parse_inet(this_name, &udp_connection_list);
#endif
			}
			break;
		default:	/* FILE */
			this_name->filename = strdup(current_argv);
			if (parse_file(this_name, &match_inodes) == 0) {
              parse_unixsockets(this_name, &match_inodes, unixsockets);
			  if (opts & OPT_MOUNTS)
				parse_mounts(this_name, &match_devices, opts);
            }
			break;
		}

		if (names_head == NULL)
			names_head = this_name;
		if (names_tail != NULL)
			names_tail->next = this_name;
		names_tail = this_name;
    } /* for across the argvs */
	if (names_head == NULL)
		usage(_("No process specification given"));

	if (opts & OPT_SILENT) {
		opts &= ~OPT_VERBOSE;
		opts &= ~OPT_USER;
		if (opts & OPT_ALLFILES)
			usage(_
			      ("all option cannot be used with silent option."));
	}
#ifdef WITH_IPV6
	if (ipv4_only && ipv6_only)
		usage(_
		      ("You cannot search for only IPv4 and only IPv6 sockets at the same time"));
	if (!ipv6_only) {
#endif
		if (tcp_connection_list != NULL)
			find_net_sockets(&match_inodes, tcp_connection_list,
					 "tcp", netdev);
		if (udp_connection_list != NULL)
			find_net_sockets(&match_inodes, udp_connection_list,
					 "udp", netdev);
#ifdef WITH_IPV6
	}
	if (!ipv4_only) {
		if (tcp6_connection_list != NULL)
			find_net6_sockets(&match_inodes, tcp6_connection_list,
					  "tcp", netdev);
		if (udp6_connection_list != NULL)
			find_net6_sockets(&match_inodes, udp6_connection_list,
					  "udp", netdev);
	}
#endif
#ifdef DEBUG
	debug_match_lists(names_head, match_inodes, match_devices);
#endif
	scan_procs(names_head, match_inodes, match_devices, unixsockets,
		   netdev);
	scan_knfsd(names_head, match_inodes, match_devices);
	scan_mounts(names_head, match_inodes, match_devices);
	scan_swaps(names_head, match_inodes, match_devices);
	return print_matches(names_head, opts, sig_number);
}