1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

Refuse to run pvcreate/pvremove on devices we can't open exclusively.

This commit is contained in:
Alasdair Kergon 2005-10-03 21:10:41 +00:00
parent 9c9e30cd6d
commit 9b02bdbce0
5 changed files with 61 additions and 9 deletions

View File

@ -1,5 +1,6 @@
Version 2.01.15 -
=================================
Refuse to run pvcreate/pvremove on devices we can't open exclusively.
Use ORPHAN lock definition throughout.
Validate chunksize in lvcreate.
Reduce chunksize limit to 512k.

View File

@ -320,15 +320,22 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
{
struct stat buf;
const char *name;
int need_excl = 0, need_rw = 0;
if ((flags & O_ACCMODE) == O_RDWR)
need_rw = 1;
if ((flags & O_EXCL))
need_excl = 1;
if (dev->fd >= 0) {
if ((dev->flags & DEV_OPENED_RW) ||
((flags & O_ACCMODE) != O_RDWR)) {
if (((dev->flags & DEV_OPENED_RW) || !need_rw) &&
((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
dev->open_count++;
return 1;
}
if (dev->open_count) {
if (dev->open_count && !need_excl) {
/* FIXME Ensure we never get here */
log_debug("WARNING: %s already opened read-only",
dev_name(dev));
@ -397,11 +404,16 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
dev->open_count++;
dev->flags &= ~DEV_ACCESSED_W;
if ((flags & O_ACCMODE) == O_RDWR)
if (need_rw)
dev->flags |= DEV_OPENED_RW;
else
dev->flags &= ~DEV_OPENED_RW;
if (need_excl)
dev->flags |= DEV_OPENED_EXCL;
else
dev->flags &= ~DEV_OPENED_EXCL;
if (!(dev->flags & DEV_REGULAR) &&
((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev))) {
log_error("%s: fstat failed: Has device name changed?", name);
@ -420,8 +432,9 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
list_add(&_open_devices, &dev->open_list);
log_debug("Opened %s %s%s", dev_name(dev),
log_debug("Opened %s %s%s%s", dev_name(dev),
dev->flags & DEV_OPENED_RW ? "RW" : "RO",
dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
return 1;
@ -445,6 +458,21 @@ int dev_open(struct device *dev)
return dev_open_flags(dev, flags, 1, 0);
}
int dev_test_excl(struct device *dev)
{
int flags;
int r;
flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
flags |= O_EXCL;
r = dev_open_flags(dev, flags, 1, 1);
if (r)
dev_close_immediate(dev);
return r;
}
static void _close(struct device *dev)
{
if (close(dev->fd))
@ -479,6 +507,11 @@ static int _dev_close(struct device *dev, int immediate)
if (dev->open_count > 0)
dev->open_count--;
if (immediate && dev->open_count) {
log_debug("%s: Immediate close attempt while still referenced");
dev->open_count = 0;
}
/* FIXME lookup device in cache to get vgname and see if it's locked? */
if (immediate || (dev->open_count < 1 && !vgs_locked()))
_close(dev);

View File

@ -23,8 +23,9 @@
#define DEV_REGULAR 0x00000002 /* Regular file? */
#define DEV_ALLOCED 0x00000004 /* dbg_malloc used */
#define DEV_OPENED_RW 0x00000008 /* Opened RW */
#define DEV_O_DIRECT 0x00000010 /* Use O_DIRECT */
#define DEV_O_DIRECT_TESTED 0x00000020 /* DEV_O_DIRECT is reliable */
#define DEV_OPENED_EXCL 0x00000010 /* Opened EXCL */
#define DEV_O_DIRECT 0x00000020 /* Use O_DIRECT */
#define DEV_O_DIRECT_TESTED 0x00000040 /* DEV_O_DIRECT is reliable */
/*
* All devices in LVM will be represented by one of these.
@ -70,6 +71,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet);
int dev_close(struct device *dev);
int dev_close_immediate(struct device *dev);
void dev_close_all(void);
int dev_test_excl(struct device *dev);
static inline int dev_fd(struct device *dev)
{

View File

@ -82,6 +82,12 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
return 0;
}
if (!dev_test_excl(dev)) {
log_error("Can't open %s exclusively. Mounted filesystem?",
name);
return 0;
}
/* Wipe superblock? */
if (dev_is_md(dev, &md_superblock) &&
((!arg_count(cmd, uuidstr_ARG) &&
@ -219,7 +225,11 @@ static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
goto error;
}
dev_zero(dev, UINT64_C(0), (size_t) 2048);
if (!dev_zero(dev, UINT64_C(0), (size_t) 2048)) {
log_error("%s not wiped: aborting", pv_name);
dev_close(dev);
goto error;
}
dev_close(dev);
}

View File

@ -86,6 +86,12 @@ static int pvremove_single(struct cmd_context *cmd, const char *pv_name,
goto error;
}
if (!dev_test_excl(dev)) {
log_error("Can't open %s exclusively. Mounted filesystem?",
dev_name(dev));
return 0;
}
/* Wipe existing label(s) */
if (!label_remove(dev)) {
log_error("Failed to wipe existing label(s) on %s", pv_name);