7712 mandoc -Tlint does always exit with error code 0
[unleashed.git] / usr / src / lib / lvm / libmeta / common / meta_devadm.c
blob0d90d2f802e8802f17c944b9a1e82a8535a4fa00
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <ctype.h>
28 #include <sys/fcntl.h>
29 #include <sys/types.h>
30 #include <devid.h>
31 #include <ftw.h>
32 #include <string.h>
33 #include <mdiox.h>
34 #include <sys/lvm/mdio.h>
35 #include <meta.h>
36 #include <syslog.h>
37 #include <sdssc.h>
38 #include <libdevinfo.h>
39 #include "meta_set_prv.h"
42 * Just in case we're not in a build environment, make sure that
43 * TEXT_DOMAIN gets set to something.
45 #if !defined(TEXT_DOMAIN)
46 #define TEXT_DOMAIN "SYS_TEST"
47 #endif
49 #define RAW_PATH 0x001 /* rdsk */
50 #define BLOCK_PATH 0x002 /* dsk */
51 #define DSK_TYPE 0x004 /* normal /dev/[r]dsk */
52 #define TEST_TYPE 0x008 /* test driver path */
53 #define DID_TYPE 0x010 /* cluster did path */
54 #define AP_TYPE 0x020 /* should be obsolete */
56 typedef struct path_list {
57 char *search_path;
58 char *search_type;
59 int path_type;
60 } path_list_t;
63 * A table of the supported path types - this should ideally be generated
64 * by reading the /etc/lvm/devpath file
66 static path_list_t plist[] = {
67 {"/dev/rdsk", DEVID_MINOR_NAME_ALL_CHR, RAW_PATH|DSK_TYPE},
68 {"/dev/dsk", DEVID_MINOR_NAME_ALL_BLK, BLOCK_PATH|DSK_TYPE},
69 {"/dev/did/rdsk", DEVID_MINOR_NAME_ALL_CHR, RAW_PATH|DID_TYPE},
70 {"/dev/did/dsk", DEVID_MINOR_NAME_ALL_BLK, BLOCK_PATH|DID_TYPE},
71 {"/dev/td/dsk", DEVID_MINOR_NAME_ALL_BLK, BLOCK_PATH|TEST_TYPE},
72 {"/dev/td/rdsk", DEVID_MINOR_NAME_ALL_CHR, RAW_PATH|TEST_TYPE},
74 static int num = sizeof (plist)/sizeof (path_list_t);
76 static mddevopts_t dev_options = 0;
78 /* indicate whether to print an error message or not */
79 static int firsttime = 1;
81 #define DEV_MATCH 0x1
82 #define NAME_MATCH 0x2
84 #define DEBUGON 1
85 #define DEBUGOFF 2
88 * Debug function: to turn on devadm function debugging include DEVADM
89 * in the MD_DEBUG enviroment variable: MD_DEBUG=...,DEVADM...
91 /*PRINTFLIKE1*/
92 static void
93 mda_debug(char *format, ...)
95 char *p;
96 static int debug_set = 0;
97 va_list ap;
99 if (debug_set == 0) {
100 if (((p = getenv("MD_DEBUG")) != NULL) &&
101 (strstr(p, "DEVADM") != NULL))
102 debug_set = DEBUGON;
103 else
104 debug_set = DEBUGOFF;
106 if (debug_set == DEBUGON) {
107 va_start(ap, format);
108 (void) vfprintf(stderr, format, ap);
109 va_end(ap);
113 /* print error messages to the terminal or syslog */
114 /*PRINTFLIKE1*/
115 static void
116 mda_print(char *message, ...)
118 va_list ap;
120 va_start(ap, message);
121 if (dev_options & DEV_LOG) {
123 * The program is a daemon in the sense that it
124 * is a system utility.
126 (void) vsyslog((LOG_ERR | LOG_DAEMON), message, ap);
127 } else {
128 (void) vfprintf(stderr, message, ap);
130 va_end(ap);
134 * Utility to find the correct options to use for the devid search
135 * based upon the path of the device.
137 * RETURN:
138 * -1 Error, the path passed in is not in the table
139 * >= 0 The element number for the options within the table
141 static int
142 mda_findpath(char *path)
144 int i = 0;
146 for (i = 0; i < num; i++) {
147 if (strncmp(plist[i].search_path, path,
148 strlen(plist[i].search_path)) == 0)
149 return (i);
151 return (-1);
155 * Utility to get the path of a device
157 static char *
158 mda_getpath(char *devname)
160 char *ptr;
161 char *pathname;
162 size_t len;
164 if ((ptr = strrchr(devname, '/')) == NULL) {
165 mda_debug("Invalid format: %s\n", devname);
166 return (NULL);
168 ptr++;
169 len = strlen(devname) - strlen(ptr);
170 pathname = Malloc(len + 1);
171 (void) strncpy(pathname, devname, len);
172 pathname[len] = '\0';
173 return (pathname);
177 * meta_update_devtree -- Update the /dev/md namespace for metadevices.
179 * Only update the specific link if a valid minor(not NODEV) is given.
180 * Otherwise, update the entire /dev/md .
184 meta_update_devtree(minor_t mnum)
186 char nodename[40];
187 di_devlink_handle_t hdl;
190 * di_devlink_init() returns once the /dev links have been
191 * updated(created or removed). If di_devlink_init returns
192 * a NULL, the link operation failed.
194 * Use the enhanced di_devlink_init interface if the mnum
195 * is available.
197 if (mnum == NODEV) {
199 * NOTE: This will take a _long_ time for large numbers
200 * of metadevices.
202 hdl = di_devlink_init("md", DI_MAKE_LINK);
203 } else {
204 /* Call di_devlink_init twice, for block and raw devices */
205 (void) sprintf(nodename, "/pseudo/md@0:%lu,%lu,raw",
206 MD_MIN2SET(mnum), MD_MIN2UNIT(mnum));
207 hdl = di_devlink_init(nodename, DI_MAKE_LINK);
209 if (hdl == NULL)
210 return (-1);
211 else
212 (void) di_devlink_fini(&hdl);
214 (void) sprintf(nodename, "/pseudo/md@0:%lu,%lu,blk",
215 MD_MIN2SET(mnum), MD_MIN2UNIT(mnum));
216 hdl = di_devlink_init(nodename, DI_MAKE_LINK);
219 if (hdl != NULL) {
220 (void) di_devlink_fini(&hdl);
221 return (0);
224 return (-1);
228 * update_locator_namespace -- Contains the ioctl call that will update
229 * the ctds and pathname (ie. /dev/dsk etc) within the
230 * locator block namespace.
232 * RETURN
233 * METADEVADM_ERR ioctl failed and ep is updated with the error
234 * METADEVADM_SUCCESS success
236 static int
237 update_locator_namespace(
238 set_t setno,
239 side_t sideno,
240 char *devname,
241 md_dev64_t dev,
242 char *pname,
243 md_error_t *ep
246 mdnm_params_t nm;
248 (void) memset(&nm, '\0', sizeof (nm));
249 nm.mde = mdnullerror;
250 nm.setno = setno;
251 nm.side = sideno;
252 nm.devname = (uintptr_t)devname;
253 nm.devname_len = strlen(devname);
254 nm.devt = dev;
255 nm.pathname = (uintptr_t)pname;
256 nm.pathname_len = strlen(pname);
257 if (metaioctl(MD_IOCUPD_LOCNM, &nm, &nm.mde, NULL) != 0) {
258 (void) mdstealerror(ep, &nm.mde);
259 return (METADEVADM_ERR);
261 return (METADEVADM_SUCCESS);
265 * meta_update_namespace -- Contains the ioctl call that will update the
266 * device name and pathname in the namespace area.
268 * RETURN
269 * METADEVADM_ERR ioctl failed and ep is updated with the error
270 * METADEVADM_SUCCESS success
273 meta_update_namespace(
274 set_t setno,
275 side_t sideno,
276 char *devname,
277 md_dev64_t dev,
278 mdkey_t key,
279 char *pname,
280 md_error_t *ep
283 mdnm_params_t nm;
285 (void) memset(&nm, '\0', sizeof (nm));
286 nm.mde = mdnullerror;
287 nm.setno = setno;
288 nm.side = sideno;
289 nm.devname = (uintptr_t)devname;
290 nm.devname_len = strlen(devname);
291 nm.mnum = meta_getminor(dev);
292 nm.major = meta_getmajor(dev);
293 nm.key = key;
294 nm.pathname = (uintptr_t)pname;
295 nm.pathname_len = strlen(pname);
296 if (metaioctl(MD_IOCUPD_NM, &nm, &nm.mde, NULL) != 0) {
297 (void) mdstealerror(ep, &nm.mde);
298 return (METADEVADM_ERR);
300 return (METADEVADM_SUCCESS);
304 * stripS - Strip s<digits> off the end of the ctds name if it exists
306 static void
307 stripS(char *name)
309 char *p;
311 /* gobble number and 's' */
312 p = name + strlen(name) - 1;
313 for (; (p > name); --p) {
314 if (!isdigit(*p))
315 break;
318 if (*p == 's') {
319 *p = '\0';
324 * getdiskname -- to be used when scanning the input from the -u arg.
325 * This routine will strip off input that is anything but cxtxdx.
326 * ie. it will call stripS to get rid of slice info. Will also
327 * strip off /dev/dsk, /dev/rdsk, /dev/ap/dsk, /dev/ap/rdsk,
328 * /dev/did/dsk, or /dev/did/rdsk. The caller will need to free
329 * the return value.
331 * RETURN
332 * string that has the disk name in it ie. c0t0d0
334 static char *
335 getdiskname(
336 char *name
339 char *p;
340 char *diskname;
342 /* regular device */
343 if ((strncmp(name, "/dev/dsk/", strlen("/dev/dsk/")) == 0) &&
344 (strchr((p = name + strlen("/dev/dsk/")), '/') == NULL)) {
345 diskname = Strdup(p);
346 stripS(diskname);
347 return (diskname);
350 if ((strncmp(name, "/dev/rdsk/", strlen("/dev/rdsk/")) == 0) &&
351 (strchr((p = name + strlen("/dev/rdsk/")), '/') == NULL)) {
352 diskname = Strdup(p);
353 stripS(diskname);
354 return (diskname);
357 if ((strncmp(name, "/dev/ap/dsk/", strlen("/dev/ap/dsk/")) == 0) &&
358 (strchr((p = name + strlen("/dev/ap/dsk/")), '/') == NULL)) {
359 diskname = Strdup(p);
360 stripS(diskname);
361 return (diskname);
364 if ((strncmp(name, "/dev/ap/rdsk/", strlen("/dev/ap/rdsk/")) == 0) &&
365 (strchr((p = name + strlen("/dev/ap/rdsk/")), '/') == NULL)) {
366 diskname = Strdup(p);
367 stripS(diskname);
368 return (diskname);
371 if ((strncmp(name, "/dev/did/dsk/", strlen("/dev/did/dsk/")) == 0) &&
372 (strchr((p = name + strlen("/dev/did/dsk/")), '/') == NULL)) {
373 diskname = Strdup(p);
374 stripS(diskname);
375 return (diskname);
378 if ((strncmp(name, "/dev/did/rdsk/", strlen("/dev/did/rdsk/")) == 0) &&
379 (strchr((p = name + strlen("/dev/did/rdsk/")), '/') == NULL)) {
380 diskname = Strdup(p);
381 stripS(diskname);
382 return (diskname);
385 diskname = Strdup(name);
386 stripS(diskname);
387 return (diskname);
391 * has_devid -- return the device ID for a given key
393 * RETURN
394 * NULL error
395 * devid devid found that corresponds to the given key.
397 static ddi_devid_t
398 has_devid(set_t setno, side_t sideno, mdkey_t key, md_error_t *ep)
400 return (meta_getdidbykey(setno, sideno, key, ep));
404 * Go through the existing list of replicas and check to see
405 * if their disk has moved, if so update the replica list
407 * RETURN
408 * -1 error
409 * 0 success
411 static int
412 fix_replicanames(
413 mdsetname_t *sp,
414 md_error_t *ep
417 md_replicalist_t *rlp = NULL;
418 md_replicalist_t *rl;
419 int ret = -1;
420 int match_type = 0;
421 devid_nmlist_t *disklist = NULL;
422 dev_t small_dev = (dev_t)NODEV;
423 side_t sideno;
424 set_t setno = sp->setno;
425 char *search_path;
426 int search_number;
427 char *ctds_name;
428 char *path_name;
429 int i;
431 sideno = getmyside(sp, ep);
432 if (sideno == MD_SIDEWILD) {
433 mda_debug("Failed to find the side number\n");
434 return (-1);
437 if (metareplicalist(sp, MD_BASICNAME_OK | PRINT_FAST, &rlp, ep) < 0) {
438 mda_debug("Unable to get a list of replicas\n");
439 return (METADEVADM_ERR);
442 for (rl = rlp; (rl != NULL); rl = rl->rl_next) {
443 md_replica_t *r = rl->rl_repp;
445 small_dev = meta_cmpldev(r->r_namep->dev);
446 search_number = mda_findpath(r->r_namep->bname);
447 if (search_number == -1) {
448 mda_debug("replica update: invalid path: %s",
449 r->r_namep->bname);
450 continue;
451 } else {
452 search_path = plist[search_number].search_path;
455 if (r->r_devid == NULL)
456 continue;
458 ret = meta_deviceid_to_nmlist(search_path, r->r_devid,
459 r->r_minor_name, &disklist);
461 mda_debug("replica update: search_path %s\n", search_path);
463 if (ret != 0) {
465 * Failed to find the disk, nothing can be done.
466 * The replica will be marked as bad later.
468 mda_debug("replica update: failed to find disk %s\n",
469 r->r_namep->cname);
470 continue;
472 mda_debug("replica update: current %s (%p)\n",
473 r->r_namep->bname, (void *) small_dev);
476 * Check to see if the returned disk matches the stored one
478 for (i = 0; disklist[i].dev != NODEV; i++) {
479 match_type = 0;
481 mda_debug("replica update: devid list: %s (%p)\n",
482 disklist[i].devname, (void *) disklist[i].dev);
484 if (disklist[i].dev == small_dev) {
485 match_type |= DEV_MATCH;
488 if (strncmp(r->r_namep->bname, disklist[i].devname,
489 strlen(r->r_namep->bname)) == 0) {
490 match_type |= NAME_MATCH;
494 * break out if some sort of match is found because
495 * we already match on the devid.
497 if (match_type != 0)
498 break;
501 mda_debug("fix_replicanames: match: %x i: %d\n", match_type, i);
503 if (match_type == (DEV_MATCH|NAME_MATCH)) {
504 /* no change */
505 mda_debug("replica update: no change %s\n",
506 disklist[i].devname);
507 devid_free_nmlist(disklist);
508 continue;
511 /* No match found - use the first entry in disklist */
512 if (disklist[i].dev == NODEV)
513 i = 0;
515 mda_debug("replica update: reloading %s %p\n",
516 disklist[i].devname,
517 (void *)(uintptr_t)meta_expldev(disklist[i].dev));
519 if (firsttime) {
520 mda_print(dgettext(TEXT_DOMAIN,
521 "Disk movement detected\n"));
522 mda_print(dgettext(TEXT_DOMAIN,
523 "Updating device names in Solaris Volume "
524 "Manager\n"));
525 firsttime = 0;
528 if (dev_options & DEV_VERBOSE) {
529 char *devidstr;
531 devidstr =
532 devid_str_encode(r->r_devid, r->r_minor_name);
533 if (devidstr == NULL) {
534 mda_print(dgettext(TEXT_DOMAIN,
535 "Failed to encode the devid\n"));
536 continue;
538 mda_print(dgettext(TEXT_DOMAIN,
539 "%s changed to %s from device relocation "
540 "information %s\n"),
541 (char *)r->r_namep->cname, disklist[i].devname,
542 devidstr);
545 if (!(dev_options & DEV_NOACTION)) {
546 mda_debug("Updating locator name\n");
547 ctds_name = strrchr(disklist[i].devname, '/');
548 ctds_name++;
549 if ((path_name = mda_getpath(disklist[i].devname))
550 == NULL) {
551 continue;
553 if (update_locator_namespace(setno, sideno,
554 ctds_name, meta_expldev(disklist[i].dev),
555 path_name, ep) != 0) {
556 mda_debug("replica update: ioctl failed\n");
557 if (dev_options & DEV_VERBOSE) {
558 mda_print(dgettext(TEXT_DOMAIN,
559 "Failed to update locator "
560 "namespace on change from %s "
561 "to %s\n"), ctds_name,
562 disklist[i].devname);
566 Free(path_name);
567 devid_free_nmlist(disklist);
569 metafreereplicalist(rlp);
570 return (0);
574 * pathname_reload - main function for the -r option. Will reload the
575 * pathname in both the main namespace and the locator namespace.
576 * Also, checks both areas for invalid device ID's and prints them
577 * out.
579 * If the set is a multi-node diskset that means there are no devid's
580 * so just return.
582 * RETURN
583 * METADEVADM_ERR error
584 * METADEVADM_SUCCESS success
585 * METADEVADM_DEVIDINVALID success, but invalid devids detected
588 pathname_reload(
589 mdsetname_t **spp,
590 set_t setno,
591 md_error_t *ep)
593 char *drvnmp;
594 minor_t mnum = 0;
595 md_dev64_t dev = 0;
596 mdnm_params_t nm;
597 char *ctds_name;
598 ddi_devid_t devidp;
599 md_i_didstat_t ds;
600 side_t sideno;
601 char *search_path = NULL;
602 int search_number;
603 devid_nmlist_t *disklist = NULL;
604 char *minor_name = NULL;
605 char *devidstr = NULL;
606 char *path = NULL;
607 int ret;
608 dev_t small_dev = (dev_t)NODEV;
609 int match_type;
610 char *tmp = NULL;
611 mdsetname_t *sp = *spp;
612 md_set_desc *sd;
613 int i;
616 * Check for multi-node diskset and return if it is one.
618 if (!metaislocalset(sp)) {
619 if ((sd = metaget_setdesc(sp, ep)) == NULL)
620 return (METADEVADM_ERR);
622 if (MD_MNSET_DESC(sd))
623 return (METADEVADM_SUCCESS);
627 * Get the entry of the namespace via the key. To do this
628 * call MD_IOCNXTKEY until no more.
629 * For each entry in the namespace we want to check
630 * for devid and update
633 (void) memset(&nm, '\0', sizeof (nm));
634 nm.key = MD_KEYWILD;
636 sideno = getmyside(*spp, ep);
637 if (sideno == MD_SIDEWILD) {
638 /* failed to find this node in the set */
639 mda_debug("Failed to find the side number\n");
640 return (METADEVADM_ERR);
643 /* LINTED */
644 while (1) {
645 nm.mde = mdnullerror;
646 nm.setno = setno;
647 nm.side = sideno;
648 /* look at each key in the namespace */
649 if (metaioctl(MD_IOCNXTKEY_NM, &nm, &nm.mde, NULL) != 0) {
650 (void) mdstealerror(ep, &nm.mde);
651 return (METADEVADM_ERR);
654 if (nm.key == MD_KEYWILD) {
655 /* no more entries */
656 break;
660 * get the nm entry using the key. Then check to see if
661 * there's a devid associated with this entry
662 * If not, go onto next key.
664 if ((nm.devname = (uintptr_t)meta_getnmentbykey(setno, sideno,
665 nm.key, &drvnmp, &mnum, &dev, ep)) == NULL) {
666 mda_debug("pathname_reload: no name for key: %d\n",
667 nm.key);
668 continue;
671 mda_debug("pathname_reload: examining %s\n",
672 (char *)(uintptr_t)nm.devname);
674 if ((devidp = has_devid(setno, sideno, nm.key, ep)) == NULL) {
675 /* metadevices do not have devid's in them */
676 mda_debug("pathname_reload: no devid for %s\n",
677 (char *)(uintptr_t)nm.devname);
678 /* Clear error if no devid and go to next nm entry */
679 mdclrerror(ep);
680 continue;
683 if ((minor_name = meta_getdidminorbykey(setno, sideno,
684 nm.key, ep)) == NULL) {
686 * In theory this is impossible because if the
687 * devidp is non-null then the minor_name has
688 * already been looked up.
690 mda_debug("No minor name for %s\n",
691 (char *)(uintptr_t)nm.devname);
692 free(devidp);
693 continue;
696 * If there is a devid then we have a real device that
697 * could have moved.
699 devidstr = devid_str_encode(devidp, minor_name);
700 if (devidstr == NULL) {
701 mda_debug("Failed to encode the devid\n");
702 free(devidp);
703 continue;
705 mda_debug("devid: %s\n", devidstr);
708 * Find the search path that should be used. This is an
709 * optimization to try and prevent a search for the complete
710 * /dev namespace.
712 search_number = mda_findpath((char *)(uintptr_t)nm.devname);
713 if (search_number == -1) {
714 search_path = "/dev";
715 } else {
716 search_path = plist[search_number].search_path;
719 /* now look for the disk name using the devid */
720 ret = meta_deviceid_to_nmlist(search_path, devidp,
721 minor_name, &disklist);
722 free(devidp);
724 if (ret != 0) {
726 * Failed to find the disk
728 devid_str_free(devidstr);
729 continue;
732 small_dev = meta_cmpldev(dev);
733 mda_debug("Old device lookup: %s (%p)\n",
734 (char *)(uintptr_t)nm.devname, (void *)small_dev);
737 * Check to see if the returned disk matches the stored one
739 for (i = 0; disklist[i].dev != NODEV; i++) {
740 match_type = 0;
741 mda_debug("From devid lookup: %s (%p)\n",
742 (char *)disklist[i].devname,
743 (void *)disklist[i].dev);
745 if (disklist[i].dev == small_dev) {
746 match_type |= DEV_MATCH;
749 if (strncmp((char *)(uintptr_t)nm.devname,
750 disklist[i].devname,
751 strlen((char *)(uintptr_t)nm.devname)) == 0) {
752 mda_debug("Name match: %s and %s (%d)\n",
753 disklist[i].devname,
754 (char *)(uintptr_t)nm.devname,
755 strlen((char *)(uintptr_t)nm.devname));
756 match_type |= NAME_MATCH;
759 if (match_type == (DEV_MATCH|NAME_MATCH))
760 break;
763 if (match_type == (DEV_MATCH|NAME_MATCH)) {
764 /* no change */
765 devid_str_free(devidstr);
766 mda_debug("All matched %s\n", disklist[i].devname);
767 devid_free_nmlist(disklist);
768 continue;
771 /* No match found - use the first entry in disklist */
772 i = 0;
774 if (firsttime) {
775 mda_print(dgettext(TEXT_DOMAIN,
776 "Disk movement detected\n"));
777 mda_print(dgettext(TEXT_DOMAIN,
778 "Updating device names in "
779 "Solaris Volume Manager\n"));
780 firsttime = 0;
782 if (dev_options & DEV_VERBOSE) {
783 mda_print(dgettext(TEXT_DOMAIN,
784 "%s changed to %s from device relocation "
785 "information %s\n"),
786 (char *)(uintptr_t)nm.devname, disklist[i].devname,
787 devidstr);
789 devid_str_free(devidstr);
791 /* need to build up the path of the disk */
792 if ((path = Strdup(disklist[i].devname)) == NULL) {
793 mda_debug("Failed to duplicate path: %s\n",
794 disklist[i].devname);
795 devid_free_nmlist(disklist);
796 continue;
798 if ((tmp = strrchr(path, '/')) == NULL) {
799 mda_debug("Failed to parse %s\n", path);
800 devid_free_nmlist(disklist);
801 Free(path);
802 continue;
804 tmp += sizeof (char);
805 *tmp = '\0';
807 if ((ctds_name = strrchr(disklist[i].devname, '/')) == NULL) {
808 mda_debug("Failed to parse ctds name: %s\n",
809 disklist[i].devname);
810 devid_free_nmlist(disklist);
811 Free(path);
812 continue;
814 ctds_name += sizeof (char);
816 mda_debug("Reloading disk %s %s %p\n",
817 ctds_name, path,
818 (void *)(uintptr_t)meta_expldev(disklist[i].dev));
820 if (!(dev_options & DEV_NOACTION)) {
821 /* Something has changed so update the namespace */
822 if (meta_update_namespace(setno, sideno, ctds_name,
823 meta_expldev(disklist[i].dev), nm.key, path,
824 ep) != 0) {
825 mda_debug("Failed to update namespace\n");
826 if (dev_options & DEV_VERBOSE) {
827 mda_print(dgettext(TEXT_DOMAIN,
828 "Failed to update namespace on "
829 "change from %s to %s\n"),
830 ctds_name, disklist[i].devname);
834 devid_free_nmlist(disklist);
835 Free(path);
838 if (fix_replicanames(*spp, ep) == -1)
839 mda_debug("Failed to update replicas\n");
842 * check for invalid device id's
844 (void) memset(&ds, '\0', sizeof (ds));
845 ds.setno = setno;
846 ds.side = sideno;
847 ds.mode = MD_FIND_INVDID;
848 /* get count of number of invalid device id's */
849 if (metaioctl(MD_IOCDID_STAT, &ds, &ds.mde, NULL) != 0) {
850 (void) mdstealerror(ep, &ds.mde);
851 return (METADEVADM_ERR);
853 if (ds.cnt != 0) {
854 char *ctdptr, *ctdp;
856 * we have some invalid device id's so we need to
857 * print them out
859 ds.mode = MD_GET_INVDID;
860 /* malloc buffer for kernel to place devid list into */
861 if ((ctdptr = (char *)Malloc((ds.cnt * ds.maxsz) + 1)) == 0) {
862 return (METADEVADM_ERR);
864 ds.ctdp = (uintptr_t)ctdptr;
865 /* get actual list of invalid device id's */
866 if (metaioctl(MD_IOCDID_STAT, &ds, &ds.mde, NULL) != 0) {
867 Free(ctdptr);
868 (void) mdstealerror(ep, &ds.mde);
869 return (METADEVADM_ERR);
872 /* print out the invalid devid's */
873 mda_print(dgettext(TEXT_DOMAIN,
874 "Invalid device relocation information "
875 "detected in Solaris Volume Manager\n"));
876 mda_print(dgettext(TEXT_DOMAIN,
877 "Please check the status of the following disk(s):\n"));
878 ctdp = (char *)(uintptr_t)ds.ctdp;
879 while (*ctdp != NULL) {
880 mda_print("\t%s\n", ctdp);
881 ctdp += ds.maxsz;
883 Free(ctdptr);
884 return (METADEVADM_DEVIDINVALID);
886 return (METADEVADM_SUCCESS);
890 * replica_update_devid - cycle through the replica list, rlp, and
891 * update the device ids on all of the replicas that are on the
892 * device specified by lp. A side effect is to update the value of
893 * cdevidpp to contain the character representation of the device
894 * id before updating if it is not already set.
896 * RETURN
897 * METADEVADM_ERR error
898 * METADEVADM_SUCCESS success
900 static int
901 replica_update_devid(
902 md_replicalist_t *rlp,
903 mddrivename_t *dnp,
904 set_t setno,
905 char **cdevidpp,
906 md_error_t *ep
909 mddb_config_t db_c;
910 md_replicalist_t *rl;
911 ddi_devid_t devidp;
912 int ret;
914 if (cdevidpp == NULL)
915 return (METADEVADM_ERR);
917 ret = devid_str_decode(dnp->devid, &devidp, NULL);
918 if (ret != 0) {
919 /* failed to encode the devid */
920 mda_debug("Failed to decode %s into a valid devid\n",
921 dnp->devid);
922 return (METADEVADM_ERR);
925 /* search replica list for give ctd name */
926 for (rl = rlp; (rl != NULL); rl = rl->rl_next) {
927 md_replica_t *r = rl->rl_repp;
928 mdname_t *rnp = r->r_namep;
930 if (strncmp(rnp->cname, dnp->cname, strlen(dnp->cname)) == 0) {
932 /* found the replica, now grab the devid */
933 if (*cdevidpp == NULL) {
934 *cdevidpp = devid_str_encode(r->r_devid, NULL);
937 if (*cdevidpp == NULL) {
938 devid_free(devidp);
939 return (METADEVADM_ERR);
942 mda_debug("Updating replica %s, set %d, old devid %s\n",
943 rnp->cname, setno, *cdevidpp);
945 if (dev_options & DEV_VERBOSE) {
946 mda_print(dgettext(TEXT_DOMAIN,
947 "Updating replica %s of set number %d from "
948 "device id %s to device id %s\n"),
949 rnp->cname, setno, *cdevidpp, dnp->devid);
952 (void) memset(&db_c, '\0', sizeof (db_c));
954 db_c.c_setno = setno;
955 db_c.c_devt = rnp->dev;
957 if (!(dev_options & DEV_NOACTION)) {
959 mda_debug("Updating replica\n");
962 * call into kernel to update lb
963 * namespace device id
964 * of given devt
966 if (metaioctl(MD_DB_SETDID, &db_c,
967 &db_c.c_mde, NULL) != 0) {
968 devid_free(devidp);
969 (void) mdstealerror(ep, &db_c.c_mde);
970 return (METADEVADM_ERR);
976 devid_free(devidp);
977 return (METADEVADM_SUCCESS);
981 * devid_update -- main routine for the -u option. Will update both the
982 * namespace and the locator block with the correct devid for the
983 * disk specified.
985 * RETURN
986 * METADEVADM_ERR error
987 * METADEVADM_SUCCESS success
989 static int
990 devid_update(
991 mdsetname_t **spp,
992 set_t setno,
993 char *ctd,
994 md_error_t *ep
997 md_drive_desc *dd, *ddp;
998 mddrivename_t *dnp;
999 mdnm_params_t nm;
1000 ddi_devid_t devidp;
1001 side_t side;
1002 char *old_cdevidp = NULL;
1003 md_replicalist_t *rlp = NULL;
1004 int rval = METADEVADM_ERR;
1005 mdname_t *np = NULL;
1006 uint_t rep_slice;
1007 char *pathname = NULL;
1008 char *diskname = NULL;
1009 int fd = -1;
1010 int len;
1011 char *fp;
1013 side = getmyside(*spp, ep);
1014 if (side == MD_SIDEWILD) {
1015 /* failed to find this node in the set */
1016 mda_debug("Failed to find the side number\n");
1017 return (METADEVADM_ERR);
1020 if ((dnp = metadrivename(spp, ctd, ep)) == NULL) {
1021 mda_debug("Failed to create a dnp for %s\n", ctd);
1022 return (METADEVADM_ERR);
1024 if (dnp->devid == NULL) {
1026 * Disk does not have a devid! So cannot update the
1027 * devid within the replica.
1029 mda_debug("%s does not have a devid\n", dnp->cname);
1030 if (dev_options & DEV_VERBOSE) {
1031 mda_print(dgettext(TEXT_DOMAIN,
1032 "%s does not have a device id. Cannot update "
1033 "device id if none exists\n"), ctd);
1035 return (METADEVADM_ERR);
1038 mda_debug("Devid update to: %s\n", dnp->devid);
1041 * Check if we own the set, if we do then do some processing
1042 * on the replicas.
1044 if (meta_check_ownership(*spp, ep) == 0) {
1046 /* get the replicas */
1047 if (metareplicalist(*spp, MD_BASICNAME_OK | PRINT_FAST, &rlp,
1048 ep) < 0)
1049 return (METADEVADM_ERR);
1051 /* update the devids in the replicas if necessary */
1052 if (replica_update_devid(rlp, dnp, setno, &old_cdevidp,
1053 ep) != METADEVADM_SUCCESS) {
1054 metafreereplicalist(rlp);
1055 return (METADEVADM_ERR);
1058 metafreereplicalist(rlp);
1062 * If this is not the LOCAL set then need to update the LOCAL
1063 * replica with the new disk record.
1066 if (setno != MD_LOCAL_SET) {
1067 mda_debug("Non-local set: %d side %d\n", setno, side);
1070 * Need to find the disk record within the set and then
1071 * update it.
1073 if ((dd =
1074 metaget_drivedesc(*spp, MD_FULLNAME_ONLY, ep)) == NULL) {
1075 if (! mdisok(ep))
1076 goto out;
1077 /* no disks in the set - no point continuing */
1078 mda_debug("No disks in diskset\n");
1079 rval = METADEVADM_SUCCESS;
1080 goto out;
1083 for (ddp = dd; ddp != NULL; ddp = ddp->dd_next) {
1084 if (strncmp(ddp->dd_dnp->cname, dnp->cname,
1085 strlen(dnp->cname)) == 0)
1086 break;
1089 if (ddp == NULL) {
1090 /* failed to finddisk in the set */
1091 mda_print(dgettext(TEXT_DOMAIN,
1092 "%s not found in set %s. Check your syntax\n"),
1093 ctd, (*spp)->setname);
1094 (void) mddserror(ep, MDE_DS_DRIVENOTINSET, setno, NULL,
1095 ctd, (*spp)->setname);
1096 goto out;
1100 * Now figure out the correct slice, for a diskset the slice
1101 * we care about is always the 'replica' slice.
1103 if (meta_replicaslice(dnp, &rep_slice, ep) != 0) {
1104 mda_debug("Unable to find replica slice for %s\n",
1105 dnp->cname);
1106 goto out;
1109 mda_debug("slice no: %d disk %s\n", rep_slice, dnp->cname);
1111 if ((np = metaslicename(dnp, rep_slice, ep)) == NULL) {
1112 mda_debug("Unable to build namespace\n");
1113 goto out;
1116 mda_debug("check: ctdname: %s\n", np->cname);
1117 mda_debug("check: ctdname: %s\n", np->rname);
1118 mda_debug("check: ctdname: %s\n", np->bname);
1120 if (!(dev_options & DEV_NOACTION)) {
1122 mda_debug("Updating record: key %d name %s\n",
1123 ddp->dd_dnp->side_names_key, np->cname);
1125 pathname = mda_getpath(np->bname);
1127 if (meta_update_namespace(MD_LOCAL_SET, side + SKEW,
1128 np->cname, np->dev, ddp->dd_dnp->side_names_key,
1129 pathname, ep) != 0) {
1130 goto out;
1134 * Now update the devid entry as well, this works
1135 * correctly because the prior call to
1136 * meta_update_namespace() above puts the correct dev_t
1137 * in the namespace which will then be resolved
1138 * to the new devid by the ioctl now called.
1140 nm.mde = mdnullerror;
1141 nm.setno = MD_LOCAL_SET;
1142 nm.side = side + SKEW;
1143 nm.key = ddp->dd_dnp->side_names_key;
1144 if (metaioctl(MD_SETNMDID, &nm, &nm.mde, NULL) != 0) {
1145 (void) mdstealerror(ep, &nm.mde);
1146 goto out;
1151 if ((dev_options & DEV_LOCAL_SET) && (setno != MD_LOCAL_SET)) {
1153 * Only want to update the local set so do not continue.
1155 rval = METADEVADM_SUCCESS;
1156 goto out;
1160 * Iterate through all of the metadevices looking for the
1161 * passed in ctd. If found then update the devid
1163 (void) memset(&nm, '\0', sizeof (nm));
1164 nm.key = MD_KEYWILD;
1165 /* LINTED */
1166 while (1) {
1167 nm.mde = mdnullerror;
1168 nm.setno = setno;
1169 nm.side = side;
1171 /* search each namespace entry */
1172 if (metaioctl(MD_IOCNXTKEY_NM, &nm, &nm.mde, NULL) != 0) {
1173 (void) mdstealerror(ep, &nm.mde);
1174 rval = METADEVADM_ERR;
1175 goto out;
1177 if (nm.key == MD_KEYWILD) {
1178 if (setno != MD_LOCAL_SET) {
1179 mda_print(dgettext(TEXT_DOMAIN,
1180 "%s not found in set %s. Check your "
1181 "syntax\n"), ctd, (*spp)->setname);
1182 goto out;
1183 } else {
1184 mda_print(dgettext(TEXT_DOMAIN,
1185 "%s not found in local set. "
1186 "Check your syntax\n"), ctd);
1187 goto out;
1191 nm.devname = (uintptr_t)meta_getnmentbykey(setno, side, nm.key,
1192 NULL, NULL, NULL, ep);
1193 if (nm.devname == NULL) {
1194 rval = METADEVADM_ERR;
1195 goto out;
1198 diskname = getdiskname((char *)(uintptr_t)nm.devname);
1200 mda_debug("Checking %s with %s\n", diskname, dnp->cname);
1201 if (strcmp(diskname, dnp->cname) != 0)
1202 continue;
1204 mda_debug("Updating device %s in namespace\n",
1205 (char *)(uintptr_t)nm.devname);
1208 * found disk, does it have a devid within the namespace ?
1209 * It might not because it does not support devid's or was
1210 * put into the namespace when there was no devid support
1212 if ((devidp = has_devid(setno, side, nm.key, ep)) == NULL) {
1213 mda_debug("%s has no devid in the namespace",
1214 (char *)(uintptr_t)nm.devname);
1215 if (dev_options & DEV_VERBOSE) {
1216 mda_print(dgettext(TEXT_DOMAIN,
1217 "SVM has no device id for "
1218 "%s, cannot update.\n"),
1219 (char *)(uintptr_t)nm.devname);
1221 continue; /* no devid. go on to next */
1223 if (old_cdevidp == NULL) {
1224 old_cdevidp = devid_str_encode(devidp, NULL);
1226 free(devidp);
1229 * has devid so update namespace, note the key has been set
1230 * by the prior MD_IOCNXTKEY_NM ioctl.
1232 nm.mde = mdnullerror;
1233 nm.setno = setno;
1234 nm.side = side;
1235 if (!(dev_options & DEV_NOACTION)) {
1237 * The call below may fail if the -u option is being
1238 * used to update a disk that has been replaced.
1239 * The -u option to metadevadm should not be used
1240 * for this purpose because we trust the dev_t of
1241 * the device in the replica and if we have replaced
1242 * the device and it is a fibre one then the dev_t
1243 * will have changed. This means we end up looking for
1244 * the devid of a non-existant disk and we subsequently
1245 * fail with NODEVID.
1247 if (metaioctl(MD_SETNMDID, &nm,
1248 &nm.mde, NULL) != 0) {
1249 if (dev_options & DEV_VERBOSE) {
1250 mda_print(dgettext(TEXT_DOMAIN,
1251 "SVM failed to update the device "
1252 "id for %s probably due to both "
1253 "devt and device id changing.\n"),
1254 (char *)(uintptr_t)nm.devname);
1256 (void) mdstealerror(ep, &nm.mde);
1257 mde_perror(ep, "");
1258 rval = METADEVADM_ERR;
1259 goto out;
1262 if (old_cdevidp == NULL) {
1263 rval = METADEVADM_ERR;
1264 goto out;
1266 break;
1267 } /* end while */
1269 mda_print(dgettext(TEXT_DOMAIN,
1270 "Updating Solaris Volume Manager device relocation "
1271 "information for %s\n"), ctd);
1273 mda_print(dgettext(TEXT_DOMAIN,
1274 "Old device reloc information:\n\t%s\n"), old_cdevidp);
1276 len = strlen(dnp->rname) + strlen("s0");
1277 if ((fp = (char *)Malloc(len + 1)) == NULL) {
1278 mda_print(dgettext(TEXT_DOMAIN,
1279 "insufficient memory, device Reloc info not "
1280 "available\n"));
1281 } else {
1282 (void) snprintf(fp, len + 1, "%ss0", dnp->rname);
1283 if ((fd = open(fp, O_RDONLY|O_NDELAY)) < 0) {
1284 mda_print(dgettext(TEXT_DOMAIN,
1285 "Open of %s failed\n"), fp);
1286 } else {
1287 int rc = -1;
1288 ddi_devid_t devid1 = NULL;
1289 char *cdevidp;
1291 rc = devid_get(fd, &devid1);
1292 if (close(fd) < 0) {
1293 mda_print(dgettext(TEXT_DOMAIN,
1294 "Close of %s failed\n"), fp);
1296 if (rc != 0) {
1297 mda_print(dgettext(TEXT_DOMAIN,
1298 "Unable to obtain device "
1299 "Reloc info for %s\n"), fp);
1300 } else {
1301 cdevidp = devid_str_encode(devid1, NULL);
1302 if (cdevidp == NULL) {
1303 mda_print(dgettext(TEXT_DOMAIN,
1304 "Unable to print "
1305 "device Reloc info for %s\n"), fp);
1306 } else {
1307 mda_print(dgettext(TEXT_DOMAIN,
1308 "New device reloc "
1309 "information:\n\t%s\n"), cdevidp);
1310 devid_str_free(cdevidp);
1312 devid_free(devid1);
1315 Free(fp);
1318 rval = METADEVADM_SUCCESS;
1320 out:
1321 if (diskname)
1322 Free(diskname);
1323 if (pathname)
1324 Free(pathname);
1325 if (old_cdevidp) {
1326 devid_str_free(old_cdevidp);
1328 return (rval);
1333 * Check the ctd name of the disk to see if the disk has moved. If it
1334 * has moved then the newname is returned in 'newname', it is up to
1335 * the caller to free the memory associated with it.
1337 * RETURN
1338 * METADEVADM_ERR error
1339 * METADEVADM_SUCCESS success
1340 * METADEVADM_DISKMOVE success, and the disk has moved
1341 * METADEVADM_DSKNAME_ERR error creating the disk name structures.
1344 meta_upd_ctdnames(
1345 mdsetname_t **spp,
1346 set_t setno,
1347 side_t sideno,
1348 mddrivename_t *dnp,
1349 char **newname,
1350 md_error_t *ep
1353 char *drvnmp;
1354 int i;
1355 minor_t mnum = 0;
1356 md_dev64_t dev = 0;
1357 dev_t small_dev = (dev_t)NODEV;
1358 mdnm_params_t nm;
1359 char *pathname;
1360 char *minor_name = NULL;
1361 ddi_devid_t devidp;
1362 devid_nmlist_t *disklist = NULL;
1363 int ret = 0;
1364 mdsidenames_t *snp;
1365 int match_type;
1366 int search_number = -1;
1367 char *search_type = NULL;
1368 char *search_path = NULL;
1369 uint_t rep_slice;
1370 mddrivename_t *newdnp;
1371 mdname_t *np;
1372 mdsetname_t *sp = *spp;
1373 md_set_desc *sd;
1376 * setno should always be 0 but we're going to
1377 * check for multi-node diskset and return if it is one.
1379 if (!metaislocalset(sp)) {
1380 if ((sd = metaget_setdesc(sp, ep)) == NULL)
1381 return (METADEVADM_ERR);
1383 if (MD_MNSET_DESC(sd))
1384 return (METADEVADM_SUCCESS);
1387 if (dnp->devid == NULL) {
1388 /* no devid, nothing can be done */
1389 mda_debug("meta_upd_ctdnames: %s has no devid\n", dnp->cname);
1390 if (dev_options & DEV_VERBOSE) {
1391 mda_print(dgettext(TEXT_DOMAIN,
1392 "%s has no devid, cannot detect "
1393 "disk movement for this disk.\n"), dnp->cname);
1395 return (ret);
1399 * Find the correct side name for the disk. There is a sidename
1400 * for each host associated with the diskset.
1402 for (snp = dnp->side_names; snp != NULL; snp = snp->next) {
1403 mda_debug("meta_upd_ctdnames: %s %d args: setno %d sideno %d\n",
1404 snp->cname, snp->sideno, setno, sideno);
1405 /* only use SKEW for the local replica */
1406 if (setno == 0) {
1407 if (snp->sideno + SKEW == sideno)
1408 break;
1409 } else {
1410 if (snp->sideno == sideno)
1411 break;
1415 if (snp == NULL) {
1417 * Failed to find the side name, this should not
1418 * be possible. However if it does happen this is an
1419 * indication of an inconsistant replica - something
1420 * might have gone wrong during an add or a delete of
1421 * a host.
1423 mda_debug("Unable to find the side information for disk %s",
1424 dnp->cname);
1425 (void) mddserror(ep, MDE_DS_HOSTNOSIDE, (*spp)->setno, mynode(),
1426 NULL, dnp->cname);
1427 return (METADEVADM_ERR);
1430 * Find the type of device we are to be searching on
1432 search_number = mda_findpath(snp->cname);
1433 if (search_number == -1) {
1434 search_path = "/dev";
1435 search_type = DEVID_MINOR_NAME_ALL;
1436 } else {
1437 search_path = plist[search_number].search_path;
1438 search_type = plist[search_number].search_type;
1441 mda_debug("Search path :%s searth_type: %x\n",
1442 search_path, (int)search_type);
1443 (void) memset(&nm, '\0', sizeof (nm));
1445 nm.mde = mdnullerror;
1446 nm.setno = setno;
1447 nm.side = sideno;
1450 * Get the devname from the name space.
1452 if ((nm.devname = (uintptr_t)meta_getnmentbykey(setno, sideno,
1453 dnp->side_names_key, &drvnmp, &mnum, &dev, ep)) == NULL) {
1454 return (METADEVADM_ERR);
1457 ret = devid_str_decode(dnp->devid, &devidp, &minor_name);
1458 devid_str_free(minor_name);
1460 if (ret != 0) {
1462 * Failed to encode the devid.
1464 devid_free(devidp);
1465 return (METADEVADM_ERR);
1469 * Use the stored devid to find the existing device node and check
1470 * to see if the disk has moved. Use the raw devices as the name
1471 * of the disk is stored as the raw device, if this is not done
1472 * then the disk will not be found.
1474 ret = meta_deviceid_to_nmlist(search_path, devidp,
1475 search_type, &disklist);
1477 if (ret != 0) {
1478 if (dev_options & DEV_VERBOSE) {
1479 mda_print(dgettext(TEXT_DOMAIN,
1480 "Device ID %s last associated with "
1481 "disk %s no longer found in system\n"),
1482 dnp->devid, dnp->cname);
1484 devid_free(devidp);
1485 devid_free_nmlist(disklist);
1486 return (METADEVADM_SUCCESS);
1489 small_dev = meta_cmpldev(dev);
1490 mda_debug("Old device lookup: %s (%p)\n",
1491 (char *)(uintptr_t)nm.devname, (void *)small_dev);
1493 * Check to see if the returned disk matches the stored one
1495 for (i = 0; disklist[i].dev != NODEV; i++) {
1496 match_type = 0;
1497 mda_debug("From devid lookup: %s (%p)\n",
1498 disklist[i].devname, (void *)disklist[i].dev);
1500 if (disklist[i].dev == small_dev) {
1501 match_type |= DEV_MATCH;
1504 if (strncmp((char *)(uintptr_t)nm.devname, disklist[i].devname,
1505 strlen((char *)(uintptr_t)nm.devname)) == 0) {
1506 match_type |= NAME_MATCH;
1509 if (match_type != 0)
1510 break;
1512 devid_free(devidp);
1514 mda_debug("meta_upd_ctdnames: match: %x i: %d\n", match_type, i);
1516 if (match_type == (DEV_MATCH|NAME_MATCH)) {
1517 /* no change */
1518 devid_free_nmlist(disklist);
1519 return (METADEVADM_SUCCESS);
1522 /* No match found - use the first entry in disklist */
1523 if (disklist[i].dev == NODEV)
1524 i = 0;
1526 if (!(match_type & DEV_MATCH)) {
1527 /* did not match on the dev, so dev_t has changed */
1528 mda_debug("Did not match on dev: %p %p\n",
1529 (void *) small_dev, (void *) disklist[i].dev);
1530 dev = meta_expldev(disklist[i].dev);
1533 if (!(match_type & NAME_MATCH)) {
1534 mda_debug("Did not match on name: %s (%p)\n",
1535 (char *)(uintptr_t)nm.devname, (void *) disklist[i].dev);
1539 * If here, then the name in the disklist is the one we
1540 * want in any case so use it.
1542 mda_debug("devname: %s\n", disklist[i].devname);
1544 * Need to remove the slice as metadrivename() expects a diskname
1546 stripS(disklist[i].devname);
1548 * Build an mddrivename_t to use
1550 if ((newdnp = metadrivename(spp, disklist[i].devname, ep)) == NULL) {
1551 mda_debug("Unable to make a dnp out of %s\n",
1552 disklist[i].devname);
1553 return (METADEVADM_DSKNAME_ERR);
1556 * Need to find the correct slice used for the replica
1558 if (meta_replicaslice(newdnp, &rep_slice, ep) != 0) {
1559 return (METADEVADM_DSKNAME_ERR);
1562 if ((np = metaslicename(newdnp, rep_slice, ep)) == NULL) {
1563 mda_debug("Failed to build an np for %s\n", dnp->rname);
1564 return (METADEVADM_DSKNAME_ERR);
1566 mda_debug("check: cname: %s\n", np->cname);
1567 mda_debug("check: rname: %s\n", np->rname);
1568 mda_debug("check: bname: %s\n", np->bname);
1570 if (newname != NULL)
1571 *newname = Strdup(np->bname);
1573 if (!(dev_options & DEV_NOACTION)) {
1575 mda_debug("update namespace\n");
1577 /* get the block path */
1578 pathname = mda_getpath(np->bname);
1580 if (meta_update_namespace(setno, sideno, np->cname,
1581 dev, dnp->side_names_key, pathname, ep) != 0) {
1582 /* finished with the list so return the memory */
1583 Free(pathname);
1584 devid_free_nmlist(disklist);
1585 return (METADEVADM_ERR);
1588 /* finished with the list so return the memory */
1589 Free(pathname);
1590 devid_free_nmlist(disklist);
1591 ret = METADEVADM_DISKMOVE;
1592 return (ret);
1596 meta_fixdevid(
1597 mdsetname_t *sp,
1598 mddevopts_t options,
1599 char *diskname,
1600 md_error_t *ep
1603 set_t setno = sp->setno;
1604 int ret = 0;
1605 char *pathname = NULL;
1606 mdsetname_t *local_sp = NULL;
1607 md_drive_desc *d = NULL;
1608 char *newname = NULL;
1609 md_drive_desc *dd;
1610 side_t sideno;
1611 md_set_desc *sd;
1613 /* if MN diskset just return */
1614 if (!metaislocalset(sp)) {
1615 if ((sd = metaget_setdesc(sp, ep)) == NULL) {
1616 return (METADEVADM_ERR);
1618 if (MD_MNSET_DESC(sd))
1619 return (METADEVADM_SUCCESS);
1622 dev_options |= options;
1623 mda_debug("dev_options: %x\n", dev_options);
1624 if (dev_options & DEV_RELOAD) {
1626 * If it's not the local set we need to check the local
1627 * namespace to see if disks have moved as it contains
1628 * entries for the disks in the set.
1630 if (setno != MD_LOCAL_SET) {
1631 if ((dd = metaget_drivedesc(sp, MD_BASICNAME_OK |
1632 PRINT_FAST, ep)) == NULL) {
1633 mde_perror(ep, "");
1634 mdclrerror(ep);
1635 return (METADEVADM_ERR);
1637 local_sp = metasetname(MD_LOCAL_NAME, ep);
1638 sideno = getmyside(sp, ep) + SKEW;
1639 for (d = dd; d != NULL; d = d->dd_next) {
1641 * Actually do the check of the disks.
1643 ret = meta_upd_ctdnames(&local_sp, 0, sideno,
1644 d->dd_dnp, &newname, ep);
1646 if ((ret == METADEVADM_ERR) ||
1647 (ret == METADEVADM_DSKNAME_ERR)) {
1648 /* check failed in unknown manner */
1649 mda_debug("meta_upd_ctdnames failed\n");
1650 return (METADEVADM_ERR);
1655 /* do a reload of the devid namespace */
1656 ret = pathname_reload(&sp, setno, ep);
1657 } else if (dev_options & DEV_UPDATE) {
1658 pathname = getdiskname(diskname);
1659 ret = devid_update(&sp, setno, pathname, ep);
1660 free(pathname);
1662 return (ret);