// This will find the library and UUID tags of the sub effect pointed by the
// node, gets the effect descriptor and lib_entry_t and adds the subeffect -
// sub_entry_t to the gSubEffectList
int addSubEffect(cnode *root)
{
    ALOGV("addSubEffect");
    cnode *node;
    effect_uuid_t uuid;
    effect_descriptor_t *d;
    lib_entry_t *l;
    list_elem_t *e;
    node = config_find(root, LIBRARY_TAG);
    if (node == NULL) {
        return -EINVAL;
    }
    l = getLibrary(node->value);
    if (l == NULL) {
        ALOGW("addSubEffect() could not get library %s", node->value);
        return -EINVAL;
    }
    node = config_find(root, UUID_TAG);
    if (node == NULL) {
        return -EINVAL;
    }
    if (stringToUuid(node->value, &uuid) != 0) {
        ALOGW("addSubEffect() invalid uuid %s", node->value);
        return -EINVAL;
    }
    d = malloc(sizeof(effect_descriptor_t));
    if (l->desc->get_descriptor(&uuid, d) != 0) {
        char s[40];
        uuidToString(&uuid, s, 40);
        ALOGW("Error querying effect %s on lib %s", s, l->name);
        free(d);
        return -EINVAL;
    }
#if (LOG_NDEBUG==0)
    char s[256];
    dumpEffectDescriptor(d, s, 256);
    ALOGV("addSubEffect() read descriptor %p:%s",d, s);
#endif
    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
        free(d);
        return -EINVAL;
    }
    sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t));
    sub_effect->object = d;
    // lib_entry_t is stored since the sub effects are not linked to the library
    sub_effect->lib = l;
    e = malloc(sizeof(list_elem_t));
    e->object = sub_effect;
    e->next = gSubEffectList->sub_elem;
    gSubEffectList->sub_elem = e;
    ALOGV("addSubEffect end");
    return 0;
}
Пример #2
0
ConfigEntry* config_push(const char* variable,const char* value)
{
	ConfigEntry* e;

	e = config_find(variable);

	if(!e)
	{
		if(confListPtr > CONF_ENTRIES_COUNT-1)
			return NULL;

		e = &confList[confListPtr++];

		e->variableLength = strlen(variable);

		if(!e->variableLength)
		{
			--confListPtr;
			return NULL;
		}

		e->valueLength = strlen(value);

		strcpy(e->variable,variable);
		strcpy(e->value,value);
	}
	else
	{
		//just update
		e->valueLength = strlen(value);
		strcpy(e->value,value);
	}

	return e;
}
Пример #3
0
/*
 * config_isolation --
 *	Isolation configuration.
 */
static void
config_isolation(void)
{
    CONFIG *cp;
    const char *cstr;

    /*
     * Isolation: choose something if isolation wasn't specified.
     */
    cp = config_find("isolation", strlen("isolation"));
    if (!(cp->flags & C_PERM)) {
        /* Avoid "maybe uninitialized" warnings. */
        switch (MMRAND(1, 4)) {
        case 1:
            cstr = "isolation=random";
            break;
        case 2:
            cstr = "isolation=read-uncommitted";
            break;
        case 3:
            cstr = "isolation=read-committed";
            break;
        case 4:
        default:
            cstr = "isolation=snapshot";
            break;
        }
        config_single(cstr, 0);
    }
}
Пример #4
0
/*
 * config_find_is_perm
 *	Return if a specific configuration entry was permanently set.
 */
static int
config_find_is_perm(const char *s, size_t len)
{
	CONFIG *cp;

	cp = config_find(s, len);
	return (cp->flags & C_PERM ? 1 : 0);
}
Пример #5
0
/*
 * config_compression --
 *	Compression configuration.
 */
