Exemple #1
0
/*
 * Checks that the config file contains vg metadata, and that it
 * we recognise the version number,
 */
static int _check_version(struct config_tree *cft)
{
    struct config_node *cn;
    struct config_value *cv;

    /*
     * Check the contents field.
     */
    if (!(cn = find_config_node(cft->root, CONTENTS_FIELD))) {
        _invalid_format("missing contents field");
        return 0;
    }

    cv = cn->v;
    if (!cv || cv->type != CFG_STRING || strcmp(cv->v.str, CONTENTS_VALUE)) {
        _invalid_format("unrecognised contents field");
        return 0;
    }

    /*
     * Check the version number.
     */
    if (!(cn = find_config_node(cft->root, FORMAT_VERSION_FIELD))) {
        _invalid_format("missing version number");
        return 0;
    }

    cv = cn->v;
    if (!cv || cv->type != CFG_INT || cv->v.i != FORMAT_VERSION_VALUE) {
        _invalid_format("unrecognised version number");
        return 0;
    }

    return 1;
}
Exemple #2
0
static int _mirrored_text_import(struct lv_segment *seg, const struct config_node *sn,
                        struct dm_hash_table *pv_hash)
{
        const struct config_node *cn;
        char *logname = NULL;

        if (find_config_node(sn, "extents_moved")) {
                if (get_config_uint32(sn, "extents_moved",
                                      &seg->extents_copied))
                        seg->status |= PVMOVE;
                else {
                        log_error("Couldn't read 'extents_moved' for "
                                  "segment '%s'.", sn->key);
                        return 0;
                }
        }

        if (find_config_node(sn, "region_size")) {
                if (!get_config_uint32(sn, "region_size",
                                      &seg->region_size)) {
                        log_error("Couldn't read 'region_size' for "
                                  "segment '%s'.", sn->key);
                        return 0;
                }
        }

        if ((cn = find_config_node(sn, "mirror_log"))) {
                if (!cn->v || !cn->v->v.str) {
                        log_error("Mirror log type must be a string.");
                        return 0;
                }
                logname = cn->v->v.str;
                if (!(seg->log_lv = find_lv(seg->lv->vg, logname))) {
                        log_error("Unrecognised mirror log in segment %s.",
                                  sn->key);
                        return 0;
                }
                seg->log_lv->status |= MIRROR_LOG;
        }

        if (logname && !seg->region_size) {
                log_error("Missing region size for mirror log for segment "
                          "'%s'.", sn->key);
                return 0;
        }

        if (!(cn = find_config_node(sn, "mirrors"))) {
                log_error("Couldn't find mirrors array for segment "
                          "'%s'.", sn->key);
                return 0;
        }

        return text_import_areas(seg, sn, cn, pv_hash, MIRROR_IMAGE);
}
static int _read_array(struct pfilter *pf, struct config_tree *cft,
		       const char *path, void *data)
{
	const struct config_node *cn;
	struct config_value *cv;

	if (!(cn = find_config_node(cft->root, path))) {
		log_very_verbose("Couldn't find %s array in '%s'",
				 path, pf->file);
		return 0;
	}

	/*
	 * iterate through the array, adding
	 * devices as we go.
	 */
	for (cv = cn->v; cv; cv = cv->next) {
		if (cv->type != CFG_STRING) {
			log_verbose("Devices array contains a value "
				    "which is not a string ... ignoring");
			continue;
		}

		if (!dm_hash_insert(pf->devices, cv->v.str, data))
			log_verbose("Couldn't add '%s' to filter ... ignoring",
				    cv->v.str);
		/* Populate dev_cache ourselves */
		dev_cache_get(cv->v.str, NULL);
	}
	return 1;
}
Exemple #4
0
int get_config_str(const struct config_node *cn, const char *path,
		   const char **result)
{
	const struct config_node *n;

	n = find_config_node(cn, path);

	if (!n || !n->v || n->v->type != CFG_STRING)
		return 0;

	*result = n->v->v.str;
	return 1;
}
Exemple #5
0
int get_config_uint64(const struct config_node *cn, const char *path,
		      uint64_t *result)
{
	const struct config_node *n;

	n = find_config_node(cn, path);

	if (!n || !n->v || n->v->type != CFG_INT)
		return 0;

	*result = (uint64_t) n->v->v.i;
	return 1;
}
Exemple #6
0
int write_config_file(struct config_tree *cft, const char *file,
		      int argc, char **argv)
{
	const struct config_node *cn;
	int r = 1;
	struct output_line outline;
	outline.fp = NULL;
	outline.putline = NULL;

	if (!file)
		file = "stdout";
	else if (!(outline.fp = fopen(file, "w"))) {
		log_sys_error("open", file);
		return 0;
	}

	if (!(outline.mem = dm_pool_create("config_line", 1024))) {
		r = 0;
		goto_out;
	}

	log_verbose("Dumping configuration to %s", file);
	if (!argc) {
		if (!_write_config(cft->root, 0, &outline, 0)) {
			log_error("Failure while writing to %s", file);
			r = 0;
		}
	} else while (argc--) {
		if ((cn = find_config_node(cft->root, *argv))) {
			if (!_write_config(cn, 1, &outline, 0)) {
				log_error("Failure while writing to %s", file);
				r = 0;
			}
		} else {
			log_error("Configuration node %s not found", *argv);
			r = 0;
		}
		argv++;
	}

	dm_pool_destroy(outline.mem);

out:
	if (outline.fp && lvm_fclose(outline.fp, file)) {
		stack;
		r = 0;
	}

	return r;
}
Exemple #7
0
/* Destructively merge a new config tree into an existing one */
int merge_config_tree(struct cmd_context *cmd, struct config_tree *cft,
		      struct config_tree *newdata)
{
	const struct config_node *root = cft->root;
	struct config_node *cn, *nextn, *oldn, *cn2;
	const struct config_node *tn;

