1fa9e4066Sahrens /* 2fa9e4066Sahrens * CDDL HEADER START 3fa9e4066Sahrens * 4fa9e4066Sahrens * The contents of this file are subject to the terms of the 5a55b6846Scristian * Common Development and Distribution License (the "License"). 6a55b6846Scristian * You may not use this file except in compliance with the License. 7fa9e4066Sahrens * 8fa9e4066Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fa9e4066Sahrens * or http://www.opensolaris.org/os/licensing. 10fa9e4066Sahrens * See the License for the specific language governing permissions 11fa9e4066Sahrens * and limitations under the License. 12fa9e4066Sahrens * 13fa9e4066Sahrens * When distributing Covered Code, include this CDDL HEADER in each 14fa9e4066Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fa9e4066Sahrens * If applicable, add the following below this CDDL HEADER, with the 16fa9e4066Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 17fa9e4066Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18fa9e4066Sahrens * 19fa9e4066Sahrens * CDDL HEADER END 20fa9e4066Sahrens */ 21186d582bSSurya Prakki 22fa9e4066Sahrens /* 23*3f9d6ad7SLin Ling * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24fa9e4066Sahrens */ 25fa9e4066Sahrens 26fa9e4066Sahrens #include "availdevs.h" 27fbfd10ffStalley #include <libzfs.h> 28fa9e4066Sahrens #include <libzfs_jni_diskmgt.h> 29c8e9ed14Stalley #include <libzfs_jni_ipool.h> 30fa9e4066Sahrens #include <libxml/parser.h> 31fa9e4066Sahrens 32fa9e4066Sahrens /* 33fa9e4066Sahrens * Function prototypes 34fa9e4066Sahrens */ 35fa9e4066Sahrens 36fa9e4066Sahrens static void handle_error(const char *, va_list); 37841f46edStalley static void set_uint64_prop(xmlNodePtr, const char *, uint64_t); 38fa9e4066Sahrens static int add_disk_to_xml(dmgt_disk_t *, void *); 39fbfd10ffStalley static int add_pool_to_xml(nvlist_t *, void *); 40fa9e4066Sahrens static xmlDocPtr create_doc(); 41fa9e4066Sahrens int main(); 42fa9e4066Sahrens 43fa9e4066Sahrens /* 44fa9e4066Sahrens * Static functions 45fa9e4066Sahrens */ 46fa9e4066Sahrens 47fa9e4066Sahrens static void 48fa9e4066Sahrens handle_error(const char *fmt, va_list ap) 49fa9e4066Sahrens { 50fa9e4066Sahrens (void) vfprintf(stderr, fmt, ap); 51fa9e4066Sahrens (void) fprintf(stderr, "\n"); 52fa9e4066Sahrens } 53fa9e4066Sahrens 54841f46edStalley static void 55841f46edStalley set_uint64_prop(xmlNodePtr node, const char *attr, uint64_t value) 56841f46edStalley { 57841f46edStalley static char tmp[64]; 58841f46edStalley (void) snprintf(tmp, sizeof (tmp), "%llu", value); 59186d582bSSurya Prakki (void) xmlSetProp(node, (xmlChar *)attr, (xmlChar *)tmp); 60841f46edStalley } 61841f46edStalley 62fa9e4066Sahrens static int 63fa9e4066Sahrens add_disk_to_xml(dmgt_disk_t *dp, void *data) 64fa9e4066Sahrens { 65c8e9ed14Stalley int i; 66fa9e4066Sahrens xmlNodePtr available = *((xmlNodePtr *)data); 67fa9e4066Sahrens 68fa9e4066Sahrens xmlNodePtr disk = xmlNewChild( 69fa9e4066Sahrens available, NULL, (xmlChar *)ELEMENT_DISK, NULL); 70186d582bSSurya Prakki (void) xmlSetProp(disk, 71fa9e4066Sahrens (xmlChar *)ATTR_DISK_NAME, (xmlChar *)dp->name); 72841f46edStalley 73841f46edStalley set_uint64_prop(disk, ATTR_DISK_SIZE, dp->size); 74fa9e4066Sahrens 75186d582bSSurya Prakki (void) xmlSetProp(disk, (xmlChar *)ATTR_DISK_INUSE, (xmlChar *) 76dc307942Stalley (dp->in_use ? VAL_ATTR_TRUE : VAL_ATTR_FALSE)); 77dc307942Stalley 78fa9e4066Sahrens if (dp->aliases != NULL) { 79fa9e4066Sahrens for (i = 0; dp->aliases[i] != NULL; i++) { 80fa9e4066Sahrens xmlNodePtr alias = xmlNewChild( 81fa9e4066Sahrens disk, NULL, (xmlChar *)ELEMENT_ALIAS, NULL); 82186d582bSSurya Prakki (void) xmlSetProp(alias, 83fa9e4066Sahrens (xmlChar *)ATTR_ALIAS_NAME, 84fa9e4066Sahrens (xmlChar *)dp->aliases[i]); 85fa9e4066Sahrens } 86fa9e4066Sahrens } 87fa9e4066Sahrens 88fa9e4066Sahrens if (dp->slices != NULL) { 89fa9e4066Sahrens for (i = 0; dp->slices[i] != NULL; i++) { 90fa9e4066Sahrens dmgt_slice_t *sp = dp->slices[i]; 91fa9e4066Sahrens xmlNodePtr slice = xmlNewChild( 92fa9e4066Sahrens disk, NULL, (xmlChar *)ELEMENT_SLICE, NULL); 93186d582bSSurya Prakki (void) xmlSetProp(slice, 94fa9e4066Sahrens (xmlChar *)ATTR_SLICE_NAME, (xmlChar *)sp->name); 95fa9e4066Sahrens 96841f46edStalley set_uint64_prop(slice, ATTR_SLICE_SIZE, sp->size); 97841f46edStalley set_uint64_prop(slice, ATTR_SLICE_START, sp->start); 98fa9e4066Sahrens 99fa9e4066Sahrens if (sp->used_name != NULL) { 100186d582bSSurya Prakki (void) xmlSetProp(slice, 101fa9e4066Sahrens (xmlChar *)ATTR_SLICE_USED_NAME, 102fa9e4066Sahrens (xmlChar *)sp->used_name); 103fa9e4066Sahrens } 104fa9e4066Sahrens 105fa9e4066Sahrens if (sp->used_by != NULL) { 106186d582bSSurya Prakki (void) xmlSetProp(slice, 107186d582bSSurya Prakki (xmlChar *)ATTR_SLICE_USED_BY, 108fa9e4066Sahrens (xmlChar *)sp->used_by); 109fa9e4066Sahrens } 110fa9e4066Sahrens } 111fa9e4066Sahrens } 112fa9e4066Sahrens 113fa9e4066Sahrens return (0); 114fa9e4066Sahrens } 115fa9e4066Sahrens 116c8e9ed14Stalley static int 117fbfd10ffStalley add_pool_to_xml(nvlist_t *config, void *data) 118c8e9ed14Stalley { 119fbfd10ffStalley char *c; 120fbfd10ffStalley char *name; 121fbfd10ffStalley uint64_t guid; 122a55b6846Scristian uint64_t version; 123fbfd10ffStalley uint64_t state; 124fbfd10ffStalley nvlist_t *devices; 125fbfd10ffStalley uint_t n; 126fbfd10ffStalley vdev_stat_t *vs; 127fbfd10ffStalley xmlNodePtr pool; 128c8e9ed14Stalley xmlNodePtr importable = *((xmlNodePtr *)data); 129c8e9ed14Stalley 130fbfd10ffStalley if (nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &name) || 131fbfd10ffStalley nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) || 132a55b6846Scristian nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) || 133fbfd10ffStalley nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, &state) || 134fbfd10ffStalley nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &devices) || 135fbfd10ffStalley nvlist_lookup_uint64_array( 136*3f9d6ad7SLin Ling devices, ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &n)) { 137fbfd10ffStalley return (-1); 138c8e9ed14Stalley } 139fbfd10ffStalley 140fbfd10ffStalley pool = xmlNewChild(importable, NULL, (xmlChar *)ELEMENT_POOL, NULL); 141186d582bSSurya Prakki (void) xmlSetProp(pool, (xmlChar *)ATTR_POOL_NAME, (xmlChar *)name); 142c8e9ed14Stalley 143841f46edStalley set_uint64_prop(pool, ATTR_POOL_ID, guid); 144a55b6846Scristian set_uint64_prop(pool, ATTR_POOL_VERSION, version); 145841f46edStalley set_uint64_prop(pool, ATTR_POOL_USED, vs->vs_alloc); 146841f46edStalley set_uint64_prop(pool, ATTR_POOL_SIZE, vs->vs_space); 147841f46edStalley set_uint64_prop(pool, ATTR_POOL_REPLACEMENT_SIZE, vs->vs_rsize); 148841f46edStalley set_uint64_prop(pool, ATTR_POOL_READ_BYTES, 149841f46edStalley vs->vs_bytes[ZIO_TYPE_READ]); 150841f46edStalley set_uint64_prop(pool, ATTR_POOL_WRITE_BYTES, 151fbfd10ffStalley vs->vs_bytes[ZIO_TYPE_WRITE]); 152841f46edStalley set_uint64_prop(pool, ATTR_POOL_READ_OPERATIONS, 153841f46edStalley vs->vs_ops[ZIO_TYPE_READ]); 154841f46edStalley set_uint64_prop(pool, ATTR_POOL_WRITE_OPERATIONS, 155841f46edStalley vs->vs_ops[ZIO_TYPE_WRITE]); 156841f46edStalley set_uint64_prop(pool, ATTR_POOL_READ_ERRORS, vs->vs_read_errors); 157841f46edStalley set_uint64_prop(pool, ATTR_POOL_WRITE_ERRORS, vs->vs_write_errors); 158841f46edStalley set_uint64_prop(pool, ATTR_POOL_CHECKSUM_ERRORS, 159841f46edStalley vs->vs_checksum_errors); 160fbfd10ffStalley 161186d582bSSurya Prakki (void) xmlSetProp(pool, (xmlChar *)ATTR_DEVICE_STATE, 162fbfd10ffStalley (xmlChar *)zjni_vdev_state_to_str(vs->vs_state)); 163fbfd10ffStalley 164186d582bSSurya Prakki (void) xmlSetProp(pool, (xmlChar *)ATTR_DEVICE_STATUS, 165fbfd10ffStalley (xmlChar *)zjni_vdev_aux_to_str(vs->vs_aux)); 166fbfd10ffStalley 167186d582bSSurya Prakki (void) xmlSetProp(pool, (xmlChar *)ATTR_POOL_STATE, 168fbfd10ffStalley (xmlChar *)zjni_pool_state_to_str(state)); 169fbfd10ffStalley 170186d582bSSurya Prakki (void) xmlSetProp(pool, (xmlChar *)ATTR_POOL_STATUS, (xmlChar *) 171fbfd10ffStalley zjni_pool_status_to_str(zpool_import_status(config, &c))); 172fbfd10ffStalley 173c8e9ed14Stalley return (0); 174c8e9ed14Stalley } 175c8e9ed14Stalley 176fa9e4066Sahrens static xmlDocPtr 177fa9e4066Sahrens create_doc(void) 178fa9e4066Sahrens { 179fa9e4066Sahrens /* Create the XML document */ 180fa9e4066Sahrens xmlDocPtr doc = xmlNewDoc((xmlChar *)"1.0"); 181fa9e4066Sahrens 182fa9e4066Sahrens /* Create the root node */ 183fa9e4066Sahrens xmlNodePtr root = xmlNewDocNode( 184fa9e4066Sahrens doc, NULL, (xmlChar *)ELEMENT_ROOT, NULL); 185186d582bSSurya Prakki (void) xmlAddChild((xmlNodePtr) doc, (xmlNodePtr)root); 186fa9e4066Sahrens 187fa9e4066Sahrens return (doc); 188fa9e4066Sahrens } 189fa9e4066Sahrens 190fa9e4066Sahrens /* 191fa9e4066Sahrens * Main entry to availdisks. 192fa9e4066Sahrens * 193fa9e4066Sahrens * @return 0 on successful exit, non-zero otherwise 194fa9e4066Sahrens */ 195fa9e4066Sahrens int 196c8e9ed14Stalley main(int argc, char **argv) 197fa9e4066Sahrens { 198c8e9ed14Stalley int error = 0; 199c8e9ed14Stalley int get_pools = 0; 200c8e9ed14Stalley int get_devices = 0; 201fa9e4066Sahrens 202c8e9ed14Stalley /* Examine first arg */ 203c8e9ed14Stalley int c = getopt(argc, argv, CLI_OPTSTRING); 204c8e9ed14Stalley switch (c) { 205c8e9ed14Stalley case CLI_ARG_ALL: 206c8e9ed14Stalley get_devices = 1; 207c8e9ed14Stalley get_pools = 1; 208c8e9ed14Stalley break; 209c8e9ed14Stalley 210c8e9ed14Stalley case CLI_ARG_DEVICES: 211c8e9ed14Stalley get_devices = 1; 212c8e9ed14Stalley break; 213c8e9ed14Stalley 214c8e9ed14Stalley case CLI_ARG_POOLS: 215c8e9ed14Stalley get_pools = 1; 216c8e9ed14Stalley break; 217c8e9ed14Stalley 218c8e9ed14Stalley default: 219c8e9ed14Stalley return (1); 220c8e9ed14Stalley break; 221c8e9ed14Stalley } 222c8e9ed14Stalley 223c8e9ed14Stalley argc -= optind; 224c8e9ed14Stalley argv += optind; 225c8e9ed14Stalley 226c8e9ed14Stalley if (get_pools || get_devices) { 227c8e9ed14Stalley xmlDocPtr doc = create_doc(); 228c8e9ed14Stalley xmlNodePtr root = xmlDocGetRootElement(doc); 229c8e9ed14Stalley 230c8e9ed14Stalley if (get_devices) { 231c8e9ed14Stalley /* Create the available node */ 232c8e9ed14Stalley xmlNodePtr available = xmlNewChild(root, NULL, 233c8e9ed14Stalley (xmlChar *)ELEMENT_AVAILABLE, NULL); 234c8e9ed14Stalley 235c8e9ed14Stalley /* libzfs_jni_diskmgt.o error handler */ 236fa9e4066Sahrens dmgt_set_error_handler(handle_error); 237fa9e4066Sahrens 238c8e9ed14Stalley error = dmgt_avail_disk_iter( 239c8e9ed14Stalley add_disk_to_xml, &available); 240c8e9ed14Stalley } 241fa9e4066Sahrens 242c8e9ed14Stalley if (get_pools && !error) { 243c8e9ed14Stalley /* Create the importable node */ 244c8e9ed14Stalley xmlNodePtr importable = xmlNewChild(root, NULL, 245c8e9ed14Stalley (xmlChar *)ELEMENT_IMPORTABLE, NULL); 246c8e9ed14Stalley 247c8e9ed14Stalley error = zjni_ipool_iter( 248c8e9ed14Stalley argc, argv, add_pool_to_xml, &importable); 249c8e9ed14Stalley } 250c8e9ed14Stalley 251fa9e4066Sahrens if (!error) { 252fa9e4066Sahrens /* Print out XML */ 253186d582bSSurya Prakki (void) xmlDocFormatDump(stdout, doc, 1); 254fa9e4066Sahrens } 255fa9e4066Sahrens 256fa9e4066Sahrens xmlFreeDoc(doc); 257c8e9ed14Stalley } 258fa9e4066Sahrens 259fa9e4066Sahrens return (error != 0); 260fa9e4066Sahrens } 261