1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-10 16:58:47 +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 - 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 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; 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 result;
int found; int found;
@ -625,9 +625,9 @@ static int _lvmetad_pv_gone(dev_t device, const char *pv_name)
return result; 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) int lvmetad_active(void)
@ -663,33 +663,8 @@ static int _pvscan_lvmetad_single(struct metadata_area *mda, void *baton)
return 1; return 1;
} }
static dev_t _parse_devt(const char *str) int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev)
{ /* 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)
{ {
struct device *dev;
struct label *label; struct label *label;
struct lvmcache_info *info; struct lvmcache_info *info;
struct physical_volume pv; struct physical_volume pv;
@ -702,26 +677,9 @@ int pvscan_lvmetad_single(struct cmd_context *cmd, const char *pv_name)
return 0; 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)) { if (!label_read(dev, &label, 0)) {
log_print("No PV label found on %s.", dev_name(dev)); 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; goto_bad;
return 1; 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); struct volume_group *vg);
/* /*
* Inform the daemon that the device no longer exists. We do not support * Inform the daemon that the device no longer exists.
* multiple device names, so this needs a unique and stable name, the same as
* provided to lvmetad_pv_found.
*/ */
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 * 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); const char *vgname, const char *vgid);
/* /*
* Scan a single device and update lvmetad with the result(s). If the device * Scan a single device and update lvmetad with the result(s).
* node does not exist, it must be supplied in a major:minor format.
*/ */
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 */ # 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_update(vg) (1)
# define lvmetad_vg_remove(vg) (1) # define lvmetad_vg_remove(vg) (1)
# define lvmetad_pv_found(pvid, device, fmt, label_sector, 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_list_to_lvmcache(cmd) (1)
# define lvmetad_pv_lookup(cmd, pvid, found) (0) # define lvmetad_pv_lookup(cmd, pvid, found) (0)
# define lvmetad_pv_lookup_by_dev(cmd, dev, found) (0) # define lvmetad_pv_lookup_by_dev(cmd, dev, found) (0)
# define lvmetad_vg_list_to_lvmcache(cmd) (1) # define lvmetad_vg_list_to_lvmcache(cmd) (1)
# define lvmetad_vg_lookup(cmd, vgname, vgid) (NULL) # 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 */ # endif /* LVMETAD_SUPPORT */

View File

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

View File

@ -663,7 +663,7 @@ xx(pvscan,
"List all physical volumes", "List all physical volumes",
PERMITTED_READ_ONLY, PERMITTED_READ_ONLY,
"pvscan " "\n" "pvscan " "\n"
"\t[--cache DevicePath [DevicePath...]] " "\n" "\t[--cache [DevicePath...]] " "\n"
"\t[-d|--debug] " "\n" "\t[-d|--debug] " "\n"
"\t{-e|--exported | -n|--novolumegroup} " "\n" "\t{-e|--exported | -n|--novolumegroup} " "\n"
"\t[-h|-?|--help]" "\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; goto out;
} }
/* FIXME Avoid error if we expect that daemon might not know device */ if (!lvmetad_pv_gone_by_dev(dev))
if (!lvmetad_pv_gone(dev))
goto_out; goto_out;
log_print("Labels on physical volume \"%s\" successfully wiped", 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) 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. * This file is part of LVM2.
* *
@ -21,6 +21,52 @@
int pv_max_name_len = 0; int pv_max_name_len = 0;
int vg_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, static void _pvscan_display_single(struct cmd_context *cmd,
struct physical_volume *pv, struct physical_volume *pv,
void *handle __attribute__((unused))) void *handle __attribute__((unused)))
@ -99,30 +145,78 @@ static void _pvscan_display_single(struct cmd_context *cmd,
pv_pe_size(pv))); 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) static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv)
{ {
int ret = ECMD_PROCESSED; int ret = ECMD_PROCESSED;
struct device *dev;
if (!argc) { const char *pv_name;
log_error("List of Physical Volumes to be cached by the lvmetad daemon required."); dev_t devno;
return EINVALID_CMD_LINE;
}
if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ)) { if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ)) {
log_error("Unable to obtain global lock."); log_error("Unable to obtain global lock.");
return ECMD_FAILED; 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"); log_verbose("Using physical volume(s) on command line");
while (argc--) { 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; ret = ECMD_FAILED;
break; break;
} }
if (sigint_caught()) if (sigint_caught())
break; break;
} }
out:
unlock_vg(cmd, VG_GLOBAL); unlock_vg(cmd, VG_GLOBAL);
return ret; return ret;
@ -184,6 +278,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
&& !(pv_status(pv) & EXPORTED_VG)) || && !(pv_status(pv) & EXPORTED_VG)) ||
(arg_count(cmd, novolumegroup_ARG) && (!is_orphan(pv)))) { (arg_count(cmd, novolumegroup_ARG) && (!is_orphan(pv)))) {
dm_list_del(&pvl->list); dm_list_del(&pvl->list);
free_pv_fid(pv);
continue; continue;
} }