static void
config_compression(void)
{
	CONFIG *cp;
	const char *cstr;

	/*
	 * Compression: choose something if compression wasn't specified,
	 * otherwise confirm the appropriate shared library is available.
	 * We don't include LZO in the test compression choices, we don't
	 * yet have an LZO module of our own.
	 */
	cp = config_find("compression", strlen("compression"));
	if (!(cp->flags & C_PERM)) {
		cstr = "compression=none";
		switch (MMRAND(1, 10)) {
		case 1: case 2: case 3:			/* 30% */
			break;
		case 4: case 5:				/* 20% */
			if (access(BZIP_PATH, R_OK) == 0)
				cstr = "compression=bzip";
			break;
		case 6:					/* 10% */
			if (access(BZIP_PATH, R_OK) == 0)
				cstr = "compression=bzip-raw";
			break;
		case 7: case 8:				/* 20% */
			if (access(SNAPPY_PATH, R_OK) == 0)
				cstr = "compression=snappy";
			break;
		case 9: case 10:			/* 20% */
			if (access(ZLIB_PATH, R_OK) == 0)
				cstr = "compression=zlib";
			break;
		}
		config_single(cstr, 0);
	}

	switch (g.c_compression_flag) {
	case COMPRESS_BZIP:
	case COMPRESS_BZIP_RAW:
		if (access(BZIP_PATH, R_OK) != 0)
			die(0, "bzip library not found or not readable");
		break;
	case COMPRESS_LZO:
		if (access(LZO_PATH, R_OK) != 0)
			die(0, "LZO library not found or not readable");
		break;
	case COMPRESS_SNAPPY:
		if (access(SNAPPY_PATH, R_OK) != 0)
			die(0, "snappy library not found or not readable");
		break;
	case COMPRESS_ZLIB:
		if (access(ZLIB_PATH, R_OK) != 0)
			die(0, "zlib library not found or not readable");
		break;
	}
}
Пример #6
0
char* config_getS(const char* variable)
{
	ConfigEntry* e;

	e = config_find(variable);

	if(!e)
		return NULL;

	return e->value;
}
Пример #7
0
ConfigEntry* config_replaceS(const char* variable,const char* newValue)
{
	ConfigEntry* e;

	e = config_find(variable);

	if(!e)
		return NULL;

	e->valueLength = strlen(newValue);
	strcpy(e->value,newValue);

	return e;
}
Пример #8
0
/*
 * config_single --
 *	Set a single configuration structure value.
 */
void
config_single(const char *s, int perm)
{
	CONFIG *cp;
	const char *ep;

	if ((ep = strchr(s, '=')) == NULL) {
		fprintf(stderr,
		    "%s: %s: illegal configuration value\n", g.progname, s);
		exit(EXIT_FAILURE);
	}

	cp = config_find(s, (size_t)(ep - s));
	cp->flags |= perm ? C_PERM : C_TEMP;
	++ep;

	if (cp->flags & C_STRING) {
		if (strncmp(s, "data_source", strlen("data_source")) == 0 &&
		    strncmp("file", ep, strlen("file")) != 0 &&
		    strncmp("table", ep, strlen("table")) != 0 &&
		    strncmp("lsm", ep, strlen("lsm")) != 0) {
			    fprintf(stderr,
				"Invalid data source option: %s\n", ep);
			    exit(EXIT_FAILURE);
		}
		if (strncmp(s, "file_type", strlen("file_type")) == 0)
			*cp->vstr = strdup(
			    config_file_type(config_translate(ep)));
		else
			*cp->vstr = strdup(ep);
		if (*cp->vstr == NULL)
			syserr("Config string parsing");
		return;
	}

	*cp->v = config_translate(ep);
	if (cp->flags & C_BOOL) {
		if (*cp->v != 0 && *cp->v != 1) {
			fprintf(stderr, "%s: %s: value of boolean not 0 or 1\n",
			    g.progname, s);
			exit(EXIT_FAILURE);
		}
	} else if (*cp->v < cp->min || *cp->v > cp->max) {
		fprintf(stderr, "%s: %s: value of %" PRIu32
		    " outside min/max values of %" PRIu32 "-%" PRIu32 "\n",
		    g.progname, s, *cp->v, cp->min, cp->max);
		exit(EXIT_FAILURE);
	}
}
int loadLibraries(cnode *root)
{
    cnode *node;

    node = config_find(root, LIBRARIES_TAG);
    if (node == NULL) {
        return -ENOENT;
    }
    node = node->first_child;
    while (node) {
        loadLibrary(node, node->name);
        node = node->next;
    }
    return 0;
}
int loadEffects(cnode *root)
{
    cnode *node;

    node = config_find(root, EFFECTS_TAG);
    if (node == NULL) {
        return -ENOENT;
    }
    node = node->first_child;
    while (node) {
        loadEffect(node);
        node = node->next;
    }
    return 0;
}
Пример #11
0
static void load_output(cnode *root, void *platform,
                        struct listnode *streams_output_cfg_list)
{
    cnode *node = config_find(root, OUTPUTS_TAG);
    if (node == NULL) {
        ALOGE("%s: could not load output, node is NULL", __func__);
        return;
    }

