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