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 37 static int meta_fd = -1; 38 static major_t meta_major; 39 40 /* 41 * open administrative device 42 */ 43 int 44 open_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 80 int 81 close_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 */ 98 int 99 meta_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 112 int 113 meta_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 125 md_dev64_t 126 metamakedev(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