    node = node->first_child;
    while (node) {
        ALOGV("%s: loading output %s", __func__, node->name);
        update_streams_output_cfg_list(node, platform, streams_output_cfg_list);
        node = node->next;
    }
}
Пример #12
0
int config_getI(const char* variable)
{
	const char* str;
    const char* base;
    int result = 0;
    unsigned char neg = 0;
	ConfigEntry* e;

	e = config_find(variable);

	if(!e)
		return 0;

	str = base = e->value;

    while(*str)
    {
        if(!isSpace(*str))
            break;

        ++str;
    }

    if(str[0] == '0')
        return 0;
    else if(str[0] == '-')
    {
        ++str;
        neg = 1;
    }

	while(*str)
	{
	    if(str - base > 9)
            break;
        else if(!isNumerical(*str))
            break;

		result = (result * 10) + (*str - '0');
		str++;
	}

    if(neg)
        result *= -1;

	return result;
}
Пример #13
0
static int
snapshot_sync(struct volume *v)
{
	struct file_header sentinel, conf;
	int next, block = 0;
	uint32_t seq;

	next = snapshot_next_free(v, &seq);
	block = config_find(v, &conf, &sentinel);
	if (is_config(&conf) && conf.seq != seq) {
		conf.magic = 0;
		volume_erase(v, next * v->block_size, 2 * v->block_size);
	}

	if (is_config(&sentinel) && (sentinel.seq != seq)) {
		sentinel.magic = 0;
		volume_erase(v, block * v->block_size, v->block_size);
	}

	if (!is_config(&conf) && !is_config(&sentinel)) {
	//	ULOG_ERR("no config found\n");
	} else if (((is_config(&conf) && is_config(&sentinel)) &&
				(memcmp(conf.md5, sentinel.md5, sizeof(conf.md5)) || (conf.seq != sentinel.seq))) ||
			(is_config(&conf) && !is_config(&sentinel))) {
		uint32_t seq;
		int next = snapshot_next_free(v, &seq);
		int ret = snapshot_read_file(v, next, "/tmp/config.tar.gz", CONF);
		if (ret > 0) {
			if (sentinel_write(v, conf.seq))
				ULOG_ERR("failed to write sentinel data");
		}
	} else if (!is_config(&conf) && is_config(&sentinel) && next) {
		int ret = snapshot_read_file(v, block, "/tmp/config.tar.gz", CONF);
		if (ret > 0)
			if (volatile_write(v, sentinel.seq))
				ULOG_ERR("failed to write sentinel data");
	} else
		ULOG_INFO("config in sync\n");

	unlink("/tmp/config.tar.gz");

	return 0;
}
Пример #14
0
/*
 * config_checksum --
 *	Checksum configuration.
 */
