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