Sat Aug 27 17:07:50 2011 UTC ()
- add a function to get the inactive table's size
- some whitespace fix from emacs...


(ahoka)
diff -r1.22 -r1.23 src/sys/dev/dm/dm.h
diff -r1.25 -r1.26 src/sys/dev/dm/dm_ioctl.c

cvs diff -r1.22 -r1.23 src/sys/dev/dm/dm.h (switch to unified diff)

--- src/sys/dev/dm/dm.h 2010/12/23 20:07:13 1.22
+++ src/sys/dev/dm/dm.h 2011/08/27 17:07:49 1.23
@@ -1,366 +1,367 @@ @@ -1,366 +1,367 @@
1/* $NetBSD: dm.h,v 1.22 2010/12/23 20:07:13 christos Exp $ */ 1/* $NetBSD: dm.h,v 1.23 2011/08/27 17:07:49 ahoka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Hamsik. 8 * by Adam Hamsik.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#ifndef _DM_DEV_H_ 32#ifndef _DM_DEV_H_
33#define _DM_DEV_H_ 33#define _DM_DEV_H_
34 34
35 35
36#ifdef _KERNEL 36#ifdef _KERNEL
37 37
38#include <sys/errno.h> 38#include <sys/errno.h>
39 39
40#include <sys/atomic.h> 40#include <sys/atomic.h>
41#include <sys/fcntl.h> 41#include <sys/fcntl.h>
42#include <sys/condvar.h> 42#include <sys/condvar.h>
43#include <sys/kauth.h> 43#include <sys/kauth.h>
44#include <sys/mutex.h> 44#include <sys/mutex.h>
45#include <sys/rwlock.h> 45#include <sys/rwlock.h>
46#include <sys/queue.h> 46#include <sys/queue.h>
47 47
48#include <sys/device.h> 48#include <sys/device.h>
49#include <sys/disk.h> 49#include <sys/disk.h>
50#include <sys/disklabel.h> 50#include <sys/disklabel.h>
51 51
52#include <prop/proplib.h> 52#include <prop/proplib.h>
53 53
54#define DM_MAX_TYPE_NAME 16 54#define DM_MAX_TYPE_NAME 16
55#define DM_NAME_LEN 128 55#define DM_NAME_LEN 128
56#define DM_UUID_LEN 129 56#define DM_UUID_LEN 129
57 57
58#define DM_VERSION_MAJOR 4 58#define DM_VERSION_MAJOR 4
59#define DM_VERSION_MINOR 16 59#define DM_VERSION_MINOR 16
60 60
61#define DM_VERSION_PATCHLEVEL 0 61#define DM_VERSION_PATCHLEVEL 0
62 62
63/*** Internal device-mapper structures ***/ 63/*** Internal device-mapper structures ***/
64 64
65/* 65/*
66 * A table entry describes a physical range of the logical volume. 66 * A table entry describes a physical range of the logical volume.
67 */ 67 */
68#define MAX_TARGET_STRING_LEN 32 68#define MAX_TARGET_STRING_LEN 32
69 69
70/* 70/*
71 * A device mapper table is a list of physical ranges plus the mapping target 71 * A device mapper table is a list of physical ranges plus the mapping target
72 * applied to them. 72 * applied to them.
73 */ 73 */
74 74
75typedef struct dm_table_entry { 75typedef struct dm_table_entry {
76 struct dm_dev *dm_dev; /* backlink */ 76 struct dm_dev *dm_dev; /* backlink */
77 uint64_t start; 77 uint64_t start;
78 uint64_t length; 78 uint64_t length;
79 79
80 struct dm_target *target; /* Link to table target. */ 80 struct dm_target *target; /* Link to table target. */
81 void *target_config; /* Target specific data. */ 81 void *target_config; /* Target specific data. */
82 SLIST_ENTRY(dm_table_entry) next; 82 SLIST_ENTRY(dm_table_entry) next;
83} dm_table_entry_t; 83} dm_table_entry_t;
84 84
85SLIST_HEAD(dm_table, dm_table_entry); 85SLIST_HEAD(dm_table, dm_table_entry);
86 86
87typedef struct dm_table dm_table_t; 87typedef struct dm_table dm_table_t;
88 88
89typedef struct dm_table_head { 89typedef struct dm_table_head {
90 /* Current active table is selected with this. */ 90 /* Current active table is selected with this. */
91 int cur_active_table;  91 int cur_active_table;
92 struct dm_table tables[2]; 92 struct dm_table tables[2];
93 93
94 kmutex_t table_mtx; 94 kmutex_t table_mtx;
95 kcondvar_t table_cv; /*IO waiting cv */ 95 kcondvar_t table_cv; /*IO waiting cv */
96 96
97 uint32_t io_cnt; 97 uint32_t io_cnt;
98} dm_table_head_t; 98} dm_table_head_t;
99 99
100#define MAX_DEV_NAME 32 100#define MAX_DEV_NAME 32
101 101
102/* 102/*
103 * This structure is used to store opened vnodes for disk with name. 103 * This structure is used to store opened vnodes for disk with name.
104 * I need this because devices can be opened only once, but I can 104 * I need this because devices can be opened only once, but I can
105 * have more then one device on one partition. 105 * have more then one device on one partition.
106 */ 106 */
107 107
108typedef struct dm_pdev { 108typedef struct dm_pdev {
109 char name[MAX_DEV_NAME]; 109 char name[MAX_DEV_NAME];
110 110
111 struct vnode *pdev_vnode; 111 struct vnode *pdev_vnode;
112 uint64_t pdev_numsec; 112 uint64_t pdev_numsec;
113 unsigned pdev_secsize; 113 unsigned pdev_secsize;
114 int ref_cnt; /* reference counter for users ofthis pdev */ 114 int ref_cnt; /* reference counter for users ofthis pdev */
115 115
116 SLIST_ENTRY(dm_pdev) next_pdev; 116 SLIST_ENTRY(dm_pdev) next_pdev;
117} dm_pdev_t; 117} dm_pdev_t;
118 118
119/* 119/*
120 * This structure is called for every device-mapper device. 120 * This structure is called for every device-mapper device.
121 * It points to SLIST of device tables and mirrored, snapshoted etc. devices. 121 * It points to SLIST of device tables and mirrored, snapshoted etc. devices.
122 */ 122 */
123TAILQ_HEAD(dm_dev_head, dm_dev) dm_devs; 123TAILQ_HEAD(dm_dev_head, dm_dev) dm_devs;
124  124
125typedef struct dm_dev { 125typedef struct dm_dev {
126 char name[DM_NAME_LEN]; 126 char name[DM_NAME_LEN];
127 char uuid[DM_UUID_LEN]; 127 char uuid[DM_UUID_LEN];
128 128
129 device_t devt; /* pointer to autoconf device_t structure */ 129 device_t devt; /* pointer to autoconf device_t structure */
130 uint64_t minor; /* Device minor number */ 130 uint64_t minor; /* Device minor number */
131 uint32_t flags; /* store communication protocol flags */ 131 uint32_t flags; /* store communication protocol flags */
132 132
133 kmutex_t dev_mtx; /* mutex for generall device lock */ 133 kmutex_t dev_mtx; /* mutex for generall device lock */
134 kcondvar_t dev_cv; /* cv for between ioctl synchronisation */ 134 kcondvar_t dev_cv; /* cv for between ioctl synchronisation */
135  135
136 uint32_t event_nr; 136 uint32_t event_nr;
137 uint32_t ref_cnt; 137 uint32_t ref_cnt;
138 138
139 uint32_t dev_type; 139 uint32_t dev_type;
140 140
141 dm_table_head_t table_head; 141 dm_table_head_t table_head;
142 142
143 struct dm_dev_head upcalls; 143 struct dm_dev_head upcalls;
144  144
145 struct disk *diskp; 145 struct disk *diskp;
146 kmutex_t diskp_mtx; 146 kmutex_t diskp_mtx;
147  147
148 TAILQ_ENTRY(dm_dev) next_upcall; /* LIST of mirrored, snapshoted devices. */ 148 TAILQ_ENTRY(dm_dev) next_upcall; /* LIST of mirrored, snapshoted devices. */
149 149
150 TAILQ_ENTRY(dm_dev) next_devlist; /* Major device list. */ 150 TAILQ_ENTRY(dm_dev) next_devlist; /* Major device list. */
151} dm_dev_t; 151} dm_dev_t;
152 152
153/* Device types used for upcalls */ 153/* Device types used for upcalls */
154#define DM_ZERO_DEV (1 << 0) 154#define DM_ZERO_DEV (1 << 0)
155#define DM_ERROR_DEV (1 << 1)  155#define DM_ERROR_DEV (1 << 1)
156#define DM_LINEAR_DEV (1 << 2) 156#define DM_LINEAR_DEV (1 << 2)
157#define DM_MIRROR_DEV (1 << 3) 157#define DM_MIRROR_DEV (1 << 3)
158#define DM_STRIPE_DEV (1 << 4) 158#define DM_STRIPE_DEV (1 << 4)
159#define DM_SNAPSHOT_DEV (1 << 5) 159#define DM_SNAPSHOT_DEV (1 << 5)
160#define DM_SNAPSHOT_ORIG_DEV (1 << 6) 160#define DM_SNAPSHOT_ORIG_DEV (1 << 6)
161#define DM_SPARE_DEV (1 << 7) 161#define DM_SPARE_DEV (1 << 7)
162/* Set this device type only during dev remove ioctl. */ 162/* Set this device type only during dev remove ioctl. */
163#define DM_DELETING_DEV (1 << 8)  163#define DM_DELETING_DEV (1 << 8)
164 164
165 165
166/* for zero, error : dm_target->target_config == NULL */ 166/* for zero, error : dm_target->target_config == NULL */
167  167
168/* 168/*
169 * Target config is initiated with target_init function. 169 * Target config is initiated with target_init function.
170 */ 170 */
171  171
172/* for linear : */ 172/* for linear : */
173typedef struct target_linear_config { 173typedef struct target_linear_config {
174 dm_pdev_t *pdev; 174 dm_pdev_t *pdev;
175 uint64_t offset; 175 uint64_t offset;
176 TAILQ_ENTRY(target_linear_config) entries; 176 TAILQ_ENTRY(target_linear_config) entries;
177} dm_target_linear_config_t; 177} dm_target_linear_config_t;
178 178
179/* 179/*
180 * Striping devices are stored in a linked list, this might be inefficient 180 * Striping devices are stored in a linked list, this might be inefficient
181 * for more than 8 striping devices and can be changed to something more 181 * for more than 8 striping devices and can be changed to something more
182 * scalable. 182 * scalable.
183 * TODO: look for other options than linked list. 183 * TODO: look for other options than linked list.
184 */ 184 */
185TAILQ_HEAD(target_linear_devs, target_linear_config); 185TAILQ_HEAD(target_linear_devs, target_linear_config);
186 186
187typedef struct target_linear_devs dm_target_linear_devs_t; 187typedef struct target_linear_devs dm_target_linear_devs_t;
188 188
189/* for stripe : */ 189/* for stripe : */
190typedef struct target_stripe_config { 190typedef struct target_stripe_config {
191#define DM_STRIPE_DEV_OFFSET 2 191#define DM_STRIPE_DEV_OFFSET 2
192 struct target_linear_devs stripe_devs; 192 struct target_linear_devs stripe_devs;
193 uint8_t stripe_num; 193 uint8_t stripe_num;
194 uint64_t stripe_chunksize; 194 uint64_t stripe_chunksize;
195 size_t params_len; 195 size_t params_len;
196} dm_target_stripe_config_t; 196} dm_target_stripe_config_t;
197 197
198/* for mirror : */ 198/* for mirror : */
199typedef struct target_mirror_config { 199typedef struct target_mirror_config {
200#define MAX_MIRROR_COPIES 4 200#define MAX_MIRROR_COPIES 4
201 dm_pdev_t *orig; 201 dm_pdev_t *orig;
202 dm_pdev_t *copies[MAX_MIRROR_COPIES]; 202 dm_pdev_t *copies[MAX_MIRROR_COPIES];
203 203
204 /* copied blocks bitmaps administration etc*/ 204 /* copied blocks bitmaps administration etc*/
205 dm_pdev_t *log_pdev; /* for administration */ 205 dm_pdev_t *log_pdev; /* for administration */
206 uint64_t log_regionsize; /* blocksize of mirror */ 206 uint64_t log_regionsize; /* blocksize of mirror */
207 207
208 /* list of parts that still need copied etc.; run length encoded? */ 208 /* list of parts that still need copied etc.; run length encoded? */
209} dm_target_mirror_config_t; 209} dm_target_mirror_config_t;
210 210
211 211
212/* for snapshot : */ 212/* for snapshot : */
213typedef struct target_snapshot_config { 213typedef struct target_snapshot_config {
214 dm_pdev_t *tsc_snap_dev; 214 dm_pdev_t *tsc_snap_dev;
215 /* cow dev is set only for persistent snapshot devices */ 215 /* cow dev is set only for persistent snapshot devices */
216 dm_pdev_t *tsc_cow_dev; 216 dm_pdev_t *tsc_cow_dev;
217  217
218 uint64_t tsc_chunk_size; 218 uint64_t tsc_chunk_size;
219 uint32_t tsc_persistent_dev; 219 uint32_t tsc_persistent_dev;
220} dm_target_snapshot_config_t; 220} dm_target_snapshot_config_t;
221 221
222/* for snapshot-origin devices */ 222/* for snapshot-origin devices */
223typedef struct target_snapshot_origin_config { 223typedef struct target_snapshot_origin_config {
224 dm_pdev_t *tsoc_real_dev; 224 dm_pdev_t *tsoc_real_dev;
225 /* list of snapshots ? */ 225 /* list of snapshots ? */
226} dm_target_snapshot_origin_config_t; 226} dm_target_snapshot_origin_config_t;
227 227
228/* constant dm_target structures for error, zero, linear, stripes etc. */ 228/* constant dm_target structures for error, zero, linear, stripes etc. */
229typedef struct dm_target { 229typedef struct dm_target {
230 char name[DM_MAX_TYPE_NAME]; 230 char name[DM_MAX_TYPE_NAME];
231 /* Initialize target_config area */ 231 /* Initialize target_config area */
232 int (*init)(dm_dev_t *, void **, char *); 232 int (*init)(dm_dev_t *, void **, char *);
233 233
234 /* Destroy target_config area */ 234 /* Destroy target_config area */
235 int (*destroy)(dm_table_entry_t *); 235 int (*destroy)(dm_table_entry_t *);
236  236
237 int (*deps) (dm_table_entry_t *, prop_array_t); 237 int (*deps) (dm_table_entry_t *, prop_array_t);
238 /* 238 /*
239 * Status routine is called to get params string, which is target 239 * Status routine is called to get params string, which is target
240 * specific. When dm_table_status_ioctl is called with flag 240 * specific. When dm_table_status_ioctl is called with flag
241 * DM_STATUS_TABLE_FLAG I have to sent params string back. 241 * DM_STATUS_TABLE_FLAG I have to sent params string back.
242 */ 242 */
243 char * (*status)(void *); 243 char * (*status)(void *);
244 int (*strategy)(dm_table_entry_t *, struct buf *); 244 int (*strategy)(dm_table_entry_t *, struct buf *);
245 int (*sync)(dm_table_entry_t *); 245 int (*sync)(dm_table_entry_t *);
246 int (*upcall)(dm_table_entry_t *, struct buf *); 246 int (*upcall)(dm_table_entry_t *, struct buf *);
247 int (*secsize)(dm_table_entry_t *, unsigned *); 247 int (*secsize)(dm_table_entry_t *, unsigned *);
248  248
249 uint32_t version[3]; 249 uint32_t version[3];
250 int ref_cnt; 250 int ref_cnt;
251  251
252 TAILQ_ENTRY(dm_target) dm_target_next; 252 TAILQ_ENTRY(dm_target) dm_target_next;
253} dm_target_t; 253} dm_target_t;
254 254
255/* Interface structures */ 255/* Interface structures */
256 256
257/* 257/*
258 * This structure is used to translate command sent to kernel driver in 258 * This structure is used to translate command sent to kernel driver in
259 * <key>command</key> 259 * <key>command</key>
260 * <value></value> 260 * <value></value>
261 * to function which I can call, and if the command is allowed for 261 * to function which I can call, and if the command is allowed for
262 * non-superusers. 262 * non-superusers.
263 */ 263 */
264struct cmd_function { 264struct cmd_function {
265 const char *cmd; 265 const char *cmd;
266 int (*fn)(prop_dictionary_t); 266 int (*fn)(prop_dictionary_t);
267 int allowed; 267 int allowed;
268}; 268};
269 269
270/* device-mapper */ 270/* device-mapper */
271void dmgetproperties(struct disk *, dm_table_head_t *); 271void dmgetproperties(struct disk *, dm_table_head_t *);
272 272
273/* dm_ioctl.c */ 273/* dm_ioctl.c */
274int dm_dev_create_ioctl(prop_dictionary_t); 274int dm_dev_create_ioctl(prop_dictionary_t);
275int dm_dev_list_ioctl(prop_dictionary_t); 275int dm_dev_list_ioctl(prop_dictionary_t);
276int dm_dev_remove_ioctl(prop_dictionary_t); 276int dm_dev_remove_ioctl(prop_dictionary_t);
277int dm_dev_rename_ioctl(prop_dictionary_t); 277int dm_dev_rename_ioctl(prop_dictionary_t);
278int dm_dev_resume_ioctl(prop_dictionary_t); 278int dm_dev_resume_ioctl(prop_dictionary_t);
279int dm_dev_status_ioctl(prop_dictionary_t); 279int dm_dev_status_ioctl(prop_dictionary_t);
280int dm_dev_suspend_ioctl(prop_dictionary_t); 280int dm_dev_suspend_ioctl(prop_dictionary_t);
281 281
282int dm_check_version(prop_dictionary_t); 282int dm_check_version(prop_dictionary_t);
283int dm_get_version_ioctl(prop_dictionary_t); 283int dm_get_version_ioctl(prop_dictionary_t);
284int dm_list_versions_ioctl(prop_dictionary_t); 284int dm_list_versions_ioctl(prop_dictionary_t);
285 285
286int dm_table_clear_ioctl(prop_dictionary_t); 286int dm_table_clear_ioctl(prop_dictionary_t);
287int dm_table_deps_ioctl(prop_dictionary_t); 287int dm_table_deps_ioctl(prop_dictionary_t);
288int dm_table_load_ioctl(prop_dictionary_t); 288int dm_table_load_ioctl(prop_dictionary_t);
289int dm_table_status_ioctl(prop_dictionary_t); 289int dm_table_status_ioctl(prop_dictionary_t);
290 290
291/* dm_target.c */ 291/* dm_target.c */
292dm_target_t* dm_target_alloc(const char *); 292dm_target_t* dm_target_alloc(const char *);
293dm_target_t* dm_target_autoload(const char *); 293dm_target_t* dm_target_autoload(const char *);
294int dm_target_destroy(void); 294int dm_target_destroy(void);
295int dm_target_insert(dm_target_t *); 295int dm_target_insert(dm_target_t *);
296prop_array_t dm_target_prop_list(void); 296prop_array_t dm_target_prop_list(void);
297dm_target_t* dm_target_lookup(const char *); 297dm_target_t* dm_target_lookup(const char *);
298int dm_target_rem(char *); 298int dm_target_rem(char *);
299void dm_target_unbusy(dm_target_t *); 299void dm_target_unbusy(dm_target_t *);
300void dm_target_busy(dm_target_t *); 300void dm_target_busy(dm_target_t *);
301 301
302/* XXX temporally add */ 302/* XXX temporally add */
303int dm_target_init(void); 303int dm_target_init(void);
304 304
305#define DM_MAX_PARAMS_SIZE 1024 305#define DM_MAX_PARAMS_SIZE 1024
306 306
307/* dm_target_linear.c */ 307/* dm_target_linear.c */
308int dm_target_linear_init(dm_dev_t *, void**, char *); 308int dm_target_linear_init(dm_dev_t *, void**, char *);
309char * dm_target_linear_status(void *); 309char * dm_target_linear_status(void *);
310int dm_target_linear_strategy(dm_table_entry_t *, struct buf *); 310int dm_target_linear_strategy(dm_table_entry_t *, struct buf *);
311int dm_target_linear_sync(dm_table_entry_t *); 311int dm_target_linear_sync(dm_table_entry_t *);
312int dm_target_linear_deps(dm_table_entry_t *, prop_array_t); 312int dm_target_linear_deps(dm_table_entry_t *, prop_array_t);
313int dm_target_linear_destroy(dm_table_entry_t *); 313int dm_target_linear_destroy(dm_table_entry_t *);
314int dm_target_linear_upcall(dm_table_entry_t *, struct buf *); 314int dm_target_linear_upcall(dm_table_entry_t *, struct buf *);
315int dm_target_linear_secsize(dm_table_entry_t *, unsigned *); 315int dm_target_linear_secsize(dm_table_entry_t *, unsigned *);
316 316
317/* Generic function used to convert char to string */ 317/* Generic function used to convert char to string */
318uint64_t atoi(const char *);  318uint64_t atoi(const char *);
319 319
320/* dm_target_stripe.c */ 320/* dm_target_stripe.c */
321int dm_target_stripe_init(dm_dev_t *, void**, char *); 321int dm_target_stripe_init(dm_dev_t *, void**, char *);
322char * dm_target_stripe_status(void *); 322char * dm_target_stripe_status(void *);
323int dm_target_stripe_strategy(dm_table_entry_t *, struct buf *); 323int dm_target_stripe_strategy(dm_table_entry_t *, struct buf *);
324int dm_target_stripe_sync(dm_table_entry_t *); 324int dm_target_stripe_sync(dm_table_entry_t *);
325int dm_target_stripe_deps(dm_table_entry_t *, prop_array_t); 325int dm_target_stripe_deps(dm_table_entry_t *, prop_array_t);
326int dm_target_stripe_destroy(dm_table_entry_t *); 326int dm_target_stripe_destroy(dm_table_entry_t *);
327int dm_target_stripe_upcall(dm_table_entry_t *, struct buf *); 327int dm_target_stripe_upcall(dm_table_entry_t *, struct buf *);
328int dm_target_stripe_secsize(dm_table_entry_t *, unsigned *); 328int dm_target_stripe_secsize(dm_table_entry_t *, unsigned *);
329 329
330/* dm_table.c */ 330/* dm_table.c */
331#define DM_TABLE_ACTIVE 0 331#define DM_TABLE_ACTIVE 0
332#define DM_TABLE_INACTIVE 1 332#define DM_TABLE_INACTIVE 1
333 333
334int dm_table_destroy(dm_table_head_t *, uint8_t); 334int dm_table_destroy(dm_table_head_t *, uint8_t);
335uint64_t dm_table_size(dm_table_head_t *); 335uint64_t dm_table_size(dm_table_head_t *);
 336uint64_t dm_inactive_table_size(dm_table_head_t *);
