1 /* $NetBSD: filter_netbsd.c,v 1.3 2009/12/02 01:53:25 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. 5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 6 * Copyright (C) 2008 Adam Hamsik. All rights reserved. 7 * Copyright (C) 2010 Alex Hornung. All rights reserved. 8 * 9 * This file is part of LVM2. 10 * 11 * This copyrighted material is made available to anyone wishing to use, 12 * modify, copy, or redistribute it subject to the terms and conditions 13 * of the GNU Lesser General Public License v.2.1. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with this program; if not, write to the Free Software Foundation, 17 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20 #include "lib.h" 21 #include "dev-cache.h" 22 #include "filter.h" 23 #include "lvm-string.h" 24 #include "config.h" 25 #include "metadata.h" 26 #include "activate.h" 27 28 #include <sys/filio.h> 29 #include <sys/device.h> 30 #include <sys/sysctl.h> 31 32 #include <ctype.h> 33 #include <dirent.h> 34 #include <fcntl.h> 35 #include <limits.h> 36 #include <unistd.h> 37 38 #define NUMBER_OF_MAJORS 4096 39 40 #define LVM_SUCCESS 1 41 #define LVM_FAILURE 0 42 43 /* -1 means LVM won't use this major number. */ 44 static int _char_device_major[NUMBER_OF_MAJORS]; 45 static int _block_device_major[NUMBER_OF_MAJORS]; 46 47 typedef struct { 48 const char *name; 49 const int max_partitions; 50 } device_info_t; 51 52 static int _md_major = -1; 53 static int _device_mapper_major = -1; 54 55 int md_major(void) 56 { 57 return _md_major; 58 } 59 60 int dev_subsystem_part_major(const struct device *dev) 61 { 62 return 0; 63 } 64 65 const char *dev_subsystem_name(const struct device *dev) 66 { 67 return ""; 68 } 69 70 71 /* 72 * Test if device passes filter tests and can be inserted in to cache. 73 */ 74 static int _passes_lvm_type_device_filter(struct dev_filter *f __attribute((unused)), 75 struct device *dev) 76 { 77 const char *name = dev_name(dev); 78 int fd, type; 79 int ret = LVM_FAILURE; 80 uint64_t size; 81 82 log_debug("Checking: %s", name); 83 84 if ((fd = open(name, O_RDONLY)) < 0) { 85 log_debug("%s: Skipping: Could not open device", name); 86 return LVM_FAILURE; 87 } 88 if (ioctl(fd, FIODTYPE, &type) == -1) { 89 close(fd); 90 log_debug("%s: Skipping: Could not get device type", name); 91 return LVM_FAILURE; 92 } else { 93 if (!(type & D_DISK)) { 94 close(fd); 95 log_debug("%s: Skipping: Device is not of type D_DISK", name); 96 return LVM_FAILURE; 97 } 98 } 99 100 close(fd); 101 102 /* Skip suspended devices */ 103 if (MAJOR(dev->dev) == _device_mapper_major && 104 ignore_suspended_devices() && !device_is_usable(dev->dev)) { 105 log_debug("%s: Skipping: Suspended dm device", name); 106 return LVM_FAILURE; 107 } 108 109 /* Check it's accessible */ 110 if (!dev_open_flags(dev, O_RDONLY, 0, 1)) { 111 log_debug("%s: Skipping: open failed", name); 112 return LVM_FAILURE; 113 } 114 115 /* Check it's not too small */ 116 if (!dev_get_size(dev, &size)) { 117 log_debug("%s: Skipping: dev_get_size failed", name); 118 goto out; 119 } 120 121 if (size < PV_MIN_SIZE) { 122 log_debug("%s: Skipping: Too small to hold a PV", name); 123 goto out; 124 } 125 126 if (is_partitioned_dev(dev)) { 127 log_debug("%s: Skipping: Partition table signature found", 128 name); 129 goto out; 130 } 131 132 ret = LVM_SUCCESS; 133 134 out: 135 dev_close(dev); 136 137 return ret; 138 } 139 140 int max_partitions(int major) 141 { 142 /* XXX */ 143 return 64; 144 } 145 146 struct dev_filter *lvm_type_filter_create(const char *proc, 147 const struct config_node *cn) 148 { 149 struct dev_filter *f; 150 151 if (!(f = dm_malloc(sizeof(struct dev_filter)))) { 152 log_error("LVM type filter allocation failed"); 153 return NULL; 154 } 155 156 f->passes_filter = _passes_lvm_type_device_filter; 157 f->destroy = lvm_type_filter_destroy; 158 f->private = NULL; 159 160 return f; 161 } 162 163 void lvm_type_filter_destroy(struct dev_filter *f) 164 { 165 dm_free(f); 166 return; 167 } 168