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

Scan all devices for lvmetad if 'pvscan --cache' used without device list.

This commit is contained in:
Alasdair Kergon 2012-03-03 18:32:53 +00:00
parent 59a5361fc4
commit 35216ca66c
7 changed files with 126 additions and 71 deletions

View File

@ -1,5 +1,8 @@
Version 2.02.95 -
================================
Scan all devices for lvmetad if 'pvscan --cache' used without device list.
Populate lvmcache from lvmetad before displaying PVs in pvscan. (2.02.94)
Suppress incorrect -n pvscan warning now always displayed. (2.02.94)
Version 2.02.94 - 3rd March 2012
================================

52
lib/cache/lvmetad.c vendored
View File

@ -607,7 +607,7 @@ int lvmetad_pv_found(struct id pvid, struct device *device, const struct format_
return result;
}
static int _lvmetad_pv_gone(dev_t device, const char *pv_name)
int lvmetad_pv_gone(dev_t device, const char *pv_name)
{
int result;
int found;
@ -625,9 +625,9 @@ static int _lvmetad_pv_gone(dev_t device, const char *pv_name)
return result;
}
int lvmetad_pv_gone(struct device *dev)
int lvmetad_pv_gone_by_dev(struct device *dev)
{
return _lvmetad_pv_gone(dev->dev, dev_name(dev));
return lvmetad_pv_gone(dev->dev, dev_name(dev));
}
int lvmetad_active(void)
@ -663,33 +663,8 @@ static int _pvscan_lvmetad_single(struct metadata_area *mda, void *baton)
return 1;
}
static dev_t _parse_devt(const char *str)
{ /* Oh. */
char *where = (char *) str;
int major = strtol(str, &where, 10);
int minor;
if (where == str)
return -1;
if (*where != ':')
return -1;
str = ++where;
minor = strtol(str, &where, 10);
if (where == str)
return -1;
if (*where)
return -1;
return MKDEV(major, minor);
}
int pvscan_lvmetad_single(struct cmd_context *cmd, const char *pv_name)
int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev)
{
struct device *dev;
struct label *label;
struct lvmcache_info *info;
struct physical_volume pv;
@ -702,26 +677,9 @@ int pvscan_lvmetad_single(struct cmd_context *cmd, const char *pv_name)
return 0;
}
dev = dev_cache_get(pv_name, NULL);
if (!dev && _parse_devt(pv_name) != -1)
dev = dev_cache_get_by_devt(_parse_devt(pv_name), NULL);
if (!dev) {
if (_parse_devt(pv_name) == -1) {
log_error("Unrecognised device name %s. (Use MAJOR:MINOR for new devices.)", pv_name);
return 0;
}
if (!_lvmetad_pv_gone(_parse_devt(pv_name), pv_name))
goto_bad;
log_print("Device %s not found. Cleared from lvmetad cache.", pv_name);
return 1;
}
if (!label_read(dev, &label, 0)) {
log_print("No PV label found on %s.", dev_name(dev));
if (!lvmetad_pv_gone(dev))
if (!lvmetad_pv_gone_by_dev(dev))
goto_bad;
return 1;
}

17
lib/cache/lvmetad.h vendored
View File

@ -67,11 +67,10 @@ int lvmetad_pv_found(struct id pvid, struct device *device,
struct volume_group *vg);
/*
* Inform the daemon that the device no longer exists. We do not support
* multiple device names, so this needs a unique and stable name, the same as
* provided to lvmetad_pv_found.
* Inform the daemon that the device no longer exists.
*/
int lvmetad_pv_gone(struct device *dev);
int lvmetad_pv_gone(dev_t devno, const char *pv_name);
int lvmetad_pv_gone_by_dev(struct device *dev);
/*
* Request a list of all PVs available to lvmetad. If requested, this will also
@ -101,10 +100,9 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd,
const char *vgname, const char *vgid);
/*
* Scan a single device and update lvmetad with the result(s). If the device
* node does not exist, it must be supplied in a major:minor format.
* Scan a single device and update lvmetad with the result(s).
*/
int pvscan_lvmetad_single(struct cmd_context *cmd, const char *pv_name);
int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev);
# else /* LVMETAD_SUPPORT */
@ -114,13 +112,14 @@ int pvscan_lvmetad_single(struct cmd_context *cmd, const char *pv_name);
# define lvmetad_vg_update(vg) (1)
# define lvmetad_vg_remove(vg) (1)
# define lvmetad_pv_found(pvid, device, fmt, label_sector, vg) (1)
# define lvmetad_pv_gone(dev) (1)
# define lvmetad_pv_gone(devno, pv_name) (1)
# define lvmetad_pv_gone_by_dev(dev) (1)
# define lvmetad_pv_list_to_lvmcache(cmd) (1)
# define lvmetad_pv_lookup(cmd, pvid, found) (0)
# define lvmetad_pv_lookup_by_dev(cmd, dev, found) (0)
# define lvmetad_vg_list_to_lvmcache(cmd) (1)
# define lvmetad_vg_lookup(cmd, vgname, vgid) (NULL)
# define pvscan_lvmetad_single(cmd, pv_name) (0)
# define pvscan_lvmetad_single(cmd, dev) (0)
# endif /* LVMETAD_SUPPORT */

