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