Print this page
3373 gcc >= 4.5 concerns about offsetof()
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/avs/ns/rdc/rdc.c
+++ new/usr/src/uts/common/avs/ns/rdc/rdc.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #define _RDC_
27 27 #include <sys/types.h>
28 28 #include <sys/ksynch.h>
29 29 #include <sys/kmem.h>
30 30 #include <sys/errno.h>
31 31 #include <sys/conf.h>
32 32 #include <sys/cmn_err.h>
33 33 #include <sys/modctl.h>
34 34 #include <sys/cred.h>
35 35 #include <sys/ddi.h>
36 36 #include <sys/unistat/spcs_s.h>
37 37 #include <sys/unistat/spcs_s_k.h>
38 38 #include <sys/unistat/spcs_errors.h>
39 39
40 40 #include <sys/nsc_thread.h>
41 41 #ifdef DS_DDICT
42 42 #include "../contract.h"
43 43 #endif
44 44 #include <sys/nsctl/nsctl.h>
45 45 #include <sys/nsctl/nsvers.h>
46 46
47 47 #include <sys/sdt.h> /* dtrace is S10 or later */
48 48
49 49 #include "rdc.h"
50 50 #include "rdc_io.h"
51 51 #include "rdc_bitmap.h"
52 52 #include "rdc_ioctl.h"
53 53 #include "rdcsrv.h"
54 54 #include "rdc_diskq.h"
55 55
56 56 #define DIDINIT 0x01
57 57 #define DIDNODES 0x02
58 58 #define DIDCONFIG 0x04
59 59
60 60 static int rdcopen(dev_t *devp, int flag, int otyp, cred_t *crp);
61 61 static int rdcclose(dev_t dev, int flag, int otyp, cred_t *crp);
62 62 static int rdcprint(dev_t dev, char *str);
63 63 static int rdcioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp,
64 64 int *rvp);
65 65 static int rdcattach(dev_info_t *dip, ddi_attach_cmd_t cmd);
66 66 static int rdcdetach(dev_info_t *dip, ddi_detach_cmd_t cmd);
67 67 static int rdcgetinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
68 68 void **result);
69 69 #ifdef DEBUG
70 70 static int rdc_clrkstat(void *);
71 71 #endif
72 72
73 73 /*
74 74 * kstat interface
75 75 */
76 76 static kstat_t *sndr_kstats;
77 77
78 78 int sndr_info_stats_update(kstat_t *ksp, int rw);
79 79
80 80 static sndr_m_stats_t sndr_info_stats = {
81 81 {RDC_MKSTAT_MAXSETS, KSTAT_DATA_ULONG},
82 82 {RDC_MKSTAT_MAXFBAS, KSTAT_DATA_ULONG},
83 83 {RDC_MKSTAT_RPC_TIMEOUT, KSTAT_DATA_ULONG},
84 84 {RDC_MKSTAT_HEALTH_THRES, KSTAT_DATA_ULONG},
85 85 {RDC_MKSTAT_BITMAP_WRITES, KSTAT_DATA_ULONG},
86 86 {RDC_MKSTAT_CLNT_COTS_CALLS, KSTAT_DATA_ULONG},
87 87 {RDC_MKSTAT_CLNT_CLTS_CALLS, KSTAT_DATA_ULONG},
88 88 {RDC_MKSTAT_SVC_COTS_CALLS, KSTAT_DATA_ULONG},
89 89 {RDC_MKSTAT_SVC_CLTS_CALLS, KSTAT_DATA_ULONG},
90 90 {RDC_MKSTAT_BITMAP_REF_DELAY, KSTAT_DATA_ULONG}
91 91 };
92 92
93 93 int rdc_info_stats_update(kstat_t *ksp, int rw);
94 94
95 95 static rdc_info_stats_t rdc_info_stats = {
96 96 {RDC_IKSTAT_FLAGS, KSTAT_DATA_ULONG},
97 97 {RDC_IKSTAT_SYNCFLAGS, KSTAT_DATA_ULONG},
98 98 {RDC_IKSTAT_BMPFLAGS, KSTAT_DATA_ULONG},
99 99 {RDC_IKSTAT_SYNCPOS, KSTAT_DATA_ULONG},
100 100 {RDC_IKSTAT_VOLSIZE, KSTAT_DATA_ULONG},
101 101 {RDC_IKSTAT_BITSSET, KSTAT_DATA_ULONG},
102 102 {RDC_IKSTAT_AUTOSYNC, KSTAT_DATA_ULONG},
103 103 {RDC_IKSTAT_MAXQFBAS, KSTAT_DATA_ULONG},
104 104 {RDC_IKSTAT_MAXQITEMS, KSTAT_DATA_ULONG},
105 105 {RDC_IKSTAT_FILE, KSTAT_DATA_STRING},
106 106 {RDC_IKSTAT_SECFILE, KSTAT_DATA_STRING},
107 107 {RDC_IKSTAT_BITMAP, KSTAT_DATA_STRING},
108 108 {RDC_IKSTAT_PRIMARY_HOST, KSTAT_DATA_STRING},
109 109 {RDC_IKSTAT_SECONDARY_HOST, KSTAT_DATA_STRING},
110 110 {RDC_IKSTAT_TYPE_FLAG, KSTAT_DATA_ULONG},
111 111 {RDC_IKSTAT_BMP_SIZE, KSTAT_DATA_ULONG},
112 112 {RDC_IKSTAT_DISK_STATUS, KSTAT_DATA_ULONG},
113 113 {RDC_IKSTAT_IF_DOWN, KSTAT_DATA_ULONG},
114 114 {RDC_IKSTAT_IF_RPC_VERSION, KSTAT_DATA_ULONG},
115 115 {RDC_IKSTAT_ASYNC_BLOCK_HWM, KSTAT_DATA_ULONG},
116 116 {RDC_IKSTAT_ASYNC_ITEM_HWM, KSTAT_DATA_ULONG},
117 117 {RDC_IKSTAT_ASYNC_THROTTLE_DELAY, KSTAT_DATA_ULONG},
118 118 {RDC_IKSTAT_ASYNC_ITEMS, KSTAT_DATA_ULONG},
119 119 {RDC_IKSTAT_ASYNC_BLOCKS, KSTAT_DATA_ULONG},
120 120 {RDC_IKSTAT_QUEUE_TYPE, KSTAT_DATA_CHAR}
121 121 };
122 122
123 123 static struct cb_ops rdc_cb_ops = {
124 124 rdcopen,
125 125 rdcclose,
126 126 nulldev, /* no strategy */
127 127 rdcprint,
128 128 nodev, /* no dump */
129 129 nodev, /* no read */
130 130 nodev, /* no write */
131 131 rdcioctl,
132 132 nodev, /* no devmap */
133 133 nodev, /* no mmap */
134 134 nodev, /* no segmap */
135 135 nochpoll,
136 136 ddi_prop_op,
137 137 NULL, /* not STREAMS */
138 138 D_NEW | D_MP | D_64BIT,
139 139 CB_REV,
140 140 nodev, /* no aread */
141 141 nodev, /* no awrite */
142 142 };
143 143
144 144 static struct dev_ops rdc_ops = {
145 145 DEVO_REV,
146 146 0,
147 147 rdcgetinfo,
148 148 nulldev, /* identify */
149 149 nulldev, /* probe */
150 150 rdcattach,
151 151 rdcdetach,
152 152 nodev, /* no reset */
153 153 &rdc_cb_ops,
154 154 (struct bus_ops *)NULL
155 155 };
156 156
157 157 static struct modldrv rdc_ldrv = {
158 158 &mod_driverops,
159 159 "nws:Remote Mirror:" ISS_VERSION_STR,
160 160 &rdc_ops
161 161 };
162 162
163 163 static struct modlinkage rdc_modlinkage = {
164 164 MODREV_1,
165 165 &rdc_ldrv,
166 166 NULL
167 167 };
168 168
169 169 const int sndr_major_rev = ISS_VERSION_MAJ;
170 170 const int sndr_minor_rev = ISS_VERSION_MIN;
171 171 const int sndr_micro_rev = ISS_VERSION_MIC;
172 172 const int sndr_baseline_rev = ISS_VERSION_NUM;
173 173 static char sndr_version[16];
174 174
175 175 static void *rdc_dip;
176 176
177 177 extern int _rdc_init_dev();
178 178 extern void _rdc_deinit_dev();
179 179 extern void rdc_link_down_free();
180 180
181 181 int rdc_bitmap_mode;
182 182 int rdc_auto_sync;
183 183 int rdc_max_sets;
184 184 extern int rdc_health_thres;
185 185
186 186 kmutex_t rdc_sync_mutex;
187 187 rdc_sync_event_t rdc_sync_event;
188 188 clock_t rdc_sync_event_timeout;
189 189
190 190 static void
191 191 rdc_sync_event_init()
192 192 {
193 193 mutex_init(&rdc_sync_mutex, NULL, MUTEX_DRIVER, NULL);
194 194 mutex_init(&rdc_sync_event.mutex, NULL, MUTEX_DRIVER, NULL);
195 195 cv_init(&rdc_sync_event.cv, NULL, CV_DRIVER, NULL);
196 196 cv_init(&rdc_sync_event.done_cv, NULL, CV_DRIVER, NULL);
197 197 rdc_sync_event.master[0] = 0;
198 198 rdc_sync_event.lbolt = (clock_t)0;
199 199 rdc_sync_event_timeout = RDC_SYNC_EVENT_TIMEOUT;
200 200 }
201 201
202 202
203 203 static void
204 204 rdc_sync_event_destroy()
205 205 {
206 206 mutex_destroy(&rdc_sync_mutex);
207 207 mutex_destroy(&rdc_sync_event.mutex);
208 208 cv_destroy(&rdc_sync_event.cv);
209 209 cv_destroy(&rdc_sync_event.done_cv);
210 210 }
211 211
212 212
213 213
214 214 int
215 215 _init(void)
216 216 {
217 217 return (mod_install(&rdc_modlinkage));
218 218 }
219 219
220 220 int
221 221 _fini(void)
222 222 {
223 223 return (mod_remove(&rdc_modlinkage));
224 224 }
225 225
226 226 int
227 227 _info(struct modinfo *modinfop)
228 228 {
229 229 return (mod_info(&rdc_modlinkage, modinfop));
230 230 }
231 231
232 232 static int
233 233 rdcattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
234 234 {
235 235 intptr_t flags;
236 236 int instance;
237 237 int i;
238 238
239 239 /*CONSTCOND*/
240 240 ASSERT(sizeof (u_longlong_t) == 8);
241 241
242 242 if (cmd != DDI_ATTACH)
243 243 return (DDI_FAILURE);
244 244
245 245 (void) strncpy(sndr_version, _VERSION_, sizeof (sndr_version));
246 246
247 247 instance = ddi_get_instance(dip);
248 248 rdc_dip = dip;
249 249
250 250 flags = 0;
251 251
252 252 rdc_sync_event_init();
253 253
254 254 /*
255 255 * rdc_max_sets must be set before calling _rdc_load().
256 256 */
257 257
258 258 rdc_max_sets = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
259 259 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "rdc_max_sets", 64);
260 260
261 261 if (_rdc_init_dev()) {
262 262 cmn_err(CE_WARN, "!rdc: _rdc_init_dev failed");
263 263 goto out;
264 264 }
265 265 flags |= DIDINIT;
266 266
267 267 if (_rdc_load() != 0) {
268 268 cmn_err(CE_WARN, "!rdc: _rdc_load failed");
269 269 goto out;
270 270 }
271 271
272 272 if (_rdc_configure()) {
273 273 cmn_err(CE_WARN, "!rdc: _rdc_configure failed");
274 274 goto out;
275 275 }
276 276 flags |= DIDCONFIG;
277 277
278 278 if (ddi_create_minor_node(dip, "rdc", S_IFCHR, instance, DDI_PSEUDO, 0)
279 279 != DDI_SUCCESS) {
280 280 cmn_err(CE_WARN, "!rdc: could not create node.");
281 281 goto out;
282 282 }
283 283 flags |= DIDNODES;
284 284
285 285 rdc_bitmap_mode = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
286 286 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
287 287 "rdc_bitmap_mode", 0);
288 288
289 289 switch (rdc_bitmap_mode) {
290 290 case RDC_BMP_AUTO: /* 0 */
291 291 break;
292 292 case RDC_BMP_ALWAYS: /* 1 */
293 293 break;
294 294 case RDC_BMP_NEVER: /* 2 */
295 295 cmn_err(CE_NOTE, "!SNDR bitmap mode override");
296 296 cmn_err(CE_CONT,
297 297 "!SNDR: bitmaps will only be written on shutdown\n");
298 298 break;
299 299 default: /* unknown */
300 300 cmn_err(CE_NOTE,
301 301 "!SNDR: unknown bitmap mode %d - autodetecting mode",
302 302 rdc_bitmap_mode);
303 303 rdc_bitmap_mode = RDC_BMP_AUTO;
304 304 break;
305 305 }
306 306
307 307 rdc_bitmap_init();
308 308
309 309 rdc_auto_sync = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
310 310 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
311 311 "rdc_auto_sync", 0);
312 312
313 313 i = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
314 314 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
315 315 "rdc_health_thres", RDC_HEALTH_THRESHOLD);
316 316 if (i >= RDC_MIN_HEALTH_THRES)
317 317 rdc_health_thres = i;
318 318 else
319 319 cmn_err(CE_WARN, "!value rdc_heath_thres from rdc.conf ignored "
320 320 "as it is smaller than the min value of %d",
321 321 RDC_MIN_HEALTH_THRES);
322 322
323 323 ddi_set_driver_private(dip, (caddr_t)flags);
324 324 ddi_report_dev(dip);
325 325
326 326 sndr_kstats = kstat_create(RDC_KSTAT_MODULE, 0,
327 327 RDC_KSTAT_MINFO, RDC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
328 328 sizeof (sndr_m_stats_t) / sizeof (kstat_named_t),
329 329 KSTAT_FLAG_VIRTUAL);
330 330
331 331 if (sndr_kstats) {
332 332 sndr_kstats->ks_data = &sndr_info_stats;
333 333 sndr_kstats->ks_update = sndr_info_stats_update;
334 334 sndr_kstats->ks_private = &rdc_k_info[0];
335 335 kstat_install(sndr_kstats);
336 336 } else
337 337 cmn_err(CE_WARN, "!SNDR: module kstats failed");
338 338
339 339 return (DDI_SUCCESS);
340 340
341 341 out:
342 342 DTRACE_PROBE(rdc_attach_failed);
343 343 ddi_set_driver_private(dip, (caddr_t)flags);
344 344 (void) rdcdetach(dip, DDI_DETACH);
345 345 return (DDI_FAILURE);
346 346 }
347 347
348 348 static int
349 349 rdcdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
350 350 {
351 351 rdc_k_info_t *krdc;
352 352 rdc_u_info_t *urdc;
353 353 int rdcd;
354 354 intptr_t flags;
355 355
356 356
357 357 if (cmd != DDI_DETACH) {
358 358 DTRACE_PROBE(rdc_detach_unknown_cmd);
359 359 return (DDI_FAILURE);
360 360 }
361 361
362 362 if (rdc_k_info == NULL || rdc_u_info == NULL)
363 363 goto cleanup;
364 364
365 365 mutex_enter(&rdc_conf_lock);
366 366
367 367 for (rdcd = 0; rdcd < rdc_max_sets; rdcd++) {
368 368 krdc = &rdc_k_info[rdcd];
369 369 urdc = &rdc_u_info[rdcd];
370 370
371 371 if (IS_ENABLED(urdc) || krdc->devices) {
372 372 #ifdef DEBUG
373 373 cmn_err(CE_WARN,
374 374 "!rdc: cannot detach, rdcd %d still in use", rdcd);
375 375 #endif
376 376 mutex_exit(&rdc_conf_lock);
377 377 DTRACE_PROBE(rdc_detach_err_busy);
378 378 return (DDI_FAILURE);
379 379 }
380 380 }
381 381
382 382 mutex_exit(&rdc_conf_lock);
383 383
384 384 cleanup:
385 385 flags = (intptr_t)ddi_get_driver_private(dip);
386 386
387 387 if (flags & DIDNODES)
388 388 ddi_remove_minor_node(dip, NULL);
389 389
390 390 if (sndr_kstats) {
391 391 kstat_delete(sndr_kstats);
392 392 }
393 393 if (flags & DIDINIT)
394 394 _rdc_deinit_dev();
395 395
396 396 if (flags & DIDCONFIG) {
397 397 (void) _rdc_deconfigure();
398 398 (void) _rdc_unload();
399 399 rdcsrv_unload();
400 400 }
401 401
402 402 rdc_sync_event_destroy();
403 403 rdc_link_down_free();
404 404
405 405 rdc_dip = NULL;
406 406 return (DDI_SUCCESS);
407 407 }
408 408
409 409 /* ARGSUSED */
410 410 static int
411 411 rdcgetinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
412 412 {
413 413 int rc = DDI_FAILURE;
414 414
415 415 switch (infocmd) {
416 416
417 417 case DDI_INFO_DEVT2DEVINFO:
418 418 *result = rdc_dip;
419 419 rc = DDI_SUCCESS;
420 420 break;
421 421
422 422 case DDI_INFO_DEVT2INSTANCE:
423 423 /* We only have a single instance */
424 424 *result = 0;
425 425 rc = DDI_SUCCESS;
426 426 break;
427 427
428 428 default:
429 429 break;
430 430 }
431 431
432 432 return (rc);
433 433 }
434 434
435 435
436 436 /* ARGSUSED */
437 437
438 438 static int
439 439 rdcopen(dev_t *devp, int flag, int otyp, cred_t *crp)
440 440 {
441 441 return (0);
442 442 }
443 443
444 444
445 445 /* ARGSUSED */
446 446
447 447 static int
448 448 rdcclose(dev_t dev, int flag, int otyp, cred_t *crp)
449 449 {
450 450 return (0);
451 451 }
452 452
453 453 /* ARGSUSED */
454 454
455 455 static int
456 456 rdcprint(dev_t dev, char *str)
457 457 {
458 458 int instance = 0;
459 459
460 460 cmn_err(CE_WARN, "!rdc%d: %s", instance, str);
461 461 return (0);
462 462 }
463 463
464 464
465 465 static int
466 466 convert_ioctl_args(int cmd, intptr_t arg, int mode, _rdc_ioctl_t *args)
467 467 {
468 468 _rdc_ioctl32_t args32;
469 469
470 470 if (ddi_copyin((void *)arg, &args32, sizeof (_rdc_ioctl32_t), mode))
471 471 return (EFAULT);
472 472
473 473 bzero((void *)args, sizeof (_rdc_ioctl_t));
474 474
475 475 switch (cmd) {
476 476 case RDC_CONFIG:
477 477 args->arg0 = (uint32_t)args32.arg0; /* _rdc_config_t * */
478 478 args->arg1 = (uint32_t)args32.arg1; /* pointer */
479 479 args->arg2 = (uint32_t)args32.arg2; /* size */
480 480 args->ustatus = (spcs_s_info_t)args32.ustatus;
481 481 break;
482 482
483 483 case RDC_STATUS:
484 484 args->arg0 = (uint32_t)args32.arg0; /* pointer */
485 485 args->ustatus = (spcs_s_info_t)args32.ustatus;
486 486 break;
487 487
488 488 case RDC_ENABLE_SVR:
489 489 args->arg0 = (uint32_t)args32.arg0; /* _rdc_svc_args * */
490 490 break;
491 491
492 492 case RDC_VERSION:
493 493 args->arg0 = (uint32_t)args32.arg0; /* _rdc_version_t * */
494 494 args->ustatus = (spcs_s_info_t)args32.ustatus;
495 495 break;
496 496
497 497 case RDC_SYNC_EVENT:
498 498 args->arg0 = (uint32_t)args32.arg0; /* char * */
499 499 args->arg1 = (uint32_t)args32.arg1; /* char * */
500 500 args->ustatus = (spcs_s_info_t)args32.ustatus;
501 501 break;
502 502
503 503 case RDC_LINK_DOWN:
504 504 args->arg0 = (uint32_t)args32.arg0; /* char * */
505 505 args->ustatus = (spcs_s_info_t)args32.ustatus;
506 506 break;
507 507 case RDC_POOL_CREATE:
508 508 args->arg0 = (uint32_t)args32.arg0; /* svcpool_args * */
509 509 break;
510 510 case RDC_POOL_WAIT:
511 511 args->arg0 = (uint32_t)args32.arg0; /* int */
512 512 break;
513 513 case RDC_POOL_RUN:
514 514 args->arg0 = (uint32_t)args32.arg0; /* int */
515 515 break;
516 516
517 517 default:
518 518 return (EINVAL);
↓ open down ↓ |
518 lines elided |
↑ open up ↑ |
519 519 }
520 520
521 521 return (0);
522 522 }
523 523
524 524
525 525 /*
526 526 * Yet another standard thing that is not standard ...
527 527 */
528 528 #ifndef offsetof
529 -#define offsetof(s, m) ((size_t)(&((s *)0)->m))
529 +#if defined(__GNUC__)
530 +#define offsetof(s, m) __builtin_offsetof(s, m)
531 +#else
532 +#define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
533 +#endif
530 534 #endif
531 535
532 536 /*
533 537 * Build a 32bit rdc_set structure and copyout to the user level.
534 538 */
535 539 int
536 540 rdc_status_copy32(const void *arg, void *usetp, size_t size, int mode)
537 541 {
538 542 rdc_u_info_t *urdc = (rdc_u_info_t *)arg;
539 543 struct rdc_set32 set32;
540 544 size_t tailsize;
541 545 #ifdef DEBUG
542 546 size_t tailsize32;
543 547 #endif
544 548
545 549 bzero(&set32, sizeof (set32));
546 550
547 551 tailsize = sizeof (struct rdc_addr32) -
548 552 offsetof(struct rdc_addr32, intf);
549 553
550 554 /* primary address structure, avoiding netbuf */
551 555 bcopy(&urdc->primary.intf[0], &set32.primary.intf[0], tailsize);
552 556
553 557 /* secondary address structure, avoiding netbuf */
554 558 bcopy(&urdc->secondary.intf[0], &set32.secondary.intf[0], tailsize);
555 559
556 560 /*
557 561 * the rest, avoiding netconfig
558 562 * note: the tail must be the same size in both structures
559 563 */
560 564 tailsize = sizeof (struct rdc_set) - offsetof(struct rdc_set, flags);
561 565 #ifdef DEBUG
562 566 /*
563 567 * ASSERT is calling for debug reason, and tailsize32 is only declared
564 568 * for ASSERT, put them under debug to avoid lint warning.
565 569 */
566 570 tailsize32 = sizeof (struct rdc_set32) -
567 571 offsetof(struct rdc_set32, flags);
568 572 ASSERT(tailsize == tailsize32);
569 573 #endif
570 574
571 575 bcopy(&urdc->flags, &set32.flags, tailsize);
572 576
573 577 /* copyout to user level */
574 578 return (ddi_copyout(&set32, usetp, size, mode));
575 579 }
576 580
577 581
578 582 /*
579 583 * Status ioctl.
580 584 */
581 585 static int
582 586 rdcstatus(_rdc_ioctl_t *args, int mode)
583 587 {
584 588 int (*copyout)(const void *, void *, size_t, int);
585 589 rdc_u_info_t *urdc;
586 590 rdc_k_info_t *krdc;
587 591 disk_queue *dqp;
588 592 char *usetp; /* pointer to user rdc_set structure */
589 593 size_t size; /* sizeof user rdc_set structure */
590 594 int32_t *maxsetsp; /* address of status->maxsets; */
591 595 int nset, max, i, j;
592 596
593 597 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
594 598 struct rdc_status32 status32;
595 599
596 600 if (ddi_copyin((void *)args->arg0, &status32,
597 601 sizeof (status32), mode)) {
598 602 return (EFAULT);
599 603 }
600 604
601 605 usetp = ((char *)args->arg0) +
602 606 offsetof(struct rdc_status32, rdc_set);
603 607 maxsetsp = (int32_t *)((char *)args->arg0 +
604 608 offsetof(struct rdc_status32, maxsets));
605 609 nset = status32.nset;
606 610
607 611 size = sizeof (struct rdc_set32);
608 612 copyout = rdc_status_copy32;
609 613 } else {
610 614 struct rdc_status status;
611 615
612 616 if (ddi_copyin((void *)args->arg0, &status,
613 617 sizeof (status), mode)) {
614 618 return (EFAULT);
615 619 }
616 620
617 621 usetp = ((char *)args->arg0) +
618 622 offsetof(struct rdc_status, rdc_set);
619 623 maxsetsp = (int32_t *)((char *)args->arg0 +
620 624 offsetof(struct rdc_status, maxsets));
621 625 nset = status.nset;
622 626
623 627 size = sizeof (struct rdc_set);
624 628 copyout = ddi_copyout;
625 629 }
626 630
627 631 max = min(nset, rdc_max_sets);
628 632
629 633 for (i = 0, j = 0; i < max; i++) {
630 634 urdc = &rdc_u_info[i];
631 635 krdc = &rdc_k_info[i];
632 636
633 637 if (!IS_ENABLED(urdc))
634 638 continue;
635 639
636 640 /*
637 641 * sneak out qstate in urdc->flags
638 642 * this is harmless because it's value is not used
639 643 * in urdc->flags. the real qstate is kept in
640 644 * group->diskq->disk_hdr.h.state
641 645 */
642 646 if (RDC_IS_DISKQ(krdc->group)) {
643 647 dqp = &krdc->group->diskq;
644 648 if (IS_QSTATE(dqp, RDC_QNOBLOCK))
645 649 urdc->flags |= RDC_QNOBLOCK;
646 650 }
647 651
648 652 j++;
649 653 if ((*copyout)(urdc, usetp, size, mode) != 0)
650 654 return (EFAULT);
651 655
652 656 urdc->flags &= ~RDC_QNOBLOCK; /* clear qstate */
653 657 usetp += size;
654 658 }
655 659
656 660 /* copyout rdc_max_sets value */
657 661
658 662 if (ddi_copyout(&rdc_max_sets, maxsetsp, sizeof (*maxsetsp), mode) != 0)
659 663 return (EFAULT);
660 664
661 665 /* copyout number of sets manipulated */
662 666
663 667 /*CONSTCOND*/
664 668 ASSERT(offsetof(struct rdc_status32, nset) == 0);
665 669 /*CONSTCOND*/
666 670 ASSERT(offsetof(struct rdc_status, nset) == 0);
667 671
668 672 return (ddi_copyout(&j, (void *)args->arg0, sizeof (int), mode));
669 673 }
670 674
671 675
672 676 /* ARGSUSED */
673 677
674 678 static int
675 679 rdcioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp)
676 680 {
677 681 spcs_s_info_t kstatus = NULL;
678 682 _rdc_ioctl_t args;
679 683 int error;
680 684 int rc = 0;
681 685
682 686 if (cmd != RDC_STATUS) {
683 687 if ((error = drv_priv(crp)) != 0)
684 688 return (error);
685 689 }
686 690 #ifdef DEBUG
687 691 if (cmd == RDC_ASYNC6) {
688 692 rc = rdc_async6((void *)arg, mode, rvp);
689 693 return (rc);
690 694 }
691 695
692 696 if (cmd == RDC_CLRKSTAT) {
693 697 rc = rdc_clrkstat((void *)arg);
694 698 return (rc);
695 699 }
696 700
697 701 if (cmd == RDC_STALL0) {
698 702 if (((int)arg > 1) || ((int)arg < 0))
699 703 return (EINVAL);
700 704 rdc_stallzero((int)arg);
701 705 return (0);
702 706 }
703 707 if (cmd == RDC_READGEN) {
704 708 rc = rdc_readgen((void *)arg, mode, rvp);
705 709 return (rc);
706 710 }
707 711 #endif
708 712 if (cmd == RDC_BITMAPOP) {
709 713 rdc_bitmap_op_t bmop;
710 714 rdc_bitmap_op32_t bmop32;
711 715
712 716 if (ddi_model_convert_from(mode & FMODELS)
713 717 == DDI_MODEL_ILP32) {
714 718 if (ddi_copyin((void *)arg, &bmop32, sizeof (bmop32),
715 719 mode))
716 720 return (EFAULT);
717 721 bmop.offset = bmop32.offset;
718 722 bmop.op = bmop32.op;
719 723 (void) strncpy(bmop.sechost, bmop32.sechost,
720 724 MAX_RDC_HOST_SIZE);
721 725 (void) strncpy(bmop.secfile, bmop32.secfile,
722 726 NSC_MAXPATH);
723 727 bmop.len = bmop32.len;
724 728 bmop.addr = (unsigned long)bmop32.addr;
725 729 } else {
726 730 if (ddi_copyin((void *)arg, &bmop, sizeof (bmop),
727 731 mode))
728 732 return (EFAULT);
729 733 }
730 734 rc = rdc_bitmapset(bmop.op, bmop.sechost, bmop.secfile,
731 735 (void *)bmop.addr, bmop.len, bmop.offset, mode);
732 736 return (rc);
733 737 }
734 738
735 739 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
736 740 if ((rc = convert_ioctl_args(cmd, arg, mode, &args)) != 0)
737 741 return (rc);
738 742 } else {
739 743 if (ddi_copyin((void *)arg, &args,
740 744 sizeof (_rdc_ioctl_t), mode)) {
741 745 return (EFAULT);
742 746 }
743 747 }
744 748
745 749 kstatus = spcs_s_kcreate();
746 750 if (!kstatus) {
747 751 return (ENOMEM);
748 752 }
749 753
750 754
751 755 switch (cmd) {
752 756
753 757 case RDC_POOL_CREATE: {
754 758 struct svcpool_args p;
755 759
756 760 if (ddi_copyin((void *)arg, &p, sizeof (p), mode)) {
757 761 spcs_s_kfree(kstatus);
758 762 return (EFAULT);
759 763 }
760 764 error = svc_pool_create(&p);
761 765
762 766 break;
763 767 }
764 768 case RDC_POOL_WAIT: {
765 769 int id;
766 770
767 771 if (ddi_copyin((void *)arg, &id, sizeof (id), mode)) {
768 772 spcs_s_kfree(kstatus);
769 773 return (EFAULT);
770 774 }
771 775
772 776 error = svc_wait(id);
773 777 break;
774 778 }
775 779 case RDC_POOL_RUN: {
776 780 int id;
777 781
778 782 if (ddi_copyin((void *)arg, &id, sizeof (id), mode)) {
779 783 spcs_s_kfree(kstatus);
780 784 return (EFAULT);
781 785 }
782 786 error = svc_do_run(id);
783 787 break;
784 788 }
785 789 case RDC_ENABLE_SVR:
786 790 {
787 791 STRUCT_DECL(rdc_svc_args, parms);
788 792
789 793 STRUCT_INIT(parms, mode);
790 794 /* Only used by sndrd which does not use unistat */
791 795
792 796 if (ddi_copyin((void *)args.arg0, STRUCT_BUF(parms),
793 797 STRUCT_SIZE(parms), mode)) {
794 798 spcs_s_kfree(kstatus);
795 799 return (EFAULT);
796 800 }
797 801 rc = rdc_start_server(STRUCT_BUF(parms), mode);
798 802 }
799 803 break;
800 804
801 805 case RDC_STATUS:
802 806 rc = rdcstatus(&args, mode);
803 807 break;
804 808
805 809 case RDC_CONFIG:
806 810 rc = _rdc_config((void *)args.arg0, mode, kstatus, rvp);
807 811 spcs_s_copyoutf(&kstatus, args.ustatus);
808 812 return (rc);
809 813
810 814 case RDC_VERSION:
811 815 {
812 816 STRUCT_DECL(rdc_version, parms);
813 817
814 818 STRUCT_INIT(parms, mode);
815 819
816 820 STRUCT_FSET(parms, major, sndr_major_rev);
817 821 STRUCT_FSET(parms, minor, sndr_minor_rev);
818 822 STRUCT_FSET(parms, micro, sndr_micro_rev);
819 823 STRUCT_FSET(parms, baseline, sndr_baseline_rev);
820 824
821 825 if (ddi_copyout(STRUCT_BUF(parms), (void *)args.arg0,
822 826 STRUCT_SIZE(parms), mode)) {
823 827 spcs_s_kfree(kstatus);
824 828 return (EFAULT);
825 829 }
826 830 break;
827 831 }
828 832
829 833 case RDC_LINK_DOWN:
830 834 /* char *host from user */
831 835 rc = _rdc_link_down((void *)args.arg0, mode, kstatus, rvp);
832 836 spcs_s_copyoutf(&kstatus, args.ustatus);
833 837
834 838 return (rc);
835 839
836 840 case RDC_SYNC_EVENT:
837 841 rc = _rdc_sync_event_wait((void *)args.arg0, (void *)args.arg1,
838 842 mode, kstatus, rvp);
839 843 spcs_s_copyoutf(&kstatus, args.ustatus);
840 844
841 845 return (rc);
842 846
843 847
844 848 default:
845 849 rc = EINVAL;
846 850 break;
847 851 }
848 852
849 853 spcs_s_kfree(kstatus);
850 854 return (rc);
851 855 }
852 856
853 857 int
854 858 sndr_info_stats_update(kstat_t *ksp, int rw)
855 859 {
856 860 extern int rdc_rpc_tmout;
857 861 extern int rdc_health_thres;
858 862 extern int rdc_bitmap_delay;
859 863 extern long rdc_clnt_count;
860 864 extern long rdc_svc_count;
861 865 sndr_m_stats_t *info_stats;
862 866 rdc_k_info_t *krdc;
863 867
864 868 info_stats = (sndr_m_stats_t *)(ksp->ks_data);
865 869 krdc = (rdc_k_info_t *)(ksp->ks_private);
866 870
867 871 /* no writes currently allowed */
868 872
869 873 if (rw == KSTAT_WRITE) {
870 874 return (EACCES);
871 875 }
872 876
873 877 /* default to READ */
874 878 info_stats->m_maxsets.value.ul = rdc_max_sets;
875 879 info_stats->m_maxfbas.value.ul = krdc->maxfbas;
876 880 info_stats->m_rpc_timeout.value.ul = rdc_rpc_tmout;
877 881 info_stats->m_health_thres.value.ul = rdc_health_thres;
878 882 info_stats->m_bitmap_writes.value.ul = krdc->bitmap_write;
879 883 info_stats->m_bitmap_ref_delay.value.ul = rdc_bitmap_delay;
880 884
881 885 /* clts counters not implemented yet */
882 886 info_stats->m_clnt_cots_calls.value.ul = rdc_clnt_count;
883 887 info_stats->m_clnt_clts_calls.value.ul = 0;
884 888 info_stats->m_svc_cots_calls.value.ul = rdc_svc_count;
885 889 info_stats->m_svc_clts_calls.value.ul = 0;
886 890
887 891 return (0);
888 892 }
889 893
890 894 /*
891 895 * copy tailsize-1 bytes of tail of s to s1.
892 896 */
893 897 void
894 898 rdc_str_tail_cpy(char *s1, char *s, size_t tailsize)
895 899 {
896 900 /* To avoid un-terminated string, max size is 16 - 1 */
897 901 ssize_t offset = strlen(s) - (tailsize - 1);
898 902
899 903 offset = (offset > 0) ? offset : 0;
900 904
901 905 /* ensure it's null terminated */
902 906 (void) strlcpy(s1, (const char *)(s + offset), tailsize);
903 907 }
904 908
905 909 int
906 910 rdc_info_stats_update(kstat_t *ksp, int rw)
907 911 {
908 912 rdc_info_stats_t *rdc_info_stats;
909 913 rdc_k_info_t *krdc;
910 914 rdc_u_info_t *urdc;
911 915
912 916 rdc_info_stats = (rdc_info_stats_t *)(ksp->ks_data);
913 917 krdc = (rdc_k_info_t *)(ksp->ks_private);
914 918 urdc = &rdc_u_info[krdc->index];
915 919
916 920 /* no writes currently allowed */
917 921
918 922 if (rw == KSTAT_WRITE) {
919 923 return (EACCES);
920 924 }
921 925
922 926 /* default to READ */
923 927 rdc_info_stats->s_flags.value.ul = urdc->flags;
924 928 rdc_info_stats->s_syncflags.value.ul =
925 929 urdc->sync_flags;
926 930 rdc_info_stats->s_bmpflags.value.ul =
927 931 urdc->bmap_flags;
928 932 rdc_info_stats->s_syncpos.value.ul =
929 933 urdc->sync_pos;
930 934 rdc_info_stats->s_volsize.value.ul =
931 935 urdc->volume_size;
932 936 rdc_info_stats->s_bits_set.value.ul =
933 937 urdc->bits_set;
934 938 rdc_info_stats->s_autosync.value.ul =
935 939 urdc->autosync;
936 940 rdc_info_stats->s_maxqfbas.value.ul =
937 941 urdc->maxqfbas;
938 942 rdc_info_stats->s_maxqitems.value.ul =
939 943 urdc->maxqitems;
940 944
941 945 kstat_named_setstr(&rdc_info_stats->s_primary_vol,
942 946 urdc->primary.file);
943 947
944 948 kstat_named_setstr(&rdc_info_stats->s_secondary_vol,
945 949 urdc->secondary.file);
946 950
947 951 if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
948 952 kstat_named_setstr(&rdc_info_stats->s_bitmap,
949 953 urdc->primary.bitmap);
950 954 } else {
951 955 kstat_named_setstr(&rdc_info_stats->s_bitmap,
952 956 urdc->secondary.bitmap);
953 957 }
954 958
955 959 kstat_named_setstr(&rdc_info_stats->s_primary_intf,
956 960 urdc->primary.intf);
957 961
958 962 kstat_named_setstr(&rdc_info_stats->s_secondary_intf,
959 963 urdc->secondary.intf);
960 964
961 965 rdc_info_stats->s_type_flag.value.ul = krdc->type_flag;
962 966 rdc_info_stats->s_bitmap_size.value.ul = krdc->bitmap_size;
963 967 rdc_info_stats->s_disk_status.value.ul = krdc->disk_status;
964 968
965 969 if (krdc->intf) {
966 970 rdc_info_stats->s_if_if_down.value.ul = krdc->intf->if_down;
967 971 rdc_info_stats->s_if_rpc_version.value.ul =
968 972 krdc->intf->rpc_version;
969 973 }
970 974
971 975 /* the type can change without disable/re-enable so... */
972 976 bzero(rdc_info_stats->s_aqueue_type.value.c, KSTAT_DATA_CHAR_LEN);
973 977 if (RDC_IS_MEMQ(krdc->group)) {
974 978 (void) strcpy(rdc_info_stats->s_aqueue_type.value.c, "memory");
975 979 rdc_info_stats->s_aqueue_blk_hwm.value.ul =
976 980 krdc->group->ra_queue.blocks_hwm;
977 981 rdc_info_stats->s_aqueue_itm_hwm.value.ul =
978 982 krdc->group->ra_queue.nitems_hwm;
979 983 rdc_info_stats->s_aqueue_throttle.value.ul =
980 984 krdc->group->ra_queue.throttle_delay;
981 985 rdc_info_stats->s_aqueue_items.value.ul =
982 986 krdc->group->ra_queue.nitems;
983 987 rdc_info_stats->s_aqueue_blocks.value.ul =
984 988 krdc->group->ra_queue.blocks;
985 989
986 990 } else if (RDC_IS_DISKQ(krdc->group)) {
987 991 disk_queue *q = &krdc->group->diskq;
988 992 rdc_info_stats->s_aqueue_blk_hwm.value.ul =
989 993 krdc->group->diskq.blocks_hwm;
990 994 rdc_info_stats->s_aqueue_itm_hwm.value.ul =
991 995 krdc->group->diskq.nitems_hwm;
992 996 rdc_info_stats->s_aqueue_throttle.value.ul =
993 997 krdc->group->diskq.throttle_delay;
994 998 rdc_info_stats->s_aqueue_items.value.ul = QNITEMS(q);
995 999 rdc_info_stats->s_aqueue_blocks.value.ul = QBLOCKS(q);
996 1000 (void) strcpy(rdc_info_stats->s_aqueue_type.value.c, "disk");
997 1001 }
998 1002
999 1003 return (0);
1000 1004 }
1001 1005
1002 1006 void
1003 1007 rdc_kstat_create(int index)
1004 1008 {
1005 1009 int j = index;
1006 1010 rdc_k_info_t *krdc = &rdc_k_info[index];
1007 1011 rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
1008 1012 size_t varsize;
1009 1013
1010 1014 if (!krdc->set_kstats) {
1011 1015 krdc->set_kstats = kstat_create(RDC_KSTAT_MODULE, j,
1012 1016 RDC_KSTAT_INFO, RDC_KSTAT_CLASS, KSTAT_TYPE_NAMED,
1013 1017 sizeof (rdc_info_stats_t) / sizeof (kstat_named_t),
1014 1018 KSTAT_FLAG_VIRTUAL);
1015 1019 #ifdef DEBUG
1016 1020 if (!krdc->set_kstats)
1017 1021 cmn_err(CE_NOTE, "!krdc:u_kstat null");
1018 1022 #endif
1019 1023
1020 1024 if (krdc->set_kstats) {
1021 1025 /* calculate exact size of KSTAT_DATA_STRINGs */
1022 1026 varsize = strlen(urdc->primary.file) + 1
1023 1027 + strlen(urdc->secondary.file) + 1
1024 1028 + strlen(urdc->primary.intf) + 1
1025 1029 + strlen(urdc->secondary.intf) + 1;
1026 1030 if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
1027 1031 varsize += strlen(urdc->primary.bitmap) + 1;
1028 1032 } else {
1029 1033 varsize += strlen(urdc->secondary.bitmap) + 1;
1030 1034 }
1031 1035
1032 1036 krdc->set_kstats->ks_data_size += varsize;
1033 1037 krdc->set_kstats->ks_data = &rdc_info_stats;
1034 1038 krdc->set_kstats->ks_update = rdc_info_stats_update;
1035 1039 krdc->set_kstats->ks_private = &rdc_k_info[j];
1036 1040 kstat_install(krdc->set_kstats);
1037 1041 } else
1038 1042 cmn_err(CE_WARN, "!SNDR: k-kstats failed");
1039 1043 }
1040 1044
1041 1045 krdc->io_kstats = kstat_create(RDC_KSTAT_MODULE, j, NULL,
1042 1046 "disk", KSTAT_TYPE_IO, 1, 0);
1043 1047 if (krdc->io_kstats) {
1044 1048 krdc->io_kstats->ks_lock = &krdc->kstat_mutex;
1045 1049 kstat_install(krdc->io_kstats);
1046 1050 }
1047 1051 krdc->bmp_kstats = kstat_create("sndrbmp", j, NULL,
1048 1052 "disk", KSTAT_TYPE_IO, 1, 0);
1049 1053 if (krdc->bmp_kstats) {
1050 1054 krdc->bmp_kstats->ks_lock = &krdc->bmp_kstat_mutex;
1051 1055 kstat_install(krdc->bmp_kstats);
1052 1056 }
1053 1057 }
1054 1058
1055 1059 void
1056 1060 rdc_kstat_delete(int index)
1057 1061 {
1058 1062 rdc_k_info_t *krdc = &rdc_k_info[index];
1059 1063
1060 1064 if (krdc->set_kstats) {
1061 1065 kstat_delete(krdc->set_kstats);
1062 1066 krdc->set_kstats = NULL;
1063 1067 }
1064 1068
1065 1069 if (krdc->io_kstats) {
1066 1070 kstat_delete(krdc->io_kstats);
1067 1071 krdc->io_kstats = NULL;
1068 1072 }
1069 1073 if (krdc->bmp_kstats) {
1070 1074 kstat_delete(krdc->bmp_kstats);
1071 1075 krdc->bmp_kstats = NULL;
1072 1076 }
1073 1077 }
1074 1078
1075 1079 #ifdef DEBUG
1076 1080 /*
1077 1081 * Reset the io_kstat structure of the krdc specified
1078 1082 * by the arg index.
1079 1083 */
1080 1084 static int
1081 1085 rdc_clrkstat(void *arg)
1082 1086 {
1083 1087 int index;
1084 1088 rdc_k_info_t *krdc;
1085 1089
1086 1090 index = (int)(unsigned long)arg;
1087 1091 if ((index < 0) || (index >= rdc_max_sets)) {
1088 1092 return (EINVAL);
1089 1093 }
1090 1094 krdc = &rdc_k_info[index];
1091 1095 if (krdc->io_kstats) {
1092 1096 kstat_delete(krdc->io_kstats);
1093 1097 krdc->io_kstats = NULL;
1094 1098 } else {
1095 1099 return (EINVAL);
1096 1100 }
1097 1101 krdc->io_kstats = kstat_create(RDC_KSTAT_MODULE, index, NULL,
1098 1102 "disk", KSTAT_TYPE_IO, 1, 0);
1099 1103 if (krdc->io_kstats) {
1100 1104 krdc->io_kstats->ks_lock = &krdc->kstat_mutex;
1101 1105 kstat_install(krdc->io_kstats);
1102 1106 } else {
1103 1107 return (EINVAL);
1104 1108 }
1105 1109 /*
1106 1110 * clear the high water marks and throttle.
1107 1111 */
1108 1112 if (krdc->group) {
1109 1113 krdc->group->ra_queue.nitems_hwm = 0;
1110 1114 krdc->group->ra_queue.blocks_hwm = 0;
1111 1115 krdc->group->ra_queue.throttle_delay = 0;
1112 1116 }
1113 1117 return (0);
1114 1118 }
1115 1119 #endif
↓ open down ↓ |
576 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX