1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29 30/* 31 * miscellaneous utilities 32 */ 33 34#include <meta.h> 35#include <zone.h> 36 37static int meta_fd = -1; 38static major_t meta_major; 39 40/* 41 * open administrative device 42 */ 43int 44open_admin( 45 md_error_t *ep 46) 47{ 48 struct stat buf; 49 50 /* if not already open */ 51 if (meta_fd < 0) { 52 ulong_t dversion = 0; 53 54 /* try read/write fall back to readonly */ 55 if ((meta_fd = open(ADMSPECIAL, O_RDWR, 0)) < 0) { 56 if (errno == ENOENT && getzoneid() != GLOBAL_ZONEID) 57 return (mderror(ep, MDE_ZONE_ADMIN, NULL)); 58 if (errno != EACCES) 59 return (mdsyserror(ep, errno, ADMSPECIAL)); 60 if ((meta_fd = open(ADMSPECIAL, O_RDONLY, 0)) < 0) 61 return (mdsyserror(ep, errno, ADMSPECIAL)); 62 } 63 64 /* get major */ 65 if (fstat(meta_fd, &buf) != 0) 66 return (mdsyserror(ep, errno, ADMSPECIAL)); 67 meta_major = major(buf.st_rdev); 68 69 /* check driver version */ 70 if (metaioctl(MD_IOCGVERSION, &dversion, ep, NULL) != 0) 71 return (-1); 72 if (dversion != MD_DVERSION) 73 return (mderror(ep, MDE_DVERSION, NULL)); 74 } 75 76 /* return fd */ 77 return (meta_fd); 78} 79 80int 81close_admin( 82 md_error_t *ep 83) 84{ 85 if (meta_fd >= 0) { 86 if (close(meta_fd) == -1) 87 return (mdsyserror(ep, errno, ADMSPECIAL)); 88 meta_fd = -1; 89 } 90 91 return (0); 92} 93 94/* 95 * Returns True if the md_dev64_t passed in is a metadevice. 96 * Else it returns False. 97 */ 98int 99meta_dev_ismeta( 100 md_dev64_t dev 101) 102{ 103 int fd; 104 md_error_t status = mdnullerror; 105 106 fd = open_admin(&status); 107 assert(fd >= 0); 108 return (meta_getmajor(dev) == meta_major); 109} 110 111 112int 113meta_get_nunits(md_error_t *ep) 114{ 115 116 static set_t max_nunits = 0; 117 118 if (max_nunits == 0) 119 if (metaioctl(MD_IOCGETNUNITS, &max_nunits, ep, NULL) != 0) 120 return (-1); 121 122 return (max_nunits); 123} 124 125md_dev64_t 126metamakedev(minor_t mnum) 127{ 128 int fd; 129 md_error_t status = mdnullerror; 130 131 fd = open_admin(&status); 132 133 assert(fd >= 0); 134 135 return (((md_dev64_t)meta_major << NBITSMINOR64) | mnum); 136} 137