mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-02 01:18:26 +03:00
o vgremove.
o filter devices by major.
This commit is contained in:
parent
e15559aa3c
commit
0dc2a4d6e4
2
configure
vendored
2
configure
vendored
@ -556,7 +556,7 @@ ac_config_sub=$ac_aux_dir/config.sub
|
||||
ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
|
||||
|
||||
|
||||
for ac_prog in mawk gawk nawk awk
|
||||
for ac_prog in gawk mawk nawk awk
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
|
@ -13,6 +13,7 @@ SOURCES=\
|
||||
datastruct/hash.c \
|
||||
device/dev-cache.c \
|
||||
device/dev-io.c \
|
||||
filters/filter.c \
|
||||
format1/disk-rep.c \
|
||||
format1/format1.c \
|
||||
format1/import-export.c \
|
||||
|
@ -23,31 +23,131 @@
|
||||
#include "dev-cache.h"
|
||||
#include "filter.h"
|
||||
|
||||
static int passes_config_device_filter (struct dev_cache_filter *f,
|
||||
struct device *dev)
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <linux/kdev_t.h>
|
||||
|
||||
#define NUMBER_OF_MAJORS 256
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int max_partitions;
|
||||
} device_info_t;
|
||||
|
||||
static device_info_t device_info[] = {
|
||||
{"ide", 16}, /* IDE disk */
|
||||
{"sd", 16}, /* SCSI disk */
|
||||
{"md", 16}, /* Multiple Disk driver (SoftRAID) */
|
||||
{"loop", 16}, /* Loop device */
|
||||
{"dasd", 4}, /* DASD disk (IBM S/390, zSeries) */
|
||||
{"dac960", 8}, /* DAC960 */
|
||||
{"nbd", 16}, /* Network Block Device */
|
||||
{"ida", 16}, /* Compaq SMART2 */
|
||||
{"cciss", 16}, /* Compaq CCISS array */
|
||||
{"ubd", 16}, /* User-mode virtual block device */
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static int *scan_proc_dev(void);
|
||||
|
||||
static int passes_config_device_filter(struct dev_filter *f, struct device *dev)
|
||||
{
|
||||
/* FIXME Check against config file scan/reject entries */
|
||||
return 1;
|
||||
|
||||
/* Is this a recognised device type? */
|
||||
if (!(((int *) f->private)[MAJOR(dev->dev)]))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct dev_filter *config_filter_create()
|
||||
{
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!(f = dbg_malloc(sizeof(struct dev_filter)))) {
|
||||
if (!(f = dbg_malloc(sizeof (struct dev_filter)))) {
|
||||
log_error("lvm_v1_filter allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f->is_available = &passes_config_device_filter();
|
||||
f->passes_filter = passes_config_device_filter;
|
||||
|
||||
if (!(f->private = scan_proc_dev()))
|
||||
return NULL;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
void config_filter_destroy(struct dev_filter *f)
|
||||
{
|
||||
dbg_free(f);
|
||||
return;
|
||||
}
|
||||
|
||||
static int *scan_proc_dev(void)
|
||||
{
|
||||
char line[80];
|
||||
FILE *procdevices = NULL;
|
||||
int ret = 0;
|
||||
int i, j = 0;
|
||||
int line_maj = 0;
|
||||
int blocksection = 0;
|
||||
int dev_len = 0;
|
||||
|
||||
int *max_partitions_by_major;
|
||||
|
||||
if (!(max_partitions_by_major = dbg_malloc(sizeof (int) * NUMBER_OF_MAJORS))) {
|
||||
log_error("Filter failed to allocate max_partitions_by_major");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(procdevices = fopen("/proc/devices", "r"))) {
|
||||
log_error("Failed to open /proc/devices: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(max_partitions_by_major, 0, sizeof (int) * NUMBER_OF_MAJORS);
|
||||
while (fgets(line, 80, procdevices) != NULL) {
|
||||
i = 0;
|
||||
while (line[i] == ' ' && line[i] != '\0')
|
||||
i++;
|
||||
|
||||
/* If it's not a number it may be name of section */
|
||||
line_maj = atoi(((char *) (line + i)));
|
||||
if (!line_maj) {
|
||||
blocksection = (line[i] == 'B') ? 1 : 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We only want block devices ... */
|
||||
if (!blocksection)
|
||||
continue;
|
||||
|
||||
/* Find the start of the device major name */
|
||||
while (line[i] != ' ' && line[i] != '\0')
|
||||
i++;
|
||||
while (line[i] == ' ' && line[i] != '\0')
|
||||
i++;
|
||||
|
||||
/* Go through the valid device names and if there is a
|
||||
match store max number of partitions */
|
||||
for (j = 0; device_info[j].name != NULL; j++) {
|
||||
|
||||
dev_len = strlen(device_info[j].name);
|
||||
if (dev_len <= strlen(line + i)
|
||||
&& !strncmp(device_info[j].name, line + i, dev_len)
|
||||
&& (line_maj < NUMBER_OF_MAJORS)) {
|
||||
max_partitions_by_major[line_maj] =
|
||||
device_info[j].max_partitions;
|
||||
ret++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(procdevices);
|
||||
return max_partitions_by_major;
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ int import_pv(struct pool *mem, struct device *dev,
|
||||
pv->status |= ACTIVE;
|
||||
|
||||
if (pvd->pv_allocatable)
|
||||
pv->status |= ALLOCATABLE;
|
||||
pv->status |= ALLOCATED_PV;
|
||||
|
||||
pv->size = pvd->pv_size;
|
||||
pv->pe_size = pvd->pe_size;
|
||||
@ -131,8 +131,8 @@ int export_pv(struct pv_disk *pvd, struct physical_volume *pv)
|
||||
if (pv->status & ACTIVE)
|
||||
pvd->pv_status |= PV_ACTIVE;
|
||||
|
||||
if (pv->status & ALLOCATABLE)
|
||||
pvd->pv_allocatable = PV_ALLOCATABLE;
|
||||
if (pv->status & ALLOCATED_PV)
|
||||
pvd->pv_allocatable = ALLOCATED_PV;
|
||||
|
||||
pvd->pv_size = pv->size;
|
||||
pvd->lv_cur = 0; /* this is set when exporting the lv list */
|
||||
|
@ -23,7 +23,7 @@
|
||||
#define ACTIVE 0x00000001 /* PV VG LV */
|
||||
#define EXPORTED_VG 0x00000002 /* VG */ /* And PV too perhaps? */
|
||||
#define EXTENDABLE_VG 0x00000004 /* VG */
|
||||
#define ALLOCATABLE 0x00000008 /* PV */
|
||||
#define ALLOCATED_PV 0x00000008 /* PV */
|
||||
|
||||
#define SPINDOWN_LV 0x00000010 /* LV */
|
||||
#define BADBLOCK_ON 0x00000020 /* LV */
|
||||
@ -125,14 +125,12 @@ struct io_space {
|
||||
component only, not full path*/
|
||||
struct list_head *(*get_vgs)(struct io_space *is);
|
||||
|
||||
/* Returns list of fully-populated pv_list
|
||||
structures */
|
||||
/* Returns list of fully-populated pv structures */
|
||||
struct list_head *(*get_pvs)(struct io_space *is);
|
||||
|
||||
/* Return PV with given name (may be full
|
||||
or relative path) */
|
||||
/* Return PV with given name (may be full or relative path) */
|
||||
struct physical_volume *(*pv_read)(struct io_space *is,
|
||||
const char *name);
|
||||
const char *pv_name);
|
||||
|
||||
/* Write a PV structure to disk. */
|
||||
/* Fails if the PV is in a VG ie
|
||||
|
@ -25,7 +25,8 @@ SOURCES=\
|
||||
lvmchange.c\
|
||||
toollib.c\
|
||||
vgck.c\
|
||||
vgrename.c
|
||||
vgrename.c\
|
||||
vgremove.c
|
||||
|
||||
TARGETS=\
|
||||
lvm
|
||||
|
@ -24,7 +24,6 @@ int lvactivate(int argc, char **argv)
|
||||
{
|
||||
int p;
|
||||
|
||||
struct io_space *ios;
|
||||
struct device *pv_dev;
|
||||
|
||||
char *lv_name;
|
||||
@ -42,8 +41,6 @@ int lvactivate(int argc, char **argv)
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
ios = active_ios();
|
||||
|
||||
while (argc--) {
|
||||
pv_name = argv[argc];
|
||||
if (!(pv_dev = dev_cache_get(pv_name))) {
|
||||
|
@ -609,7 +609,7 @@ static int init(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!dev_cache_add_dir(prefix)) {
|
||||
if (!dev_cache_add_dir("/dev")) {
|
||||
log_error("Failed to add %s to internal device cache", prefix);
|
||||
goto out;
|
||||
}
|
||||
|
@ -50,11 +50,9 @@ int lvremove_single(char *lv_name)
|
||||
char *vg_name = NULL;
|
||||
char buffer[NAME_LEN];
|
||||
|
||||
struct io_space *ios;
|
||||
struct volume_group *vg;
|
||||
struct logical_volume *lv;
|
||||
|
||||
ios = active_ios();
|
||||
|
||||
lv_name = lvm_check_default_vg_name(lv_name, buffer, sizeof (buffer));
|
||||
/* does VG exist? */
|
||||
@ -84,12 +82,14 @@ int lvremove_single(char *lv_name)
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
/********** FIXME Ensure logical volume is not open on *any* machine
|
||||
if (lv->open) {
|
||||
log_error("can't remove open %s logical volume %s",
|
||||
lv->status & SNAPSHOT ? "snapshot" : "",
|
||||
lv_name);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
************/
|
||||
|
||||
if (!arg_count(force_ARG)) {
|
||||
if (yes_no_prompt
|
||||
|
@ -37,7 +37,6 @@ int pvchange(int argc, char **argv)
|
||||
char *pv_name;
|
||||
char *vg_name;
|
||||
|
||||
struct io_space *ios;
|
||||
struct physical_volume *pv = NULL;
|
||||
struct volume_group *vg = NULL;
|
||||
struct device *pv_dev;
|
||||
@ -51,8 +50,6 @@ int pvchange(int argc, char **argv)
|
||||
return EINVALID_CMD_LINE;
|
||||
}
|
||||
|
||||
ios = active_ios();
|
||||
|
||||
if (!(arg_count(all_ARG)) && !argc) {
|
||||
log_error("Please give a physical volume path");
|
||||
return EINVALID_CMD_LINE;
|
||||
|
@ -47,11 +47,8 @@ void pvcreate_single(const char *pv_name)
|
||||
int size;
|
||||
struct physical_volume *pv = NULL;
|
||||
|
||||
struct io_space *ios;
|
||||
struct device *pv_dev;
|
||||
|
||||
ios = active_ios();
|
||||
|
||||
if (!(pv_dev = dev_cache_get(pv_name))) {
|
||||
log_error("Device %s not found", pv_name);
|
||||
return;
|
||||
|
@ -31,7 +31,6 @@ int pvscan(int argc, char **argv)
|
||||
int pvs_found = 0;
|
||||
char *s1, *s2, *s3;
|
||||
|
||||
struct io_space *ios;
|
||||
struct pv_list *pvs_list, *pvl;
|
||||
struct list_head *pvh;
|
||||
struct physical_volume *pv;
|
||||
@ -56,8 +55,6 @@ int pvscan(int argc, char **argv)
|
||||
|
||||
log_verbose("Walking through all physical volumes");
|
||||
|
||||
ios = active_ios();
|
||||
|
||||
if (!(pvs_list = ios->get_pvs(ios)))
|
||||
return ECMD_FAILED;
|
||||
|
||||
|
@ -46,7 +46,6 @@ int vgimport(int argc, char **argv) {return 1;}
|
||||
int vgmerge(int argc, char **argv) {return 1;}
|
||||
int vgmknodes(int argc, char **argv) {return 1;}
|
||||
int vgreduce(int argc, char **argv) {return 1;}
|
||||
int vgremove(int argc, char **argv) {return 1;}
|
||||
int vgscan(int argc, char **argv) {return 1;}
|
||||
int vgsplit(int argc, char **argv) {return 1;}
|
||||
|
||||
|
@ -95,7 +95,7 @@ int process_each_vg(int argc, char **argv,
|
||||
int ret = 0;
|
||||
|
||||
struct list_head *vgh;
|
||||
struct name_list *vgs_list;
|
||||
struct list_head *vgs_list;
|
||||
|
||||
if (argc) {
|
||||
log_verbose("Using volume group(s) on command line");
|
||||
@ -108,7 +108,7 @@ int process_each_vg(int argc, char **argv,
|
||||
log_error("No volume groups found");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
list_for_each(vgh, &vgs_list->list) {
|
||||
list_for_each(vgh, vgs_list) {
|
||||
ret =
|
||||
process_single(list_entry
|
||||
(vgh, struct name_list, list)->name);
|
||||
|
@ -17,8 +17,8 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _LVM_TOOLS_H
|
||||
#define _LVM_TOOLS_H
|
||||
#ifndef _LVM_LVM_H
|
||||
#define _LVM_LVM_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -48,10 +48,6 @@ int vgcreate(int argc, char **argv)
|
||||
char *pv_name = NULL;
|
||||
char **vg_name_ptr = NULL;
|
||||
|
||||
struct io_space *ios;
|
||||
|
||||
ios = active_ios();
|
||||
|
||||
if (arg_count(maxlogicalvolumes_ARG))
|
||||
max_lv = arg_int_value(maxlogicalvolumes_ARG, 0);
|
||||
|
||||
|
76
tools/vgremove.c
Normal file
76
tools/vgremove.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Sistina Software
|
||||
*
|
||||
* vgremove 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.
|
||||
*
|
||||
* vgremove 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tools.h"
|
||||
|
||||
static int vgremove_single(const char *vg_name);
|
||||
|
||||
int vgremove(int argc, char **argv)
|
||||
{
|
||||
return process_each_vg(argc, argv, &vgremove_single);
|
||||
}
|
||||
|
||||
static int vgremove_single(const char *vg_name)
|
||||
{
|
||||
struct volume_group *vg;
|
||||
struct physical_volume *pv;
|
||||
struct list_head *pvh;
|
||||
|
||||
log_verbose("Checking for volume group %s", vg_name);
|
||||
if (!(vg = ios->vg_read(ios, vg_name))) {
|
||||
log_error("Volume group %s doesn't exist", vg_name);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
|
||||
if (vg->status & ACTIVE) {
|
||||
log_error("Volume group %s is still active", vg_name);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (vg->lv_count) {
|
||||
log_error("Volume group %s still contains %d logical volume(s)",
|
||||
vg_name, vg->lv_count);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
/************ FIXME
|
||||
if (vg_remove_dir_and_group_and_nodes(vg_name) < 0) {
|
||||
log_error("removing special files of volume group %s",
|
||||
vg_name);
|
||||
}
|
||||
*************/
|
||||
|
||||
|
||||
/* init physical volumes */
|
||||
list_for_each(pvh, &vg->pvs) {
|
||||
pv = &list_entry(pvh, struct pv_list, list)->pv;
|
||||
log_verbose("Removing physical volume %s from volume group %s",
|
||||
pv->dev->name, vg_name);
|
||||
pv->vg_name = '\0';
|
||||
if (!(ios->pv_write(ios, pv)))
|
||||
log_error("Failed to remove physical volume %s from "
|
||||
"volume group %s", pv->dev->name, vg_name);
|
||||
}
|
||||
|
||||
log_print("Volume group %s successfully removed", vg_name);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user