View File

@ -3,7 +3,7 @@
pvscan \- scan all disks for physical volumes
.SH SYNOPSIS
.B pvscan
.RB [ \-\-cache " " DevicePath [ DevicePath ... ] ]
.RB [ \-\-cache " " [ DevicePath ... ] ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-\-help ]
.RB [ \-v | \-\-verbose ]
@ -31,10 +31,11 @@ Short listing format.
.BR \-u ", " \-\-uuid
Show UUIDs (Uniform Unique Identifiers) in addition to device special names.
.TP
.BR \-\-cache " " DevicePath [ DevicePath... ]
Scan a single device and instruct the lvmetad daemon to update its cached
state. Called internally by udev rules. The device is processed
\fBregardless\fP of any device filters set in lvm.conf.
.BR \-\-cache " " [ DevicePath... ]
Scan one or more devices and instruct the lvmetad daemon to update its cached
state accordingly. Called internally by udev rules.
All devices listed explicitly are processed \fBregardless\fP of any device
filters set in lvm.conf.
.SH SEE ALSO
.BR lvm (8),
.BR pvcreate (8),

View File

@ -663,7 +663,7 @@ xx(pvscan,
"List all physical volumes",
PERMITTED_READ_ONLY,
"pvscan " "\n"
"\t[--cache DevicePath [DevicePath...]] " "\n"
"\t[--cache [DevicePath...]] " "\n"
"\t[-d|--debug] " "\n"
"\t{-e|--exported | -n|--novolumegroup} " "\n"
"\t[-h|-?|--help]" "\n"

View File

@ -128,8 +128,7 @@ static int pvremove_single(struct cmd_context *cmd, const char *pv_name,
goto out;
}
/* FIXME Avoid error if we expect that daemon might not know device */
if (!lvmetad_pv_gone(dev))
if (!lvmetad_pv_gone_by_dev(dev))
goto_out;
log_print("Labels on physical volume \"%s\" successfully wiped",

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -21,6 +21,52 @@
int pv_max_name_len = 0;
int vg_max_name_len = 0;
static dev_t _parse_devt(const char *str)
{ /* Oh. */
char *where = (char *) str;
int major = strtol(str, &where, 10);
int minor;
if (where == str)
return -1;
if (*where != ':')
return -1;
str = ++where;
minor = strtol(str, &where, 10);
if (where == str)
return -1;
if (*where)
return -1;
return MKDEV(major, minor);
}
/*
* Convert pv_name to struct device or to *devno.
*/
static struct device *_device_from_pv_name(const char *pv_name, dev_t *devno)
{
struct device *dev;
if ((dev = dev_cache_get(pv_name, NULL)))
return dev;
if ((*devno = _parse_devt(pv_name)) == -1) {
log_error("Unrecognised device name %s. "
"(Use MAJOR:MINOR for new devices.)", pv_name);
return NULL;
}
if ((dev = dev_cache_get_by_devt(*devno, NULL)))
return dev;
return NULL;
}
static void _pvscan_display_single(struct cmd_context *cmd,
struct physical_volume *pv,
void *handle __attribute__((unused)))
@ -99,30 +145,78 @@ static void _pvscan_display_single(struct cmd_context *cmd,
pv_pe_size(pv)));
}
static int _pvscan_lvmetad_all_devs(struct cmd_context *cmd)
{
struct dev_iter *iter;
struct device *dev;
int r = 1;
if (!(iter = dev_iter_create(cmd->filter, 1))) {
log_error("dev_iter creation failed");
return 0;
}
while ((dev = dev_iter_get(iter))) {
if (!pvscan_lvmetad_single(cmd, dev)) {
r = 0;
break;
}
if (sigint_caught())
break;
}
dev_iter_destroy(iter);
return r;
}
static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv)
{
int ret = ECMD_PROCESSED;
if (!argc) {
log_error("List of Physical Volumes to be cached by the lvmetad daemon required.");
return EINVALID_CMD_LINE;
}
struct device *dev;
const char *pv_name;
dev_t devno;
if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ)) {
log_error("Unable to obtain global lock.");
return ECMD_FAILED;
}
if (!argc) {
if (!_pvscan_lvmetad_all_devs(cmd))
ret = ECMD_FAILED;
goto out;
}
log_verbose("Using physical volume(s) on command line");
while (argc--) {
if (!pvscan_lvmetad_single(cmd, *argv++)) {
pv_name = *argv++;
dev = _device_from_pv_name(pv_name, &devno);
if (!dev && devno != -1) {
/* FIXME Filters? */
if (!lvmetad_pv_gone(devno, pv_name)) {
ret = ECMD_FAILED;
break;
}
log_print("Device %s not found. "
"Cleared from lvmetad cache.", pv_name);
continue;
}
if (!pvscan_lvmetad_single(cmd, dev)) {
ret = ECMD_FAILED;
break;
}
if (sigint_caught())
break;
}
out:
unlock_vg(cmd, VG_GLOBAL);
return ret;
@ -184,6 +278,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
&& !(pv_status(pv) & EXPORTED_VG)) ||
(arg_count(cmd, novolumegroup_ARG) && (!is_orphan(pv)))) {
dm_list_del(&pvl->list);
free_pv_fid(pv);
continue;
}