static void
config_checksum(void)
{
	CONFIG *cp;

	/* Choose a checksum mode if nothing was specified. */
	cp = config_find("checksum", strlen("checksum"));
	if (!(cp->flags & C_PERM))
		switch (MMRAND(1, 10)) {
		case 1:					/* 10% */
			config_single("checksum=on", 0);
			break;
		case 2:					/* 10% */
			config_single("checksum=off", 0);
			break;
		default:				/* 80% */
			config_single("checksum=uncompressed", 0);
			break;
		}
}
Пример #15
0
unsigned long pi_configlock_event_load_old (plugin_user_t * user, void *dummy, unsigned long event,
        buffer_t * token)
{
    FILE *fp;
    unsigned long l;
    char buffer[1024], *c;
    configlock_t *lock;
    config_element_t *elem;

    while (locklist) {
        lock = locklist;
        locklist = locklist->next;
        free (lock);
    }

    config_load_old (filename);

    fp = fopen (filename, "r");
    if (!fp)
        return PLUGIN_RETVAL_CONTINUE;

    while (fgets (buffer, 1024, fp)) {
        for (c = buffer; *c && *c != ' '; c++);
        if (!*c)
            continue;
        *c++ = '\0';
        elem = config_find (buffer);
        if (!elem)
            continue;

        lock = malloc (sizeof (configlock_t));
        memset (lock, 0, sizeof (configlock_t));

        lock->elem = elem;
        strncpy (lock->name, elem->name, CONFIG_NAMELENGTH);
        switch (elem->type) {
        case CFG_ELEM_PTR:
            sscanf (c, "%p", &lock->data.v_ptr);
            break;
        case CFG_ELEM_LONG:
            sscanf (c, "%ld", &lock->data.v_long);
            break;
        case CFG_ELEM_ULONG:
        case CFG_ELEM_CAP:
        case CFG_ELEM_MEMSIZE:
            sscanf (c, "%lu", &lock->data.v_ulong);
            break;
        case CFG_ELEM_BYTESIZE:
        case CFG_ELEM_ULONGLONG:
#ifndef USE_WINDOWS
            sscanf (c, "%Lu", &lock->data.v_ulonglong);
#else
            sscanf (c, "%I64u", &lock->data.v_ulonglong);
#endif
            break;
        case CFG_ELEM_INT:
            sscanf (c, "%d", &lock->data.v_int);
            break;
        case CFG_ELEM_UINT:
            sscanf (c, "%u", &lock->data.v_uint);
            break;
        case CFG_ELEM_DOUBLE:
            sscanf (c, "%lf", &lock->data.v_double);
            break;
        case CFG_ELEM_STRING:
            if (lock->data.v_string)
                free (lock->data.v_string);
            l = strlen (c);
            if (c[l - 1] == '\n')
                c[l-- - 1] = '\0';
            if ((*c == '"') && (c[l - 1] == '"')) {
                c[l - 1] = '\0';
                c++;
            };
            lock->data.v_string = string_unescape (c);
            break;
        case CFG_ELEM_IP:
        {
#ifdef HAVE_INET_NTOA
            struct in_addr ia;

            if (inet_aton (c, &ia))
                lock->data.v_ip = ia.s_addr;
#else
#warning "inet_ntoa not support. Support for CFG_ELEM_IP disabled."
#endif
            break;
        }
        }
        lock->next = locklist;
        locklist = lock;
    }
    fclose (fp);

    return PLUGIN_RETVAL_CONTINUE;
}
Пример #16
0
unsigned long pi_configlock_event_load (plugin_user_t * user, void *dummy, unsigned long event,
                                        void *arg)
{
    FILE *fp;
    configlock_t *lock;
    config_element_t *elem;
    xml_node_t *base, *node;

    if (!arg)
        goto leave;

    while (locklist) {
        lock = locklist;
        locklist = locklist->next;
        free (lock);
    }

    fp = fopen ("configlock.xml", "r");
    if (!fp)
        goto leave;

    base = xml_read (fp);
    if (!base) {
        fclose (fp);
        goto leave;
    }

    if (strcmp (base->name, HUBSOFT_NAME)) {
        xml_free (base);
        goto leave;
    }

    config_load (base);

    node = xml_node_find (base, "Config");
    for (node = node->children; node; node = xml_next (node)) {
        elem = config_find (node->name);
        if (!elem)
            continue;

        lock = malloc (sizeof (configlock_t));
        memset (lock, 0, sizeof (configlock_t));

        lock->elem = elem;
        strncpy (lock->name, elem->name, CONFIG_NAMELENGTH);

        xml_node_get (node, elem->type, &lock->data.v_ptr);

        lock->next = locklist;
        locklist = lock;
    }

    xml_free (base);

    fclose (fp);

    return PLUGIN_RETVAL_CONTINUE;

leave:
    return pi_configlock_event_load_old (user, dummy, event, NULL);
}
Пример #17
0
/*
 * config_single --
 *	Set a single configuration structure value.
 */
