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]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
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 */
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).
57 struct mdnm_params nm
;
58 static char device_name
[MAXPATHLEN
];
60 (void) memset(&nm
, '\0', sizeof (nm
));
64 nm
.devname
= (uintptr_t)device_name
;
66 if (metaioctl(MD_IOCGET_NM
, &nm
, &nm
.mde
, NULL
) != 0) {
67 (void) mdstealerror(ep
, &nm
.mde
);
72 *drvnm
= Strdup(nm
.drvnm
);
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).
97 struct mdhspnm_params nm
;
100 device_name
= Malloc(MAXPATHLEN
);
101 device_name
[0] = '\0';
103 (void) memset(&nm
, '\0', sizeof (nm
));
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
);
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).
127 meta_gethspnmentbyname(
134 struct mdhspnm_params nm
;
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
));
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
);
157 return (MD_HSP_NONE
);
160 if (nm
.ret_hspid
== MD_HSPID_WILD
) {
162 return (MD_HSP_NONE
);
166 return (nm
.ret_hspid
);
171 * Ask the driver for the minor name which has been stored in the
172 * metadevice state database.
176 meta_getdidminorbykey(
183 struct mdnm_params nm
;
184 static char minorname
[MAXPATHLEN
];
186 (void) memset(&nm
, '\0', sizeof (nm
));
190 nm
.minorname
= (uintptr_t)minorname
;
192 if (metaioctl(MD_IOCGET_DIDMIN
, &nm
, &nm
.mde
, NULL
) != 0) {
193 (void) mdstealerror(ep
, &nm
.mde
);
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).
213 struct mdnm_params nm
;
215 (void) memset(&nm
, '\0', sizeof (nm
));
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.
225 if (metaioctl(MD_IOCGET_DID
, &nm
, &nm
.mde
, NULL
) != 0) {
226 (void) mdstealerror(ep
, &nm
.mde
);
231 * If the devid_size is still zero then something is wrong.
233 if (nm
.devid_size
== 0) {
234 (void) mdstealerror(ep
, &nm
.mde
);
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
) {
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
);
251 return ((void *)(uintptr_t)nm
.devid
);
265 struct mdnm_params nm
;
268 (void) memset(&nm
, '\0', sizeof (nm
));
273 if (metaioctl(MD_IOCSET_DID
, &nm
, &nm
.mde
, NULL
) != 0) {
274 (void) mdstealerror(ep
, &nm
.mde
);
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
298 if (nm
.side
== sideno
)
300 if (metaioctl(MD_IOCSET_DID
, &nm
, &nm
.mde
, NULL
) != 0) {
301 if (mdissyserror(&nm
.mde
, ENODEV
)) {
304 (void) mdstealerror(ep
, &nm
.mde
);
313 * Ask the driver for the name, which has been stored in the
314 * metadevice state database (on behalf of the utilities).
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).
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
));
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
);
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
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.
383 *drvnm
= Strdup(nm
.drvnm
);
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.
405 char *minorname
, /* only used with a partial import */
406 ddi_devid_t devid
, /* only used with a partial import */
410 struct mdnm_params nm
;
412 (void) memset(&nm
, '\0', sizeof (nm
));
413 nm
.setno
= sp
->setno
;
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
));
434 * Remove the device name which corresponds to the given device number.
444 struct mdnm_params nm
;
446 (void) memset(&nm
, '\0', sizeof (nm
));
447 nm
.setno
= sp
->setno
;
451 if (metaioctl(MD_IOCREM_NM
, &nm
, &nm
.mde
, NULL
) != 0)
452 return (mdstealerror(ep
, &nm
.mde
));
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
;
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.
496 side_t sideno
= MD_SIDEWILD
;
497 minor_t mnum
= NODEV
;
505 if ((err
= meta_getnextside_devinfo(sp
, np
->bname
, &sideno
,
506 &bname
, &dname
, &mnum
, ep
)) == -1)
512 /* the sideno gives us the index into the array */
513 add_to_devicelist(sideno
, bname
, dname
, mnum
);
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.
535 side_t sideno
= MD_SIDEWILD
;
537 mdkey_t key
= MD_KEYWILD
;
541 /* should have a set */
544 if (! metaislocalset(sp
)) {
545 if ((sd
= metaget_setdesc(sp
, ep
)) == NULL
) {
550 if (build_sidenamelist(sp
, np
, ep
) == -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
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
,
591 if ((err
= add_name(sp
, thisside
, key
, devlist
[thisside
].dname
,
592 devlist
[thisside
].mnum
, devlist
[thisside
].bname
, NULL
,
598 /* We now have a 'key' so add in the other sides */
601 if (metaislocalset(sp
))
604 if (MD_MNSET_DESC(sd
))
605 maxsides
= MD_MNMAXSIDES
;
607 maxsides
= MD_MAXSIDES
;
609 for (sideno
= 0; sideno
< maxsides
; sideno
++) {
610 /* ignore thisside, as it has been added above */
611 if (sideno
== thisside
)
614 if (devlist
[sideno
].dname
!= NULL
) {
615 err
= add_name(sp
, sideno
, key
, devlist
[sideno
].dname
,
616 devlist
[sideno
].mnum
, devlist
[sideno
].bname
,
627 /* save key, return success */
630 (void) metanamelist_append(nlpp
, np
);
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.
647 side_t sideno
= MD_SIDEWILD
;
652 /* should have a set */
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 */
662 if ((err
= meta_getnextside_devinfo(sp
, np
->bname
, &sideno
,
663 NULL
, NULL
, NULL
, ep
)) == -1)
669 /* ignore thisside */
670 if (thisside
== sideno
) {
673 if ((err
= del_name(sp
, sideno
, np
->key
, ep
)) == -1)
677 /* now remove this side */
679 if ((err
= del_name(sp
, thisside
, np
->key
, ep
)) == -1)
687 * delete namelist keys
688 * the meta_create* functions should be the only ones using this
698 md_error_t status
= mdnullerror
;
701 /* if ignoring errors */
706 for (p
= nlp
; (p
!= NULL
); p
= p
->next
) {
707 mdname_t
*np
= p
->namep
;
709 if (del_key_name(sp
, np
, ep
) != 0)
713 /* cleanup, return success */
721 * This routine when is called will store the metadevice name
722 * when it is first created
728 md_mkdev_params_t
*params
,
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
, '/');
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
);
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",
764 * Add self to the namespace
766 if ((myside
= getmyside(sp
, ep
)) == MD_SIDEWILD
) {
771 if (metaislocalset(sp
)) {
772 if ((key
= add_name(sp
, myside
, MD_KEYWILD
, drvname
,
773 minor
, devname
, NULL
, NULL
, ep
)) == MD_KEYBAD
) {
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
) {
788 * Add for all other sides
790 if ((sd
= metaget_setdesc(sp
, ep
)) == NULL
) {
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
)
800 if (add_name(sp
, mnside
->nd_nodeid
, key
,
801 drvname
, minor
, devname
, NULL
, NULL
,
808 for (side
= 0; side
< MD_MAXSIDES
; side
++) {
809 if (sd
->sd_nodes
[side
][0] == '\0')
813 if (add_name(sp
, side
, key
, drvname
, minor
,
814 devname
, NULL
, NULL
, ep
) == -1) {
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
843 md_mnnode_desc
*mnside
;
845 assert(key
!= MD_KEYBAD
);
847 if ((myside
= getmyside(sp
, ep
)) == MD_SIDEWILD
)
850 if (metaislocalset(sp
)) {
851 rval
= del_name(sp
, myside
, key
, ep
);
854 * Remove all other sides first
856 if ((sd
= metaget_setdesc(sp
, ep
)) == NULL
) {
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
)
865 if ((rval
= del_name(sp
, mnside
->nd_nodeid
, key
,
871 for (side
= 0; side
< MD_MAXSIDES
; side
++) {
872 if (sd
->sd_nodes
[side
][0] == '\0')
876 if ((rval
= del_name(sp
, side
, key
,
886 rval
= del_name(sp
, myside
, key
, ep
);