	for (cn = newdata->root; cn; cn = nextn) {
		nextn = cn->sib;
		/* Ignore tags section */
		if (!strcmp(cn->key, "tags"))
			continue;
		/* If there's a tags node, skip if host tags don't match */
		if ((tn = find_config_node(cn->child, "tags"))) {
			if (!_match_host_tags(&cmd->tags, tn))
				continue;
		}
		if (!(oldn = (struct config_node *)find_config_node(root, cn->key))) {
			_insert_config_node(&cft->root, cn);
			/* Remove any "tags" nodes */
			for (cn2 = cn->child; cn2; cn2 = cn2->sib) {
				if (!strcmp(cn2->key, "tags")) {
					cn->child = cn2->sib;
					continue;
				}
				if (cn2->sib && !strcmp(cn2->sib->key, "tags")) {
					cn2->sib = cn2->sib->sib;
					continue;
				}
			}
			continue;
		}
		_merge_section(oldn, cn);
	}

	return 1;
}
Exemple #8
0
static int _read_flag_config(struct config_node *n, uint64_t *status, int type)
{
    struct config_node *cn;
    *status = 0;

    if (!(cn = find_config_node(n, "status"))) {
        log_error("Could not find status flags.");
        return 0;
    }

    if (!(read_flags(status, type | STATUS_FLAG, cn->v))) {
        log_error("Could not read status flags.");
        return 0;
    }

    if ((cn = find_config_node(n, "flags"))) {
        if (!(read_flags(status, type, cn->v))) {
            log_error("Could not read flags.");
            return 0;
        }
    }

    return 1;
}
Exemple #9
0
static int _read_id(struct id *id, struct config_node *cn, const char *path)
{
    struct config_value *cv;

    if (!(cn = find_config_node(cn, path))) {
        log_error("Couldn't find uuid.");
        return 0;
    }

    cv = cn->v;
    if (!cv || !cv->v.str) {
        log_error("uuid must be a string.");
        return 0;
    }

    if (!id_read_format(id, cv->v.str)) {
        log_error("Invalid uuid.");
        return 0;
    }

    return 1;
}
Exemple #10
0
static int _striped_text_import(struct lv_segment *seg, const struct config_node *sn,
			struct dm_hash_table *pv_hash)
{
	struct config_node *cn;

	if ((seg->area_count != 1) &&
	    !get_config_uint32(sn, "stripe_size", &seg->stripe_size)) {
		log_error("Couldn't read stripe_size for segment %s "
			  "of logical volume %s.", config_parent_name(sn), seg->lv->name);
		return 0;
	}

	if (!(cn = find_config_node(sn, "stripes"))) {
		log_error("Couldn't find stripes array for segment %s "
			  "of logical volume %s.", config_parent_name(sn), seg->lv->name);
		return 0;
	}

	seg->area_len /= seg->area_count;

	return text_import_areas(seg, sn, cn, pv_hash, 0);
}
Exemple #11
0
/*
 * Merge section cn2 into section cn1 (which has the same name)
 * overwriting any existing cn1 nodes with matching names.
 */
static void _merge_section(struct config_node *cn1, struct config_node *cn2)
{
	struct config_node *cn, *nextn, *oldn;
	struct config_value *cv;

	for (cn = cn2->child; cn; cn = nextn) {
		nextn = cn->sib;

		/* Skip "tags" */
		if (!strcmp(cn->key, "tags"))
			continue;

		/* Subsection? */
		if (!cn->v)
			/* Ignore - we don't have any of these yet */
			continue;
		/* Not already present? */
		if (!(oldn = (struct config_node*)find_config_node(cn1->child, cn->key))) {
			_insert_config_node(&cn1->child, cn);
			continue;
		}
		/* Merge certain value lists */
		if ((!strcmp(cn1->key, "activation") &&
		     !strcmp(cn->key, "volume_list")) ||
		    (!strcmp(cn1->key, "devices") &&
		     (!strcmp(cn->key, "filter") || !strcmp(cn->key, "types")))) {
			cv = cn->v;
			while (cv->next)
				cv = cv->next;
			cv->next = oldn->v;
		}

		/* Replace values */
		oldn->v = cn->v;
	}
}