void
config_single(const char *s, int perm)
{
	CONFIG *cp;
	int v;
	const char *ep;

	if ((ep = strchr(s, '=')) == NULL) {
		fprintf(stderr,
		    "%s: %s: illegal configuration value\n", g.progname, s);
		exit(EXIT_FAILURE);
	}

	cp = config_find(s, (size_t)(ep - s));
	cp->flags |= perm ? C_PERM : C_TEMP;
	++ep;

	if (cp->flags & C_STRING) {
		if (strncmp(s, "data_source", strlen("data_source")) == 0 &&
		    strncmp("file", ep, strlen("file")) != 0 &&
		    strncmp("helium", ep, strlen("helium")) != 0 &&
		    strncmp("kvsbdb", ep, strlen("kvsbdb")) != 0 &&
		    strncmp("lsm", ep, strlen("lsm")) != 0 &&
		    strncmp("table", ep, strlen("table")) != 0) {
			    fprintf(stderr,
				"Invalid data source option: %s\n", ep);
			    exit(EXIT_FAILURE);
		}

		if (strncmp(s, "checksum", strlen("checksum")) == 0) {
			config_map_checksum(ep, &g.c_checksum_flag);
			*cp->vstr = strdup(ep);
		} else if (strncmp(
		    s, "compression", strlen("compression")) == 0) {
			config_map_compression(ep, &g.c_compression_flag);
			*cp->vstr = strdup(ep);
		} else if (strncmp(s, "file_type", strlen("file_type")) == 0) {
			config_map_file_type(ep, &g.type);
			*cp->vstr = strdup(config_file_type(g.type));
		} else
			*cp->vstr = strdup(ep);
		if (*cp->vstr == NULL)
			syserr("malloc");

		return;
	}

	v = atoi(ep);
	if (cp->flags & C_BOOL) {
		if (v != 0 && v != 1) {
			fprintf(stderr, "%s: %s: value of boolean not 0 or 1\n",
			    g.progname, s);
			exit(EXIT_FAILURE);
		}
	} else if (v < 0 || (u_int)v < cp->min || (u_int)v > cp->maxset) {
		fprintf(stderr, "%s: %s: value of %" PRIu32
		    " outside min/max values of %" PRIu32 "-%" PRIu32 "\n",
		    g.progname, s, *cp->v, cp->min, cp->maxset);
		exit(EXIT_FAILURE);
	}
	*cp->v = (u_int)v;
}
Пример #18
0
/*
 * config_setup --
 *	Initialize configuration for a run.
 */
