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 #include "availdevs.h" 30 #include <libzfs_jni_diskmgt.h> 31 #include <libzfs_jni_ipool.h> 32 #include <libxml/parser.h> 33 34 /* 35 * Function prototypes 36 */ 37 38 static void handle_error(const char *, va_list); 39 static int add_disk_to_xml(dmgt_disk_t *, void *); 40 static int add_pool_to_xml(char *, uint64_t, uint64_t, char *, void *); 41 static xmlDocPtr create_doc(); 42 int main(); 43 44 /* 45 * Static functions 46 */ 47 48 static void 49 handle_error(const char *fmt, va_list ap) 50 { 51 (void) vfprintf(stderr, fmt, ap); 52 (void) fprintf(stderr, "\n"); 53 } 54 55 static int 56 add_disk_to_xml(dmgt_disk_t *dp, void *data) 57 { 58 int i; 59 char tmp[64]; 60 xmlNodePtr available = *((xmlNodePtr *)data); 61 62 xmlNodePtr disk = xmlNewChild( 63 available, NULL, (xmlChar *)ELEMENT_DISK, NULL); 64 xmlSetProp(disk, 65 (xmlChar *)ATTR_DISK_NAME, (xmlChar *)dp->name); 66 (void) snprintf(tmp, sizeof (tmp), "%llu", dp->size); 67 xmlSetProp(disk, (xmlChar *)ATTR_DISK_SIZE, (xmlChar *)tmp); 68 69 xmlSetProp(disk, (xmlChar *)ATTR_DISK_INUSE, (xmlChar *) 70 (dp->in_use ? VAL_ATTR_TRUE : VAL_ATTR_FALSE)); 71 72 if (dp->aliases != NULL) { 73 for (i = 0; dp->aliases[i] != NULL; i++) { 74 xmlNodePtr alias = xmlNewChild( 75 disk, NULL, (xmlChar *)ELEMENT_ALIAS, NULL); 76 xmlSetProp(alias, 77 (xmlChar *)ATTR_ALIAS_NAME, 78 (xmlChar *)dp->aliases[i]); 79 } 80 } 81 82 if (dp->slices != NULL) { 83 for (i = 0; dp->slices[i] != NULL; i++) { 84 dmgt_slice_t *sp = dp->slices[i]; 85 xmlNodePtr slice = xmlNewChild( 86 disk, NULL, (xmlChar *)ELEMENT_SLICE, NULL); 87 xmlSetProp(slice, 88 (xmlChar *)ATTR_SLICE_NAME, (xmlChar *)sp->name); 89 90 (void) snprintf(tmp, sizeof (tmp), "%llu", sp->size); 91 xmlSetProp(slice, (xmlChar *)ATTR_SLICE_SIZE, 92 (xmlChar *)tmp); 93 94 (void) snprintf(tmp, sizeof (tmp), "%llu", sp->start); 95 xmlSetProp(slice, (xmlChar *)ATTR_SLICE_START, 96 (xmlChar *)tmp); 97 98 if (sp->used_name != NULL) { 99 xmlSetProp(slice, 100 (xmlChar *)ATTR_SLICE_USED_NAME, 101 (xmlChar *)sp->used_name); 102 } 103 104 if (sp->used_by != NULL) { 105 xmlSetProp(slice, (xmlChar *)ATTR_SLICE_USED_BY, 106 (xmlChar *)sp->used_by); 107 } 108 } 109 } 110 111 return (0); 112 } 113 114 static int 115 add_pool_to_xml(char *name, uint64_t guid, 116 uint64_t pool_state, char *health, void *data) 117 { 118 char *state; 119 char tmp[64]; 120 xmlNodePtr importable = *((xmlNodePtr *)data); 121 122 xmlNodePtr pool = xmlNewChild( 123 importable, NULL, (xmlChar *)ELEMENT_POOL, NULL); 124 xmlSetProp(pool, (xmlChar *)ATTR_POOL_NAME, (xmlChar *)name); 125 126 state = zjni_get_state_str(pool_state); 127 if (state == NULL) { 128 state = ""; 129 } 130 xmlSetProp(pool, (xmlChar *)ATTR_POOL_STATE, (xmlChar *)state); 131 xmlSetProp(pool, (xmlChar *)ATTR_POOL_HEALTH, (xmlChar *)health); 132 133 (void) snprintf(tmp, sizeof (tmp), "%llu", guid); 134 xmlSetProp(pool, (xmlChar *)ATTR_POOL_ID, (xmlChar *)tmp); 135 136 return (0); 137 } 138 139 static xmlDocPtr 140 create_doc(void) 141 { 142 /* Create the XML document */ 143 xmlDocPtr doc = xmlNewDoc((xmlChar *)"1.0"); 144 145 /* Create the root node */ 146 xmlNodePtr root = xmlNewDocNode( 147 doc, NULL, (xmlChar *)ELEMENT_ROOT, NULL); 148 xmlAddChild((xmlNodePtr) doc, (xmlNodePtr)root); 149 150 return (doc); 151 } 152 153 /* 154 * Main entry to availdisks. 155 * 156 * @return 0 on successful exit, non-zero otherwise 157 */ 158 int 159 main(int argc, char **argv) 160 { 161 int error = 0; 162 int get_pools = 0; 163 int get_devices = 0; 164 165 /* Examine first arg */ 166 int c = getopt(argc, argv, CLI_OPTSTRING); 167 switch (c) { 168 case CLI_ARG_ALL: 169 get_devices = 1; 170 get_pools = 1; 171 break; 172 173 case CLI_ARG_DEVICES: 174 get_devices = 1; 175 break; 176 177 case CLI_ARG_POOLS: 178 get_pools = 1; 179 break; 180 181 default: 182 return (1); 183 break; 184 } 185 186 argc -= optind; 187 argv += optind; 188 189 if (get_pools || get_devices) { 190 xmlDocPtr doc = create_doc(); 191 xmlNodePtr root = xmlDocGetRootElement(doc); 192 193 if (get_devices) { 194 /* Create the available node */ 195 xmlNodePtr available = xmlNewChild(root, NULL, 196 (xmlChar *)ELEMENT_AVAILABLE, NULL); 197 198 /* libzfs_jni_diskmgt.o error handler */ 199 dmgt_set_error_handler(handle_error); 200 201 error = dmgt_avail_disk_iter( 202 add_disk_to_xml, &available); 203 } 204 205 if (get_pools && !error) { 206 /* Create the importable node */ 207 xmlNodePtr importable = xmlNewChild(root, NULL, 208 (xmlChar *)ELEMENT_IMPORTABLE, NULL); 209 210 error = zjni_ipool_iter( 211 argc, argv, add_pool_to_xml, &importable); 212 } 213 214 if (!error) { 215 /* Print out XML */ 216 xmlDocFormatDump(stdout, doc, 1); 217 } 218 219 xmlFreeDoc(doc); 220 } 221 222 return (error != 0); 223 } 224