10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /*
23*645Sgjelinek * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate
300Sstevel@tonic-gate /*
310Sstevel@tonic-gate * miscellaneous utilities
320Sstevel@tonic-gate */
330Sstevel@tonic-gate
340Sstevel@tonic-gate #include <meta.h>
35*645Sgjelinek #include <zone.h>
360Sstevel@tonic-gate
370Sstevel@tonic-gate static int meta_fd = -1;
380Sstevel@tonic-gate static major_t meta_major;
390Sstevel@tonic-gate
400Sstevel@tonic-gate /*
410Sstevel@tonic-gate * open administrative device
420Sstevel@tonic-gate */
430Sstevel@tonic-gate int
open_admin(md_error_t * ep)440Sstevel@tonic-gate open_admin(
450Sstevel@tonic-gate md_error_t *ep
460Sstevel@tonic-gate )
470Sstevel@tonic-gate {
480Sstevel@tonic-gate struct stat buf;
490Sstevel@tonic-gate
500Sstevel@tonic-gate /* if not already open */
510Sstevel@tonic-gate if (meta_fd < 0) {
520Sstevel@tonic-gate ulong_t dversion = 0;
530Sstevel@tonic-gate
540Sstevel@tonic-gate /* try read/write fall back to readonly */
550Sstevel@tonic-gate if ((meta_fd = open(ADMSPECIAL, O_RDWR, 0)) < 0) {
56*645Sgjelinek if (errno == ENOENT && getzoneid() != GLOBAL_ZONEID)
57*645Sgjelinek return (mderror(ep, MDE_ZONE_ADMIN, NULL));
580Sstevel@tonic-gate if (errno != EACCES)
590Sstevel@tonic-gate return (mdsyserror(ep, errno, ADMSPECIAL));
600Sstevel@tonic-gate if ((meta_fd = open(ADMSPECIAL, O_RDONLY, 0)) < 0)
610Sstevel@tonic-gate return (mdsyserror(ep, errno, ADMSPECIAL));
620Sstevel@tonic-gate }
630Sstevel@tonic-gate
640Sstevel@tonic-gate /* get major */
650Sstevel@tonic-gate if (fstat(meta_fd, &buf) != 0)
660Sstevel@tonic-gate return (mdsyserror(ep, errno, ADMSPECIAL));
670Sstevel@tonic-gate meta_major = major(buf.st_rdev);
680Sstevel@tonic-gate
690Sstevel@tonic-gate /* check driver version */
700Sstevel@tonic-gate if (metaioctl(MD_IOCGVERSION, &dversion, ep, NULL) != 0)
710Sstevel@tonic-gate return (-1);
720Sstevel@tonic-gate if (dversion != MD_DVERSION)
730Sstevel@tonic-gate return (mderror(ep, MDE_DVERSION, NULL));
740Sstevel@tonic-gate }
750Sstevel@tonic-gate
760Sstevel@tonic-gate /* return fd */
770Sstevel@tonic-gate return (meta_fd);
780Sstevel@tonic-gate }
790Sstevel@tonic-gate
800Sstevel@tonic-gate int
close_admin(md_error_t * ep)810Sstevel@tonic-gate close_admin(
820Sstevel@tonic-gate md_error_t *ep
830Sstevel@tonic-gate )
840Sstevel@tonic-gate {
850Sstevel@tonic-gate if (meta_fd >= 0) {
860Sstevel@tonic-gate if (close(meta_fd) == -1)
870Sstevel@tonic-gate return (mdsyserror(ep, errno, ADMSPECIAL));
880Sstevel@tonic-gate meta_fd = -1;
890Sstevel@tonic-gate }
900Sstevel@tonic-gate
910Sstevel@tonic-gate return (0);
920Sstevel@tonic-gate }
930Sstevel@tonic-gate
940Sstevel@tonic-gate /*
950Sstevel@tonic-gate * Returns True if the md_dev64_t passed in is a metadevice.
960Sstevel@tonic-gate * Else it returns False.
970Sstevel@tonic-gate */
980Sstevel@tonic-gate int
meta_dev_ismeta(md_dev64_t dev)990Sstevel@tonic-gate meta_dev_ismeta(
1000Sstevel@tonic-gate md_dev64_t dev
1010Sstevel@tonic-gate )
1020Sstevel@tonic-gate {
1030Sstevel@tonic-gate int fd;
1040Sstevel@tonic-gate md_error_t status = mdnullerror;
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate fd = open_admin(&status);
1070Sstevel@tonic-gate assert(fd >= 0);
1080Sstevel@tonic-gate return (meta_getmajor(dev) == meta_major);
1090Sstevel@tonic-gate }
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate int
meta_get_nunits(md_error_t * ep)1130Sstevel@tonic-gate meta_get_nunits(md_error_t *ep)
1140Sstevel@tonic-gate {
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate static set_t max_nunits = 0;
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate if (max_nunits == 0)
1190Sstevel@tonic-gate if (metaioctl(MD_IOCGETNUNITS, &max_nunits, ep, NULL) != 0)
1200Sstevel@tonic-gate return (-1);
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate return (max_nunits);
1230Sstevel@tonic-gate }
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate md_dev64_t
metamakedev(minor_t mnum)1260Sstevel@tonic-gate metamakedev(minor_t mnum)
1270Sstevel@tonic-gate {
1280Sstevel@tonic-gate int fd;
1290Sstevel@tonic-gate md_error_t status = mdnullerror;
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate fd = open_admin(&status);
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate assert(fd >= 0);
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate return (((md_dev64_t)meta_major << NBITSMINOR64) | mnum);
1360Sstevel@tonic-gate }
137