336void dm_table_disksize(dm_table_head_t *, uint64_t *, unsigned *); 337void dm_table_disksize(dm_table_head_t *, uint64_t *, unsigned *);
337dm_table_t * dm_table_get_entry(dm_table_head_t *, uint8_t); 338dm_table_t * dm_table_get_entry(dm_table_head_t *, uint8_t);
338int dm_table_get_target_count(dm_table_head_t *, uint8_t); 339int dm_table_get_target_count(dm_table_head_t *, uint8_t);
339void dm_table_release(dm_table_head_t *, uint8_t s); 340void dm_table_release(dm_table_head_t *, uint8_t s);
340void dm_table_switch_tables(dm_table_head_t *); 341void dm_table_switch_tables(dm_table_head_t *);
341void dm_table_head_init(dm_table_head_t *); 342void dm_table_head_init(dm_table_head_t *);
342void dm_table_head_destroy(dm_table_head_t *); 343void dm_table_head_destroy(dm_table_head_t *);
343 344
344/* dm_dev.c */ 345/* dm_dev.c */
345dm_dev_t* dm_dev_alloc(void); 346dm_dev_t* dm_dev_alloc(void);
346void dm_dev_busy(dm_dev_t *); 347void dm_dev_busy(dm_dev_t *);
347int dm_dev_destroy(void); 348int dm_dev_destroy(void);
348dm_dev_t* dm_dev_detach(device_t); 349dm_dev_t* dm_dev_detach(device_t);
349int dm_dev_free(dm_dev_t *); 350int dm_dev_free(dm_dev_t *);
350int dm_dev_init(void); 351int dm_dev_init(void);
351int dm_dev_insert(dm_dev_t *); 352int dm_dev_insert(dm_dev_t *);
352dm_dev_t* dm_dev_lookup(const char *, const char *, int); 353dm_dev_t* dm_dev_lookup(const char *, const char *, int);
353prop_array_t dm_dev_prop_list(void); 354prop_array_t dm_dev_prop_list(void);
354dm_dev_t* dm_dev_rem(const char *, const char *, int); 355dm_dev_t* dm_dev_rem(const char *, const char *, int);
355/*int dm_dev_test_minor(int);*/ 356/*int dm_dev_test_minor(int);*/
356void dm_dev_unbusy(dm_dev_t *); 357void dm_dev_unbusy(dm_dev_t *);
357 358
358/* dm_pdev.c */ 359/* dm_pdev.c */
359int dm_pdev_decr(dm_pdev_t *); 360int dm_pdev_decr(dm_pdev_t *);
360int dm_pdev_destroy(void); 361int dm_pdev_destroy(void);
361int dm_pdev_init(void); 362int dm_pdev_init(void);
362dm_pdev_t* dm_pdev_insert(const char *); 363dm_pdev_t* dm_pdev_insert(const char *);
363 364
364#endif /*_KERNEL*/ 365#endif /*_KERNEL*/
365 366
366#endif /*_DM_DEV_H_*/ 367#endif /*_DM_DEV_H_*/

