コード例 #1
0
ファイル: config_t.c プロジェクト: cardamon/lvm2
static void test_cascade(void)
{
	struct dm_config_tree *t1 = dm_config_from_string(conf),
		              *t2 = dm_config_from_string(overlay),
		              *tree = dm_config_insert_cascaded_tree(t2, t1);

	CU_ASSERT(!strcmp(dm_config_tree_find_str(tree, "id", "foo"), "yoda-soda"));
	CU_ASSERT(!strcmp(dm_config_tree_find_str(tree, "idt", "foo"), "foo"));

	CU_ASSERT(!strcmp(dm_config_tree_find_str(tree, "physical_volumes/pv0/bb", "foo"), "foo"));
	CU_ASSERT(!strcmp(dm_config_tree_find_str(tree, "physical_volumes/pv1/id", "foo"), "hgfe-dcba"));
	CU_ASSERT(!strcmp(dm_config_tree_find_str(tree, "physical_volumes/pv3/id", "foo"), "dbcd-efgh"));

	dm_config_destroy(t1);
	dm_config_destroy(t2);
}
コード例 #2
0
ファイル: config_t.c プロジェクト: cardamon/lvm2
static void test_parse(void)
{
	struct dm_config_tree *tree = dm_config_from_string(conf);
	const struct dm_config_value *value;

	CU_ASSERT((long) tree);
	CU_ASSERT(dm_config_has_node(tree->root, "id"));
	CU_ASSERT(dm_config_has_node(tree->root, "physical_volumes"));
	CU_ASSERT(dm_config_has_node(tree->root, "physical_volumes/pv0"));
	CU_ASSERT(dm_config_has_node(tree->root, "physical_volumes/pv0/id"));

	CU_ASSERT(!strcmp(dm_config_find_str(tree->root, "id", "foo"), "yada-yada"));
	CU_ASSERT(!strcmp(dm_config_find_str(tree->root, "idt", "foo"), "foo"));

	CU_ASSERT(!strcmp(dm_config_find_str(tree->root, "physical_volumes/pv0/bb", "foo"), "foo"));
	CU_ASSERT(!strcmp(dm_config_find_str(tree->root, "physical_volumes/pv0/id", "foo"), "abcd-efgh"));

	CU_ASSERT(!dm_config_get_uint32(tree->root, "id", NULL));
	CU_ASSERT(dm_config_get_uint32(tree->root, "extent_size", NULL));

	/* FIXME: Currently everything parses as a list, even if it's not */
	// CU_ASSERT(!dm_config_get_list(tree->root, "id", NULL));
	// CU_ASSERT(!dm_config_get_list(tree->root, "extent_size", NULL));

	CU_ASSERT(dm_config_get_list(tree->root, "flags", &value));
	CU_ASSERT(value->next == NULL); /* an empty list */
	CU_ASSERT(dm_config_get_list(tree->root, "status", &value));
	CU_ASSERT(value->next != NULL); /* a non-empty list */

	dm_config_destroy(tree);
}
コード例 #3
0
ファイル: config.c プロジェクト: Find7s/Lvm_for_Android
int override_config_tree_from_string(struct cmd_context *cmd,
				     const char *config_settings)
{
	struct dm_config_tree *cft_new;
	struct config_source *cs = dm_config_get_custom(cmd->cft);

	/*
	 * Follow this sequence:
	 * CONFIG_STRING -> CONFIG_PROFILE -> CONFIG_FILE/CONFIG_MERGED_FILES
	 */

	if (cs->type == CONFIG_STRING) {
		log_error(INTERNAL_ERROR "override_config_tree_from_string: "
			  "config cascade already contains a string config.");
		return 0;
	}

	if (!(cft_new = dm_config_from_string(config_settings))) {
		log_error("Failed to set overridden configuration entries.");
		return 0;
	}

	if (!(cs = dm_pool_zalloc(cft_new->mem, sizeof(struct config_source)))) {
		log_error("Failed to allocate config source.");
		dm_config_destroy(cft_new);
		return 0;
	}

	cs->type = CONFIG_STRING;
	dm_config_set_custom(cft_new, cs);

	cmd->cft = dm_config_insert_cascaded_tree(cft_new, cmd->cft);

	return 1;
}
コード例 #4
0
ファイル: config.c プロジェクト: andyvand/cyglvm2
/*
 * public interface
 */