void
config_setup(void)
{
	CONFIG *cp;

	/* Clear any temporary values. */
	config_clear();

	/*
	 * Choose a data source type and a file type: they're interrelated (LSM
	 * trees are only compatible with row-store) and other items depend on
	 * them.
	 */
	if (!config_find_is_perm("data_source", strlen("data_source")))
		switch (MMRAND(0, 2)) {
		case 0:
			config_single("data_source=file", 0);
			break;
		case 1:
#if 0
			config_single("data_source=lsm", 0);
			break;
#endif
		case 2:
			config_single("data_source=table", 0);
			break;
		}

	if (!config_find_is_perm("file_type", strlen("file_type"))) {
		if (strcmp(g.c_data_source, "lsm") == 0)
			config_single("file_type=row", 0);
		else
			switch (MMRAND(0, 2)) {
			case 0:
				config_single("file_type=fix", 0);
				break;
			case 1:
				config_single("file_type=var", 0);
				break;
			case 2:
				config_single("file_type=row", 0);
				break;
			}
	}
	g.type = config_translate(g.c_file_type);

	/*
	 * If data_source and file_type were both "permanent", we may still
	 * have a mismatch.
	 */
	if (g.type != ROW && strcmp(g.c_data_source, "lsm") == 0) {
		fprintf(stderr,
	    "%s: lsm data_source is only compatible with row file_type\n",
		    g.progname);
		exit(EXIT_FAILURE);
	}

	/* Build the object name. */
	if ((g.uri = malloc(
	    strlen(g.c_data_source) + strlen(WT_NAME) + 2)) == NULL)
		syserr("malloc");
	strcpy(g.uri, g.c_data_source);
	strcat(g.uri, ":");
	strcat(g.uri, WT_NAME);

	/* Default single-threaded half of the time. */
	cp = config_find("threads", strlen("threads"));
	if (!(cp->flags & C_PERM))
		*cp->v = MMRAND(0, 1) ? 1: CONF_RAND(cp);

	/* Fill in random values for the rest of the run. */
	for (cp = c; cp->name != NULL; ++cp) {
		if (cp->flags & (C_IGNORE | C_PERM | C_TEMP))
			continue;

		/*
		 * Boolean flags are 0 or 1, but only set N in 100 where the
		 * variable's min value is N.  Set the flag if we rolled >=
		 * the min, 0 otherwise.
		 */
		if (cp->flags & C_BOOL)
			*cp->v = MMRAND(1, 100) <= cp->min ? 1 : 0;
		else
			*cp->v = CONF_RAND(cp);
	}

	config_compression();

	/* Clear operations values if the whole run is read-only. */
	if (g.c_ops == 0)
		for (cp = c; cp->name != NULL; ++cp)
			if (cp->flags & C_OPS)
				*cp->v = 0;

	/* Multi-threaded runs cannot be replayed. */
	if (g.replay && !SINGLETHREADED)
		die(0, "-r is incompatible with threaded runs");

	/*
	 * Periodically, set the delete percentage to 0 so salvage gets run,
	 * as long as the delete percentage isn't nailed down.
	 */
	if (!g.replay && g.run_cnt % 10 == 0) {
		cp = config_find("delete_pct", strlen("delete_pct"));
		if (cp->name != NULL &&
		    !(cp->flags & (C_IGNORE | C_PERM | C_TEMP)))
			g.c_delete_pct = 0;
	}

	/* Reset the key count. */
	g.key_cnt = 0;
}
Пример #19
0
/*
 * config_setup --
 *	Initialize configuration for a run.
 */
