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