|
|
d617b2 |
From 945de675c47d891d1f181f15971d26ff959ac631 Mon Sep 17 00:00:00 2001
|
|
|
d617b2 |
From: David Teigland <teigland@redhat.com>
|
|
|
d617b2 |
Date: Tue, 14 Jan 2020 14:12:20 -0600
|
|
|
d617b2 |
Subject: [PATCH 1/3] move pv_list code into lib
|
|
|
d617b2 |
|
|
|
d617b2 |
(cherry picked from commit b6b4ad8e28eff7476cb04c4cb93312b06605b82f)
|
|
|
d617b2 |
---
|
|
|
d617b2 |
lib/Makefile.in | 1 +
|
|
|
d617b2 |
lib/metadata/metadata-exported.h | 4 +
|
|
|
d617b2 |
lib/metadata/pv_list.c | 291 +++++++++++++++++++++++++++++++++++++++
|
|
|
d617b2 |
tools/toollib.c | 270 ------------------------------------
|
|
|
d617b2 |
tools/toollib.h | 9 --
|
|
|
d617b2 |
5 files changed, 296 insertions(+), 279 deletions(-)
|
|
|
d617b2 |
create mode 100644 lib/metadata/pv_list.c
|
|
|
d617b2 |
|
|
|
d617b2 |
diff --git a/lib/Makefile.in b/lib/Makefile.in
|
|
|
d617b2 |
index c037b41..2a064f3 100644
|
|
|
d617b2 |
--- a/lib/Makefile.in
|
|
|
d617b2 |
+++ b/lib/Makefile.in
|
|
|
d617b2 |
@@ -74,6 +74,7 @@ SOURCES =\
|
|
|
d617b2 |
metadata/mirror.c \
|
|
|
d617b2 |
metadata/pool_manip.c \
|
|
|
d617b2 |
metadata/pv.c \
|
|
|
d617b2 |
+ metadata/pv_list.c \
|
|
|
d617b2 |
metadata/pv_manip.c \
|
|
|
d617b2 |
metadata/pv_map.c \
|
|
|
d617b2 |
metadata/raid_manip.c \
|
|
|
d617b2 |
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
|
|
|
d617b2 |
index c61c85c..35c1231 100644
|
|
|
d617b2 |
--- a/lib/metadata/metadata-exported.h
|
|
|
d617b2 |
+++ b/lib/metadata/metadata-exported.h
|
|
|
d617b2 |
@@ -1385,4 +1385,8 @@ int vg_is_foreign(struct volume_group *vg);
|
|
|
d617b2 |
|
|
|
d617b2 |
void vg_write_commit_bad_mdas(struct cmd_context *cmd, struct volume_group *vg);
|
|
|
d617b2 |
|
|
|
d617b2 |
+struct dm_list *create_pv_list(struct dm_pool *mem, struct volume_group *vg, int argc,
|
|
|
d617b2 |
+ char **argv, int allocatable_only);
|
|
|
d617b2 |
+struct dm_list *clone_pv_list(struct dm_pool *mem, struct dm_list *pvsl);
|
|
|
d617b2 |
+
|
|
|
d617b2 |
#endif
|
|
|
d617b2 |
diff --git a/lib/metadata/pv_list.c b/lib/metadata/pv_list.c
|
|
|
d617b2 |
new file mode 100644
|
|
|
d617b2 |
index 0000000..143b573
|
|
|
d617b2 |
--- /dev/null
|
|
|
d617b2 |
+++ b/lib/metadata/pv_list.c
|
|
|
d617b2 |
@@ -0,0 +1,291 @@
|
|
|
d617b2 |
+/*
|
|
|
d617b2 |
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
|
|
d617b2 |
+ * Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
|
|
|
d617b2 |
+ *
|
|
|
d617b2 |
+ * This file is part of LVM2.
|
|
|
d617b2 |
+ *
|
|
|
d617b2 |
+ * This copyrighted material is made available to anyone wishing to use,
|
|
|
d617b2 |
+ * modify, copy, or redistribute it subject to the terms and conditions
|
|
|
d617b2 |
+ * of the GNU Lesser General Public License v.2.1.
|
|
|
d617b2 |
+ *
|
|
|
d617b2 |
+ * You should have received a copy of the GNU Lesser General Public License
|
|
|
d617b2 |
+ * along with this program; if not, write to the Free Software Foundation,
|
|
|
d617b2 |
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
d617b2 |
+ */
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+#include "lib/misc/lib.h"
|
|
|
d617b2 |
+#include "lib/misc/lvm-string.h"
|
|
|
d617b2 |
+#include "lib/datastruct/str_list.h"
|
|
|
d617b2 |
+#include "lib/device/device.h"
|
|
|
d617b2 |
+#include "lib/metadata/metadata.h"
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+/*
|
|
|
d617b2 |
+ * Process physical extent range specifiers
|
|
|
d617b2 |
+ */
|
|
|
d617b2 |
+static int _add_pe_range(struct dm_pool *mem, const char *pvname,
|
|
|
d617b2 |
+ struct dm_list *pe_ranges, uint32_t start, uint32_t count)
|
|
|
d617b2 |
+{
|
|
|
d617b2 |
+ struct pe_range *per;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ log_debug("Adding PE range: start PE " FMTu32 " length " FMTu32 " on %s.",
|
|
|
d617b2 |
+ start, count, pvname);
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ /* Ensure no overlap with existing areas */
|
|
|
d617b2 |
+ dm_list_iterate_items(per, pe_ranges) {
|
|
|
d617b2 |
+ if (((start < per->start) && (start + count - 1 >= per->start)) ||
|
|
|
d617b2 |
+ ((start >= per->start) &&
|
|
|
d617b2 |
+ (per->start + per->count - 1) >= start)) {
|
|
|
d617b2 |
+ log_error("Overlapping PE ranges specified (" FMTu32
|
|
|
d617b2 |
+ "-" FMTu32 ", " FMTu32 "-" FMTu32 ") on %s.",
|
|
|
d617b2 |
+ start, start + count - 1, per->start,
|
|
|
d617b2 |
+ per->start + per->count - 1, pvname);
|
|
|
d617b2 |
+ return 0;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (!(per = dm_pool_alloc(mem, sizeof(*per)))) {
|
|
|
d617b2 |
+ log_error("Allocation of list failed.");
|
|
|
d617b2 |
+ return 0;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ per->start = start;
|
|
|
d617b2 |
+ per->count = count;
|
|
|
d617b2 |
+ dm_list_add(pe_ranges, &per->list);
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ return 1;
|
|
|
d617b2 |
+}
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+static int _xstrtouint32(const char *s, char **p, int base, uint32_t *result)
|
|
|
d617b2 |
+{
|
|
|
d617b2 |
+ unsigned long ul;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ errno = 0;
|
|
|
d617b2 |
+ ul = strtoul(s, p, base);
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (errno || *p == s || ul > UINT32_MAX)
|
|
|
d617b2 |
+ return 0;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ *result = ul;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ return 1;
|
|
|
d617b2 |
+}
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+static int _parse_pes(struct dm_pool *mem, char *c, struct dm_list *pe_ranges,
|
|
|
d617b2 |
+ const char *pvname, uint32_t size)
|
|
|
d617b2 |
+{
|
|
|
d617b2 |
+ char *endptr;
|
|
|
d617b2 |
+ uint32_t start, end, len;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ /* Default to whole PV */
|
|
|
d617b2 |
+ if (!c) {
|
|
|
d617b2 |
+ if (!_add_pe_range(mem, pvname, pe_ranges, UINT32_C(0), size))
|
|
|
d617b2 |
+ return_0;
|
|
|
d617b2 |
+ return 1;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ while (*c) {
|
|
|
d617b2 |
+ if (*c != ':')
|
|
|
d617b2 |
+ goto error;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ c++;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ /* Disallow :: and :\0 */
|
|
|
d617b2 |
+ if (*c == ':' || !*c)
|
|
|
d617b2 |
+ goto error;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ /* Default to whole range */
|
|
|
d617b2 |
+ start = UINT32_C(0);
|
|
|
d617b2 |
+ end = size - 1;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ /* Start extent given? */
|
|
|
d617b2 |
+ if (isdigit(*c)) {
|
|
|
d617b2 |
+ if (!_xstrtouint32(c, &endptr, 10, &start))
|
|
|
d617b2 |
+ goto error;
|
|
|
d617b2 |
+ c = endptr;
|
|
|
d617b2 |
+ /* Just one number given? */
|
|
|
d617b2 |
+ if (!*c || *c == ':')
|
|
|
d617b2 |
+ end = start;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+ /* Range? */
|
|
|
d617b2 |
+ if (*c == '-') {
|
|
|
d617b2 |
+ c++;
|
|
|
d617b2 |
+ if (isdigit(*c)) {
|
|
|
d617b2 |
+ if (!_xstrtouint32(c, &endptr, 10, &end))
|
|
|
d617b2 |
+ goto error;
|
|
|
d617b2 |
+ c = endptr;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+ } else if (*c == '+') { /* Length? */
|
|
|
d617b2 |
+ c++;
|
|
|
d617b2 |
+ if (isdigit(*c)) {
|
|
|
d617b2 |
+ if (!_xstrtouint32(c, &endptr, 10, &len))
|
|
|
d617b2 |
+ goto error;
|
|
|
d617b2 |
+ c = endptr;
|
|
|
d617b2 |
+ end = start + (len ? (len - 1) : 0);
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (*c && *c != ':')
|
|
|
d617b2 |
+ goto error;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if ((start > end) || (end > size - 1)) {
|
|
|
d617b2 |
+ log_error("PE range error: start extent %" PRIu32 " to "
|
|
|
d617b2 |
+ "end extent %" PRIu32 ".", start, end);
|
|
|
d617b2 |
+ return 0;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (!_add_pe_range(mem, pvname, pe_ranges, start, end - start + 1))
|
|
|
d617b2 |
+ return_0;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ return 1;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ error:
|
|
|
d617b2 |
+ log_error("Physical extent parsing error at %s.", c);
|
|
|
d617b2 |
+ return 0;
|
|
|
d617b2 |
+}
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+static int _create_pv_entry(struct dm_pool *mem, struct pv_list *pvl,
|
|
|
d617b2 |
+ char *colon, int allocatable_only, struct dm_list *r)
|
|
|
d617b2 |
+{
|
|
|
d617b2 |
+ const char *pvname;
|
|
|
d617b2 |
+ struct pv_list *new_pvl = NULL, *pvl2;
|
|
|
d617b2 |
+ struct dm_list *pe_ranges;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ pvname = pv_dev_name(pvl->pv);
|
|
|
d617b2 |
+ if (allocatable_only && !(pvl->pv->status & ALLOCATABLE_PV)) {
|
|
|
d617b2 |
+ log_warn("WARNING: Physical volume %s not allocatable.", pvname);
|
|
|
d617b2 |
+ return 1;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (allocatable_only && is_missing_pv(pvl->pv)) {
|
|
|
d617b2 |
+ log_warn("WARNING: Physical volume %s is missing.", pvname);
|
|
|
d617b2 |
+ return 1;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (allocatable_only &&
|
|
|
d617b2 |
+ (pvl->pv->pe_count == pvl->pv->pe_alloc_count)) {
|
|
|
d617b2 |
+ log_warn("WARNING: No free extents on physical volume \"%s\".", pvname);
|
|
|
d617b2 |
+ return 1;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ dm_list_iterate_items(pvl2, r)
|
|
|
d617b2 |
+ if (pvl->pv->dev == pvl2->pv->dev) {
|
|
|
d617b2 |
+ new_pvl = pvl2;
|
|
|
d617b2 |
+ break;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (!new_pvl) {
|
|
|
d617b2 |
+ if (!(new_pvl = dm_pool_alloc(mem, sizeof(*new_pvl)))) {
|
|
|
d617b2 |
+ log_error("Unable to allocate physical volume list.");
|
|
|
d617b2 |
+ return 0;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ memcpy(new_pvl, pvl, sizeof(*new_pvl));
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (!(pe_ranges = dm_pool_alloc(mem, sizeof(*pe_ranges)))) {
|
|
|
d617b2 |
+ log_error("Allocation of pe_ranges list failed.");
|
|
|
d617b2 |
+ return 0;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+ dm_list_init(pe_ranges);
|
|
|
d617b2 |
+ new_pvl->pe_ranges = pe_ranges;
|
|
|
d617b2 |
+ dm_list_add(r, &new_pvl->list);
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ /* Determine selected physical extents */
|
|
|
d617b2 |
+ if (!_parse_pes(mem, colon, new_pvl->pe_ranges, pv_dev_name(pvl->pv),
|
|
|
d617b2 |
+ pvl->pv->pe_count))
|
|
|
d617b2 |
+ return_0;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ return 1;
|
|
|
d617b2 |
+}
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+struct dm_list *create_pv_list(struct dm_pool *mem, struct volume_group *vg, int argc,
|
|
|
d617b2 |
+ char **argv, int allocatable_only)
|
|
|
d617b2 |
+{
|
|
|
d617b2 |
+ struct dm_list *r;
|
|
|
d617b2 |
+ struct pv_list *pvl;
|
|
|
d617b2 |
+ struct dm_list tagsl, arg_pvnames;
|
|
|
d617b2 |
+ char *pvname = NULL;
|
|
|
d617b2 |
+ char *colon, *at_sign, *tagname;
|
|
|
d617b2 |
+ int i;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ /* Build up list of PVs */
|
|
|
d617b2 |
+ if (!(r = dm_pool_alloc(mem, sizeof(*r)))) {
|
|
|
d617b2 |
+ log_error("Allocation of list failed.");
|
|
|
d617b2 |
+ return NULL;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+ dm_list_init(r);
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ dm_list_init(&tagsl);
|
|
|
d617b2 |
+ dm_list_init(&arg_pvnames);
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ for (i = 0; i < argc; i++) {
|
|
|
d617b2 |
+ dm_unescape_colons_and_at_signs(argv[i], &colon, &at_sign);
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (at_sign && (at_sign == argv[i])) {
|
|
|
d617b2 |
+ tagname = at_sign + 1;
|
|
|
d617b2 |
+ if (!validate_tag(tagname)) {
|
|
|
d617b2 |
+ log_error("Skipping invalid tag %s.", tagname);
|
|
|
d617b2 |
+ continue;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+ dm_list_iterate_items(pvl, &vg->pvs) {
|
|
|
d617b2 |
+ if (str_list_match_item(&pvl->pv->tags,
|
|
|
d617b2 |
+ tagname)) {
|
|
|
d617b2 |
+ if (!_create_pv_entry(mem, pvl, NULL,
|
|
|
d617b2 |
+ allocatable_only,
|
|
|
d617b2 |
+ r))
|
|
|
d617b2 |
+ return_NULL;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+ continue;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ pvname = argv[i];
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (colon && !(pvname = dm_pool_strndup(mem, pvname,
|
|
|
d617b2 |
+ (unsigned) (colon - pvname)))) {
|
|
|
d617b2 |
+ log_error("Failed to clone PV name.");
|
|
|
d617b2 |
+ return NULL;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (!(pvl = find_pv_in_vg(vg, pvname))) {
|
|
|
d617b2 |
+ log_error("Physical Volume \"%s\" not found in "
|
|
|
d617b2 |
+ "Volume Group \"%s\".", pvname, vg->name);
|
|
|
d617b2 |
+ return NULL;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+ if (!_create_pv_entry(mem, pvl, colon, allocatable_only, r))
|
|
|
d617b2 |
+ return_NULL;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ if (dm_list_empty(r))
|
|
|
d617b2 |
+ log_error("No specified PVs have space available.");
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ return dm_list_empty(r) ? NULL : r;
|
|
|
d617b2 |
+}
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+struct dm_list *clone_pv_list(struct dm_pool *mem, struct dm_list *pvsl)
|
|
|
d617b2 |
+{
|
|
|
d617b2 |
+ struct dm_list *r;
|
|
|
d617b2 |
+ struct pv_list *pvl, *new_pvl;
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ /* Build up list of PVs */
|
|
|
d617b2 |
+ if (!(r = dm_pool_alloc(mem, sizeof(*r)))) {
|
|
|
d617b2 |
+ log_error("Allocation of list failed.");
|
|
|
d617b2 |
+ return NULL;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+ dm_list_init(r);
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ dm_list_iterate_items(pvl, pvsl) {
|
|
|
d617b2 |
+ if (!(new_pvl = dm_pool_zalloc(mem, sizeof(*new_pvl)))) {
|
|
|
d617b2 |
+ log_error("Unable to allocate physical volume list.");
|
|
|
d617b2 |
+ return NULL;
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ memcpy(new_pvl, pvl, sizeof(*new_pvl));
|
|
|
d617b2 |
+ dm_list_add(r, &new_pvl->list);
|
|
|
d617b2 |
+ }
|
|
|
d617b2 |
+
|
|
|
d617b2 |
+ return r;
|
|
|
d617b2 |
+}
|
|
|
d617b2 |
+
|
|
|
d617b2 |
diff --git a/tools/toollib.c b/tools/toollib.c
|
|
|
d617b2 |
index a5304bf..6386a69 100644
|
|
|
d617b2 |
--- a/tools/toollib.c
|
|
|
d617b2 |
+++ b/tools/toollib.c
|
|
|
d617b2 |
@@ -457,276 +457,6 @@ const char *extract_vgname(struct cmd_context *cmd, const char *lv_name)
|
|
|
d617b2 |
return vg_name;
|
|
|
d617b2 |
}
|
|
|
d617b2 |
|
|
|
d617b2 |
-/*
|
|
|
d617b2 |
- * Process physical extent range specifiers
|
|
|
d617b2 |
- */
|
|
|
d617b2 |
-static int _add_pe_range(struct dm_pool *mem, const char *pvname,
|
|
|
d617b2 |
- struct dm_list *pe_ranges, uint32_t start, uint32_t count)
|
|
|
d617b2 |
-{
|
|
|
d617b2 |
- struct pe_range *per;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- log_debug("Adding PE range: start PE " FMTu32 " length " FMTu32 " on %s.",
|
|
|
d617b2 |
- start, count, pvname);
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- /* Ensure no overlap with existing areas */
|
|
|
d617b2 |
- dm_list_iterate_items(per, pe_ranges) {
|
|
|
d617b2 |
- if (((start < per->start) && (start + count - 1 >= per->start)) ||
|
|
|
d617b2 |
- ((start >= per->start) &&
|
|
|
d617b2 |
- (per->start + per->count - 1) >= start)) {
|
|
|
d617b2 |
- log_error("Overlapping PE ranges specified (" FMTu32
|
|
|
d617b2 |
- "-" FMTu32 ", " FMTu32 "-" FMTu32 ") on %s.",
|
|
|
d617b2 |
- start, start + count - 1, per->start,
|
|
|
d617b2 |
- per->start + per->count - 1, pvname);
|
|
|
d617b2 |
- return 0;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (!(per = dm_pool_alloc(mem, sizeof(*per)))) {
|
|
|
d617b2 |
- log_error("Allocation of list failed.");
|
|
|
d617b2 |
- return 0;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- per->start = start;
|
|
|
d617b2 |
- per->count = count;
|
|
|
d617b2 |
- dm_list_add(pe_ranges, &per->list);
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- return 1;
|
|
|
d617b2 |
-}
|
|
|
d617b2 |
-
|
|
|
d617b2 |
-static int _xstrtouint32(const char *s, char **p, int base, uint32_t *result)
|
|
|
d617b2 |
-{
|
|
|
d617b2 |
- unsigned long ul;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- errno = 0;
|
|
|
d617b2 |
- ul = strtoul(s, p, base);
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (errno || *p == s || ul > UINT32_MAX)
|
|
|
d617b2 |
- return 0;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- *result = ul;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- return 1;
|
|
|
d617b2 |
-}
|
|
|
d617b2 |
-
|
|
|
d617b2 |
-static int _parse_pes(struct dm_pool *mem, char *c, struct dm_list *pe_ranges,
|
|
|
d617b2 |
- const char *pvname, uint32_t size)
|
|
|
d617b2 |
-{
|
|
|
d617b2 |
- char *endptr;
|
|
|
d617b2 |
- uint32_t start, end, len;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- /* Default to whole PV */
|
|
|
d617b2 |
- if (!c) {
|
|
|
d617b2 |
- if (!_add_pe_range(mem, pvname, pe_ranges, UINT32_C(0), size))
|
|
|
d617b2 |
- return_0;
|
|
|
d617b2 |
- return 1;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- while (*c) {
|
|
|
d617b2 |
- if (*c != ':')
|
|
|
d617b2 |
- goto error;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- c++;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- /* Disallow :: and :\0 */
|
|
|
d617b2 |
- if (*c == ':' || !*c)
|
|
|
d617b2 |
- goto error;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- /* Default to whole range */
|
|
|
d617b2 |
- start = UINT32_C(0);
|
|
|
d617b2 |
- end = size - 1;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- /* Start extent given? */
|
|
|
d617b2 |
- if (isdigit(*c)) {
|
|
|
d617b2 |
- if (!_xstrtouint32(c, &endptr, 10, &start))
|
|
|
d617b2 |
- goto error;
|
|
|
d617b2 |
- c = endptr;
|
|
|
d617b2 |
- /* Just one number given? */
|
|
|
d617b2 |
- if (!*c || *c == ':')
|
|
|
d617b2 |
- end = start;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
- /* Range? */
|
|
|
d617b2 |
- if (*c == '-') {
|
|
|
d617b2 |
- c++;
|
|
|
d617b2 |
- if (isdigit(*c)) {
|
|
|
d617b2 |
- if (!_xstrtouint32(c, &endptr, 10, &end))
|
|
|
d617b2 |
- goto error;
|
|
|
d617b2 |
- c = endptr;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
- } else if (*c == '+') { /* Length? */
|
|
|
d617b2 |
- c++;
|
|
|
d617b2 |
- if (isdigit(*c)) {
|
|
|
d617b2 |
- if (!_xstrtouint32(c, &endptr, 10, &len))
|
|
|
d617b2 |
- goto error;
|
|
|
d617b2 |
- c = endptr;
|
|
|
d617b2 |
- end = start + (len ? (len - 1) : 0);
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (*c && *c != ':')
|
|
|
d617b2 |
- goto error;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if ((start > end) || (end > size - 1)) {
|
|
|
d617b2 |
- log_error("PE range error: start extent %" PRIu32 " to "
|
|
|
d617b2 |
- "end extent %" PRIu32 ".", start, end);
|
|
|
d617b2 |
- return 0;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (!_add_pe_range(mem, pvname, pe_ranges, start, end - start + 1))
|
|
|
d617b2 |
- return_0;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- return 1;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- error:
|
|
|
d617b2 |
- log_error("Physical extent parsing error at %s.", c);
|
|
|
d617b2 |
- return 0;
|
|
|
d617b2 |
-}
|
|
|
d617b2 |
-
|
|
|
d617b2 |
-static int _create_pv_entry(struct dm_pool *mem, struct pv_list *pvl,
|
|
|
d617b2 |
- char *colon, int allocatable_only, struct dm_list *r)
|
|
|
d617b2 |
-{
|
|
|
d617b2 |
- const char *pvname;
|
|
|
d617b2 |
- struct pv_list *new_pvl = NULL, *pvl2;
|
|
|
d617b2 |
- struct dm_list *pe_ranges;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- pvname = pv_dev_name(pvl->pv);
|
|
|
d617b2 |
- if (allocatable_only && !(pvl->pv->status & ALLOCATABLE_PV)) {
|
|
|
d617b2 |
- log_warn("WARNING: Physical volume %s not allocatable.", pvname);
|
|
|
d617b2 |
- return 1;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (allocatable_only && is_missing_pv(pvl->pv)) {
|
|
|
d617b2 |
- log_warn("WARNING: Physical volume %s is missing.", pvname);
|
|
|
d617b2 |
- return 1;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (allocatable_only &&
|
|
|
d617b2 |
- (pvl->pv->pe_count == pvl->pv->pe_alloc_count)) {
|
|
|
d617b2 |
- log_warn("WARNING: No free extents on physical volume \"%s\".", pvname);
|
|
|
d617b2 |
- return 1;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- dm_list_iterate_items(pvl2, r)
|
|
|
d617b2 |
- if (pvl->pv->dev == pvl2->pv->dev) {
|
|
|
d617b2 |
- new_pvl = pvl2;
|
|
|
d617b2 |
- break;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (!new_pvl) {
|
|
|
d617b2 |
- if (!(new_pvl = dm_pool_alloc(mem, sizeof(*new_pvl)))) {
|
|
|
d617b2 |
- log_error("Unable to allocate physical volume list.");
|
|
|
d617b2 |
- return 0;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- memcpy(new_pvl, pvl, sizeof(*new_pvl));
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (!(pe_ranges = dm_pool_alloc(mem, sizeof(*pe_ranges)))) {
|
|
|
d617b2 |
- log_error("Allocation of pe_ranges list failed.");
|
|
|
d617b2 |
- return 0;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
- dm_list_init(pe_ranges);
|
|
|
d617b2 |
- new_pvl->pe_ranges = pe_ranges;
|
|
|
d617b2 |
- dm_list_add(r, &new_pvl->list);
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- /* Determine selected physical extents */
|
|
|
d617b2 |
- if (!_parse_pes(mem, colon, new_pvl->pe_ranges, pv_dev_name(pvl->pv),
|
|
|
d617b2 |
- pvl->pv->pe_count))
|
|
|
d617b2 |
- return_0;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- return 1;
|
|
|
d617b2 |
-}
|
|
|
d617b2 |
-
|
|
|
d617b2 |
-struct dm_list *create_pv_list(struct dm_pool *mem, struct volume_group *vg, int argc,
|
|
|
d617b2 |
- char **argv, int allocatable_only)
|
|
|
d617b2 |
-{
|
|
|
d617b2 |
- struct dm_list *r;
|
|
|
d617b2 |
- struct pv_list *pvl;
|
|
|
d617b2 |
- struct dm_list tagsl, arg_pvnames;
|
|
|
d617b2 |
- char *pvname = NULL;
|
|
|
d617b2 |
- char *colon, *at_sign, *tagname;
|
|
|
d617b2 |
- int i;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- /* Build up list of PVs */
|
|
|
d617b2 |
- if (!(r = dm_pool_alloc(mem, sizeof(*r)))) {
|
|
|
d617b2 |
- log_error("Allocation of list failed.");
|
|
|
d617b2 |
- return NULL;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
- dm_list_init(r);
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- dm_list_init(&tagsl);
|
|
|
d617b2 |
- dm_list_init(&arg_pvnames);
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- for (i = 0; i < argc; i++) {
|
|
|
d617b2 |
- dm_unescape_colons_and_at_signs(argv[i], &colon, &at_sign);
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (at_sign && (at_sign == argv[i])) {
|
|
|
d617b2 |
- tagname = at_sign + 1;
|
|
|
d617b2 |
- if (!validate_tag(tagname)) {
|
|
|
d617b2 |
- log_error("Skipping invalid tag %s.", tagname);
|
|
|
d617b2 |
- continue;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
- dm_list_iterate_items(pvl, &vg->pvs) {
|
|
|
d617b2 |
- if (str_list_match_item(&pvl->pv->tags,
|
|
|
d617b2 |
- tagname)) {
|
|
|
d617b2 |
- if (!_create_pv_entry(mem, pvl, NULL,
|
|
|
d617b2 |
- allocatable_only,
|
|
|
d617b2 |
- r))
|
|
|
d617b2 |
- return_NULL;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
- continue;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- pvname = argv[i];
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (colon && !(pvname = dm_pool_strndup(mem, pvname,
|
|
|
d617b2 |
- (unsigned) (colon - pvname)))) {
|
|
|
d617b2 |
- log_error("Failed to clone PV name.");
|
|
|
d617b2 |
- return NULL;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (!(pvl = find_pv_in_vg(vg, pvname))) {
|
|
|
d617b2 |
- log_error("Physical Volume \"%s\" not found in "
|
|
|
d617b2 |
- "Volume Group \"%s\".", pvname, vg->name);
|
|
|
d617b2 |
- return NULL;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
- if (!_create_pv_entry(mem, pvl, colon, allocatable_only, r))
|
|
|
d617b2 |
- return_NULL;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- if (dm_list_empty(r))
|
|
|
d617b2 |
- log_error("No specified PVs have space available.");
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- return dm_list_empty(r) ? NULL : r;
|
|
|
d617b2 |
-}
|
|
|
d617b2 |
-
|
|
|
d617b2 |
-struct dm_list *clone_pv_list(struct dm_pool *mem, struct dm_list *pvsl)
|
|
|
d617b2 |
-{
|
|
|
d617b2 |
- struct dm_list *r;
|
|
|
d617b2 |
- struct pv_list *pvl, *new_pvl;
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- /* Build up list of PVs */
|
|
|
d617b2 |
- if (!(r = dm_pool_alloc(mem, sizeof(*r)))) {
|
|
|
d617b2 |
- log_error("Allocation of list failed.");
|
|
|
d617b2 |
- return NULL;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
- dm_list_init(r);
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- dm_list_iterate_items(pvl, pvsl) {
|
|
|
d617b2 |
- if (!(new_pvl = dm_pool_zalloc(mem, sizeof(*new_pvl)))) {
|
|
|
d617b2 |
- log_error("Unable to allocate physical volume list.");
|
|
|
d617b2 |
- return NULL;
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- memcpy(new_pvl, pvl, sizeof(*new_pvl));
|
|
|
d617b2 |
- dm_list_add(r, &new_pvl->list);
|
|
|
d617b2 |
- }
|
|
|
d617b2 |
-
|
|
|
d617b2 |
- return r;
|
|
|
d617b2 |
-}
|
|
|
d617b2 |
-
|
|
|
d617b2 |
const char _pe_size_may_not_be_negative_msg[] = "Physical extent size may not be negative.";
|
|
|
d617b2 |
|
|
|
d617b2 |
int vgcreate_params_set_defaults(struct cmd_context *cmd,
|
|
|
d617b2 |
diff --git a/tools/toollib.h b/tools/toollib.h
|
|
|
d617b2 |
index 9102f55..53a5e5b 100644
|
|
|
d617b2 |
--- a/tools/toollib.h
|
|
|
d617b2 |
+++ b/tools/toollib.h
|
|
|
d617b2 |
@@ -182,15 +182,6 @@ void opt_array_to_str(struct cmd_context *cmd, int *opts, int count,
|
|
|
d617b2 |
int pvcreate_params_from_args(struct cmd_context *cmd, struct pvcreate_params *pp);
|
|
|
d617b2 |
int pvcreate_each_device(struct cmd_context *cmd, struct processing_handle *handle, struct pvcreate_params *pp);
|
|
|
d617b2 |
|
|
|
d617b2 |
-/*
|
|
|
d617b2 |
- * Builds a list of pv's from the names in argv. Used in
|
|
|
d617b2 |
- * lvcreate/extend.
|
|
|
d617b2 |
- */
|
|
|
d617b2 |
-struct dm_list *create_pv_list(struct dm_pool *mem, struct volume_group *vg, int argc,
|
|
|
d617b2 |
- char **argv, int allocatable_only);
|
|
|
d617b2 |
-
|
|
|
d617b2 |
-struct dm_list *clone_pv_list(struct dm_pool *mem, struct dm_list *pvs);
|
|
|
d617b2 |
-
|
|
|
d617b2 |
int vgcreate_params_set_defaults(struct cmd_context *cmd,
|
|
|
d617b2 |
struct vgcreate_params *vp_def,
|
|
|
d617b2 |
struct volume_group *vg);
|
|
|
d617b2 |
--
|
|
|
d617b2 |
1.8.3.1
|
|
|
d617b2 |
|