7712 mandoc -Tlint does always exit with error code 0
[unleashed.git] / usr / src / lib / lvm / libmeta / common / meta_namespace.c
blob365ddd11d8dee34960e0143dc68cab330c113762
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 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * namespace utilities
30 #include <meta.h>
32 typedef struct deviceinfo {
33 char *bname; /* block name of the device */
34 char *dname; /* driver for the device */
35 minor_t mnum; /* minor number for the device */
36 } deviceinfo_t;
38 static deviceinfo_t devlist[MD_MNMAXSIDES];
41 * Ask the driver for the device name, driver name, and minor number;
42 * which has been stored in the metadevice state database
43 * (on behalf of the utilities).
44 * (by key)
46 char *
47 meta_getnmentbykey(
48 set_t setno,
49 side_t sideno,
50 mdkey_t key,
51 char **drvnm,
52 minor_t *mnum,
53 md_dev64_t *dev,
54 md_error_t *ep
57 struct mdnm_params nm;
58 static char device_name[MAXPATHLEN];
60 (void) memset(&nm, '\0', sizeof (nm));
61 nm.setno = setno;
62 nm.side = sideno;
63 nm.key = key;
64 nm.devname = (uintptr_t)device_name;
66 if (metaioctl(MD_IOCGET_NM, &nm, &nm.mde, NULL) != 0) {
67 (void) mdstealerror(ep, &nm.mde);
68 return (NULL);
71 if (drvnm != NULL)
72 *drvnm = Strdup(nm.drvnm);
74 if (mnum != NULL)
75 *mnum = nm.mnum;
77 if (dev != NULL)
78 *dev = meta_expldev(makedevice(nm.major, nm.mnum));
80 return (Strdup(device_name));
84 * Ask the driver for the hsp name, driver name, and minor number;
85 * which has been stored in the metadevice state database
86 * (on behalf of the utilities).
87 * (by key)
89 char *
90 meta_gethspnmentbyid(
91 set_t setno,
92 side_t sideno,
93 hsp_t hspid,
94 md_error_t *ep
97 struct mdhspnm_params nm;
98 char *device_name;
100 device_name = Malloc(MAXPATHLEN);
101 device_name[0] = '\0';
103 (void) memset(&nm, '\0', sizeof (nm));
104 nm.setno = setno;
105 nm.side = sideno;
106 nm.hspid = hspid;
107 nm.ret_hspid = MD_HSPID_WILD;
108 nm.hspname_len = MAXPATHLEN;
109 nm.hspname = (uintptr_t)device_name;
111 if (metaioctl(MD_IOCGET_HSP_NM, &nm, &nm.mde, NULL) != 0) {
112 (void) mdstealerror(ep, &nm.mde);
113 Free(device_name);
114 return (NULL);
117 return (device_name);
121 * Ask the driver for the hsp_self_id;
122 * which has been stored in the metadevice state database
123 * (on behalf of the utilities).
124 * (by hsp name)
126 hsp_t
127 meta_gethspnmentbyname(
128 set_t setno,
129 side_t sideno,
130 char *hspname,
131 md_error_t *ep
134 struct mdhspnm_params nm;
135 char *device_name;
137 /* must have a hsp name */
138 assert(hspname != NULL);
140 device_name = Malloc(MAXPATHLEN);
141 (void) strcpy(device_name, hspname);
143 (void) memset(&nm, '\0', sizeof (nm));
144 nm.setno = setno;
145 nm.side = sideno;
146 nm.hspid = MD_HSPID_WILD;
147 nm.ret_hspid = MD_HSPID_WILD;
148 nm.hspname_len = strlen(device_name) + 1;
149 nm.hspname = (uintptr_t)device_name;
152 * The ioctl expects the a hsp name and return its hsp_self_id.
154 if (metaioctl(MD_IOCGET_HSP_NM, &nm, &nm.mde, NULL) != 0) {
155 (void) mdstealerror(ep, &nm.mde);
156 Free(device_name);
157 return (MD_HSP_NONE);
160 if (nm.ret_hspid == MD_HSPID_WILD) {
161 Free(device_name);
162 return (MD_HSP_NONE);
165 Free(device_name);
166 return (nm.ret_hspid);
171 * Ask the driver for the minor name which has been stored in the
172 * metadevice state database.
173 * (by key)
175 char *
176 meta_getdidminorbykey(
177 set_t setno,
178 side_t sideno,
179 mdkey_t key,
180 md_error_t *ep
183 struct mdnm_params nm;
184 static char minorname[MAXPATHLEN];
186 (void) memset(&nm, '\0', sizeof (nm));
187 nm.setno = setno;
188 nm.side = sideno;
189 nm.key = key;
190 nm.minorname = (uintptr_t)minorname;
192 if (metaioctl(MD_IOCGET_DIDMIN, &nm, &nm.mde, NULL) != 0) {
193 (void) mdstealerror(ep, &nm.mde);
194 return (NULL);
197 return (Strdup(minorname));
201 * Ask the driver for the device id string which has been stored in the
202 * metadevice state database (on behalf of the utilities).
203 * (by key)
205 ddi_devid_t
206 meta_getdidbykey(
207 set_t setno,
208 side_t sideno,
209 mdkey_t key,
210 md_error_t *ep
213 struct mdnm_params nm;
215 (void) memset(&nm, '\0', sizeof (nm));
216 nm.setno = setno;
217 nm.side = sideno;
218 nm.key = key;
221 * First ask the driver for the size of the device id string. This is
222 * signaled by passing the driver a devid_size of zero.
224 nm.devid_size = 0;
225 if (metaioctl(MD_IOCGET_DID, &nm, &nm.mde, NULL) != 0) {
226 (void) mdstealerror(ep, &nm.mde);
227 return (NULL);
231 * If the devid_size is still zero then something is wrong.
233 if (nm.devid_size == 0) {
234 (void) mdstealerror(ep, &nm.mde);
235 return (NULL);
239 * Now go get the actual device id string. Caller is responsible for
240 * free'ing device id memory buffer.
242 if ((nm.devid = (uintptr_t)malloc(nm.devid_size)) == NULL) {
243 return (NULL);
245 if (metaioctl(MD_IOCGET_DID, &nm, &nm.mde, NULL) != 0) {
246 (void) mdstealerror(ep, &nm.mde);
247 (void) free((void *)(uintptr_t)nm.devid);
248 return (NULL);
251 return ((void *)(uintptr_t)nm.devid);
255 * set the devid.
258 meta_setdid(
259 set_t setno,
260 side_t sideno,
261 mdkey_t key,
262 md_error_t *ep
265 struct mdnm_params nm;
266 int i;
268 (void) memset(&nm, '\0', sizeof (nm));
269 nm.setno = setno;
270 nm.side = sideno;
271 nm.key = key;
273 if (metaioctl(MD_IOCSET_DID, &nm, &nm.mde, NULL) != 0) {
274 (void) mdstealerror(ep, &nm.mde);
275 return (-1);
278 if (setno == MD_LOCAL_SET) {
280 * If this is the local set then we are adding in the devids
281 * for the disks in the diskset and so this means adding
282 * a reference count for each side. Need to do this after
283 * the initial add so that the correct devid is picked up.
284 * The key is the key of the drive record and as such this
285 * means the minor number of the device which is used to
286 * get the devid. If the wrong side is used then it would
287 * be possible to get the wrong devid in the namespace, hence
288 * the requirement to process the local side first of all.
290 for (i = 0 + SKEW; i < MD_MAXSIDES; i++) {
292 * We can just call the ioctl again because it will
293 * fail with ENOENT if the side does not exist, and
294 * more importantly does not increment the usage count
295 * on the devid.
297 nm.side = (side_t)i;
298 if (nm.side == sideno)
299 continue;
300 if (metaioctl(MD_IOCSET_DID, &nm, &nm.mde, NULL) != 0) {
301 if (mdissyserror(&nm.mde, ENODEV)) {
302 mdclrerror(&nm.mde);
303 } else {
304 (void) mdstealerror(ep, &nm.mde);
305 return (-1);
310 return (0);
313 * Ask the driver for the name, which has been stored in the
314 * metadevice state database (on behalf of the utilities).
315 * (by key)
317 char *
318 meta_getnmbykey(
319 set_t setno,
320 side_t sideno,
321 mdkey_t key,
322 md_error_t *ep
325 return (meta_getnmentbykey(setno, sideno, key, NULL, NULL, NULL, ep));
329 * Ask the driver for the device name, driver name, minor number, and key;
330 * which has been stored in the metadevice state database
331 * (on behalf of the utilities).
332 * (by md_dev64_t)
334 char *
335 meta_getnmentbydev(
336 set_t setno,
337 side_t sideno,
338 md_dev64_t dev,
339 char **drvnm,
340 minor_t *mnum,
341 mdkey_t *key,
342 md_error_t *ep
345 struct mdnm_params nm;
346 static char device_name[MAXPATHLEN];
348 /* must have a dev */
349 assert(dev != NODEV64);
351 (void) memset(&nm, '\0', sizeof (nm));
352 nm.setno = setno;
353 nm.side = sideno;
354 nm.key = MD_KEYWILD;
355 nm.major = meta_getmajor(dev);
356 nm.mnum = meta_getminor(dev);
357 nm.devname = (uintptr_t)device_name;
359 if (metaioctl(MD_IOCGET_NM, &nm, &nm.mde, NULL) != 0) {
360 (void) mdstealerror(ep, &nm.mde);
361 return (NULL);
365 * With the friendly name work, each metadevice will have
366 * an NM entry. However, to allow backward compatibility,
367 * systems upgraded to a friendly name release won't have
368 * NM entries for the pre-existing top level metadevices. This
369 * implementation allows users to downgrade to a pre-friendly
370 * name release since the configuration information (mddb) is
371 * not modified.
373 * meta_getnmentbydev is called to get nm entry for all metadevices
374 * and expects the minor and major number and returns a key and
375 * name. For upgraded systems with pre-existing metadevices,
376 * the only returning value will be the name since there's no nm
377 * entry for pre-friendly name top level metadevices. So a return
378 * key for the device will not be available and will be NULL.
379 * Thus, the caller is responsible for making sure the returned key
380 * is valid, not NULL.
382 if (drvnm != NULL)
383 *drvnm = Strdup(nm.drvnm);
384 if (mnum != NULL)
385 *mnum = nm.mnum;
387 if (key != NULL)
388 *key = nm.retkey;
390 return (Strdup(device_name));
394 * The arguments, minorname and devid, are only used with the partial
395 * import code and should be NULL otherwise.
398 add_name(
399 mdsetname_t *sp,
400 side_t sideno,
401 mdkey_t key,
402 char *dname,
403 minor_t mnum,
404 char *bname,
405 char *minorname, /* only used with a partial import */
406 ddi_devid_t devid, /* only used with a partial import */
407 md_error_t *ep
410 struct mdnm_params nm;
412 (void) memset(&nm, '\0', sizeof (nm));
413 nm.setno = sp->setno;
414 nm.side = sideno;
415 nm.key = key;
416 nm.mnum = mnum;
417 (void) strncpy(nm.drvnm, dname, sizeof (nm.drvnm));
418 nm.devname_len = strlen(bname) + 1;
419 nm.devname = (uintptr_t)bname;
420 if (devid && minorname) {
421 nm.minorname_len = strlen(minorname) + 1;
422 nm.minorname = (uintptr_t)minorname;
423 nm.devid_size = devid_sizeof(devid);
424 nm.devid = (uintptr_t)devid;
425 nm.imp_flag = MDDB_C_IMPORT;
427 if (metaioctl(MD_IOCSET_NM, &nm, &nm.mde, bname) < 0)
428 return (mdstealerror(ep, &nm.mde));
430 return (nm.key);
434 * Remove the device name which corresponds to the given device number.
437 del_name(
438 mdsetname_t *sp,
439 side_t sideno,
440 mdkey_t key,
441 md_error_t *ep
444 struct mdnm_params nm;
446 (void) memset(&nm, '\0', sizeof (nm));
447 nm.setno = sp->setno;
448 nm.side = sideno;
449 nm.key = key;
451 if (metaioctl(MD_IOCREM_NM, &nm, &nm.mde, NULL) != 0)
452 return (mdstealerror(ep, &nm.mde));
454 return (0);
457 static void
458 empty_devicelist()
460 side_t sideno;
462 for (sideno = 0; sideno < MD_MNMAXSIDES; sideno++) {
463 if (devlist[sideno].bname != (char *)NULL) {
464 Free(devlist[sideno].bname);
465 Free(devlist[sideno].dname);
466 devlist[sideno].mnum = NODEV;
471 static void
472 add_to_devicelist(
473 side_t sideno,
474 char *bname,
475 char *dname,
476 minor_t mnum
479 devlist[sideno].bname = Strdup(bname);
480 devlist[sideno].dname = Strdup(dname);
482 devlist[sideno].mnum = mnum;
486 * Build a list of the names on the systems, if this fails the caller
487 * will tidy up the entries in the devlist.
489 static int
490 build_sidenamelist(
491 mdsetname_t *sp,
492 mdname_t *np,
493 md_error_t *ep
496 side_t sideno = MD_SIDEWILD;
497 minor_t mnum = NODEV;
498 char *bname = NULL;
499 char *dname = NULL;
500 int err;
502 /*CONSTCOND*/
503 while (1) {
505 if ((err = meta_getnextside_devinfo(sp, np->bname, &sideno,
506 &bname, &dname, &mnum, ep)) == -1)
507 return (-1);
509 if (err == 0)
510 break;
512 /* the sideno gives us the index into the array */
513 add_to_devicelist(sideno, bname, dname, mnum);
515 return (0);
519 * add name key
520 * the meta_create* functions should be the only ones using this. The
521 * adding of a name to the namespace must be done in a particular order
522 * to devid support for the disksets. The order is: add the 'local' side
523 * first of all, so the devid lookup in the kernel will use the correct
524 * device information and then add in the other sides.
527 add_key_name(
528 mdsetname_t *sp,
529 mdname_t *np,
530 mdnamelist_t **nlpp,
531 md_error_t *ep
534 int err;
535 side_t sideno = MD_SIDEWILD;
536 side_t thisside;
537 mdkey_t key = MD_KEYWILD;
538 md_set_desc *sd;
539 int maxsides;
541 /* should have a set */
542 assert(sp != NULL);
544 if (! metaislocalset(sp)) {
545 if ((sd = metaget_setdesc(sp, ep)) == NULL) {
546 return (-1);
550 if (build_sidenamelist(sp, np, ep) == -1) {
551 empty_devicelist();
552 return (-1);
556 * When a disk is added into the namespace the local information for
557 * that disk is added in first of all. For the local set this is not
558 * a concern and for the host that owns the diskset it is not a concern
559 * but when a disk is added in the remote namespace we *must* use the
560 * local information for that disk first of all. This is because when
561 * in the kernel (md_setdevname) the passed in dev_t is used to find
562 * the devid of the disk. This means we have to cater for the following:
564 * - a disk on the remote host having the dev_t that has been passed
565 * into the kernel and this disk is not actually the disk that is
566 * being added into the diskset.
567 * - the dev_t does not exist on this node
569 * So putting in the local information first of all makes sure that the
570 * dev_t passed into the kernel is correct with respect to that node
571 * and then any further additions for that name match on the key
572 * passed back.
574 thisside = getmyside(sp, ep);
576 if (devlist[thisside].dname == NULL ||
577 strlen(devlist[thisside].dname) == 0) {
579 * Did not find the disk information for the disk. This can
580 * be because of an inconsistancy in the namespace: that is the
581 * devid we have in the namespace does not exist on the
582 * system and thus when looking up the disk information
583 * using this devid we fail to find anything.
585 (void) mdcomperror(ep, MDE_SP_COMP_OPEN_ERR, 0, np->dev,
586 np->cname);
587 empty_devicelist();
588 return (-1);
591 if ((err = add_name(sp, thisside, key, devlist[thisside].dname,
592 devlist[thisside].mnum, devlist[thisside].bname, NULL,
593 NULL, ep)) == -1) {
594 empty_devicelist();
595 return (-1);
598 /* We now have a 'key' so add in the other sides */
599 key = (mdkey_t)err;
601 if (metaislocalset(sp))
602 goto done;
604 if (MD_MNSET_DESC(sd))
605 maxsides = MD_MNMAXSIDES;
606 else
607 maxsides = MD_MAXSIDES;
609 for (sideno = 0; sideno < maxsides; sideno++) {
610 /* ignore thisside, as it has been added above */
611 if (sideno == thisside)
612 continue;
614 if (devlist[sideno].dname != NULL) {
615 err = add_name(sp, sideno, key, devlist[sideno].dname,
616 devlist[sideno].mnum, devlist[sideno].bname,
617 NULL, NULL, ep);
618 if (err == -1) {
619 empty_devicelist();
620 return (-1);
625 done:
626 empty_devicelist();
627 /* save key, return success */
628 np->key = key;
629 if (nlpp != NULL)
630 (void) metanamelist_append(nlpp, np);
631 return (0);
635 * delete name key
636 * the meta_create* functions should be the only ones using this. The
637 * removal of the names must be done in a particular order: remove the
638 * non-local entries first of all and then finally the local entry.
641 del_key_name(
642 mdsetname_t *sp,
643 mdname_t *np,
644 md_error_t *ep
647 side_t sideno = MD_SIDEWILD;
648 int err;
649 int retval = 0;
650 side_t thisside;
652 /* should have a set */
653 assert(sp != NULL);
655 /* should have a key */
656 assert((np->key != MD_KEYWILD) && (np->key != MD_KEYBAD));
658 thisside = getmyside(sp, ep);
660 /* remove the remote sides first of all */
661 for (;;) {
662 if ((err = meta_getnextside_devinfo(sp, np->bname, &sideno,
663 NULL, NULL, NULL, ep)) == -1)
664 return (-1);
666 if (err == 0)
667 break;
669 /* ignore thisside */
670 if (thisside == sideno) {
671 continue;
673 if ((err = del_name(sp, sideno, np->key, ep)) == -1)
674 retval = -1;
677 /* now remove this side */
678 if (retval == 0)
679 if ((err = del_name(sp, thisside, np->key, ep)) == -1)
680 retval = -1;
682 np->key = MD_KEYBAD;
683 return (retval);
687 * delete namelist keys
688 * the meta_create* functions should be the only ones using this
691 del_key_names(
692 mdsetname_t *sp,
693 mdnamelist_t *nlp,
694 md_error_t *ep
697 mdnamelist_t *p;
698 md_error_t status = mdnullerror;
699 int rval = 0;
701 /* if ignoring errors */
702 if (ep == NULL)
703 ep = &status;
705 /* delete names */
706 for (p = nlp; (p != NULL); p = p->next) {
707 mdname_t *np = p->namep;
709 if (del_key_name(sp, np, ep) != 0)
710 rval = -1;
713 /* cleanup, return success */
714 if (ep == &status)
715 mdclrerror(&status);
716 return (rval);
721 * This routine when is called will store the metadevice name
722 * when it is first created
724 mdkey_t
725 add_self_name(
726 mdsetname_t *sp,
727 char *uname,
728 md_mkdev_params_t *params,
729 md_error_t *ep
732 char *p, *devname;
733 side_t myside, side;
734 mdkey_t key;
735 md_set_desc *sd;
736 int len;
737 char *drvname = params->md_driver.md_drivername;
738 minor_t minor = MD_MKMIN(sp->setno, params->un);
739 md_mnnode_desc *mnside;
741 p = strrchr(uname, '/');
742 if (p == NULL)
743 p = uname;
744 else
745 p++;
748 * The valid qualified name
750 if (metaislocalset(sp)) {
751 len = strlen(p) + strlen("/dev/md/dsk/") + 1;
752 devname = Malloc(len);
753 (void) strcpy(devname, "/dev/md/dsk/");
754 (void) strcat(devname, p);
755 } else {
756 len = strlen(sp->setname) + strlen(p) +
757 strlen("/dev/md//dsk/") + 1;
758 devname = Malloc(len);
759 (void) snprintf(devname, len, "/dev/md/%s/dsk/%s",
760 sp->setname, p);
764 * Add self to the namespace
766 if ((myside = getmyside(sp, ep)) == MD_SIDEWILD) {
767 Free(devname);
768 return (-1);
771 if (metaislocalset(sp)) {
772 if ((key = add_name(sp, myside, MD_KEYWILD, drvname,
773 minor, devname, NULL, NULL, ep)) == MD_KEYBAD) {
774 Free(devname);
775 return (-1);
777 } else {
779 * Add myside first and use the returned key to add other sides
781 if ((key = add_name(sp, myside, MD_KEYWILD, drvname,
782 minor, devname, NULL, NULL, ep)) == MD_KEYBAD) {
783 Free(devname);
784 return (-1);
788 * Add for all other sides
790 if ((sd = metaget_setdesc(sp, ep)) == NULL) {
791 Free(devname);
792 return (-1);
795 if (MD_MNSET_DESC(sd)) {
796 for (mnside = sd->sd_nodelist; mnside != NULL;
797 mnside = mnside->nd_next) {
798 if (mnside->nd_nodeid == myside)
799 continue;
800 if (add_name(sp, mnside->nd_nodeid, key,
801 drvname, minor, devname, NULL, NULL,
802 ep) == -1) {
803 Free(devname);
804 return (-1);
807 } else {
808 for (side = 0; side < MD_MAXSIDES; side++) {
809 if (sd->sd_nodes[side][0] == '\0')
810 continue;
811 if (side == myside)
812 continue;
813 if (add_name(sp, side, key, drvname, minor,
814 devname, NULL, NULL, ep) == -1) {
815 Free(devname);
816 return (-1);
822 Free(devname);
823 return (key);
828 * This routine when is called will remove the metadevice name
829 * from the namespace and it is the last thing to do in the
830 * metaclear operation
833 del_self_name(
834 mdsetname_t *sp,
835 mdkey_t key,
836 md_error_t *ep
839 side_t myside;
840 int rval = 0;
841 side_t side;
842 md_set_desc *sd;
843 md_mnnode_desc *mnside;
845 assert(key != MD_KEYBAD);
847 if ((myside = getmyside(sp, ep)) == MD_SIDEWILD)
848 return (-1);
850 if (metaislocalset(sp)) {
851 rval = del_name(sp, myside, key, ep);
852 } else {
854 * Remove all other sides first
856 if ((sd = metaget_setdesc(sp, ep)) == NULL) {
857 return (-1);
860 if (MD_MNSET_DESC(sd)) {
861 for (mnside = sd->sd_nodelist; mnside != NULL;
862 mnside = mnside->nd_next) {
863 if (mnside->nd_nodeid == myside)
864 continue;
865 if ((rval = del_name(sp, mnside->nd_nodeid, key,
866 ep)) == -1) {
867 goto out;
870 } else {
871 for (side = 0; side < MD_MAXSIDES; side++) {
872 if (sd->sd_nodes[side][0] == '\0')
873 continue;
874 if (side == myside)
875 continue;
876 if ((rval = del_name(sp, side, key,
877 ep)) == -1) {
878 goto out;
884 * del myside
886 rval = del_name(sp, myside, key, ep);
889 out:
890 return (rval);