../lib/mm/dbg_malloc.h
../lib/mm/pool.h
../lib/mm/xlate.h
+../lib/uuid/uuid.h
datastruct/hash.c \
device/dev-cache.c \
device/dev-io.c \
+ device/device.c \
filters/filter.c \
format1/disk-rep.c \
format1/format1.c \
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
#include <linux/major.h>
#include <linux/genhd.h>
+
+
#if 0
int _get_partition_type(struct dev_filter *filter, struct device *d);
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 */
}
pv->exported = NULL;
-
pv->status = ACTIVE;
if (!dev_get_size(pv->dev, &pv->size)) {
/*
- * 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 <string.h>
-#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)
-{
- /* FIXME: Use config to select lvm_v1 format? Cache results? */
- /* Pass structure around rather than pv_name? */
-
- log_very_verbose("Reading metadata from %s", pv_name);
-
- return pv_read_lvm_v1(dm, pv_name);
-
-}
+#include <string.h>
-pe_disk_t *pv_read_pe(const char *pv_name, const pv_t * pv)
+struct physical_volume *pv_create(const char *name, struct io_space *ios)
{
- log_very_verbose("Reading PE metadata from %s", pv_name);
-
- return pv_read_pe_lvm_v1(pv_name, pv);
+ struct physical_volume *pv = pool_alloc(ios->mem, sizeof(*pv));
+
+ if (!pv) {
+ stack;
+ return NULL;
+ }
+
+ 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;
}
-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);
-}
+
/*
- * Copyright (C) 2001 Sistina Software
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
*
#include <sys/types.h>
#include "dev-cache.h"
#include "list.h"
+#include "uuid.h"
-#define ID_LEN 32
#define NAME_LEN 128
/* Various flags */
#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;
struct logical_volume {
/* disk */
struct id id;
- char *name; /* LV component of name only - not full path */
+ char *name;
uint32_t status;
struct volume_group {
struct id id;
- char *name; /* VG component of name only - not full path */
+ char *name;
uint32_t status;
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,
/* 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);
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;
/* 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 */
--- /dev/null
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+ *
+ * This file is released under the GPL.
+ */
+
+#include "uuid.h"
+#include "log.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+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));
+}
--- /dev/null
+/*
+ * 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
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=\
/*
- * 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"
#include <syslog.h>
#include <libgen.h>
#include <sys/stat.h>
+#include <ctype.h>
#include "stub.h"
return 1;
}
-char yes_no_prompt(char *prompt, ...)
+char yes_no_prompt(const char *prompt, ...)
{
int c = 0;
va_list ap;
}
c = tolower(getchar());
}
- while (getchar() != '\n') ;
+
+ while (getchar() != '\n')
+ ;
+
return c;
}
/*
- * 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]? ";
-int pvcreate(int argc, char **argv)
+/*
+ * See if we may pvcreate on this device.
+ * 0 indicates we may not.
+ */
+static int _check(const char *name)
{
- int opt;
-
- if (!argc) {
- log_error("Please enter a physical volume path");
- return EINVALID_CMD_LINE;
- }
-
- if (arg_count(yes_ARG) && !arg_count(force_ARG)) {
- log_error("Option y can only be used with option f");
- return EINVALID_CMD_LINE;
- }
+ struct physical_volume *pv;
- for (opt = 0; opt < argc; opt++)
- pvcreate_single(argv[opt]);
+ /* is the partition type set correctly ? */
+ if ((arg_count(force_ARG) < 1) && !is_lvm_partition(name))
+ return 0;
- return 0;
-}
+ /* is there a pv here already */
+ if (!(pv = ios->pv_read(ios, name)))
+ return 1;
-void pvcreate_single(const char *pv_name)
-{
- int size;
- struct physical_volume *pv = NULL;
+ /* orphan ? */
+ if (!pv->vg_name[0])
+ return 1;
- struct device *pv_dev;
+ /* 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;
+ }
- if (!(pv_dev = dev_cache_get(pv_name))) {
- log_error("Device %s not found", pv_name);
- return;
+ /* 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;
}
- if ((size = dev_get_size(pv_dev)) < 0) {
- log_error("Unable to get size of %s", pv_name);
- return;
+ /* 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 (arg_count(force_ARG) < 1 && !partition_type_is_lvm(ios, pv_dev)) {
- return;
+ if (pv->status & ACTIVE) {
+ log_error("Can't create on active physical volume %s", name);
+ return 0;
}
- pv = ios->pv_read(ios, pv_dev);
+ return 1;
+}
+
+void _single(const char *name)
+{
+ struct physical_volume *pv;
- if (pv && (pv->status & STATUS_EXPORTED)) {
- log_error("Physical volume %s belongs to exported volume"
- " group %s", pv_name, pv->vg_name);
+ if (!_check(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 (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->status & ACTIVE)) {
- log_error("Can't create on active physical volume %s", pv_name);
+ 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);
- 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");
+ 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;
}
- /* FIXME: If PV is in VG, remove it. NoOp? Or cache? */
+ log_print("physical volume %s successfully created", name);
+}
- log_verbose("Creating new physical volume");
- log_verbose("Setting up physical volume for %s with %u sectors",
- pv_name, size);
+int pvcreate(int argc, char **argv)
+{
+ int i;
- log_verbose("Writing physical volume data to disk %s", pv_name);
+ if (!argc) {
+ log_error("Please enter a physical volume path");
+ return EINVALID_CMD_LINE;
+ }
- if (!(pv_write(ios, pv))) {
- log_error("Failed to create physical volume %s", pv_name);
- return;
+ if (arg_count(yes_ARG) && !arg_count(force_ARG)) {
+ log_error("option y can only be given with option f");
+ return EINVALID_CMD_LINE;
}
- log_print("Physical volume %s successfully created", pv_name);
+ for (i = 0; i < argc; i++) {
+ _single(argv[i]);
+ pool_empty(ios->mem);
+ }
-/* FIXME: Add the dbg_frees throughout! */
- return;
+ return 0;
}
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;}
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) {