From a648372757811cf869f037c4b5386213de7ab1a2 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Tue, 3 Dec 2002 16:20:38 +0000 Subject: [PATCH] New devices/types config file entry to add new types of block devices. --- doc/example.conf | 5 ++ lib/commands/toolcontext.c | 4 +- lib/filters/filter.c | 116 +++++++++++++++++++++++-------------- lib/filters/filter.h | 6 +- man/lvm.conf.5 | 7 +++ 5 files changed, 93 insertions(+), 45 deletions(-) diff --git a/doc/example.conf b/doc/example.conf index df97131ba..f88c97c1e 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -49,6 +49,11 @@ devices { # You can turn off writing this cache file by setting this to 0. write_cache_state = 1 + + # An advanced setting. + # List of pairs of additional acceptable block device types found + # in /proc/devices with maximum (non-zero) number of partitions. + # types = [ "fd", 16 ] } # This section that allows you to configure the nature of the diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c index 8c10945e6..c3fcbda29 100644 --- a/lib/commands/toolcontext.c +++ b/lib/commands/toolcontext.c @@ -239,7 +239,9 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd) struct config_node *cn; struct dev_filter *f1, *f2, *f3; - if (!(f2 = lvm_type_filter_create(cmd->proc_dir))) + cn = find_config_node(cmd->cf->root, "devices/types", '/'); + + if (!(f2 = lvm_type_filter_create(cmd->proc_dir, cn))) return NULL; if (!(cn = find_config_node(cmd->cf->root, "devices/filter", '/'))) { diff --git a/lib/filters/filter.c b/lib/filters/filter.c index 3e89e4eeb..e3919221f 100644 --- a/lib/filters/filter.c +++ b/lib/filters/filter.c @@ -22,6 +22,7 @@ #include "dev-cache.h" #include "filter.h" #include "lvm-string.h" +#include "config.h" #include #include @@ -39,7 +40,12 @@ typedef struct { static int _md_major = -1; -/* FIXME Move list into config file */ +int md_major(void) +{ + return _md_major; +} + +/* This list can be supplemented with devices/types in the config file */ static device_info_t device_info[] = { {"ide", 16}, /* IDE disk */ {"sd", 16}, /* SCSI disk */ @@ -55,10 +61,8 @@ static device_info_t device_info[] = { {NULL, 0} }; -static int *scan_proc_dev(const char *proc); - -static int passes_lvm_type_device_filter(struct dev_filter *f, - struct device *dev) +static int _passes_lvm_type_device_filter(struct dev_filter *f, + struct device *dev) { int fd; const char *name = dev_name(dev); @@ -78,48 +82,18 @@ static int passes_lvm_type_device_filter(struct dev_filter *f, return 1; } -struct dev_filter *lvm_type_filter_create(const char *proc) -{ - struct dev_filter *f; - - if (!(f = dbg_malloc(sizeof(struct dev_filter)))) { - log_error("LVM type filter allocation failed"); - return NULL; - } - - f->passes_filter = passes_lvm_type_device_filter; - f->destroy = lvm_type_filter_destroy; - - if (!(f->private = scan_proc_dev(proc))) - return NULL; - - return f; -} - -int md_major(void) -{ - return _md_major; -} - -void lvm_type_filter_destroy(struct dev_filter *f) -{ - dbg_free(f->private); - dbg_free(f); - return; -} - -static int *scan_proc_dev(const char *proc) +static int *_scan_proc_dev(const char *proc, struct config_node *cn) { char line[80]; char proc_devices[PATH_MAX]; FILE *pd = NULL; - int ret = 0; int i, j = 0; int line_maj = 0; int blocksection = 0; int dev_len = 0; - + struct config_value *cv; int *max_partitions_by_major; + char *name; if (!(max_partitions_by_major = dbg_malloc(sizeof(int) * NUMBER_OF_MAJORS))) { @@ -170,12 +144,44 @@ static int *scan_proc_dev(const char *proc) 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)) { + 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; + } + } + + if (max_partitions_by_major[line_maj] || !cn) + continue; + + /* Check devices/types for local variations */ + for (cv = cn->v; cv; cv = cv->next) { + if (cv->type != CFG_STRING) { + log_error("Expecting string in devices/types " + "in config file"); + return NULL; + } + dev_len = strlen(cv->v.str); + name = cv->v.str; + cv = cv->next; + if (!cv || cv->type != CFG_INT) { + log_error("Max partition count missing for %s " + "in devices/types in config file", + name); + return NULL; + } + if (!cv->v.i) { + log_error("Zero partition count invalid for " + "%s in devices/types in config file", + name); + return NULL; + } + 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; break; } } @@ -183,3 +189,29 @@ static int *scan_proc_dev(const char *proc) fclose(pd); return max_partitions_by_major; } + +struct dev_filter *lvm_type_filter_create(const char *proc, + struct config_node *cn) +{ + struct dev_filter *f; + + if (!(f = dbg_malloc(sizeof(struct dev_filter)))) { + log_error("LVM type filter allocation failed"); + return NULL; + } + + f->passes_filter = _passes_lvm_type_device_filter; + f->destroy = lvm_type_filter_destroy; + + if (!(f->private = _scan_proc_dev(proc, cn))) + return NULL; + + return f; +} + +void lvm_type_filter_destroy(struct dev_filter *f) +{ + dbg_free(f->private); + dbg_free(f); + return; +} diff --git a/lib/filters/filter.h b/lib/filters/filter.h index a7a5113b9..f262d0964 100644 --- a/lib/filters/filter.h +++ b/lib/filters/filter.h @@ -21,11 +21,13 @@ #ifndef _LVM_FILTER_H #define _LVM_FILTER_H -struct dev_filter *lvm_type_filter_create(const char *proc); +#include "config.h" + +struct dev_filter *lvm_type_filter_create(const char *proc, + struct config_node *cn); void lvm_type_filter_destroy(struct dev_filter *f); int md_major(void); #endif - diff --git a/man/lvm.conf.5 b/man/lvm.conf.5 index 8be669fd4..46251ee48 100644 --- a/man/lvm.conf.5 +++ b/man/lvm.conf.5 @@ -91,6 +91,13 @@ Defaults to "/etc/lvm/.cache". \fBwrite_cache_state\fP \(em Set to 0 to disable the writing out of the persistent filter cache file when \fBlvm\fP exits. Defaults to 1. +.IP +\fBtypes\fP \(em List of pairs of additional acceptable block device types +found in /proc/devices together with maximum (non-zero) number of +partitions (normally 16). By default, LVM2 supports ide, sd, md, loop, +dasd, dac960, nbd, ida, cciss, ubd and ataraid. Block devices with major +numbers of different types are ignored by LVM2. Example: +\fBtypes = ["fd", 16]\fP .TP \fBlog\fP \(em Default log settings .IP -- 2.43.5