cvs diff -r1.25 -r1.26 src/sys/dev/dm/dm_ioctl.c (switch to unified diff)

--- src/sys/dev/dm/dm_ioctl.c 2011/05/24 15:23:41 1.25
+++ src/sys/dev/dm/dm_ioctl.c 2011/08/27 17:07:49 1.26
@@ -1,977 +1,978 @@ @@ -1,977 +1,978 @@
1/* $NetBSD: dm_ioctl.c,v 1.25 2011/05/24 15:23:41 joerg Exp $ */ 1/* $NetBSD: dm_ioctl.c,v 1.26 2011/08/27 17:07:49 ahoka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Hamsik. 8 * by Adam Hamsik.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Locking is used to synchronise between ioctl calls and between dm_table's 33 * Locking is used to synchronise between ioctl calls and between dm_table's
34 * users. 34 * users.
35 * 35 *
36 * ioctl locking: 36 * ioctl locking:
37 * Simple reference counting, to count users of device will be used routines 37 * Simple reference counting, to count users of device will be used routines
38 * dm_dev_busy/dm_dev_unbusy are used for that. 38 * dm_dev_busy/dm_dev_unbusy are used for that.
39 * dm_dev_lookup/dm_dev_rem call dm_dev_busy before return(caller is therefore 39 * dm_dev_lookup/dm_dev_rem call dm_dev_busy before return(caller is therefore
40 * holder of reference_counter last). 40 * holder of reference_counter last).
41 * 41 *
42 * ioctl routines which change/remove dm_dev parameters must wait on 42 * ioctl routines which change/remove dm_dev parameters must wait on
43 * dm_dev::dev_cv and when last user will call dm_dev_unbusy they will wake 43 * dm_dev::dev_cv and when last user will call dm_dev_unbusy they will wake
44 * up them. 44 * up them.
45 * 45 *
46 * table_head locking: 46 * table_head locking:
47 * To access table entries dm_table_* routines must be used. 47 * To access table entries dm_table_* routines must be used.
48 * 48 *
49 * dm_table_get_entry will increment table users reference 49 * dm_table_get_entry will increment table users reference
50 * counter. It will return active or inactive table depends 50 * counter. It will return active or inactive table depends
51 * on uint8_t argument. 51 * on uint8_t argument.
52 * 52 *
53 * dm_table_release must be called for every table_entry from 53 * dm_table_release must be called for every table_entry from
54 * dm_table_get_entry. Between these to calls tables can'tbe switched 54 * dm_table_get_entry. Between these to calls tables can'tbe switched
55 * or destroyed. 55 * or destroyed.
56 * 56 *
57 * dm_table_head_init initialize talbe_entries SLISTS and io_cv. 57 * dm_table_head_init initialize talbe_entries SLISTS and io_cv.
58 * 58 *
59 * dm_table_head_destroy destroy cv. 59 * dm_table_head_destroy destroy cv.
60 * 60 *
61 * There are two types of users for dm_table_head first type will 61 * There are two types of users for dm_table_head first type will
62 * only read list and try to do anything with it e.g. dmstrategy, 62 * only read list and try to do anything with it e.g. dmstrategy,
63 * dm_table_size etc. There is another user for table_head which wants 63 * dm_table_size etc. There is another user for table_head which wants
64 * to change table lists e.g. dm_dev_resume_ioctl, dm_dev_remove_ioctl, 64 * to change table lists e.g. dm_dev_resume_ioctl, dm_dev_remove_ioctl,
65 * dm_table_clear_ioctl. 65 * dm_table_clear_ioctl.
66 * 66 *
67 * NOTE: It is not allowed to call dm_table_destroy, dm_table_switch_tables 67 * NOTE: It is not allowed to call dm_table_destroy, dm_table_switch_tables
68 * with hold table reference counter. Table reference counter is hold 68 * with hold table reference counter. Table reference counter is hold
69 * after calling dm_table_get_entry routine. After calling this 69 * after calling dm_table_get_entry routine. After calling this
70 * function user must call dm_table_release before any writer table 70 * function user must call dm_table_release before any writer table
71 * operation. 71 * operation.
72 * 72 *
73 * Example: dm_table_get_entry 73 * Example: dm_table_get_entry
74 * dm_table_destroy/dm_table_switch_tables 74 * dm_table_destroy/dm_table_switch_tables
75 * This exaple will lead to deadlock situation because after dm_table_get_entry 75 * This exaple will lead to deadlock situation because after dm_table_get_entry
76 * table reference counter is != 0 and dm_table_destroy have to wait on cv until 76 * table reference counter is != 0 and dm_table_destroy have to wait on cv until
77 * reference counter is 0. 77 * reference counter is 0.
78 * 78 *
79 */ 79 */
80 80
81#include <sys/types.h> 81#include <sys/types.h>
82#include <sys/param.h> 82#include <sys/param.h>
83 83
84#include <sys/device.h> 84#include <sys/device.h>
85#include <sys/disk.h> 85#include <sys/disk.h>
86#include <sys/disklabel.h> 86#include <sys/disklabel.h>
87#include <sys/kmem.h> 87#include <sys/kmem.h>
88#include <sys/malloc.h> 88#include <sys/malloc.h>
89#include <sys/vnode.h> 89#include <sys/vnode.h>
90 90
91#include <machine/int_fmtio.h> 91#include <machine/int_fmtio.h>
92 92
93#include "netbsd-dm.h" 93#include "netbsd-dm.h"
94#include "dm.h" 94#include "dm.h"
95 95
96static uint32_t sc_minor_num; 96static uint32_t sc_minor_num;
97extern const struct dkdriver dmdkdriver; 97extern const struct dkdriver dmdkdriver;
98uint32_t dm_dev_counter; 98uint32_t dm_dev_counter;
99 99
100/* Generic cf_data for device-mapper driver */ 100/* Generic cf_data for device-mapper driver */
101static struct cfdata dm_cfdata = { 101static struct cfdata dm_cfdata = {
102 .cf_name = "dm", 102 .cf_name = "dm",
103 .cf_atname = "dm", 103 .cf_atname = "dm",
104 .cf_fstate = FSTATE_STAR, 104 .cf_fstate = FSTATE_STAR,
105 .cf_unit = 0 105 .cf_unit = 0
106}; 106};
107#define DM_REMOVE_FLAG(flag, name) do { \ 107#define DM_REMOVE_FLAG(flag, name) do { \
108 prop_dictionary_get_uint32(dm_dict,DM_IOCTL_FLAGS,&flag); \ 108 prop_dictionary_get_uint32(dm_dict,DM_IOCTL_FLAGS,&flag); \
109 flag &= ~name; \ 109 flag &= ~name; \
110 prop_dictionary_set_uint32(dm_dict,DM_IOCTL_FLAGS,flag); \ 110 prop_dictionary_set_uint32(dm_dict,DM_IOCTL_FLAGS,flag); \
111} while (/*CONSTCOND*/0) 111} while (/*CONSTCOND*/0)
112 112
113#define DM_ADD_FLAG(flag, name) do { \ 113#define DM_ADD_FLAG(flag, name) do { \
114 prop_dictionary_get_uint32(dm_dict,DM_IOCTL_FLAGS,&flag); \ 114 prop_dictionary_get_uint32(dm_dict,DM_IOCTL_FLAGS,&flag); \
115 flag |= name; \ 115 flag |= name; \
116 prop_dictionary_set_uint32(dm_dict,DM_IOCTL_FLAGS,flag); \ 116 prop_dictionary_set_uint32(dm_dict,DM_IOCTL_FLAGS,flag); \
117} while (/*CONSTCOND*/0) 117} while (/*CONSTCOND*/0)
118 118
119static int dm_dbg_print_flags(int); 119static int dm_dbg_print_flags(int);
120 120
121/* 121/*
122 * Print flags sent to the kernel from libevmapper. 122 * Print flags sent to the kernel from libevmapper.
123 */ 123 */
124static int 124static int
125dm_dbg_print_flags(int flags) 125dm_dbg_print_flags(int flags)
126{ 126{
127 aprint_debug("dbg_print --- %d\n", flags); 127 aprint_debug("dbg_print --- %d\n", flags);
128 128
129 if (flags & DM_READONLY_FLAG) 129 if (flags & DM_READONLY_FLAG)
130 aprint_debug("dbg_flags: DM_READONLY_FLAG set In/Out\n"); 130 aprint_debug("dbg_flags: DM_READONLY_FLAG set In/Out\n");
131 131
132 if (flags & DM_SUSPEND_FLAG) 132 if (flags & DM_SUSPEND_FLAG)
133 aprint_debug("dbg_flags: DM_SUSPEND_FLAG set In/Out \n"); 133 aprint_debug("dbg_flags: DM_SUSPEND_FLAG set In/Out \n");
134 134
135 if (flags & DM_PERSISTENT_DEV_FLAG) 135 if (flags & DM_PERSISTENT_DEV_FLAG)
136 aprint_debug("db_flags: DM_PERSISTENT_DEV_FLAG set In\n"); 136 aprint_debug("db_flags: DM_PERSISTENT_DEV_FLAG set In\n");
137 137
138 if (flags & DM_STATUS_TABLE_FLAG) 138 if (flags & DM_STATUS_TABLE_FLAG)
139 aprint_debug("dbg_flags: DM_STATUS_TABLE_FLAG set In\n"); 139 aprint_debug("dbg_flags: DM_STATUS_TABLE_FLAG set In\n");
140 140
141 if (flags & DM_ACTIVE_PRESENT_FLAG) 141 if (flags & DM_ACTIVE_PRESENT_FLAG)
142 aprint_debug("dbg_flags: DM_ACTIVE_PRESENT_FLAG set Out\n"); 142 aprint_debug("dbg_flags: DM_ACTIVE_PRESENT_FLAG set Out\n");
143 143
144 if (flags & DM_INACTIVE_PRESENT_FLAG) 144 if (flags & DM_INACTIVE_PRESENT_FLAG)
145 aprint_debug("dbg_flags: DM_INACTIVE_PRESENT_FLAG set Out\n"); 145 aprint_debug("dbg_flags: DM_INACTIVE_PRESENT_FLAG set Out\n");
146 146
147 if (flags & DM_BUFFER_FULL_FLAG) 147 if (flags & DM_BUFFER_FULL_FLAG)
148 aprint_debug("dbg_flags: DM_BUFFER_FULL_FLAG set Out\n"); 148 aprint_debug("dbg_flags: DM_BUFFER_FULL_FLAG set Out\n");
149 149
150 if (flags & DM_SKIP_BDGET_FLAG) 150 if (flags & DM_SKIP_BDGET_FLAG)
151 aprint_debug("dbg_flags: DM_SKIP_BDGET_FLAG set In\n"); 151 aprint_debug("dbg_flags: DM_SKIP_BDGET_FLAG set In\n");
152 152
153 if (flags & DM_SKIP_LOCKFS_FLAG) 153 if (flags & DM_SKIP_LOCKFS_FLAG)
154 aprint_debug("dbg_flags: DM_SKIP_LOCKFS_FLAG set In\n"); 154 aprint_debug("dbg_flags: DM_SKIP_LOCKFS_FLAG set In\n");
155 155
156 if (flags & DM_NOFLUSH_FLAG) 156 if (flags & DM_NOFLUSH_FLAG)
157 aprint_debug("dbg_flags: DM_NOFLUSH_FLAG set In\n"); 157 aprint_debug("dbg_flags: DM_NOFLUSH_FLAG set In\n");
158 158
159 return 0; 159 return 0;
160} 160}
161/* 161/*
162 * Get version ioctl call I do it as default therefore this 162 * Get version ioctl call I do it as default therefore this
163 * function is unused now. 163 * function is unused now.
164 */ 164 */
165int 165int
166dm_get_version_ioctl(prop_dictionary_t dm_dict) 166dm_get_version_ioctl(prop_dictionary_t dm_dict)
167{ 167{
168 168
169 return 0; 169 return 0;
170} 170}
171/* 171/*
172 * Get list of all available targets from global 172 * Get list of all available targets from global
173 * target list and sent them back to libdevmapper. 173 * target list and sent them back to libdevmapper.
174 */ 174 */
175int 175int
176dm_list_versions_ioctl(prop_dictionary_t dm_dict) 176dm_list_versions_ioctl(prop_dictionary_t dm_dict)
177{ 177{
178 prop_array_t target_list; 178 prop_array_t target_list;
179 uint32_t flags; 179 uint32_t flags;
180 180
181 flags = 0; 181 flags = 0;
182 182
183 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 183 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
184 184
185 dm_dbg_print_flags(flags); 185 dm_dbg_print_flags(flags);
186 target_list = dm_target_prop_list(); 186 target_list = dm_target_prop_list();
187 187
188 prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, target_list); 188 prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, target_list);
189 prop_object_release(target_list); 189 prop_object_release(target_list);
190 190
191 return 0; 191 return 0;
192} 192}
193/* 193/*
194 * Create in-kernel entry for device. Device attributes such as name, uuid are 194 * Create in-kernel entry for device. Device attributes such as name, uuid are
195 * taken from proplib dictionary. 195 * taken from proplib dictionary.
196 * 196 *
197 */ 197 */
198int 198int
199dm_dev_create_ioctl(prop_dictionary_t dm_dict) 199dm_dev_create_ioctl(prop_dictionary_t dm_dict)
200{ 200{
201 dm_dev_t *dmv; 201 dm_dev_t *dmv;
202 const char *name, *uuid; 202 const char *name, *uuid;
203 int r, flags; 203 int r, flags;
204 device_t devt; 204 device_t devt;
205 205
206 r = 0; 206 r = 0;
207 flags = 0; 207 flags = 0;
208 name = NULL; 208 name = NULL;
209 uuid = NULL; 209 uuid = NULL;
210 210
211 /* Get needed values from dictionary. */ 211 /* Get needed values from dictionary. */
212 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); 212 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
213 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); 213 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
214 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 214 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
215 215
216 dm_dbg_print_flags(flags); 216 dm_dbg_print_flags(flags);
217 217
218 /* Lookup name and uuid if device already exist quit. */ 218 /* Lookup name and uuid if device already exist quit. */
219 if ((dmv = dm_dev_lookup(name, uuid, -1)) != NULL) { 219 if ((dmv = dm_dev_lookup(name, uuid, -1)) != NULL) {
220 DM_ADD_FLAG(flags, DM_EXISTS_FLAG); /* Device already exists */ 220 DM_ADD_FLAG(flags, DM_EXISTS_FLAG); /* Device already exists */
221 dm_dev_unbusy(dmv); 221 dm_dev_unbusy(dmv);
222 return EEXIST; 222 return EEXIST;
223 } 223 }
224 if ((devt = config_attach_pseudo(&dm_cfdata)) == NULL) { 224 if ((devt = config_attach_pseudo(&dm_cfdata)) == NULL) {
225 aprint_error("Unable to attach pseudo device dm/%s\n", name); 225 aprint_error("Unable to attach pseudo device dm/%s\n", name);
226 return (ENOMEM); 226 return (ENOMEM);
227 } 227 }
228 if ((dmv = dm_dev_alloc()) == NULL) 228 if ((dmv = dm_dev_alloc()) == NULL)
229 return ENOMEM; 229 return ENOMEM;
230 230
231 if (uuid) 231 if (uuid)
232 strncpy(dmv->uuid, uuid, DM_UUID_LEN); 232 strncpy(dmv->uuid, uuid, DM_UUID_LEN);
233 else 233 else
234 dmv->uuid[0] = '\0'; 234 dmv->uuid[0] = '\0';
235 235
236 if (name) 236 if (name)
237 strlcpy(dmv->name, name, DM_NAME_LEN); 237 strlcpy(dmv->name, name, DM_NAME_LEN);
238 238
239 dmv->minor = (uint64_t)atomic_inc_32_nv(&sc_minor_num); 239 dmv->minor = (uint64_t)atomic_inc_32_nv(&sc_minor_num);
240 dmv->flags = 0; /* device flags are set when needed */ 240 dmv->flags = 0; /* device flags are set when needed */
241 dmv->ref_cnt = 0; 241 dmv->ref_cnt = 0;
242 dmv->event_nr = 0; 242 dmv->event_nr = 0;
243 dmv->dev_type = 0; 243 dmv->dev_type = 0;
244 dmv->devt = devt; 244 dmv->devt = devt;
245 245
246 dm_table_head_init(&dmv->table_head); 246 dm_table_head_init(&dmv->table_head);
247 247
248 mutex_init(&dmv->dev_mtx, MUTEX_DEFAULT, IPL_NONE); 248 mutex_init(&dmv->dev_mtx, MUTEX_DEFAULT, IPL_NONE);
249 mutex_init(&dmv->diskp_mtx, MUTEX_DEFAULT, IPL_NONE); 249 mutex_init(&dmv->diskp_mtx, MUTEX_DEFAULT, IPL_NONE);
250 cv_init(&dmv->dev_cv, "dm_dev"); 250 cv_init(&dmv->dev_cv, "dm_dev");
251 251
252 if (flags & DM_READONLY_FLAG) 252 if (flags & DM_READONLY_FLAG)
253 dmv->flags |= DM_READONLY_FLAG; 253 dmv->flags |= DM_READONLY_FLAG;
254 254
255 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); 255 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
256 256
257 disk_init(dmv->diskp, dmv->name, &dmdkdriver); 257 disk_init(dmv->diskp, dmv->name, &dmdkdriver);
258 disk_attach(dmv->diskp); 258 disk_attach(dmv->diskp);
259 259
260 dmv->diskp->dk_info = NULL; 260 dmv->diskp->dk_info = NULL;
261 261
262 if ((r = dm_dev_insert(dmv)) != 0) 262 if ((r = dm_dev_insert(dmv)) != 0)
263 dm_dev_free(dmv); 263 dm_dev_free(dmv);
264 264
265 DM_ADD_FLAG(flags, DM_EXISTS_FLAG); 265 DM_ADD_FLAG(flags, DM_EXISTS_FLAG);
266 DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); 266 DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);
267 267
268 /* Increment device counter After creating device */ 268 /* Increment device counter After creating device */
269 atomic_inc_32(&dm_dev_counter); 269 atomic_inc_32(&dm_dev_counter);
270 270
271 return r; 271 return r;
272} 272}
273/* 273/*
274 * Get list of created device-mapper devices fromglobal list and 274 * Get list of created device-mapper devices fromglobal list and
275 * send it to kernel. 275 * send it to kernel.
276 * 276 *
277 * Output dictionary: 277 * Output dictionary:
278 * 278 *
279 * <key>cmd_data</key> 279 * <key>cmd_data</key>
280 * <array> 280 * <array>
281 * <dict> 281 * <dict>
282 * <key>name<key> 282 * <key>name<key>
283 * <string>...</string> 283 * <string>...</string>
284 * 284 *
285 * <key>dev</key> 285 * <key>dev</key>
286 * <integer>...</integer> 286 * <integer>...</integer>
287 * </dict> 287 * </dict>
288 * </array> 288 * </array>
289 * 289 *
290 */ 290 */
291int 291int
292dm_dev_list_ioctl(prop_dictionary_t dm_dict) 292dm_dev_list_ioctl(prop_dictionary_t dm_dict)
293{ 293{
294 prop_array_t dev_list; 294 prop_array_t dev_list;
295 295
296 uint32_t flags; 296 uint32_t flags;
297 297
298 flags = 0; 298 flags = 0;
299 299
300 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 300 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
301 301
302 dm_dbg_print_flags(flags); 302 dm_dbg_print_flags(flags);
303 303
304 dev_list = dm_dev_prop_list(); 304 dev_list = dm_dev_prop_list();
305 305
306 prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, dev_list); 306 prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, dev_list);
307 prop_object_release(dev_list); 307 prop_object_release(dev_list);
308 308
309 return 0; 309 return 0;
310} 310}
311/* 311/*
312 * Rename selected devices old name is in struct dm_ioctl. 312 * Rename selected devices old name is in struct dm_ioctl.
313 * newname is taken from dictionary 313 * newname is taken from dictionary
314 * 314 *
315 * <key>cmd_data</key> 315 * <key>cmd_data</key>
316 * <array> 316 * <array>
317 * <string>...</string> 317 * <string>...</string>
318 * </array> 318 * </array>
319 */ 319 */
320int 320int
321dm_dev_rename_ioctl(prop_dictionary_t dm_dict) 321dm_dev_rename_ioctl(prop_dictionary_t dm_dict)
322{ 322{
323 prop_array_t cmd_array; 323 prop_array_t cmd_array;
324 dm_dev_t *dmv; 324 dm_dev_t *dmv;
325 325
326 const char *name, *uuid, *n_name; 326 const char *name, *uuid, *n_name;
327 uint32_t flags, minor; 327 uint32_t flags, minor;
328 328
329 name = NULL; 329 name = NULL;
330 uuid = NULL; 330 uuid = NULL;
331 minor = 0; 331 minor = 0;
332 332
333 /* Get needed values from dictionary. */ 333 /* Get needed values from dictionary. */
334 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); 334 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
335 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); 335 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
336 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 336 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
337 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor); 337 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);
338 338
339 dm_dbg_print_flags(flags); 339 dm_dbg_print_flags(flags);
340 340
341 cmd_array = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA); 341 cmd_array = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA);
342 342
343 prop_array_get_cstring_nocopy(cmd_array, 0, &n_name); 343 prop_array_get_cstring_nocopy(cmd_array, 0, &n_name);
344 344
345 if (strlen(n_name) + 1 > DM_NAME_LEN) 345 if (strlen(n_name) + 1 > DM_NAME_LEN)
346 return EINVAL; 346 return EINVAL;
347 347
348 if ((dmv = dm_dev_rem(name, uuid, minor)) == NULL) { 348 if ((dmv = dm_dev_rem(name, uuid, minor)) == NULL) {
349 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG); 349 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
350 return ENOENT; 350 return ENOENT;
351 } 351 }
352 /* change device name */ 352 /* change device name */
353 /* 353 /*
354 * XXX How to deal with this change, name only used in 354 * XXX How to deal with this change, name only used in
355 * dm_dev_routines, should I add dm_dev_change_name which will run 355 * dm_dev_routines, should I add dm_dev_change_name which will run
356 * under the dm_dev_list mutex ? 356 * under the dm_dev_list mutex ?
357 */ 357 */
358 strlcpy(dmv->name, n_name, DM_NAME_LEN); 358 strlcpy(dmv->name, n_name, DM_NAME_LEN);
359 359
360 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt); 360 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt);
361 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); 361 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
362 prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmv->uuid); 362 prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmv->uuid);
363 363
364 dm_dev_insert(dmv); 364 dm_dev_insert(dmv);
365 365
366 return 0; 366 return 0;
367} 367}
368/* 368/*
369 * Remove device from global list I have to remove active 369 * Remove device from global list I have to remove active
370 * and inactive tables first. 370 * and inactive tables first.
371 */ 371 */
372int 372int
373dm_dev_remove_ioctl(prop_dictionary_t dm_dict) 373dm_dev_remove_ioctl(prop_dictionary_t dm_dict)
374{ 374{
375 dm_dev_t *dmv; 375 dm_dev_t *dmv;
376 const char *name, *uuid; 376 const char *name, *uuid;
377 uint32_t flags, minor; 377 uint32_t flags, minor;
378 device_t devt; 378 device_t devt;
379 379
380 flags = 0; 380 flags = 0;
381 name = NULL; 381 name = NULL;
382 uuid = NULL; 382 uuid = NULL;
383 383
384 /* Get needed values from dictionary. */ 384 /* Get needed values from dictionary. */
385 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); 385 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
386 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); 386 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
387 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 387 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
388 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor); 388 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);
389 389
390 dm_dbg_print_flags(flags); 390 dm_dbg_print_flags(flags);
391 391
392 /* 392 /*
393 * This seems as hack to me, probably use routine dm_dev_get_devt to 393 * This seems as hack to me, probably use routine dm_dev_get_devt to
394 * atomicaly get devt from device. 394 * atomicaly get devt from device.
395 */ 395 */
396 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) { 396 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
397 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG); 397 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
398 return ENOENT; 398 return ENOENT;
399 } 399 }
400 devt = dmv->devt; 400 devt = dmv->devt;
401 401
402 dm_dev_unbusy(dmv); 402 dm_dev_unbusy(dmv);
403 403
404 /* 404 /*
405 * This will call dm_detach routine which will actually removes 405 * This will call dm_detach routine which will actually removes
406 * device. 406 * device.
407 */ 407 */
408 return config_detach(devt, DETACH_QUIET); 408 return config_detach(devt, DETACH_QUIET);
409} 409}
410/* 410/*
411 * Return actual state of device to libdevmapper. 411 * Return actual state of device to libdevmapper.
412 */ 412 */
413int 413int
414dm_dev_status_ioctl(prop_dictionary_t dm_dict) 414dm_dev_status_ioctl(prop_dictionary_t dm_dict)
415{ 415{
416 dm_dev_t *dmv; 416 dm_dev_t *dmv;
417 const char *name, *uuid; 417 const char *name, *uuid;
418 uint32_t flags, j, minor; 418 uint32_t flags, j, minor;
419 419
420 name = NULL; 420 name = NULL;
421 uuid = NULL; 421 uuid = NULL;
422 flags = 0; 422 flags = 0;
423 j = 0; 423 j = 0;
424 424
425 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); 425 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
426 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); 426 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
427 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 427 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
428 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor); 428 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);
429 429
430 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) { 430 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
431 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG); 431 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
432 return ENOENT; 432 return ENOENT;
433 } 433 }
434 dm_dbg_print_flags(dmv->flags); 434 dm_dbg_print_flags(dmv->flags);
435 435
436 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt); 436 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt);
437 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); 437 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
438 prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmv->uuid); 438 prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmv->uuid);
439 439
440 if (dmv->flags & DM_SUSPEND_FLAG) 440 if (dmv->flags & DM_SUSPEND_FLAG)
441 DM_ADD_FLAG(flags, DM_SUSPEND_FLAG); 441 DM_ADD_FLAG(flags, DM_SUSPEND_FLAG);
442 442
443 /* 443 /*
444 * Add status flags for tables I have to check both active and 444 * Add status flags for tables I have to check both active and
445 * inactive tables. 445 * inactive tables.
446 */ 446 */
447 if ((j = dm_table_get_target_count(&dmv->table_head, DM_TABLE_ACTIVE))) { 447 if ((j = dm_table_get_target_count(&dmv->table_head, DM_TABLE_ACTIVE))) {
448 DM_ADD_FLAG(flags, DM_ACTIVE_PRESENT_FLAG); 448 DM_ADD_FLAG(flags, DM_ACTIVE_PRESENT_FLAG);
449 } else 449 } else
450 DM_REMOVE_FLAG(flags, DM_ACTIVE_PRESENT_FLAG); 450 DM_REMOVE_FLAG(flags, DM_ACTIVE_PRESENT_FLAG);
451 451
452 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_TARGET_COUNT, j); 452 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_TARGET_COUNT, j);
453 453
454 if (dm_table_get_target_count(&dmv->table_head, DM_TABLE_INACTIVE)) 454 if (dm_table_get_target_count(&dmv->table_head, DM_TABLE_INACTIVE))
455 DM_ADD_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); 455 DM_ADD_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);
456 else 456 else
457 DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); 457 DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);
458 458
459 dm_dev_unbusy(dmv); 459 dm_dev_unbusy(dmv);
460 460
461 return 0; 461 return 0;
462} 462}
463/* 463/*
464 * Set only flag to suggest that device is suspended. This call is 464 * Set only flag to suggest that device is suspended. This call is
465 * not supported in NetBSD. 465 * not supported in NetBSD.
466 * 466 *
467 */ 467 */
468int 468int
469dm_dev_suspend_ioctl(prop_dictionary_t dm_dict) 469dm_dev_suspend_ioctl(prop_dictionary_t dm_dict)
470{ 470{
471 dm_dev_t *dmv; 471 dm_dev_t *dmv;
472 const char *name, *uuid; 472 const char *name, *uuid;
473 uint32_t flags, minor; 473 uint32_t flags, minor;
474 474
475 name = NULL; 475 name = NULL;
476 uuid = NULL; 476 uuid = NULL;
477 flags = 0; 477 flags = 0;
478 478
479 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); 479 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
480 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); 480 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
481 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 481 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
482 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor); 482 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);
483 483
484 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) { 484 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
485 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG); 485 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
486 return ENOENT; 486 return ENOENT;
487 } 487 }
488 atomic_or_32(&dmv->flags, DM_SUSPEND_FLAG); 488 atomic_or_32(&dmv->flags, DM_SUSPEND_FLAG);
489 489
490 dm_dbg_print_flags(dmv->flags); 490 dm_dbg_print_flags(dmv->flags);
491 491
492 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt); 492 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt);
493 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_FLAGS, dmv->flags); 493 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_FLAGS, dmv->flags);
494 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); 494 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
495 495
496 dm_dev_unbusy(dmv); 496 dm_dev_unbusy(dmv);
497 497
498 /* Add flags to dictionary flag after dmv -> dict copy */ 498 /* Add flags to dictionary flag after dmv -> dict copy */
499 DM_ADD_FLAG(flags, DM_EXISTS_FLAG); 499 DM_ADD_FLAG(flags, DM_EXISTS_FLAG);
500 500
501 return 0; 501 return 0;
502} 502}
503/* 503/*
504 * Simulate Linux behaviour better and switch tables here and not in 504 * Simulate Linux behaviour better and switch tables here and not in
505 * dm_table_load_ioctl. 505 * dm_table_load_ioctl.
506 */ 506 */
507int 507int
508dm_dev_resume_ioctl(prop_dictionary_t dm_dict) 508dm_dev_resume_ioctl(prop_dictionary_t dm_dict)
509{ 509{
510 dm_dev_t *dmv; 510 dm_dev_t *dmv;
511 const char *name, *uuid; 511 const char *name, *uuid;
512 uint32_t flags, minor; 512 uint32_t flags, minor;
513 513
514 name = NULL; 514 name = NULL;
515 uuid = NULL; 515 uuid = NULL;
516 flags = 0; 516 flags = 0;
517 517
518 /* 518 /*
519 * char *xml; xml = prop_dictionary_externalize(dm_dict); 519 * char *xml; xml = prop_dictionary_externalize(dm_dict);
520 * printf("%s\n",xml); 520 * printf("%s\n",xml);
521 */ 521 */
522 522
523 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); 523 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
524 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); 524 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
525 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 525 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
526 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor); 526 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);
527 527
528 /* Remove device from global device list */ 528 /* Remove device from global device list */
529 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) { 529 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
530 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG); 530 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
531 return ENOENT; 531 return ENOENT;
532 } 532 }
533 atomic_and_32(&dmv->flags, ~(DM_SUSPEND_FLAG | DM_INACTIVE_PRESENT_FLAG)); 533 atomic_and_32(&dmv->flags, ~(DM_SUSPEND_FLAG | DM_INACTIVE_PRESENT_FLAG));
534 atomic_or_32(&dmv->flags, DM_ACTIVE_PRESENT_FLAG); 534 atomic_or_32(&dmv->flags, DM_ACTIVE_PRESENT_FLAG);
535 535
536 dm_table_switch_tables(&dmv->table_head); 536 dm_table_switch_tables(&dmv->table_head);
537 537
538 DM_ADD_FLAG(flags, DM_EXISTS_FLAG); 538 DM_ADD_FLAG(flags, DM_EXISTS_FLAG);
539 539
540 dmgetproperties(dmv->diskp, &dmv->table_head); 540 dmgetproperties(dmv->diskp, &dmv->table_head);
541 541
542 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt); 542 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt);
543 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_FLAGS, flags); 543 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_FLAGS, flags);
544 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); 544 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
545 545
546 dm_dev_unbusy(dmv); 546 dm_dev_unbusy(dmv);
547 547
548 /* Destroy inactive table after resume. */ 548 /* Destroy inactive table after resume. */
549 dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE); 549 dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);
550 550
551 return 0; 551 return 0;
552} 552}
553/* 553/*
554 * Table management routines 554 * Table management routines
555 * lvm2tools doens't send name/uuid to kernel with table 555 * lvm2tools doens't send name/uuid to kernel with table
556 * for lookup I have to use minor number. 556 * for lookup I have to use minor number.
557 */ 557 */
558 558
559/* 559/*
560 * Remove inactive table from device. Routines which work's with inactive tables 560 * Remove inactive table from device. Routines which work's with inactive tables
561 * doesn't need to synchronise with dmstrategy. They can synchronise themselves with mutex?. 561 * doesn't need to synchronise with dmstrategy. They can synchronise themselves with mutex?.
562 * 562 *
563 */ 563 */
564int 564int
565dm_table_clear_ioctl(prop_dictionary_t dm_dict) 565dm_table_clear_ioctl(prop_dictionary_t dm_dict)
566{ 566{
567 dm_dev_t *dmv; 567 dm_dev_t *dmv;
568 const char *name, *uuid; 568 const char *name, *uuid;
569 uint32_t flags, minor; 569 uint32_t flags, minor;
570 570
571 dmv = NULL; 571 dmv = NULL;
572 name = NULL; 572 name = NULL;
573 uuid = NULL; 573 uuid = NULL;
574 flags = 0; 574 flags = 0;
575 minor = 0; 575 minor = 0;
576 576
577 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); 577 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
578 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); 578 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
579 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 579 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
580 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor); 580 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);
581 581
582 aprint_debug("Clearing inactive table from device: %s--%s\n", 582 aprint_debug("Clearing inactive table from device: %s--%s\n",
583 name, uuid); 583 name, uuid);
584 584
585 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) { 585 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
586 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG); 586 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
587 return ENOENT; 587 return ENOENT;
588 } 588 }
589 /* Select unused table */ 589 /* Select unused table */
590 dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE); 590 dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);
591 591
592 atomic_and_32(&dmv->flags, ~DM_INACTIVE_PRESENT_FLAG); 592 atomic_and_32(&dmv->flags, ~DM_INACTIVE_PRESENT_FLAG);
593 593
594 dm_dev_unbusy(dmv); 594 dm_dev_unbusy(dmv);
595 595
596 return 0; 596 return 0;
597} 597}
598/* 598/*
599 * Get list of physical devices for active table. 599 * Get list of physical devices for active table.
600 * Get dev_t from pdev vnode and insert it into cmd_array. 600 * Get dev_t from pdev vnode and insert it into cmd_array.
601 * 601 *
602 * XXX. This function is called from lvm2tools to get information 602 * XXX. This function is called from lvm2tools to get information
603 * about physical devices, too e.g. during vgcreate. 603 * about physical devices, too e.g. during vgcreate.
604 */ 604 */
605int 605int
606dm_table_deps_ioctl(prop_dictionary_t dm_dict) 606dm_table_deps_ioctl(prop_dictionary_t dm_dict)
607{ 607{
608 dm_dev_t *dmv; 608 dm_dev_t *dmv;
609 dm_table_t *tbl; 609 dm_table_t *tbl;
610 dm_table_entry_t *table_en; 610 dm_table_entry_t *table_en;
611 611
612 prop_array_t cmd_array; 612 prop_array_t cmd_array;
613 const char *name, *uuid; 613 const char *name, *uuid;
614 uint32_t flags, minor; 614 uint32_t flags, minor;
615 615
616 int table_type; 616 int table_type;
617 size_t i; 617 size_t i;
618 618
619 name = NULL; 619 name = NULL;
620 uuid = NULL; 620 uuid = NULL;
621 dmv = NULL; 621 dmv = NULL;
622 flags = 0; 622 flags = 0;
623 623
624 i = 0; 624 i = 0;
625 625
626 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); 626 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
627 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); 627 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
628 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 628 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
629 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor); 629 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);
630 630
631 /* create array for dev_t's */ 631 /* create array for dev_t's */
632 cmd_array = prop_array_create(); 632 cmd_array = prop_array_create();
633 633
634 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) { 634 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
635 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG); 635 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
636 return ENOENT; 636 return ENOENT;
637 } 637 }
638 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); 638 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
639 prop_dictionary_set_cstring(dm_dict, DM_IOCTL_NAME, dmv->name); 639 prop_dictionary_set_cstring(dm_dict, DM_IOCTL_NAME, dmv->name);
640 prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmv->uuid); 640 prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmv->uuid);
641 641
642 aprint_debug("Getting table deps for device: %s\n", dmv->name); 642 aprint_debug("Getting table deps for device: %s\n", dmv->name);
643 643
644 /* 644 /*
645 * if DM_QUERY_INACTIVE_TABLE_FLAG is passed we need to query 645 * if DM_QUERY_INACTIVE_TABLE_FLAG is passed we need to query
646 * INACTIVE TABLE 646 * INACTIVE TABLE
647 */ 647 */
648 if (flags & DM_QUERY_INACTIVE_TABLE_FLAG) 648 if (flags & DM_QUERY_INACTIVE_TABLE_FLAG)
649 table_type = DM_TABLE_INACTIVE; 649 table_type = DM_TABLE_INACTIVE;
650 else 650 else
651 table_type = DM_TABLE_ACTIVE; 651 table_type = DM_TABLE_ACTIVE;
652 652
653 tbl = dm_table_get_entry(&dmv->table_head, table_type); 653 tbl = dm_table_get_entry(&dmv->table_head, table_type);
654 654
655 SLIST_FOREACH(table_en, tbl, next) 655 SLIST_FOREACH(table_en, tbl, next)
656 table_en->target->deps(table_en, cmd_array); 656 table_en->target->deps(table_en, cmd_array);
657 657
658 dm_table_release(&dmv->table_head, table_type); 658 dm_table_release(&dmv->table_head, table_type);
659 dm_dev_unbusy(dmv); 659 dm_dev_unbusy(dmv);
660 660
661 prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, cmd_array); 661 prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, cmd_array);
662 prop_object_release(cmd_array); 662 prop_object_release(cmd_array);
663 663
664 return 0; 664 return 0;
665} 665}
666/* 666/*
667 * Load new table/tables to device. 667 * Load new table/tables to device.
668 * Call apropriate target init routine open all physical pdev's and 668 * Call apropriate target init routine open all physical pdev's and
669 * link them to device. For other targets mirror, strip, snapshot 669 * link them to device. For other targets mirror, strip, snapshot
670 * etc. also add dependency devices to upcalls list. 670 * etc. also add dependency devices to upcalls list.
671 * 671 *
672 * Load table to inactive slot table are switched in dm_device_resume_ioctl. 672 * Load table to inactive slot table are switched in dm_device_resume_ioctl.
673 * This simulates Linux behaviour better there should not be any difference. 673 * This simulates Linux behaviour better there should not be any difference.
674 * 674 *
675 */ 675 */
676int 676int
677dm_table_load_ioctl(prop_dictionary_t dm_dict) 677dm_table_load_ioctl(prop_dictionary_t dm_dict)
678{ 678{
679 dm_dev_t *dmv; 679 dm_dev_t *dmv;
680 dm_table_entry_t *table_en, *last_table; 680 dm_table_entry_t *table_en, *last_table;
681 dm_table_t *tbl; 681 dm_table_t *tbl;
682 dm_target_t *target; 682 dm_target_t *target;
683 683
684 prop_object_iterator_t iter; 684 prop_object_iterator_t iter;
685 prop_array_t cmd_array; 685 prop_array_t cmd_array;
686 prop_dictionary_t target_dict; 686 prop_dictionary_t target_dict;
687 687
688 const char *name, *uuid, *type; 688 const char *name, *uuid, *type;
689 689
690 uint32_t flags, ret, minor; 690 uint32_t flags, ret, minor;
691 691
692 char *str; 692 char *str;
693 693
694 ret = 0; 694 ret = 0;
695 flags = 0; 695 flags = 0;
696 name = NULL; 696 name = NULL;
697 uuid = NULL; 697 uuid = NULL;
698 dmv = NULL; 698 dmv = NULL;
699 last_table = NULL; 699 last_table = NULL;
700 str = NULL; 700 str = NULL;
701 701
702 /* 702 /*
703 * char *xml; xml = prop_dictionary_externalize(dm_dict); 703 * char *xml; xml = prop_dictionary_externalize(dm_dict);
704 * printf("%s\n",xml); 704 * printf("%s\n",xml);
705 */ 705 */
706 706
707 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); 707 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
708 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); 708 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
709 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 709 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
710 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor); 710 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);
711 711
712 cmd_array = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA); 712 cmd_array = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA);
713 iter = prop_array_iterator(cmd_array); 713 iter = prop_array_iterator(cmd_array);
714 dm_dbg_print_flags(flags); 714 dm_dbg_print_flags(flags);
715 715
716 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) { 716 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
717 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG); 717 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
718 return ENOENT; 718 return ENOENT;
719 } 719 }
720 aprint_debug("Loading table to device: %s--%d\n", name, 720 aprint_debug("Loading table to device: %s--%d\n", name,
721 dmv->table_head.cur_active_table); 721 dmv->table_head.cur_active_table);
722 722
723 /* 723 /*
724 * I have to check if this table slot is not used by another table list. 724 * I have to check if this table slot is not used by another table list.
725 * if it is used I should free them. 725 * if it is used I should free them.
726 */ 726 */
727 if (dmv->flags & DM_INACTIVE_PRESENT_FLAG) 727 if (dmv->flags & DM_INACTIVE_PRESENT_FLAG)
728 dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE); 728 dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);
729 729
730 dm_dbg_print_flags(dmv->flags); 730 dm_dbg_print_flags(dmv->flags);
731 tbl = dm_table_get_entry(&dmv->table_head, DM_TABLE_INACTIVE); 731 tbl = dm_table_get_entry(&dmv->table_head, DM_TABLE_INACTIVE);
732 732
733 aprint_debug("dmv->name = %s\n", dmv->name); 733 aprint_debug("dmv->name = %s\n", dmv->name);
734 734
735 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); 735 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
736 736
737 while ((target_dict = prop_object_iterator_next(iter)) != NULL) { 737 while ((target_dict = prop_object_iterator_next(iter)) != NULL) {
738 738
739 prop_dictionary_get_cstring_nocopy(target_dict, 739 prop_dictionary_get_cstring_nocopy(target_dict,
740 DM_TABLE_TYPE, &type); 740 DM_TABLE_TYPE, &type);
741 /* 741 /*
742 * If we want to deny table with 2 or more different 742 * If we want to deny table with 2 or more different
743 * target we should do it here 743 * target we should do it here
744 */ 744 */
745 if (((target = dm_target_lookup(type)) == NULL) && 745 if (((target = dm_target_lookup(type)) == NULL) &&
746 ((target = dm_target_autoload(type)) == NULL)) { 746 ((target = dm_target_autoload(type)) == NULL)) {
747 dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE); 747 dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE);
748 dm_dev_unbusy(dmv); 748 dm_dev_unbusy(dmv);
749 return ENOENT; 749 return ENOENT;
750 } 750 }
751 if ((table_en = kmem_alloc(sizeof(dm_table_entry_t), 751 if ((table_en = kmem_alloc(sizeof(dm_table_entry_t),
752 KM_SLEEP)) == NULL) { 752 KM_SLEEP)) == NULL) {
753 dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE); 753 dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE);
754 dm_dev_unbusy(dmv); 754 dm_dev_unbusy(dmv);
755 return ENOMEM; 755 return ENOMEM;
756 } 756 }
757 prop_dictionary_get_uint64(target_dict, DM_TABLE_START, 757 prop_dictionary_get_uint64(target_dict, DM_TABLE_START,
758 &table_en->start); 758 &table_en->start);
759 prop_dictionary_get_uint64(target_dict, DM_TABLE_LENGTH, 759 prop_dictionary_get_uint64(target_dict, DM_TABLE_LENGTH,
760 &table_en->length); 760 &table_en->length);
761 761
762 table_en->target = target; 762 table_en->target = target;
763 table_en->dm_dev = dmv; 763 table_en->dm_dev = dmv;
764 table_en->target_config = NULL; 764 table_en->target_config = NULL;
765 765
766 /* 766 /*
767 * There is a parameter string after dm_target_spec 767 * There is a parameter string after dm_target_spec
768 * structure which points to /dev/wd0a 284 part of 768 * structure which points to /dev/wd0a 284 part of
769 * table. String str points to this text. This can be 769 * table. String str points to this text. This can be
770 * null and therefore it should be checked before we try to 770 * null and therefore it should be checked before we try to
771 * use it. 771 * use it.
772 */ 772 */
773 prop_dictionary_get_cstring(target_dict, 773 prop_dictionary_get_cstring(target_dict,
774 DM_TABLE_PARAMS, (char **) &str); 774 DM_TABLE_PARAMS, (char **) &str);
775 775
776 if (SLIST_EMPTY(tbl)) 776 if (SLIST_EMPTY(tbl))
777 /* insert this table to head */ 777 /* insert this table to head */
778 SLIST_INSERT_HEAD(tbl, table_en, next); 778 SLIST_INSERT_HEAD(tbl, table_en, next);
779 else 779 else
780 SLIST_INSERT_AFTER(last_table, table_en, next); 780 SLIST_INSERT_AFTER(last_table, table_en, next);
781 781
782 /* 782 /*
783 * Params string is different for every target, 783 * Params string is different for every target,
784 * therfore I have to pass it to target init 784 * therfore I have to pass it to target init
785 * routine and parse parameters there. 785 * routine and parse parameters there.
786 */ 786 */
787 787
788 if ((ret = target->init(dmv, &table_en->target_config, 788 if ((ret = target->init(dmv, &table_en->target_config,
789 str)) != 0) { 789 str)) != 0) {
790 790
791 dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE); 791 dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE);
792 dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE); 792 dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);
793 free(str, M_TEMP); 793 free(str, M_TEMP);
794 794
795 dm_dev_unbusy(dmv); 795 dm_dev_unbusy(dmv);
 796 dm_target_unbusy(target);
