Print this page
6198 Let's EOL cachefs
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/lvm/libmeta/common/meta_check.c
+++ new/usr/src/lib/lvm/libmeta/common/meta_check.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.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
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 /*
23 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 + * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 26 */
26 27
27 28 /*
28 29 * Just in case we're not in a build environment, make sure that
29 30 * TEXT_DOMAIN gets set to something.
30 31 */
31 32 #if !defined(TEXT_DOMAIN)
32 33 #define TEXT_DOMAIN "SYS_TEST"
33 34 #endif
34 35
35 36 /*
36 37 * check componets
37 38 */
38 39
39 40 #include <meta.h>
40 41 #include "meta_lib_prv.h"
41 42
42 43 #include <sys/mnttab.h>
43 44 #include <sys/swap.h>
44 45 #include <devid.h>
45 46 #include <sys/dumpadm.h>
46 47
47 48 /* possible returns from meta_check_samedrive */
48 49 #define CANT_TELL -1
49 50 #define NOT_SAMEDRIVE 0
50 51 #define IDENTICAL_NAME_DEVT 1
51 52 #define IDENTICAL_DEVIDS 2
52 53
53 54 /*
54 55 * static list(s)
55 56 */
56 57 typedef struct dev_list {
57 58 char *dev_name;
58 59 ddi_devid_t devid;
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
59 60 struct dev_list *dev_nxt;
60 61 } dev_list_t;
61 62
62 63 static dev_list_t *devnamelist = NULL;
63 64
64 65 static char *skip_these_mntents[] = {
65 66 "nfs",
66 67 "autofs",
67 68 "proc",
68 69 "tmpfs",
69 - "cachefs",
70 70 "rfs",
71 71 "fd",
72 72 "mntfs",
73 73 "lofs",
74 74 "devfs",
75 75 "dev",
76 76 "ctfs",
77 77 "objfs",
78 78 "sharefs",
79 79 NULL
80 80 };
81 81
82 82 /*
83 83 * free swap info
84 84 */
85 85 static void
86 86 free_swapinfo(
87 87 struct swaptable *swtp
88 88 )
89 89 {
90 90 int i;
91 91
92 92 if (swtp == NULL)
93 93 return;
94 94
95 95 for (i = 0; (i < swtp->swt_n); ++i) {
96 96 if (swtp->swt_ent[i].ste_path != NULL)
97 97 Free(swtp->swt_ent[i].ste_path);
98 98 }
99 99
100 100 Free(swtp);
101 101 }
102 102
103 103 /*
104 104 * get swap info
105 105 */
106 106 static int
107 107 get_swapinfo(
108 108 struct swaptable **swtpp,
109 109 int *nswap,
110 110 md_error_t *ep
111 111 )
112 112 {
113 113 int i;
114 114 size_t swtsize;
115 115
116 116 *swtpp = NULL;
117 117
118 118 /* get number of entries */
119 119 if ((*nswap = swapctl(SC_GETNSWP, NULL)) < 0) {
120 120 return (mdsyserror(ep, errno, "swapctl(SC_GETNSWP)"));
121 121 }
122 122
123 123 /* allocate structure */
124 124 swtsize = sizeof ((*swtpp)->swt_n) +
125 125 ((*nswap) * sizeof ((*swtpp)->swt_ent[0]));
126 126 *swtpp = (struct swaptable *)Zalloc(swtsize);
127 127 (*swtpp)->swt_n = *nswap;
128 128 for (i = 0; (i < (*nswap)); ++i)
129 129 (*swtpp)->swt_ent[i].ste_path = Zalloc(MAXPATHLEN);
130 130
131 131 /* get info */
132 132 if (((*nswap) = swapctl(SC_LIST, (*swtpp))) < 0) {
133 133 (void) mdsyserror(ep, errno, "swapctl(SC_LIST)");
134 134 free_swapinfo(*swtpp);
135 135 return (-1);
136 136 }
137 137
138 138 /* return success */
139 139 return (0);
140 140 }
141 141
142 142 /*
143 143 * check whether device is swapped on
144 144 */
145 145 static int
146 146 meta_check_swapped(
147 147 mdsetname_t *sp,
148 148 mdname_t *np,
149 149 md_error_t *ep
150 150 )
151 151 {
152 152 struct swaptable *swtp;
153 153 int nswap;
154 154 int i;
155 155 int rval = 0;
156 156
157 157 /* should have a set */
158 158 assert(sp != NULL);
159 159
160 160 /* get swap info */
161 161 if (get_swapinfo(&swtp, &nswap, ep) != 0)
162 162 return (-1);
163 163
164 164 /* look for match */
165 165 for (i = 0; ((i < nswap) && (rval == 0)); ++i) {
166 166 mdname_t *snp;
167 167
168 168 if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path,
169 169 UNKNOWN, ep)) == NULL) {
170 170 mdclrerror(ep);
171 171 continue;
172 172 }
173 173 if (np->dev == snp->dev) {
174 174 rval = mddeverror(ep, MDE_IS_SWAPPED,
175 175 np->dev, np->cname);
176 176 } else { /* not swap - does it overlap */
177 177 rval = meta_check_overlap(snp->cname, np, 0, -1,
178 178 snp, 0, -1, ep);
179 179 if (rval != 0) {
180 180 (void) mdoverlaperror(ep, MDE_OVERLAP_SWAP,
181 181 np->cname, NULL, snp->cname);
182 182 }
183 183 }
184 184 }
185 185 free_swapinfo(swtp);
186 186
187 187 /* return success */
188 188 return (rval);
189 189 }
190 190
191 191 /*
192 192 * Is a driver currently swapped on?
193 193 */
194 194 int
195 195 meta_check_driveswapped(
196 196 mdsetname_t *sp,
197 197 mddrivename_t *dnp,
198 198 md_error_t *ep
199 199 )
200 200 {
201 201 struct swaptable *swtp;
202 202 int nswap;
203 203 int i;
204 204 int rval = 0;
205 205
206 206 /* should have a set */
207 207 assert(sp != NULL);
208 208
209 209 /* get swap info */
210 210 if (get_swapinfo(&swtp, &nswap, ep) != 0)
211 211 return (-1);
212 212
213 213 /* look for match */
214 214 for (i = 0; (i < nswap); ++i) {
215 215 mdname_t *snp;
216 216
217 217 if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path,
218 218 LOGICAL_DEVICE, ep)) == NULL) {
219 219 mdclrerror(ep);
220 220 continue;
221 221 }
222 222
223 223 if (strcmp(dnp->cname, snp->drivenamep->cname) == 0) {
224 224 rval = mddeverror(ep, MDE_IS_SWAPPED, NODEV64,
225 225 dnp->cname);
226 226 }
227 227 }
228 228 free_swapinfo(swtp);
229 229
230 230 /* return success */
231 231 return (rval);
232 232 }
233 233
234 234 /*
235 235 * check whether device is a dump device
236 236 */
237 237 static int
238 238 meta_check_dump(
239 239 mdsetname_t *sp,
240 240 mdname_t *np,
241 241 md_error_t *ep
242 242 )
243 243 {
244 244 int rval = 0;
245 245 int dump_fd;
246 246 char device[MAXPATHLEN];
247 247
248 248
249 249 if ((dump_fd = open("/dev/dump", O_RDONLY)) < 0)
250 250 return (mdsyserror(ep, errno, "/dev/dump"));
251 251
252 252 if (ioctl(dump_fd, DIOCGETDEV, device) != -1) {
253 253 mdname_t *dump_np;
254 254
255 255 if ((dump_np = metaname(&sp, device, UNKNOWN, ep)) == NULL) {
256 256 mdclrerror(ep);
257 257 (void) close(dump_fd);
258 258 return (0);
259 259 }
260 260
261 261 if (np->dev == dump_np->dev) {
262 262 rval = mddeverror(ep, MDE_IS_DUMP,
263 263 np->dev, np->cname);
264 264 } else { /* not a dump device - but does it overlap? */
265 265 rval = meta_check_overlap(dump_np->cname, np, 0, -1,
266 266 dump_np, 0, -1, ep);
267 267 if (rval != 0) {
268 268 (void) mdoverlaperror(ep, MDE_OVERLAP_DUMP,
269 269 np->cname, NULL, dump_np->cname);
270 270 }
271 271 }
272 272 }
273 273 (void) close(dump_fd);
274 274 return (rval);
275 275 }
276 276
277 277 /*
278 278 * check whether device is mounted
279 279 */
280 280 static int
281 281 meta_check_mounted(
282 282 mdsetname_t *sp,
283 283 mdname_t *np,
284 284 md_error_t *ep
285 285 )
286 286 {
287 287 FILE *mfp;
288 288 struct mnttab m;
289 289 int rval = 0;
290 290 char mountp[MNT_LINE_MAX];
291 291 char mnt_special[MNT_LINE_MAX];
292 292
293 293 /* should have a set */
294 294 assert(sp != NULL);
295 295
296 296 /* look in mnttab */
297 297 if ((mfp = open_mnttab()) == NULL)
298 298 return (mdsyserror(ep, errno, MNTTAB));
299 299 while ((getmntent(mfp, &m) == 0) && (rval == 0)) {
300 300 char **fstype = skip_these_mntents;
301 301 int skipit = 0;
302 302 mdname_t *mnp;
303 303
304 304 if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL))
305 305 continue;
306 306
307 307 if (m.mnt_mountp[0] != '/')
308 308 continue;
309 309
310 310 while (*fstype != NULL)
311 311 if (strcmp(m.mnt_fstype, *fstype++) == 0) {
312 312 skipit++;
313 313 break;
314 314 }
315 315
316 316 if (skipit == 1)
317 317 continue;
318 318
319 319 (void) strcpy(mountp, m.mnt_mountp);
320 320 (void) strcpy(mnt_special, m.mnt_special);
321 321
322 322 if ((mnp = metaname(&sp, mnt_special, UNKNOWN, ep)) == NULL) {
323 323 mdclrerror(ep);
324 324 continue;
325 325 }
326 326
327 327 if (np->dev == mnp->dev) {
328 328 rval = mduseerror(ep, MDE_IS_MOUNTED,
329 329 np->dev, mountp, np->cname);
330 330 } else { /* device isn't in mnttab - does it overlap? */
331 331 rval = meta_check_overlap(mnp->cname, np, 0, -1,
332 332 mnp, 0, -1, ep);
333 333 if (rval != 0) {
334 334 (void) mdoverlaperror(ep, MDE_OVERLAP_MOUNTED,
335 335 np->cname, mountp, mnp->cname);
336 336 }
337 337 }
338 338 }
339 339
340 340 /* return success */
341 341 return (rval);
342 342 }
343 343
344 344
345 345 /*
346 346 * Is a file system currently mounted on this disk drive?
347 347 */
348 348 int
349 349 meta_check_drivemounted(
350 350 mdsetname_t *sp,
351 351 mddrivename_t *dnp,
352 352 md_error_t *ep
353 353 )
354 354 {
355 355 FILE *mfp;
356 356 struct mnttab m;
357 357 int rval = 0;
358 358 char mountp[MNT_LINE_MAX];
359 359 char mnt_special[MNT_LINE_MAX];
360 360
361 361 /* should have a set */
362 362 assert(sp != NULL);
363 363
364 364 /* look in mnttab */
365 365 if ((mfp = open_mnttab()) == NULL)
366 366 return (mdsyserror(ep, errno, MNTTAB));
367 367 while ((getmntent(mfp, &m) == 0) && (rval == 0)) {
368 368 char **fstype = skip_these_mntents;
369 369 int skipit = 0;
370 370 mdname_t *mnp;
371 371
372 372 if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL))
373 373 continue;
374 374
375 375 if (m.mnt_mountp[0] != '/')
376 376 continue;
377 377
378 378 while (*fstype != NULL)
379 379 if (strcmp(m.mnt_fstype, *fstype++) == 0) {
380 380 skipit++;
381 381 break;
382 382 }
383 383
384 384 if (skipit == 1)
385 385 continue;
386 386
387 387 (void) strcpy(mountp, m.mnt_mountp);
388 388 (void) strcpy(mnt_special, m.mnt_special);
389 389 if ((mnp = metaname(&sp, mnt_special,
390 390 LOGICAL_DEVICE, ep)) == NULL) {
391 391 mdclrerror(ep);
392 392 continue;
393 393 }
394 394 if (strcmp(dnp->cname, mnp->drivenamep->cname) == 0) {
395 395 rval = mduseerror(ep, MDE_IS_MOUNTED, NODEV64,
396 396 mountp, dnp->cname);
397 397 }
398 398 }
399 399
400 400 /* return success */
401 401 return (rval);
402 402 }
403 403
404 404 /*
405 405 * Check to see if the specified name is already in use or overlaps
406 406 * with a device already in use. Checks are made to determine whether
407 407 * the device is mounted, is a swap device, or a dump device. In each
408 408 * case if the device is not in use then an overlap check is done to ensure
409 409 * that the specified slice does not overlap.
410 410 */
411 411 int
412 412 meta_check_inuse(
413 413 mdsetname_t *sp,
414 414 mdname_t *np,
415 415 mdinuseopts_t inuse_flags,
416 416 md_error_t *ep
417 417 )
418 418 {
419 419 int rval = 0;
420 420
421 421 if ((inuse_flags & MDCHK_MOUNTED) &&
422 422 (rval = meta_check_mounted(sp, np, ep)) != 0)
423 423 return (rval);
424 424
425 425 if ((inuse_flags & MDCHK_SWAP) &&
426 426 (rval = meta_check_swapped(sp, np, ep)) != 0)
427 427 return (rval);
428 428
429 429 if ((inuse_flags & MDCHK_DUMP) &&
430 430 (rval = meta_check_dump(sp, np, ep)) != 0)
431 431 return (rval);
432 432
433 433 return (rval);
434 434 }
435 435
436 436 int
437 437 meta_check_driveinset(mdsetname_t *sp, mddrivename_t *dn, md_error_t *ep)
438 438 {
439 439 set_t setno;
440 440 set_t max_sets;
441 441
442 442 if ((max_sets = get_max_sets(ep)) == 0)
443 443 return (-1);
444 444
445 445 for (setno = 1; setno < max_sets; setno++) {
446 446 mdsetname_t *sp1;
447 447 int is_it;
448 448
449 449 if (setno == sp->setno)
450 450 continue;
451 451
452 452 if ((sp1 = metasetnosetname(setno, ep)) == NULL) {
453 453 if (mdismddberror(ep, MDE_DB_NODB)) {
454 454 mdclrerror(ep);
455 455 return (0);
456 456 }
457 457 if (mdiserror(ep, MDE_NO_SET)) {
458 458 mdclrerror(ep);
459 459 continue;
460 460 }
461 461 return (-1);
462 462 }
463 463
464 464 metaflushsetname(sp1);
465 465
466 466 if ((is_it = meta_is_drive_in_thisset(sp1, dn, FALSE, ep))
467 467 == -1)
468 468 return (-1);
469 469
470 470 if (is_it)
471 471 return (mddserror(ep, MDE_DS_DRIVEINSET, sp->setno,
472 472 sp1->setname, dn->cname, sp->setname));
473 473 }
474 474
475 475 return (0);
476 476 }
477 477
478 478 /*
479 479 * Add a device/device id tuple to the devname cache
480 480 */
481 481 static void
482 482 add_to_devname_list(
483 483 char *device_name, /* fully qualified dev name */
484 484 ddi_devid_t devid /* device id */
485 485 )
486 486 {
487 487 dev_list_t *dnlp;
488 488
489 489 dnlp = Zalloc(sizeof (*dnlp));
490 490 dnlp->dev_name = Strdup(device_name);
491 491 dnlp->devid = devid;
492 492
493 493 /* link the node into the devname list */
494 494 dnlp->dev_nxt = devnamelist;
495 495 devnamelist = dnlp;
496 496 }
497 497
498 498 /*
499 499 * check for same drive
500 500 *
501 501 * Differentiate between matching on name/dev_t and devid. In the latter
502 502 * case it is correct to fail but misleading to give the same error msg as
503 503 * for an overlapping slice.
504 504 *
505 505 */
506 506 int
507 507 meta_check_samedrive(
508 508 mdname_t *np1, /* first comp */
509 509 mdname_t *np2, /* second comp */
510 510 md_error_t *ep
511 511 )
512 512 {
513 513
514 514 mdcinfo_t *cinfop1, *cinfop2;
515 515 mdnmtype_t type1 = np1->drivenamep->type;
516 516 mdnmtype_t type2 = np2->drivenamep->type;
517 517 int l = 0;
518 518
519 519 char *name1 = NULL;
520 520 char *name2 = NULL;
521 521
522 522 int retval = CANT_TELL;
523 523 int fd1 = -1;
524 524 int fd2 = -1;
525 525 int rc1 = -2, rc2 = -2;
526 526 uint_t strl1 = 0, strl2 = 0;
527 527 int devid1_found = 0;
528 528 int devid2_found = 0;
529 529
530 530 ddi_devid_t devid1 = NULL;
531 531 ddi_devid_t devid2 = NULL;
532 532 dev_list_t *dnlp = NULL;
533 533
534 534 assert(type1 != MDT_FAST_META && type1 != MDT_FAST_COMP);
535 535 assert(type2 != MDT_FAST_META && type2 != MDT_FAST_COMP);
536 536
537 537 /*
538 538 * The process of determining if 2 names are the same drive is
539 539 * as follows:
540 540 *
541 541 * Case 1 - The filenames are identical
542 542 *
543 543 * Case 2 - Both devices have a devid
544 544 * get and compare the devids for the devices. If both
545 545 * devices have a devid then the compare will is all
546 546 * that is needed we are done.
547 547 *
548 548 * Case 3 - One or more devices does not have a devid
549 549 * start by doing a simple compare of the name, if they
550 550 * are the same just return.
551 551 *
552 552 * If the names differ then keep going and see if the
553 553 * may be the same underlying devic. First check to
554 554 * see if the sd name is the same (old code).
555 555 *
556 556 * Then check the major and minor numbers to see if
557 557 * they are the same. If they are then return (old code).
558 558 *
559 559 * Next compare the raw name and the component name and
560 560 * if they are the same then return.
561 561 *
562 562 * All else has failed so use the component name (cname)
563 563 * component number and unit number. If they all are
564 564 * equal then call them the same drive.
565 565 *
566 566 */
567 567
568 568 if ((np1 == NULL) || (np2 == NULL))
569 569 return (NOT_SAMEDRIVE);
570 570
571 571 /* if the name structs are the same then the drives must be */
572 572 if (np1 == np2)
573 573 return (IDENTICAL_NAME_DEVT);
574 574
575 575 name1 = np1->bname;
576 576 name2 = np2->bname;
577 577
578 578 if ((name1 == NULL) || ((strl1 = strlen(name1)) == 0) ||
579 579 (name2 == NULL) || ((strl2 = strlen(name2)) == 0))
580 580 return (NOT_SAMEDRIVE);
581 581
582 582 if ((strl1 == strl2) && (strcmp(name1, name2) == 0)) {
583 583 /* names are identical */
584 584 return (IDENTICAL_NAME_DEVT);
585 585 }
586 586
587 587 if (is_metaname(name1) || is_metaname(name2))
588 588 return (NOT_SAMEDRIVE);
589 589
590 590 /*
591 591 * Check to see if the devicename is in the static list. If so,
592 592 * use its devid. Otherwise do the expensive operations
593 593 * of opening the device, getting the devid, and closing the
594 594 * device. Add the result into the static list.
595 595 *
596 596 * The case where this list will be useful is when there are soft
597 597 * partitions on multiple drives and a new soft partition is being
598 598 * created. In that situation the underlying physical device name
599 599 * for the new soft partition would be compared against each of the
600 600 * existing soft partititions. Without this static list that would
601 601 * involve 2 opens, closes, and devid gets for each existing soft
602 602 * partition
603 603 */
604 604 for (dnlp = devnamelist; (dnlp != NULL) &&
605 605 !(devid1_found && devid2_found); dnlp = dnlp->dev_nxt) {
606 606 if (!devid1_found && (strcmp(dnlp->dev_name, name1) == 0)) {
607 607 devid1_found = 1;
608 608 devid1 = dnlp->devid;
609 609 if (devid1 == NULL)
610 610 rc1 = 1;
611 611 else
612 612 rc1 = 0;
613 613 continue;
614 614 }
615 615 if (!devid2_found && (strcmp(dnlp->dev_name, name2) == 0)) {
616 616 devid2_found = 1;
617 617 devid2 = dnlp->devid;
618 618 if (devid2 == NULL)
619 619 rc2 = 1;
620 620 else
621 621 rc2 = 0;
622 622 continue;
623 623 }
624 624 }
625 625
626 626 /*
627 627 * Start by checking if the device has a device id, and if they
628 628 * are equal. If they are there is no question there is a match.
629 629 *
630 630 * The process here is open each disk, get the devid for each
631 631 * disk. If they both have a devid compare them and return
632 632 * the results.
633 633 */
634 634 if (!devid1_found) {
635 635 if ((fd1 = open(name1, O_RDONLY | O_NDELAY)) < 0) {
636 636 return (NOT_SAMEDRIVE);
637 637 }
638 638 rc1 = devid_get(fd1, &devid1);
639 639 (void) close(fd1);
640 640
641 641 /* add the name and devid to the cache */
642 642 add_to_devname_list(name1, devid1);
643 643 }
644 644
645 645 if (!devid2_found) {
646 646 if ((fd2 = open(name2, O_RDONLY | O_NDELAY)) < 0) {
647 647 return (NOT_SAMEDRIVE);
648 648 }
649 649 rc2 = devid_get(fd2, &devid2);
650 650 (void) close(fd2);
651 651
652 652 /* add the name and devid to the cache */
653 653 add_to_devname_list(name2, devid2);
654 654 }
655 655
656 656
657 657 if ((rc1 == 0) && (rc2 == 0)) {
658 658 if (devid_compare(devid1, devid2) == 0)
659 659 retval = IDENTICAL_DEVIDS; /* same devid */
660 660 else
661 661 retval = NOT_SAMEDRIVE; /* different drives */
662 662
663 663 }
664 664
665 665 if (retval >= 0) {
666 666 return (retval);
667 667 }
668 668
669 669 /*
670 670 * At this point in time one of the two drives did not have a
671 671 * device ID. Do not make the assumption that is one drive
672 672 * did have a device id and the other did not that they are not
673 673 * the same. One drive could be covered by a device and still
674 674 * be the same drive. This is a general flaw in the system at
675 675 * this time.
676 676 */
677 677
678 678 /*
679 679 * The optimization can not happen if we are given an old style name
680 680 * in the form /dev/XXNN[a-h], since the name caches differently and
681 681 * allows overlaps to happen.
682 682 */
683 683 if (! ((sscanf(np1->bname, "/dev/%*[^0-9/]%*u%*[a-h]%n", &l) == 0 &&
684 684 l == strlen(np1->bname)) ||
685 685 (sscanf(np2->bname, "/dev/%*[^0-9/]%*u%*[a-h]%n", &l) == 0 &&
686 686 l == strlen(np2->bname))) &&
687 687 ((type1 == MDT_COMP) || (type1 == MDT_META)) &&
688 688 ((type2 == MDT_COMP) || (type2 == MDT_META)))
689 689 if (np1->drivenamep == np2->drivenamep)
690 690 return (IDENTICAL_NAME_DEVT);
691 691 else
692 692 return (NOT_SAMEDRIVE);
693 693
694 694 /* check for same drive */
695 695 if (meta_getmajor(np1->dev) != meta_getmajor(np2->dev))
696 696 return (NOT_SAMEDRIVE); /* not same drive */
697 697
698 698 if (((cinfop1 = metagetcinfo(np1, ep)) == NULL) ||
699 699 ((cinfop2 = metagetcinfo(np2, ep)) == NULL)) {
700 700 if ((strcmp(np1->drivenamep->cname,
701 701 np2->drivenamep->cname) != 0) &&
702 702 (strcmp(np1->drivenamep->rname,
703 703 np2->drivenamep->rname) != 0)) {
704 704 mdclrerror(ep);
705 705 return (NOT_SAMEDRIVE); /* not same drive */
706 706 } else {
707 707 return (CANT_TELL); /* can't tell */
708 708 }
709 709 } else if ((strncmp(cinfop1->cname, cinfop2->cname,
710 710 sizeof (cinfop1->cname)) != 0) ||
711 711 (cinfop1->cnum != cinfop2->cnum) ||
712 712 (cinfop1->unit != cinfop2->unit)) {
713 713 return (NOT_SAMEDRIVE); /* not same drive */
714 714 }
715 715
716 716 /* same drive */
717 717 return (IDENTICAL_NAME_DEVT);
718 718 }
719 719
720 720 /*
721 721 * check for overlap
722 722 */
723 723 int
724 724 meta_check_overlap(
725 725 char *uname, /* user supplied name for errors */
726 726 mdname_t *np1, /* first comp */
727 727 diskaddr_t slblk1, /* first comp - start logical block */
728 728 diskaddr_t nblks1, /* first comp - # of blocks */
729 729 mdname_t *np2, /* second comp */
730 730 diskaddr_t slblk2, /* second comp - start logical block */
731 731 diskaddr_t nblks2, /* second comp - # of blocks */
732 732 md_error_t *ep
733 733 )
734 734 {
735 735 diskaddr_t sblk1, sblk2;
736 736 mdvtoc_t *vtocp1, *vtocp2;
737 737 uint_t partno1, partno2;
738 738 mdpart_t *partp1, *partp2;
739 739 int ret;
740 740
741 741 /* verify args */
742 742 if (slblk1 == MD_DISKADDR_ERROR) {
743 743 assert(0);
744 744 return (mdsyserror(ep, EINVAL, np1->cname));
745 745 }
746 746 if (slblk2 == MD_DISKADDR_ERROR) {
747 747 assert(0);
748 748 return (mdsyserror(ep, EINVAL, np2->cname));
749 749 }
750 750
751 751 /* check for same drive */
752 752 if ((ret = meta_check_samedrive(np1, np2, ep)) == 0) {
753 753 return (0); /* not same drive */
754 754 } else if (ret < 0) {
755 755 return (-1); /* can't tell */
756 756 }
757 757
758 758 /* check for overlap */
759 759 if (((vtocp1 = metagetvtoc(np1, FALSE, &partno1, ep)) == NULL) ||
760 760 ((vtocp2 = metagetvtoc(np2, FALSE, &partno2, ep)) == NULL)) {
761 761 return (-1); /* can't tell */
762 762 }
763 763 partp1 = &vtocp1->parts[partno1];
764 764 partp2 = &vtocp2->parts[partno2];
765 765 sblk1 = partp1->start + slblk1;
766 766 if (nblks1 == -1)
767 767 nblks1 = partp1->size - slblk1;
768 768 sblk2 = partp2->start + slblk2;
769 769 if (nblks2 == -1)
770 770 nblks2 = partp2->size - slblk2;
771 771 if (((sblk1 >= sblk2) && (sblk1 < (sblk2 + nblks2))) ||
772 772 ((sblk2 >= sblk1) && (sblk2 < (sblk1 + nblks1)))) {
773 773 if (np1->dev == np2->dev) { /* slice in use */
774 774 return (mduseerror(ep, MDE_ALREADY, np1->dev,
775 775 uname, np1->cname));
776 776 }
777 777 if (ret == IDENTICAL_NAME_DEVT)
778 778 return (mduseerror(ep, /* slice overlaps */
779 779 MDE_OVERLAP, np1->dev, uname, np1->cname));
780 780 else
781 781 return (mduseerror(ep, /* same devid */
782 782 MDE_SAME_DEVID, np1->dev, uname, np2->cname));
783 783 }
784 784
785 785 /* return success */
786 786 return (0); /* no overlap */
787 787 }
788 788
789 789 /*
790 790 * check to see if a device is in a metadevice
791 791 */
792 792 int
793 793 meta_check_inmeta(
794 794 mdsetname_t *sp,
795 795 mdname_t *np,
796 796 mdchkopts_t options,
797 797 diskaddr_t slblk,
798 798 diskaddr_t nblks,
799 799 md_error_t *ep
800 800 )
801 801 {
802 802 uint_t partno;
803 803
804 804 /* see if replica slice is ok, only applies to disks in sets */
805 805 if (! (options & MDCHK_ALLOW_REPSLICE) &&
806 806 ! metaislocalset(sp)) {
807 807 uint_t rep_slice;
808 808
809 809 if (metagetvtoc(np, FALSE, &partno, ep) == NULL)
810 810 return (-1);
811 811 if (meta_replicaslice(np->drivenamep, &rep_slice, ep)
812 812 != 0)
813 813 return (-1);
814 814 if (partno == rep_slice)
815 815 return (mddeverror(ep, MDE_REPCOMP_INVAL, np->dev,
816 816 np->cname));
817 817 }
818 818
819 819 /* check for databases */
820 820 if (meta_check_inreplica(sp, np, slblk, nblks, ep) != 0) {
821 821 if (mdisuseerror(ep, MDE_ALREADY)) {
822 822 if (options & MDCHK_ALLOW_MDDB) {
823 823 mdclrerror(ep);
824 824 } else {
825 825 return (mddeverror(ep, MDE_HAS_MDDB,
826 826 np->dev, np->cname));
827 827 }
828 828 } else {
829 829 return (-1);
830 830 }
831 831 }
832 832
833 833 /* check metadevices */
834 834 if (meta_check_instripe(sp, np, slblk, nblks, ep) != 0)
835 835 return (-1);
836 836 if (meta_check_inmirror(sp, np, slblk, nblks, ep) != 0)
837 837 return (-1);
838 838 if (meta_check_intrans(sp, np, options, slblk, nblks, ep) != 0)
839 839 return (-1);
840 840 if (meta_check_insp(sp, np, slblk, nblks, ep) != 0)
841 841 return (-1);
842 842 if (! (options & MDCHK_ALLOW_HS)) {
843 843 if (meta_check_inhsp(sp, np, slblk, nblks, ep) != 0)
844 844 return (-1);
845 845 }
846 846 if (meta_check_inraid(sp, np, slblk, nblks, ep) != 0)
847 847 return (-1);
848 848
849 849 /* return success */
850 850 return (0);
851 851 }
852 852
853 853 /*
854 854 * check to see if a device is in its set
855 855 */
856 856 int
857 857 meta_check_inset(
858 858 mdsetname_t *sp,
859 859 mdname_t *np,
860 860 md_error_t *ep
861 861 )
862 862 {
863 863 mdsetname_t *npsp;
864 864 int bypass_daemon = FALSE;
865 865
866 866
867 867 /* check devices set */
868 868 if (metaislocalset(sp))
869 869 bypass_daemon = TRUE;
870 870 if ((npsp = metagetset(np, bypass_daemon, ep)) == NULL) {
871 871 if ((! metaismeta(np)) &&
872 872 (metaislocalset(sp)) &&
873 873 (mdismddberror(ep, MDE_DB_NODB))) {
874 874 mdclrerror(ep);
875 875 npsp = sp;
876 876 } else {
877 877 return (-1);
878 878 }
879 879 }
880 880
881 881 /* check set */
882 882 if (metaissameset(sp, npsp))
883 883 return (0);
884 884
885 885 /* return appropriate error */
886 886 if (metaislocalset(sp))
887 887 return (mddeverror(ep, MDE_IN_SHARED_SET, np->dev, np->cname));
888 888 else
889 889 return (mddeverror(ep, MDE_NOT_IN_SET, np->dev, np->cname));
890 890 }
891 891
892 892 /*
893 893 * check to see if current user is root
894 894 */
895 895 int
896 896 meta_check_root(md_error_t *ep)
897 897 {
898 898 if (geteuid() != 0) {
899 899 (void) mderror(ep, MDE_NOPERM, "");
900 900 return (-1);
901 901 }
902 902 return (0);
903 903 }
↓ open down ↓ |
824 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX