From 72a5e12b5c19e9c85561fa8e946a9bc2e67501e1 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 12 Oct 2001 10:32:06 +0000 Subject: [PATCH] o pvcreate o added uuid unit o stubbed partition stuff --- include/.symlinks | 1 + lib/Makefile.in | 5 +- lib/device/device.c | 2 + lib/device/device.h | 6 +- lib/format1/format1.c | 1 - lib/metadata/metadata.c | 70 +++++++------- lib/metadata/metadata.h | 24 +++-- lib/mm/pool.c | 5 + lib/mm/pool.h | 1 + lib/uuid/uuid.c | 49 ++++++++++ lib/uuid/uuid.h | 22 +++++ tools/Makefile.in | 15 +-- tools/lvm.c | 25 ++--- tools/pvcreate.c | 201 ++++++++++++++++++---------------------- tools/stub.h | 1 - tools/tools.h | 2 +- 16 files changed, 247 insertions(+), 183 deletions(-) create mode 100644 lib/uuid/uuid.c create mode 100644 lib/uuid/uuid.h diff --git a/include/.symlinks b/include/.symlinks index 59c61cda2..8a8e1251b 100644 --- a/include/.symlinks +++ b/include/.symlinks @@ -12,3 +12,4 @@ ../lib/mm/dbg_malloc.h ../lib/mm/pool.h ../lib/mm/xlate.h +../lib/uuid/uuid.h diff --git a/lib/Makefile.in b/lib/Makefile.in index cb4a08597..0fb07dbff 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -13,6 +13,7 @@ SOURCES=\ datastruct/hash.c \ device/dev-cache.c \ device/dev-io.c \ + device/device.c \ filters/filter.c \ format1/disk-rep.c \ format1/format1.c \ @@ -20,8 +21,10 @@ SOURCES=\ format1/layout.c \ format1/vg_number.c \ log/log.c \ + metadata/metadata.c \ mm/dbg_malloc.c \ - mm/pool.c + mm/pool.c \ + uuid/uuid.c TARGETS=liblvm.a diff --git a/lib/device/device.c b/lib/device/device.c index 12c5e2264..a410a17c7 100644 --- a/lib/device/device.c +++ b/lib/device/device.c @@ -38,6 +38,8 @@ #include #include + + #if 0 int _get_partition_type(struct dev_filter *filter, struct device *d); diff --git a/lib/device/device.h b/lib/device/device.h index 079c26ba5..7bf30d073 100644 --- a/lib/device/device.h +++ b/lib/device/device.h @@ -29,8 +29,10 @@ int64_t dev_read(struct device *dev, int64_t dev_write(struct device *dev, uint64_t offset, int64_t len, void *buffer); -/* FIXME: Alasdair lets add more query functions here for accessing - the partition information, this can then be used by your filter. */ + +static inline int is_lvm_partition(const char *name) { + return 1; +} #define LVM_DEFAULT_DIR_PREFIX "/dev/" /* FIXME Allow config file override */ diff --git a/lib/format1/format1.c b/lib/format1/format1.c index 858e3c70d..b72f7d6de 100644 --- a/lib/format1/format1.c +++ b/lib/format1/format1.c @@ -332,7 +332,6 @@ static int _pv_setup(struct io_space *is, struct physical_volume *pv, } pv->exported = NULL; - pv->status = ACTIVE; if (!dev_get_size(pv->dev, &pv->size)) { diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index e0c82a634..5981b305c 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -1,49 +1,51 @@ /* - * Copyright (C) 2001 Sistina Software + * Copyright (C) 2001 Sistina Software (UK) Limited. * - * This LVM library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This LVM library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this LVM library; if not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA + * This file is released under the GPL. */ -#include -#include "dbg_malloc.h" -#include "dev-cache.h" #include "log.h" +#include "pool.h" +#include "device.h" +#include "dev-cache.h" #include "metadata.h" -pv_t *pv_read(struct dev_mgr *dm, const char *pv_name) +#include + +struct physical_volume *pv_create(const char *name, struct io_space *ios) { - /* FIXME: Use config to select lvm_v1 format? Cache results? */ - /* Pass structure around rather than pv_name? */ + struct physical_volume *pv = pool_alloc(ios->mem, sizeof(*pv)); - log_very_verbose("Reading metadata from %s", pv_name); + if (!pv) { + stack; + return NULL; + } - return pv_read_lvm_v1(dm, pv_name); + id_create(&pv->id); + if (!(pv->dev = dev_cache_get(name, ios->filter))) { + log_err("Couldn't find device '%s'", name); + goto bad; + } + pv->vg_name = NULL; + pv->exported = NULL; + pv->status = 0; + + if (!dev_get_size(pv->dev, &pv->size)) { + log_err("Couldn't get size of device '%s'", name); + goto bad; + } + + pv->pe_size = 0; + pv->pe_start = 0; + pv->pe_count = 0; + pv->pe_allocated = 0; + return pv; + + bad: + pool_free(ios->mem, pv); + return NULL; } -pe_disk_t *pv_read_pe(const char *pv_name, const pv_t * pv) -{ - log_very_verbose("Reading PE metadata from %s", pv_name); - return pv_read_pe_lvm_v1(pv_name, pv); -} -lv_disk_t *pv_read_lvs(const pv_t *pv) -{ - log_very_verbose("Reading LV metadata from %s", pv->pv_name); - - return pv_read_lvs_lvm_v1(pv); -} diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index c31c80713..9ecf5515a 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Sistina Software + * Copyright (C) 2001 Sistina Software (UK) Limited. * * This file is released under the GPL. * @@ -13,8 +13,8 @@ #include #include "dev-cache.h" #include "list.h" +#include "uuid.h" -#define ID_LEN 32 #define NAME_LEN 128 /* Various flags */ @@ -43,14 +43,10 @@ #define IMPORTED_TAG "PV_IMP" /* Identifier of imported PV */ -struct id { - uint8_t uuid[ID_LEN]; -}; - struct physical_volume { struct id id; struct device *dev; - char *vg_name; /* VG component of name only - not full path */ + char *vg_name; char *exported; uint32_t status; @@ -71,7 +67,7 @@ struct pe_specifier { struct logical_volume { /* disk */ struct id id; - char *name; /* LV component of name only - not full path */ + char *name; uint32_t status; @@ -84,7 +80,7 @@ struct logical_volume { struct volume_group { struct id id; - char *name; /* VG component of name only - not full path */ + char *name; uint32_t status; @@ -194,6 +190,15 @@ struct io_space { void *private; }; +/* + * Utility functions + */ +struct physical_volume *pv_create(const char *name, struct io_space *ios); + + + + + /* FIXME: Move to other files */ struct io_space *create_text_format(struct dev_filter *filter, @@ -203,7 +208,6 @@ int id_eq(struct id *op1, struct id *op2); /* Create consistent new empty structures, populated with defaults */ struct volume_group *vg_create(); -struct physical_volume *pv_create(); int vg_destroy(struct volume_group *vg); diff --git a/lib/mm/pool.c b/lib/mm/pool.c index 11680c57e..34d68cb8f 100644 --- a/lib/mm/pool.c +++ b/lib/mm/pool.c @@ -91,6 +91,11 @@ void *pool_alloc_aligned(struct pool *p, size_t s, unsigned alignment) return r; } +void pool_empty(struct pool *p) +{ + pool_free(p, p->chunk->begin); +} + void pool_free(struct pool *p, void *ptr) { struct chunk *c = p->chunk; diff --git a/lib/mm/pool.h b/lib/mm/pool.h index e77c8b598..1bfaf8e0c 100644 --- a/lib/mm/pool.h +++ b/lib/mm/pool.h @@ -18,6 +18,7 @@ void pool_destroy(struct pool *p); /* simple allocation/free routines */ void *pool_alloc(struct pool *p, size_t s); void *pool_alloc_aligned(struct pool *p, size_t s, unsigned alignment); +void pool_empty(struct pool *p); void pool_free(struct pool *p, void *ptr); /* object building routines */ diff --git a/lib/uuid/uuid.c b/lib/uuid/uuid.c new file mode 100644 index 000000000..a96b5ad67 --- /dev/null +++ b/lib/uuid/uuid.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#include "uuid.h" +#include "log.h" + +#include +#include +#include +#include + +static unsigned char _c[] = + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +int id_create(struct id *id) +{ + int random, i, len = sizeof(id->uuid); + + memset(id->uuid, 0, len); + if ((random = open("/dev/urandom", O_RDONLY)) < 0) { + log_sys_error("open", "id_create"); + return 0; + } + + if (read(random, id->uuid, len) != len) { + log_sys_error("read", "id_create"); + return 0; + } + close(random); + + for (i = 0; i < len; i++) + id->uuid[i] = _c[id->uuid[i] % (sizeof(_c) - 1)]; + + return 1; +} + +int id_valid(struct id *id) +{ + log_err("Joe hasn't written id_valid yet"); + return 1; +} + +int id_cmp(struct id *lhs, struct id *rhs) +{ + return memcmp(lhs->uuid, rhs->uuid, sizeof(lhs->uuid)); +} diff --git a/lib/uuid/uuid.h b/lib/uuid/uuid.h new file mode 100644 index 000000000..15de1b7de --- /dev/null +++ b/lib/uuid/uuid.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the GPL. + */ + +#ifndef _LVM_UUID_H +#define _LVM_UUID_H + +#include "lvm-types.h" + +#define ID_LEN 32 + +struct id { + uint8_t uuid[ID_LEN]; +}; + +int id_create(struct id *id); +int id_valid(struct id *id); +int id_cmp(struct id *lhs, struct id *rhs); + +#endif diff --git a/tools/Makefile.in b/tools/Makefile.in index 1c75460d6..40a359959 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -21,13 +21,14 @@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ SOURCES=\ - lvm.c\ - lvmchange.c\ - toollib.c\ - vgck.c\ - vgreduce.c\ - vgrename.c\ - vgremove.c\ + lvm.c \ + lvmchange.c \ + pvcreate.c \ + toollib.c \ + vgck.c \ + vgreduce.c \ + vgrename.c \ + vgremove.c \ vgscan.c TARGETS=\ diff --git a/tools/lvm.c b/tools/lvm.c index 00d6245fd..e439ce2f1 100644 --- a/tools/lvm.c +++ b/tools/lvm.c @@ -1,20 +1,7 @@ /* - * Copyright (C) 2001 Sistina Software + * Copyright (C) 2001 Sistina Software (UK) Limited. * - * LVM is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * LVM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU CC; see the file COPYING. If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * This file is released under the GPL. */ #include "tools.h" @@ -25,6 +12,7 @@ #include #include #include +#include #include "stub.h" @@ -224,7 +212,7 @@ int permission_arg(struct arg *a) return 1; } -char yes_no_prompt(char *prompt, ...) +char yes_no_prompt(const char *prompt, ...) { int c = 0; va_list ap; @@ -237,7 +225,10 @@ char yes_no_prompt(char *prompt, ...) } c = tolower(getchar()); } - while (getchar() != '\n') ; + + while (getchar() != '\n') + ; + return c; } diff --git a/tools/pvcreate.c b/tools/pvcreate.c index 77ad78b22..deccb2903 100644 --- a/tools/pvcreate.c +++ b/tools/pvcreate.c @@ -1,30 +1,99 @@ /* - * Copyright (C) 2001 Sistina Software - * - * LVM is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * LVM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LVM; see the file COPYING. If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Copyright (C) 2001 Sistina Software (UK) Limited. * + * This file is released under the GPL. */ #include "tools.h" -void pvcreate_single(const char *pv_name); +const char _really_init[] = + "Really INITIALIZE physical volume %s of volume group %s [y/n]? "; + +/* + * See if we may pvcreate on this device. + * 0 indicates we may not. + */ +static int _check(const char *name) +{ + struct physical_volume *pv; + + /* is the partition type set correctly ? */ + if ((arg_count(force_ARG) < 1) && !is_lvm_partition(name)) + return 0; + + /* is there a pv here already */ + if (!(pv = ios->pv_read(ios, name))) + return 1; + + /* orphan ? */ + if (!pv->vg_name[0]) + return 1; + + /* never overwrite exported pv's */ + if (pv->status & EXPORTED_VG) { + log_error("Physical volume %s belongs to exported volume" + " group %s", name, pv->vg_name); + return 0; + } + + /* we must have -ff to overwrite a non orphan */ + if (arg_count(force_ARG) < 2) { + log_error("Can't initialize physical volume %s of " + "volume group %s without -ff", name, pv->vg_name); + return 0; + } + + /* prompt */ + if (!arg_count(yes_ARG) && + yes_no_prompt(_really_init, name, pv->vg_name) == 'n') { + log_print("physical volume %s not initialized", name); + return 0; + } + + if (pv->status & ACTIVE) { + log_error("Can't create on active physical volume %s", name); + return 0; + } + + return 1; +} + +void _single(const char *name) +{ + struct physical_volume *pv; + + if (!_check(name)) + return; + + if (arg_count(force_ARG)) { + log_print("WARNING: forcing physical volume creation on %s", + name); + + if (pv->vg_name[0]) + log_print(" of volume group %s", pv->vg_name); + printf("\n"); + } + + if (!(pv = pv_create(name, ios))) { + log_err("Failed to setup physical volume %s", name); + return; + } + log_verbose("set up physical volume for %s with %llu sectors", + name, pv->size); + + + log_verbose("writing physical volume data to disk %s", name); + if (!(ios->pv_write(ios, pv))) { + log_error("Failed to write physical volume %s", name); + return; + } + + log_print("physical volume %s successfully created", name); +} int pvcreate(int argc, char **argv) { - int opt; + int i; if (!argc) { log_error("Please enter a physical volume path"); @@ -32,100 +101,14 @@ int pvcreate(int argc, char **argv) } if (arg_count(yes_ARG) && !arg_count(force_ARG)) { - log_error("Option y can only be used with option f"); + log_error("option y can only be given with option f"); return EINVALID_CMD_LINE; } - for (opt = 0; opt < argc; opt++) - pvcreate_single(argv[opt]); + for (i = 0; i < argc; i++) { + _single(argv[i]); + pool_empty(ios->mem); + } return 0; } - -void pvcreate_single(const char *pv_name) -{ - int size; - struct physical_volume *pv = NULL; - - struct device *pv_dev; - - if (!(pv_dev = dev_cache_get(pv_name))) { - log_error("Device %s not found", pv_name); - return; - } - - if ((size = dev_get_size(pv_dev)) < 0) { - log_error("Unable to get size of %s", pv_name); - return; - } - - if (arg_count(force_ARG) < 1 && !partition_type_is_lvm(ios, pv_dev)) { - return; - } - - pv = ios->pv_read(ios, pv_dev); - - if (pv && (pv->status & STATUS_EXPORTED)) { - log_error("Physical volume %s belongs to exported volume" - " group %s", pv_name, pv->vg_name); - return; - } - - if (pv && pv->vg_name[0]) { - if (arg_count(force_ARG) < 2) { - log_error("Can't initialize physical volume %s of " - "volume group %s without -ff", pv_name, - pv->vg_name); - return; - } - if (!arg_count(yes_ARG)) { - if (yes_no_prompt - ("Really INITIALIZE physical volume %s" - " of volume group %s [y/n]? ", pv_name, - pv->vg_name) == 'n') { - log_print("Physical volume %s not initialized", - pv_name); - return; - } - } - - } - - if (pv && (pv->status & ACTIVE)) { - log_error("Can't create on active physical volume %s", pv_name); - return; - } - - if (!pv) { - if (!(pv = pv_create())) - return; - /* FIXME: Set up initial size & PEs here */ - } - - if (arg_count(force_ARG)) { - /* FIXME: Change to log_print */ - printf("Warning: Forcing physical volume creation on %s", - pv_name); - if (pv->vg_name[0]) - printf(" of volume group %s", pv->vg_name); - printf("\n"); - } - - /* FIXME: If PV is in VG, remove it. NoOp? Or cache? */ - - log_verbose("Creating new physical volume"); - log_verbose("Setting up physical volume for %s with %u sectors", - pv_name, size); - - log_verbose("Writing physical volume data to disk %s", pv_name); - - if (!(pv_write(ios, pv))) { - log_error("Failed to create physical volume %s", pv_name); - return; - } - - log_print("Physical volume %s successfully created", pv_name); - -/* FIXME: Add the dbg_frees throughout! */ - return; -} diff --git a/tools/stub.h b/tools/stub.h index 933281221..906fdf068 100644 --- a/tools/stub.h +++ b/tools/stub.h @@ -30,7 +30,6 @@ int lvreduce(int argc, char **argv) {return 1;} int lvremove(int argc, char **argv) {return 1;} int lvrename(int argc, char **argv) {return 1;} int lvscan(int argc, char **argv) {return 1;} -int pvcreate(int argc, char **argv) {return 1;} int pvchange(int argc, char **argv) {return 1;} int pvdisplay(int argc, char **argv) {return 1;} int pvdata(int argc, char **argv) {return 1;} diff --git a/tools/tools.h b/tools/tools.h index 684b57e1b..971bb34b4 100644 --- a/tools/tools.h +++ b/tools/tools.h @@ -79,7 +79,7 @@ int int_arg(struct arg *a); int string_arg(struct arg *a); int permission_arg(struct arg *a); -char yes_no_prompt(char *prompt, ...); +char yes_no_prompt(const char *prompt, ...); /* we use the enums to access the switches */ static inline int arg_count(int a) {