struct dm_config_tree *config_file_open(const char *filename, int keep_open)
{
	struct dm_config_tree *cft = dm_config_create();
	struct config_file *cf;
	if (!cft)
		return NULL;

	cf = dm_pool_zalloc(cft->mem, sizeof(struct config_file));
	if (!cf) goto fail;

	cf->timestamp = 0;
	cf->exists = 0;
	cf->keep_open = keep_open;
	dm_config_set_custom(cft, cf);

	if (filename &&
	    !(cf->filename = dm_pool_strdup(cft->mem, filename))) {
		log_error("Failed to duplicate filename.");
		goto fail;
	}

	return cft;
fail:
	dm_config_destroy(cft);
	return NULL;
}
コード例 #5
0
ファイル: config.c プロジェクト: andyvand/cyglvm2
void config_file_destroy(struct dm_config_tree *cft)
{
	struct config_file *cf = dm_config_get_custom(cft);

	if (cf && cf->dev)
		if (!dev_close(cf->dev))
			stack;

	dm_config_destroy(cft);
}
コード例 #6
0
ファイル: libdm-config.c プロジェクト: Find7s/Lvm_for_Android
struct dm_config_tree *dm_config_from_string(const char *config_settings)
{
	struct dm_config_tree *cft;

	if (!(cft = dm_config_create()))
		return_NULL;

	if (!dm_config_parse(cft, config_settings, config_settings + strlen(config_settings))) {
		dm_config_destroy(cft);
		return_NULL;
	}

	return cft;
}
コード例 #7
0
ファイル: config.c プロジェクト: Find7s/Lvm_for_Android
void config_destroy(struct dm_config_tree *cft)
{
	struct config_source *cs;
	struct config_file *cf;

	if (!cft)
		return;

	cs = dm_config_get_custom(cft);

	if ((cs->type == CONFIG_FILE) || (cs->type == CONFIG_PROFILE)) {
		cf = cs->source.file;
		if (cf && cf->dev)
			if (!dev_close(cf->dev))
				stack;
	}

	dm_config_destroy(cft);
}
コード例 #8
0
ファイル: config.c プロジェクト: Find7s/Lvm_for_Android
/*
 * public interface
 */