796 return ret; 797 return ret;
797 } 798 }
798 last_table = table_en; 799 last_table = table_en;
799 free(str, M_TEMP); 800 free(str, M_TEMP);
800 } 801 }
801 prop_object_iterator_release(iter); 802 prop_object_iterator_release(iter);
802 803
803 DM_ADD_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); 804 DM_ADD_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);
804 atomic_or_32(&dmv->flags, DM_INACTIVE_PRESENT_FLAG); 805 atomic_or_32(&dmv->flags, DM_INACTIVE_PRESENT_FLAG);
805 806
806 dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE); 807 dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE);
807 dm_dev_unbusy(dmv); 808 dm_dev_unbusy(dmv);
808 return 0; 809 return 0;
809} 810}
810/* 811/*
811 * Get description of all tables loaded to device from kernel 812 * Get description of all tables loaded to device from kernel
812 * and send it to libdevmapper. 813 * and send it to libdevmapper.
813 * 814 *
814 * Output dictionary for every table: 815 * Output dictionary for every table:
815 * 816 *
816 * <key>cmd_data</key> 817 * <key>cmd_data</key>
817 * <array> 818 * <array>
818 * <dict> 819 * <dict>
819 * <key>type<key> 820 * <key>type<key>
820 * <string>...</string> 821 * <string>...</string>
821 * 822 *
822 * <key>start</key> 823 * <key>start</key>
823 * <integer>...</integer> 824 * <integer>...</integer>
824 * 825 *
825 * <key>length</key> 826 * <key>length</key>
826 * <integer>...</integer> 827 * <integer>...</integer>
827 * 828 *
828 * <key>params</key> 829 * <key>params</key>
829 * <string>...</string> 830 * <string>...</string>
830 * </dict> 831 * </dict>
831 * </array> 832 * </array>
832 * 833 *
833 */ 834 */
834int 835int
835dm_table_status_ioctl(prop_dictionary_t dm_dict) 836dm_table_status_ioctl(prop_dictionary_t dm_dict)
836{ 837{
837 dm_dev_t *dmv; 838 dm_dev_t *dmv;
838 dm_table_t *tbl; 839 dm_table_t *tbl;
839 dm_table_entry_t *table_en; 840 dm_table_entry_t *table_en;
840 841
841 prop_array_t cmd_array; 842 prop_array_t cmd_array;
842 prop_dictionary_t target_dict; 843 prop_dictionary_t target_dict;
843 844
844 uint32_t rec_size, minor; 845 uint32_t rec_size, minor;
845 846
846 const char *name, *uuid; 847 const char *name, *uuid;
847 char *params; 848 char *params;
848 int flags; 849 int flags;
849 int table_type; 850 int table_type;
850 851
851 dmv = NULL; 852 dmv = NULL;
852 uuid = NULL; 853 uuid = NULL;
853 name = NULL; 854 name = NULL;
854 params = NULL; 855 params = NULL;
855 flags = 0; 856 flags = 0;
856 rec_size = 0; 857 rec_size = 0;
857 858
858 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); 859 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
859 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); 860 prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
860 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); 861 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
861 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor); 862 prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);
862 863
863 cmd_array = prop_array_create(); 864 cmd_array = prop_array_create();
864 865
865 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) { 866 if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
866 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG); 867 DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
867 return ENOENT; 868 return ENOENT;
868 } 869 }
869 /* 870 /*
870 * if DM_QUERY_INACTIVE_TABLE_FLAG is passed we need to query 871 * if DM_QUERY_INACTIVE_TABLE_FLAG is passed we need to query
871 * INACTIVE TABLE 872 * INACTIVE TABLE
872 */ 873 */
873 if (flags & DM_QUERY_INACTIVE_TABLE_FLAG) 874 if (flags & DM_QUERY_INACTIVE_TABLE_FLAG)
874 table_type = DM_TABLE_INACTIVE; 875 table_type = DM_TABLE_INACTIVE;
875 else 876 else
876 table_type = DM_TABLE_ACTIVE; 877 table_type = DM_TABLE_ACTIVE;
877 878
878 if (dm_table_get_target_count(&dmv->table_head, DM_TABLE_ACTIVE)) 879 if (dm_table_get_target_count(&dmv->table_head, DM_TABLE_ACTIVE))
879 DM_ADD_FLAG(flags, DM_ACTIVE_PRESENT_FLAG); 880 DM_ADD_FLAG(flags, DM_ACTIVE_PRESENT_FLAG);
880 else { 881 else {
881 DM_REMOVE_FLAG(flags, DM_ACTIVE_PRESENT_FLAG); 882 DM_REMOVE_FLAG(flags, DM_ACTIVE_PRESENT_FLAG);
882 883
883 if (dm_table_get_target_count(&dmv->table_head, DM_TABLE_INACTIVE)) 884 if (dm_table_get_target_count(&dmv->table_head, DM_TABLE_INACTIVE))
884 DM_ADD_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); 885 DM_ADD_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);
885 else { 886 else {
886 DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); 887 DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);
887 } 888 }
888 } 889 }
889 890
890 if (dmv->flags & DM_SUSPEND_FLAG) 891 if (dmv->flags & DM_SUSPEND_FLAG)
891 DM_ADD_FLAG(flags, DM_SUSPEND_FLAG); 892 DM_ADD_FLAG(flags, DM_SUSPEND_FLAG);
892 893
893 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); 894 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
894 895
895 aprint_debug("Status of device tables: %s--%d\n", 896 aprint_debug("Status of device tables: %s--%d\n",
896 name, dmv->table_head.cur_active_table); 897 name, dmv->table_head.cur_active_table);
897 898
898 tbl = dm_table_get_entry(&dmv->table_head, table_type); 899 tbl = dm_table_get_entry(&dmv->table_head, table_type);
899 900
900 SLIST_FOREACH(table_en, tbl, next) { 901 SLIST_FOREACH(table_en, tbl, next) {
901 target_dict = prop_dictionary_create(); 902 target_dict = prop_dictionary_create();
902 aprint_debug("%016" PRIu64 ", length %016" PRIu64 903 aprint_debug("%016" PRIu64 ", length %016" PRIu64
903 ", target %s\n", table_en->start, table_en->length, 904 ", target %s\n", table_en->start, table_en->length,
904 table_en->target->name); 905 table_en->target->name);
905 906
906 prop_dictionary_set_uint64(target_dict, DM_TABLE_START, 907 prop_dictionary_set_uint64(target_dict, DM_TABLE_START,
907 table_en->start); 908 table_en->start);
908 prop_dictionary_set_uint64(target_dict, DM_TABLE_LENGTH, 909 prop_dictionary_set_uint64(target_dict, DM_TABLE_LENGTH,
909 table_en->length); 910 table_en->length);
910 911
911 prop_dictionary_set_cstring(target_dict, DM_TABLE_TYPE, 912 prop_dictionary_set_cstring(target_dict, DM_TABLE_TYPE,
912 table_en->target->name); 913 table_en->target->name);
913 914
914 /* dm_table_get_cur_actv.table ?? */ 915 /* dm_table_get_cur_actv.table ?? */
915 prop_dictionary_set_int32(target_dict, DM_TABLE_STAT, 916 prop_dictionary_set_int32(target_dict, DM_TABLE_STAT,
916 dmv->table_head.cur_active_table); 917 dmv->table_head.cur_active_table);
917 918
918 if (flags & DM_STATUS_TABLE_FLAG) { 919 if (flags & DM_STATUS_TABLE_FLAG) {
919 params = table_en->target->status 920 params = table_en->target->status
920 (table_en->target_config); 921 (table_en->target_config);
921 922
922 if (params != NULL) { 923 if (params != NULL) {
923 prop_dictionary_set_cstring(target_dict, 924 prop_dictionary_set_cstring(target_dict,
924 DM_TABLE_PARAMS, params); 925 DM_TABLE_PARAMS, params);
925 926
926 kmem_free(params, DM_MAX_PARAMS_SIZE); 927 kmem_free(params, DM_MAX_PARAMS_SIZE);
927 } 928 }
928 } 929 }
929 prop_array_add(cmd_array, target_dict); 930 prop_array_add(cmd_array, target_dict);
930 prop_object_release(target_dict); 931 prop_object_release(target_dict);
931 } 932 }
932 933
933 dm_table_release(&dmv->table_head, table_type); 934 dm_table_release(&dmv->table_head, table_type);
934 dm_dev_unbusy(dmv); 935 dm_dev_unbusy(dmv);
935 936
936 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_FLAGS, flags); 937 prop_dictionary_set_uint32(dm_dict, DM_IOCTL_FLAGS, flags);
937 prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, cmd_array); 938 prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, cmd_array);
938 prop_object_release(cmd_array); 939 prop_object_release(cmd_array);
939 940
940 return 0; 941 return 0;
941} 942}
942 943
943 944
944/* 945/*
945 * For every call I have to set kernel driver version. 946 * For every call I have to set kernel driver version.
946 * Because I can have commands supported only in other 947 * Because I can have commands supported only in other
947 * newer/later version. This routine is called for every 948 * newer/later version. This routine is called for every
948 * ioctl command. 949 * ioctl command.
949 */ 950 */
950int 951int
951dm_check_version(prop_dictionary_t dm_dict) 952dm_check_version(prop_dictionary_t dm_dict)
952{ 953{
953 size_t i; 954 size_t i;
954 int dm_version[3]; 955 int dm_version[3];
955 prop_array_t ver; 956 prop_array_t ver;
956 957
957 ver = prop_dictionary_get(dm_dict, DM_IOCTL_VERSION); 958 ver = prop_dictionary_get(dm_dict, DM_IOCTL_VERSION);
958 959
959 for (i = 0; i < 3; i++) 960 for (i = 0; i < 3; i++)
960 prop_array_get_uint32(ver, i, &dm_version[i]); 961 prop_array_get_uint32(ver, i, &dm_version[i]);
961 962
962 if (DM_VERSION_MAJOR != dm_version[0] || DM_VERSION_MINOR < dm_version[1]) { 963 if (DM_VERSION_MAJOR != dm_version[0] || DM_VERSION_MINOR < dm_version[1]) {
963 aprint_debug("libdevmapper/kernel version mismatch " 964 aprint_debug("libdevmapper/kernel version mismatch "
964 "kernel: %d.%d.%d libdevmapper: %d.%d.%d\n", 965 "kernel: %d.%d.%d libdevmapper: %d.%d.%d\n",
965 DM_VERSION_MAJOR, DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, 966 DM_VERSION_MAJOR, DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL,
966 dm_version[0], dm_version[1], dm_version[2]); 967 dm_version[0], dm_version[1], dm_version[2]);
967 968
968 return EIO; 969 return EIO;
969 } 970 }
970 prop_array_set_uint32(ver, 0, DM_VERSION_MAJOR); 971 prop_array_set_uint32(ver, 0, DM_VERSION_MAJOR);
971 prop_array_set_uint32(ver, 1, DM_VERSION_MINOR); 972 prop_array_set_uint32(ver, 1, DM_VERSION_MINOR);
972 prop_array_set_uint32(ver, 2, DM_VERSION_PATCHLEVEL); 973 prop_array_set_uint32(ver, 2, DM_VERSION_PATCHLEVEL);
973 974
974 prop_dictionary_set(dm_dict, DM_IOCTL_VERSION, ver); 975 prop_dictionary_set(dm_dict, DM_IOCTL_VERSION, ver);
975 976
976 return 0; 977 return 0;
977} 978}