mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-30 17:18:21 +03:00
Detect partition table signature.
This commit is contained in:
parent
82416639c4
commit
985ef4617f
@ -1,5 +1,6 @@
|
||||
Version 2.00.26 -
|
||||
=====================================
|
||||
Detect partition table signature.
|
||||
pvcreate wipes md superblocks. (With --uuid or --restorefile it prompts.)
|
||||
Separate out md superblock detection code.
|
||||
Prevent snapshot origin resizing.
|
||||
|
@ -13,6 +13,54 @@
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "lvm-types.h"
|
||||
#include "device.h"
|
||||
#include "metadata.h"
|
||||
#include "filter.h"
|
||||
|
||||
#define PART_MAGIC 0xAA55
|
||||
|
||||
static int _is_whole_disk(struct device *dev)
|
||||
{
|
||||
int parts = max_partitions(MINOR(dev->dev));
|
||||
|
||||
if (!parts || !(MINOR(dev->dev) % parts))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _has_partition_table(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t part_magic;
|
||||
uint64_t part_offset;
|
||||
|
||||
if (!dev_open(dev)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
|
||||
part_offset = sizeof(unsigned short) * 255;
|
||||
if (dev_read(dev, part_offset, sizeof(part_magic), &part_magic) &&
|
||||
(part_magic == PART_MAGIC))
|
||||
ret = 1;
|
||||
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int is_partitioned_dev(struct device *dev)
|
||||
{
|
||||
if (_is_whole_disk(dev))
|
||||
return 0;
|
||||
|
||||
return _has_partition_table(dev);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
@ -27,24 +75,13 @@
|
||||
#include <linux/major.h>
|
||||
#include <linux/genhd.h>
|
||||
|
||||
#include "dbg_malloc.h"
|
||||
#include "log.h"
|
||||
#include "dev-cache.h"
|
||||
#include "metadata.h"
|
||||
#include "device.h"
|
||||
|
||||
int _get_partition_type(struct dev_filter *filter, struct device *d);
|
||||
|
||||
#define MINOR_PART(dm, d) (MINOR((d)->dev) % dev_max_partitions(dm, (d)->dev))
|
||||
#define MINOR_PART(dev) (MINOR((dev)->dev) % max_partitions(MINOR((dev)->dev)))
|
||||
|
||||
int is_whole_disk(struct dev_filter *filter, struct device *d)
|
||||
int is_extended_partition(struct device *d)
|
||||
{
|
||||
return (MINOR_PART(dm, d)) ? 0 : 1;
|
||||
}
|
||||
|
||||
int is_extended_partition(struct dev_mgr *dm, struct device *d)
|
||||
{
|
||||
return (MINOR_PART(dm, d) > 4) ? 1 : 0;
|
||||
return (MINOR_PART(d) > 4) ? 1 : 0;
|
||||
}
|
||||
|
||||
struct device *dev_primary(struct dev_mgr *dm, struct device *d)
|
||||
|
@ -95,12 +95,8 @@ int dev_is_md(struct device *dev, uint64_t *sb);
|
||||
/* FIXME Check partition type if appropriate */
|
||||
|
||||
#define is_lvm_partition(a) 1
|
||||
/* int is_lvm_partition(const char *name); */
|
||||
|
||||
/*
|
||||
static inline int is_lvm_partition(const char *name)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
int is_partitioned_dev(struct device *dev);
|
||||
|
||||
#endif
|
||||
|
@ -27,6 +27,9 @@
|
||||
|
||||
#define NUMBER_OF_MAJORS 4096
|
||||
|
||||
/* FIXME Make this sparse */
|
||||
static int _max_partitions_by_major[NUMBER_OF_MAJORS];
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const int max_partitions;
|
||||
@ -62,29 +65,34 @@ static const device_info_t device_info[] = {
|
||||
static int _passes_lvm_type_device_filter(struct dev_filter *f,
|
||||
struct device *dev)
|
||||
{
|
||||
int fd;
|
||||
const char *name = dev_name(dev);
|
||||
int ret = 1;
|
||||
|
||||
/* Is this a recognised device type? */
|
||||
if (!(((int *) f->private)[MAJOR(dev->dev)])) {
|
||||
if (!_max_partitions_by_major[MAJOR(dev->dev)]) {
|
||||
log_debug("%s: Skipping: Unrecognised LVM device type %"
|
||||
PRIu64, name, (uint64_t) MAJOR(dev->dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check it's accessible */
|
||||
if ((fd = open(name, O_RDONLY)) < 0) {
|
||||
log_debug("%s: Skipping: open failed: %s", name,
|
||||
strerror(errno));
|
||||
if (!dev_open_flags(dev, O_RDONLY, 0, 0)) {
|
||||
log_debug("%s: Skipping: open failed", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return 1;
|
||||
if (is_partitioned_dev(dev)) {
|
||||
log_debug("%s: Skipping: partition table signature found",
|
||||
name);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
static int *_scan_proc_dev(const char *proc, const struct config_node *cn)
|
||||
dev_close(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _scan_proc_dev(const char *proc, const struct config_node *cn)
|
||||
{
|
||||
char line[80];
|
||||
char proc_devices[PATH_MAX];
|
||||
@ -94,36 +102,29 @@ static int *_scan_proc_dev(const char *proc, const struct config_node *cn)
|
||||
int blocksection = 0;
|
||||
size_t dev_len = 0;
|
||||
struct config_value *cv;
|
||||
int *max_partitions_by_major;
|
||||
char *name;
|
||||
|
||||
/* FIXME Make this sparse */
|
||||
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 (!*proc) {
|
||||
log_verbose("No proc filesystem found: using all block device "
|
||||
"types");
|
||||
for (i = 0; i < NUMBER_OF_MAJORS; i++)
|
||||
max_partitions_by_major[i] = 1;
|
||||
return max_partitions_by_major;
|
||||
_max_partitions_by_major[i] = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(_max_partitions_by_major, 0, sizeof(int) * NUMBER_OF_MAJORS);
|
||||
|
||||
if (lvm_snprintf(proc_devices, sizeof(proc_devices),
|
||||
"%s/devices", proc) < 0) {
|
||||
log_error("Failed to create /proc/devices string");
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pd = fopen(proc_devices, "r"))) {
|
||||
log_sys_error("fopen", proc_devices);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(max_partitions_by_major, 0, sizeof(int) * NUMBER_OF_MAJORS);
|
||||
while (fgets(line, 80, pd) != NULL) {
|
||||
i = 0;
|
||||
while (line[i] == ' ' && line[i] != '\0')
|
||||
@ -158,13 +159,13 @@ static int *_scan_proc_dev(const char *proc, const struct config_node *cn)
|
||||
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] =
|
||||
_max_partitions_by_major[line_maj] =
|
||||
device_info[j].max_partitions;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_partitions_by_major[line_maj] || !cn)
|
||||
if (_max_partitions_by_major[line_maj] || !cn)
|
||||
continue;
|
||||
|
||||
/* Check devices/types for local variations */
|
||||
@ -172,7 +173,7 @@ static int *_scan_proc_dev(const char *proc, const struct config_node *cn)
|
||||
if (cv->type != CFG_STRING) {
|
||||
log_error("Expecting string in devices/types "
|
||||
"in config file");
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
dev_len = strlen(cv->v.str);
|
||||
name = cv->v.str;
|
||||
@ -181,24 +182,29 @@ static int *_scan_proc_dev(const char *proc, const struct config_node *cn)
|
||||
log_error("Max partition count missing for %s "
|
||||
"in devices/types in config file",
|
||||
name);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
if (!cv->v.i) {
|
||||
log_error("Zero partition count invalid for "
|
||||
"%s in devices/types in config file",
|
||||
name);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
if (dev_len <= strlen(line + i) &&
|
||||
!strncmp(name, line + i, dev_len) &&
|
||||
(line_maj < NUMBER_OF_MAJORS)) {
|
||||
max_partitions_by_major[line_maj] = cv->v.i;
|
||||
_max_partitions_by_major[line_maj] = cv->v.i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(pd);
|
||||
return max_partitions_by_major;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int max_partitions(int major)
|
||||
{
|
||||
return _max_partitions_by_major[major];
|
||||
}
|
||||
|
||||
struct dev_filter *lvm_type_filter_create(const char *proc,
|
||||
@ -213,8 +219,9 @@ struct dev_filter *lvm_type_filter_create(const char *proc,
|
||||
|
||||
f->passes_filter = _passes_lvm_type_device_filter;
|
||||
f->destroy = lvm_type_filter_destroy;
|
||||
f->private = NULL;
|
||||
|
||||
if (!(f->private = _scan_proc_dev(proc, cn))) {
|
||||
if (!_scan_proc_dev(proc, cn)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@ -224,7 +231,6 @@ struct dev_filter *lvm_type_filter_create(const char *proc,
|
||||
|
||||
void lvm_type_filter_destroy(struct dev_filter *f)
|
||||
{
|
||||
dbg_free(f->private);
|
||||
dbg_free(f);
|
||||
return;
|
||||
}
|
||||
|
@ -37,4 +37,6 @@ void lvm_type_filter_destroy(struct dev_filter *f);
|
||||
|
||||
int md_major(void);
|
||||
|
||||
int max_partitions(int major);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user