struct dm_config_tree *config_open(config_source_t source,
				   const char *filename,
				   int keep_open)
{
	struct dm_config_tree *cft = dm_config_create();
	struct config_source *cs;
	struct config_file *cf;

	if (!cft)
		return NULL;

	if (!(cs = dm_pool_zalloc(cft->mem, sizeof(struct config_source)))) {
		log_error("Failed to allocate config source.");
		goto fail;
	}

	if ((source == CONFIG_FILE) || (source == CONFIG_PROFILE)) {
		if (!(cf = dm_pool_zalloc(cft->mem, sizeof(struct config_file)))) {
			log_error("Failed to allocate config file.");
			goto fail;
		}

		cf->keep_open = keep_open;
		if (filename &&
		    !(cf->filename = dm_pool_strdup(cft->mem, filename))) {
			log_error("Failed to duplicate filename.");
			goto fail;
		}

		cs->source.file = cf;
	}

	cs->type = source;
	dm_config_set_custom(cft, cs);
	return cft;
fail:
	dm_config_destroy(cft);
	return NULL;
}
コード例 #9
0
ファイル: config_t.c プロジェクト: cardamon/lvm2
static void test_clone(void)
{
	struct dm_config_tree *tree = dm_config_from_string(conf);
	struct dm_config_node *n = dm_config_clone_node(tree, tree->root, 1);
	const struct dm_config_value *value;

	/* Check that the nodes are actually distinct. */
	CU_ASSERT(n != tree->root);
	CU_ASSERT(n->sib != tree->root->sib);
	CU_ASSERT(dm_config_find_node(n, "physical_volumes") != NULL);
	CU_ASSERT(dm_config_find_node(tree->root, "physical_volumes") != NULL);
	CU_ASSERT(dm_config_find_node(n, "physical_volumes") != dm_config_find_node(tree->root, "physical_volumes"));

	CU_ASSERT(dm_config_has_node(n, "id"));
	CU_ASSERT(dm_config_has_node(n, "physical_volumes"));
	CU_ASSERT(dm_config_has_node(n, "physical_volumes/pv0"));
	CU_ASSERT(dm_config_has_node(n, "physical_volumes/pv0/id"));

	CU_ASSERT(!strcmp(dm_config_find_str(n, "id", "foo"), "yada-yada"));
	CU_ASSERT(!strcmp(dm_config_find_str(n, "idt", "foo"), "foo"));

	CU_ASSERT(!strcmp(dm_config_find_str(n, "physical_volumes/pv0/bb", "foo"), "foo"));
	CU_ASSERT(!strcmp(dm_config_find_str(n, "physical_volumes/pv0/id", "foo"), "abcd-efgh"));

	CU_ASSERT(!dm_config_get_uint32(n, "id", NULL));
	CU_ASSERT(dm_config_get_uint32(n, "extent_size", NULL));

	/* FIXME: Currently everything parses as a list, even if it's not */
	// CU_ASSERT(!dm_config_get_list(tree->root, "id", NULL));
	// CU_ASSERT(!dm_config_get_list(tree->root, "extent_size", NULL));

	CU_ASSERT(dm_config_get_list(n, "flags", &value));
	CU_ASSERT(value->next == NULL); /* an empty list */
	CU_ASSERT(dm_config_get_list(n, "status", &value));
	CU_ASSERT(value->next != NULL); /* a non-empty list */

	dm_config_destroy(tree);
}
コード例 #10
0
ファイル: dumpconfig.c プロジェクト: jesuszhu/LVM2
int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
{
    const char *file = arg_str_value(cmd, file_ARG, NULL);
    const char *type = arg_str_value(cmd, configtype_ARG, arg_count(cmd, list_ARG) ? "list" : "current");
    struct config_def_tree_spec tree_spec = {0};
    struct dm_config_tree *cft = NULL;
    struct cft_check_handle *cft_check_handle = NULL;
    struct profile *profile = NULL;
    int r = ECMD_PROCESSED;

    tree_spec.cmd = cmd;

    if (arg_count(cmd, configtype_ARG) && arg_count(cmd, validate_ARG)) {
        log_error("Only one of --type and --validate permitted.");
        return EINVALID_CMD_LINE;
    }

    if (arg_count(cmd, configtype_ARG) && arg_count(cmd, list_ARG)) {
        log_error("Only one of --type and --list permitted.");
        return EINVALID_CMD_LINE;
    }

    if (arg_count(cmd, atversion_ARG)) {
        if (arg_count(cmd, sinceversion_ARG)) {
            log_error("Only one of --atversion and --sinceversion permitted.");
            return EINVALID_CMD_LINE;
        }

        if (!arg_count(cmd, configtype_ARG) && !arg_count(cmd, list_ARG)) {
            log_error("--atversion requires --type or --list");
            return EINVALID_CMD_LINE;
        }
    } else if (arg_count(cmd, sinceversion_ARG)) {
        if (!arg_count(cmd, configtype_ARG) || strcmp(type, "new")) {
            log_error("--sinceversion requires --type new");
            return EINVALID_CMD_LINE;
        }
    }

    if (arg_count(cmd, ignoreadvanced_ARG))
        tree_spec.ignoreadvanced = 1;

    if (arg_count(cmd, ignoreunsupported_ARG)) {
        if (arg_count(cmd, showunsupported_ARG)) {
            log_error("Only one of --ignoreunsupported and --showunsupported permitted.");
            return EINVALID_CMD_LINE;
        }
        tree_spec.ignoreunsupported = 1;
    } else if (arg_count(cmd, showunsupported_ARG)) {
        tree_spec.ignoreunsupported = 0;
    } else if (strcmp(type, "current") && strcmp(type, "diff")) {
        /*
         * By default hide unsupported settings
         * for all display types except "current"
         * and "diff".
         */
        tree_spec.ignoreunsupported = 1;
    }

    if (strcmp(type, "current") && strcmp(type, "diff")) {
        /*
         * By default hide deprecated settings
         * for all display types except "current"
         * and "diff" unless --showdeprecated is set.
         *
         * N.B. Deprecated settings are visible if
         * --atversion is used with a version that
         * is lower than the version in which the
         * setting was deprecated.
         */
        if (!arg_count(cmd, showdeprecated_ARG))
            tree_spec.ignoredeprecated = 1;
    }

    if (arg_count(cmd, ignorelocal_ARG))
        tree_spec.ignorelocal = 1;

    if (!strcmp(type, "current") || !strcmp(type, "full")) {
        if (arg_count(cmd, atversion_ARG)) {
            log_error("--atversion has no effect with --type %s", type);
            return EINVALID_CMD_LINE;
        }

        if ((arg_count(cmd, ignoreunsupported_ARG) ||
                arg_count(cmd, ignoreadvanced_ARG)) &&
                !strcmp(type, "current")) {
            /* FIXME: allow these even for --type current */
            log_error("--ignoreadvanced and --ignoreunsupported has "
                      "no effect with --type current");
            return EINVALID_CMD_LINE;
        }
    } else if (arg_count(cmd, mergedconfig_ARG)) {
        log_error("--mergedconfig has no effect without --type current or --type full");
        return EINVALID_CMD_LINE;
    }

    if (!_get_vsn(cmd, &tree_spec.version))
        return EINVALID_CMD_LINE;

    /*
     * The profile specified by --profile cmd arg is like --commandprofile,
     * but it is used just for dumping the profile content and not for
     * application.
     */
    if (arg_count(cmd, profile_ARG) &&
            (!(profile = add_profile(cmd, arg_str_value(cmd, profile_ARG, NULL), CONFIG_PROFILE_COMMAND)) ||
             !override_config_tree_from_profile(cmd, profile))) {
        log_error("Failed to load profile %s.", arg_str_value(cmd, profile_ARG, NULL));
        return ECMD_FAILED;
    }

    /*
     * Set the 'cft' to work with based on whether we need the plain
     * config tree or merged config tree cascade if --mergedconfig is used.
     */
    if ((arg_count(cmd, mergedconfig_ARG) || !strcmp(type, "full")) && cmd->cft->cascade) {
        if (!_merge_config_cascade(cmd, cmd->cft, &cft)) {
            log_error("Failed to merge configuration.");
            r = ECMD_FAILED;
            goto out;
        }
    } else
        cft = cmd->cft;
    tree_spec.current_cft = cft;

    if (arg_count(cmd, validate_ARG)) {
        if (_config_validate(cmd, cft)) {
            log_print("LVM configuration valid.");
            goto out;
        } else {
            log_error("LVM configuration invalid.");
            r = ECMD_FAILED;
            goto out;
        }
    }

    if (!strcmp(type, "list") || arg_count(cmd, list_ARG)) {
        tree_spec.type = CFG_DEF_TREE_LIST;
        if (arg_count(cmd, withcomments_ARG)) {
            log_error("--withcomments has no effect with --type list");
            return EINVALID_CMD_LINE;
        }
        /* list type does not require status check */
    } else if (!strcmp(type, "full")) {
        tree_spec.type = CFG_DEF_TREE_FULL;
        if (!_do_def_check(&tree_spec, cft, &cft_check_handle)) {
            r = ECMD_FAILED;
            goto_out;
        }
    } else if (!strcmp(type, "current")) {
        tree_spec.type = CFG_DEF_TREE_CURRENT;
        if (!_do_def_check(&tree_spec, cft, &cft_check_handle)) {
            r = ECMD_FAILED;
            goto_out;
        }
    }
    else if (!strcmp(type, "missing")) {
        tree_spec.type = CFG_DEF_TREE_MISSING;
        if (!_do_def_check(&tree_spec, cft, &cft_check_handle)) {
            r = ECMD_FAILED;
            goto_out;
        }
    }
    else if (!strcmp(type, "default")) {
        tree_spec.type = CFG_DEF_TREE_DEFAULT;
        /* default type does not require check status */
    }
    else if (!strcmp(type, "diff")) {
        tree_spec.type = CFG_DEF_TREE_DIFF;
        if (!_do_def_check(&tree_spec, cft, &cft_check_handle)) {
            r = ECMD_FAILED;
            goto_out;
        }
    }
    else if (!strcmp(type, "new")) {
        tree_spec.type = arg_count(cmd, sinceversion_ARG) ? CFG_DEF_TREE_NEW_SINCE
                         : CFG_DEF_TREE_NEW;
        /* new type does not require check status */
    }
    else if (!strcmp(type, "profilable")) {
        tree_spec.type = CFG_DEF_TREE_PROFILABLE;
        /* profilable type does not require check status */
    }
    else if (!strcmp(type, "profilable-command")) {
        tree_spec.type = CFG_DEF_TREE_PROFILABLE_CMD;
        /* profilable-command type does not require check status */
    }
    else if (!strcmp(type, "profilable-metadata")) {
        tree_spec.type = CFG_DEF_TREE_PROFILABLE_MDA;
        /* profilable-metadata  type does not require check status */
    }
    else {
        log_error("Incorrect type of configuration specified. "
                  "Expected one of: current, default, diff, full, list, missing, "
                  "new, profilable, profilable-command, profilable-metadata.");
        r = EINVALID_CMD_LINE;
        goto out;
    }

    if (arg_count(cmd, withsummary_ARG) || arg_count(cmd, list_ARG))
        tree_spec.withsummary = 1;
    if (arg_count(cmd, withcomments_ARG))
        tree_spec.withcomments = 1;
    if (arg_count(cmd, unconfigured_ARG))
        tree_spec.unconfigured = 1;

    if (arg_count(cmd, withversions_ARG))
        tree_spec.withversions = 1;

    if (arg_count(cmd, withspaces_ARG))
        tree_spec.withspaces = 1;

    if (cft_check_handle)
        tree_spec.check_status = cft_check_handle->status;

    if ((tree_spec.type != CFG_DEF_TREE_CURRENT) &&
            (tree_spec.type != CFG_DEF_TREE_DIFF) &&
            !(cft = config_def_create_tree(&tree_spec))) {
        r = ECMD_FAILED;
        goto_out;
    }

    if (!config_write(cft, &tree_spec, file, argc, argv)) {
        stack;
        r = ECMD_FAILED;
    }
out:
    if (tree_spec.current_cft && (tree_spec.current_cft != cft) &&
            (tree_spec.current_cft != cmd->cft))
        /*
         * This happens in case of CFG_DEF_TREE_FULL where we
         * have merged explicitly defined config trees and also
         * we have used default tree.
         */
        dm_config_destroy(tree_spec.current_cft);

    if (cft && (cft != cmd->cft))
        dm_config_destroy(cft);
    else if (profile)
        remove_config_tree_by_source(cmd, CONFIG_PROFILE_COMMAND);

    /*
     * The cmd->cft (the "current" tree) is destroyed
     * together with cmd context destroy...
     */

    return r;
}