void
config_setup(void)
{
	CONFIG *cp;

	/* Clear any temporary values. */
	config_clear();

	/*
	 * Choose a data source type and a file type: they're interrelated (LSM
	 * trees are only compatible with row-store) and other items depend on
	 * them.
	 */
	if (!config_find_is_perm("data_source", strlen("data_source")))
		switch (MMRAND(1, 3)) {
		case 1:
			config_single("data_source=file", 0);
			break;
		case 2:
			config_single("data_source=lsm", 0);
			break;
		case 3:
			config_single("data_source=table", 0);
			break;
		}

	if (!config_find_is_perm("file_type", strlen("file_type")))
		switch (DATASOURCE("lsm") ? 3 : MMRAND(1, 3)) {
		case 1:
			config_single("file_type=fix", 0);
			break;
		case 2:
			config_single("file_type=var", 0);
			break;
		case 3:
			config_single("file_type=row", 0);
			break;
		}
	config_map_file_type(g.c_file_type, &g.type);

	/*
	 * If data_source and file_type were both "permanent", we may still
	 * have a mismatch.
	 */
	if (DATASOURCE("lsm") && g.type != ROW) {
		fprintf(stderr,
	    "%s: lsm data_source is only compatible with row file_type\n",
		    g.progname);
		exit(EXIT_FAILURE);
	}

	/*
	 * Build the top-level object name: we're overloading data_source in
	 * our configuration, LSM or KVS devices are "tables", but files are
	 * tested as well.
	 */
	if ((g.uri = malloc(256)) == NULL)
		syserr("malloc");
	strcpy(g.uri, DATASOURCE("file") ? "file:" : "table:");
	if (DATASOURCE("helium"))
		strcat(g.uri, "dev1/");
	strcat(g.uri, WT_NAME);

	/* Default single-threaded 10% of the time. */
	cp = config_find("threads", strlen("threads"));
	if (!(cp->flags & C_PERM))
		*cp->v = MMRAND(1, 100) < 10 ? 1: CONF_RAND(cp);

	/* Fill in random values for the rest of the run. */
	for (cp = c; cp->name != NULL; ++cp) {
		if (cp->flags & (C_IGNORE | C_PERM | C_TEMP))
			continue;

		/*
		 * Boolean flags are 0 or 1, but only set N in 100 where the
		 * variable's min value is N.  Set the flag if we rolled >=
		 * the min, 0 otherwise.
		 */
		if (cp->flags & C_BOOL)
			*cp->v = MMRAND(1, 100) <= cp->min ? 1 : 0;
		else
			*cp->v = CONF_RAND(cp);
	}

	/* Required shared libraries. */
	if (DATASOURCE("helium") && access(HELIUM_PATH, R_OK) != 0)
		die(errno, "Levyx/helium shared library: %s", HELIUM_PATH);
	if (DATASOURCE("kvsbdb") && access(KVS_BDB_PATH, R_OK) != 0)
		die(errno, "kvsbdb shared library: %s", KVS_BDB_PATH);

	/* Some data-sources don't support user-specified collations. */
	if (DATASOURCE("helium") || DATASOURCE("kvsbdb"))
		g.c_reverse = 0;

	config_checksum();
	config_compression();

	/* Clear operations values if the whole run is read-only. */
	if (g.c_ops == 0)
		for (cp = c; cp->name != NULL; ++cp)
			if (cp->flags & C_OPS)
				*cp->v = 0;

	/*
	 * Periodically, set the delete percentage to 0 so salvage gets run,
	 * as long as the delete percentage isn't nailed down.
	 */
	if (!g.replay && g.run_cnt % 10 == 0) {
		cp = config_find("delete_pct", strlen("delete_pct"));
		if (cp->name != NULL &&
		    !(cp->flags & (C_IGNORE | C_PERM | C_TEMP)))
			g.c_delete_pct = 0;
	}

	/*
	 * If this is an LSM run, set the cache size and crank up the insert
	 * percentage.
	 */
	if (DATASOURCE("lsm")) {
		cp = config_find("cache", strlen("cache"));
		if (!(cp->flags & C_PERM))
			g.c_cache = 30 * g.c_chunk_size;

		cp = config_find("insert_pct", strlen("insert_pct"));
		if (cp->name != NULL &&
		    !(cp->flags & (C_IGNORE | C_PERM | C_TEMP)))
			g.c_insert_pct = MMRAND(50, 85);
	}

	/*
	 * Key/value minimum/maximum are related, correct unless specified by
	 * the configuration.
	 */
	cp = config_find("key_min", strlen("key_min"));
	if (!(cp->flags & C_PERM) && g.c_key_min > g.c_key_max)
		g.c_key_min = g.c_key_max;
	cp = config_find("key_max", strlen("key_max"));
	if (!(cp->flags & C_PERM) && g.c_key_max < g.c_key_min)
		g.c_key_max = g.c_key_min;
	if (g.c_key_min > g.c_key_max)
		die(EINVAL, "key_min may not be larger than key_max");

	cp = config_find("value_min", strlen("value_min"));
	if (!(cp->flags & C_PERM) && g.c_value_min > g.c_value_max)
		g.c_value_min = g.c_value_max;
	cp = config_find("value_max", strlen("value_max"));
	if (!(cp->flags & C_PERM) && g.c_value_max < g.c_value_min)
		g.c_value_max = g.c_value_min;
	if (g.c_value_min > g.c_value_max)
		die(EINVAL, "value_min may not be larger than value_max");

	/* Reset the key count. */
	g.key_cnt = 0;
}
int loadEffect(cnode *root)
{
    cnode *node;
    effect_uuid_t uuid;
    lib_entry_t *l;
    effect_descriptor_t *d;
    list_elem_t *e;

    node = config_find(root, LIBRARY_TAG);
    if (node == NULL) {
        return -EINVAL;
    }

    l = getLibrary(node->value);
    if (l == NULL) {
        ALOGW("loadEffect() could not get library %s", node->value);
        return -EINVAL;
    }

    node = config_find(root, UUID_TAG);
    if (node == NULL) {
        return -EINVAL;
    }
    if (stringToUuid(node->value, &uuid) != 0) {
        ALOGW("loadEffect() invalid uuid %s", node->value);
        return -EINVAL;
    }
    d = malloc(sizeof(effect_descriptor_t));
    if (!d) {
        ALOGE("failed to allocate effect descriptor");
        return -EINVAL;
    }

    if (l->desc->get_descriptor(&uuid, d) != 0) {
        char s[40];
        uuidToString(&uuid, s, 40);
        ALOGW("Error querying effect %s on lib %s", s, l->name);
        free(d);
        return -EINVAL;
    }
#if (LOG_NDEBUG==0)
    char s[256];
    dumpEffectDescriptor(d, s, 256);
    ALOGV("loadEffect() read descriptor %p:%s",d, s);
#endif
    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
        free(d);
        return -EINVAL;
    }
    e = malloc(sizeof(list_elem_t));
    if (!e) {
        return -ENOMEM;
    }

    e->object = d;
    e->next = l->effects;
    l->effects = e;

    // After the UUID node in the config_tree, if node->next is valid,
    // that would be sub effect node.
    // Find the sub effects and add them to the gSubEffectList
    node = node->next;
    int count = 2;
    bool hwSubefx = false, swSubefx = false;
    list_sub_elem_t *sube = NULL;
    if (node != NULL) {
        ALOGV("Adding the effect to gEffectSubList as there are sub effects");
        sube = malloc(sizeof(list_sub_elem_t));
        if (!sube) {
            ALOGE("failed to allocate sub element list");
            return -ENOMEM;
        }

        sube->object = d;
        sube->sub_elem = NULL;
        sube->next = gSubEffectList;
        gSubEffectList = sube;
    }
    while (node != NULL && count) {
       if (addSubEffect(node)) {
           ALOGW("loadEffect() could not add subEffect %s", node->value);
           // Change the gSubEffectList to point to older list;
           gSubEffectList = sube->next;
           free(sube->sub_elem);// Free an already added sub effect
           sube->sub_elem = NULL;
           free(sube);
           return -ENOENT;
       }
       sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object;
       effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object);
       // Since we return a dummy descriptor for the proxy during
       // get_descriptor call,we replace it with the correspoding
       // sw effect descriptor, but with Proxy UUID
       // check for Sw desc
        if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) ==
                                           EFFECT_FLAG_HW_ACC_TUNNEL)) {
             swSubefx = true;
             *d = *subEffectDesc;
             d->uuid = uuid;
             ALOGV("loadEffect() Changed the Proxy desc");
       } else
           hwSubefx = true;
       count--;
       node = node->next;
    }
    // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc
    if (hwSubefx && swSubefx) {
        d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
    }
    return 0;
}
int loadLibrary(cnode *root, const char *name)
{
    cnode *node;
    void *hdl;
    audio_effect_library_t *desc;
    list_elem_t *e;
    lib_entry_t *l;

    node = config_find(root, PATH_TAG);
    if (node == NULL) {
        return -EINVAL;
    }

    hdl = dlopen(node->value, RTLD_NOW);
    if (hdl == NULL) {
        ALOGW("loadLibrary() failed to open %s", node->value);
        goto error;
    }

    desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
    if (desc == NULL) {
        ALOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
        goto error;
    }

    if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
        ALOGW("getLibrary() bad tag %08x in lib info struct", desc->tag);
        goto error;
    }

    if (EFFECT_API_VERSION_MAJOR(desc->version) !=
            EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
        ALOGW("loadLibrary() bad lib version %08x", desc->version);
        goto error;
    }

    // add entry for library in gLibraryList
    l = malloc(sizeof(lib_entry_t));
    l->name = strndup(name, PATH_MAX);
    l->path = strndup(node->value, PATH_MAX);
    l->handle = hdl;
    l->desc = desc;
    l->effects = NULL;
    pthread_mutex_init(&l->lock, NULL);

    e = malloc(sizeof(list_elem_t));
    e->object = l;
    pthread_mutex_lock(&gLibLock);
    e->next = gLibraryList;
    gLibraryList = e;
    pthread_mutex_unlock(&gLibLock);
    ALOGV("getLibrary() linked library %p for path %s", l, node->value);

    return 0;

error:
    if (hdl != NULL) {
        dlclose(hdl);
    }
    return -EINVAL;
}