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 /* 233f9d6ad7SLin Ling * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24*33f5ff17SMilan Jurik * Copyright 2012 Milan Jurik. All rights reserved. 25fa9e4066Sahrens */ 26fa9e4066Sahrens 27fa9e4066Sahrens #include "availdevs.h" 28fbfd10ffStalley #include <libzfs.h> 29fa9e4066Sahrens #include <libzfs_jni_diskmgt.h> 30c8e9ed14Stalley #include <libzfs_jni_ipool.h> 31fa9e4066Sahrens #include <libxml/parser.h> 32fa9e4066Sahrens 33fa9e4066Sahrens /* 34fa9e4066Sahrens * Function prototypes 35fa9e4066Sahrens */ 36fa9e4066Sahrens 37fa9e4066Sahrens static void handle_error(const char *, va_list); 38841f46edStalley static void set_uint64_prop(xmlNodePtr, const char *, uint64_t); 39fa9e4066Sahrens static int add_disk_to_xml(dmgt_disk_t *, void *); 40fbfd10ffStalley static int add_pool_to_xml(nvlist_t *, void *); 41fa9e4066Sahrens static xmlDocPtr create_doc(); 42fa9e4066Sahrens int main(); 43fa9e4066Sahrens 44fa9e4066Sahrens /* 45fa9e4066Sahrens * Static functions 46fa9e4066Sahrens */ 47fa9e4066Sahrens 48fa9e4066Sahrens static void 49fa9e4066Sahrens handle_error(const char *fmt, va_list ap) 50fa9e4066Sahrens { 51fa9e4066Sahrens (void) vfprintf(stderr, fmt, ap); 52fa9e4066Sahrens (void) fprintf(stderr, "\n"); 53fa9e4066Sahrens } 54fa9e4066Sahrens 55841f46edStalley static void 56841f46edStalley set_uint64_prop(xmlNodePtr node, const char *attr, uint64_t value) 57841f46edStalley { 58841f46edStalley static char tmp[64]; 59841f46edStalley (void) snprintf(tmp, sizeof (tmp), "%llu", value); 60186d582bSSurya Prakki (void) xmlSetProp(node, (xmlChar *)attr, (xmlChar *)tmp); 61841f46edStalley } 62841f46edStalley 63fa9e4066Sahrens static int 64fa9e4066Sahrens add_disk_to_xml(dmgt_disk_t *dp, void *data) 65fa9e4066Sahrens { 66c8e9ed14Stalley int i; 67fa9e4066Sahrens xmlNodePtr available = *((xmlNodePtr *)data); 68fa9e4066Sahrens 69fa9e4066Sahrens xmlNodePtr disk = xmlNewChild( 70fa9e4066Sahrens available, NULL, (xmlChar *)ELEMENT_DISK, NULL); 71186d582bSSurya Prakki (void) xmlSetProp(disk, 72fa9e4066Sahrens (xmlChar *)ATTR_DISK_NAME, (xmlChar *)dp->name); 73841f46edStalley 74841f46edStalley set_uint64_prop(disk, ATTR_DISK_SIZE, dp->size); 75fa9e4066Sahrens 76186d582bSSurya Prakki (void) xmlSetProp(disk, (xmlChar *)ATTR_DISK_INUSE, (xmlChar *) 77dc307942Stalley (dp->in_use ? VAL_ATTR_TRUE : VAL_ATTR_FALSE)); 78dc307942Stalley 79fa9e4066Sahrens if (dp->aliases != NULL) { 80fa9e4066Sahrens for (i = 0; dp->aliases[i] != NULL; i++) { 81fa9e4066Sahrens xmlNodePtr alias = xmlNewChild( 82fa9e4066Sahrens disk, NULL, (xmlChar *)ELEMENT_ALIAS, NULL); 83186d582bSSurya Prakki (void) xmlSetProp(alias, 84fa9e4066Sahrens (xmlChar *)ATTR_ALIAS_NAME, 85fa9e4066Sahrens (xmlChar *)dp->aliases[i]); 86fa9e4066Sahrens } 87fa9e4066Sahrens } 88fa9e4066Sahrens 89fa9e4066Sahrens if (dp->slices != NULL) { 90fa9e4066Sahrens for (i = 0; dp->slices[i] != NULL; i++) { 91fa9e4066Sahrens dmgt_slice_t *sp = dp->slices[i]; 92fa9e4066Sahrens xmlNodePtr slice = xmlNewChild( 93fa9e4066Sahrens disk, NULL, (xmlChar *)ELEMENT_SLICE, NULL); 94186d582bSSurya Prakki (void) xmlSetProp(slice, 95fa9e4066Sahrens (xmlChar *)ATTR_SLICE_NAME, (xmlChar *)sp->name); 96fa9e4066Sahrens 97841f46edStalley set_uint64_prop(slice, ATTR_SLICE_SIZE, sp->size); 98841f46edStalley set_uint64_prop(slice, ATTR_SLICE_START, sp->start); 99fa9e4066Sahrens 100fa9e4066Sahrens if (sp->used_name != NULL) { 101186d582bSSurya Prakki (void) xmlSetProp(slice, 102fa9e4066Sahrens (xmlChar *)ATTR_SLICE_USED_NAME, 103fa9e4066Sahrens (xmlChar *)sp->used_name); 104fa9e4066Sahrens } 105fa9e4066Sahrens 106fa9e4066Sahrens if (sp->used_by != NULL) { 107186d582bSSurya Prakki (void) xmlSetProp(slice, 108186d582bSSurya Prakki (xmlChar *)ATTR_SLICE_USED_BY, 109fa9e4066Sahrens (xmlChar *)sp->used_by); 110fa9e4066Sahrens } 111fa9e4066Sahrens } 112fa9e4066Sahrens } 113fa9e4066Sahrens 114fa9e4066Sahrens return (0); 115fa9e4066Sahrens } 116fa9e4066Sahrens 117c8e9ed14Stalley static int 118fbfd10ffStalley add_pool_to_xml(nvlist_t *config, void *data) 119c8e9ed14Stalley { 120fbfd10ffStalley char *c; 121fbfd10ffStalley char *name; 122fbfd10ffStalley uint64_t guid; 123a55b6846Scristian uint64_t version; 124fbfd10ffStalley uint64_t state; 125fbfd10ffStalley nvlist_t *devices; 126fbfd10ffStalley uint_t n; 127fbfd10ffStalley vdev_stat_t *vs; 128fbfd10ffStalley xmlNodePtr pool; 129c8e9ed14Stalley xmlNodePtr importable = *((xmlNodePtr *)data); 130c8e9ed14Stalley 131fbfd10ffStalley if (nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &name) || 132fbfd10ffStalley nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) || 133a55b6846Scristian nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) || 134fbfd10ffStalley nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, &state) || 135fbfd10ffStalley nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &devices) || 136fbfd10ffStalley nvlist_lookup_uint64_array( 1373f9d6ad7SLin Ling devices, ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &n)) { 138fbfd10ffStalley return (-1); 139c8e9ed14Stalley } 140fbfd10ffStalley 141fbfd10ffStalley pool = xmlNewChild(importable, NULL, (xmlChar *)ELEMENT_POOL, NULL); 142186d582bSSurya Prakki (void) xmlSetProp(pool, (xmlChar *)ATTR_POOL_NAME, (xmlChar *)name); 143c8e9ed14Stalley 144841f46edStalley set_uint64_prop(pool, ATTR_POOL_ID, guid); 145a55b6846Scristian set_uint64_prop(pool, ATTR_POOL_VERSION, version); 146841f46edStalley set_uint64_prop(pool, ATTR_POOL_USED, vs->vs_alloc); 147841f46edStalley set_uint64_prop(pool, ATTR_POOL_SIZE, vs->vs_space); 148841f46edStalley set_uint64_prop(pool, ATTR_POOL_REPLACEMENT_SIZE, vs->vs_rsize); 149841f46edStalley set_uint64_prop(pool, ATTR_POOL_READ_BYTES, 150841f46edStalley vs->vs_bytes[ZIO_TYPE_READ]); 151841f46edStalley set_uint64_prop(pool, ATTR_POOL_WRITE_BYTES, 152fbfd10ffStalley vs->vs_bytes[ZIO_TYPE_WRITE]); 153841f46edStalley set_uint64_prop(pool, ATTR_POOL_READ_OPERATIONS, 154841f46edStalley vs->vs_ops[ZIO_TYPE_READ]); 155841f46edStalley set_uint64_prop(pool, ATTR_POOL_WRITE_OPERATIONS, 156841f46edStalley vs->vs_ops[ZIO_TYPE_WRITE]); 157841f46edStalley set_uint64_prop(pool, ATTR_POOL_READ_ERRORS, vs->vs_read_errors); 158841f46edStalley set_uint64_prop(pool, ATTR_POOL_WRITE_ERRORS, vs->vs_write_errors); 159841f46edStalley set_uint64_prop(pool, ATTR_POOL_CHECKSUM_ERRORS, 160841f46edStalley vs->vs_checksum_errors); 161fbfd10ffStalley 162186d582bSSurya Prakki (void) xmlSetProp(pool, (xmlChar *)ATTR_DEVICE_STATE, 163fbfd10ffStalley (xmlChar *)zjni_vdev_state_to_str(vs->vs_state)); 164fbfd10ffStalley 165186d582bSSurya Prakki (void) xmlSetProp(pool, (xmlChar *)ATTR_DEVICE_STATUS, 166fbfd10ffStalley (xmlChar *)zjni_vdev_aux_to_str(vs->vs_aux)); 167fbfd10ffStalley 168186d582bSSurya Prakki (void) xmlSetProp(pool, (xmlChar *)ATTR_POOL_STATE, 169fbfd10ffStalley (xmlChar *)zjni_pool_state_to_str(state)); 170fbfd10ffStalley 171186d582bSSurya Prakki (void) xmlSetProp(pool, (xmlChar *)ATTR_POOL_STATUS, (xmlChar *) 172fbfd10ffStalley zjni_pool_status_to_str(zpool_import_status(config, &c))); 173fbfd10ffStalley 174c8e9ed14Stalley return (0); 175c8e9ed14Stalley } 176c8e9ed14Stalley 177fa9e4066Sahrens static xmlDocPtr 178fa9e4066Sahrens create_doc(void) 179fa9e4066Sahrens { 180fa9e4066Sahrens /* Create the XML document */ 181fa9e4066Sahrens xmlDocPtr doc = xmlNewDoc((xmlChar *)"1.0"); 182fa9e4066Sahrens 183fa9e4066Sahrens /* Create the root node */ 184fa9e4066Sahrens xmlNodePtr root = xmlNewDocNode( 185fa9e4066Sahrens doc, NULL, (xmlChar *)ELEMENT_ROOT, NULL); 186186d582bSSurya Prakki (void) xmlAddChild((xmlNodePtr) doc, (xmlNodePtr)root); 187fa9e4066Sahrens 188fa9e4066Sahrens return (doc); 189fa9e4066Sahrens } 190fa9e4066Sahrens 191fa9e4066Sahrens /* 192fa9e4066Sahrens * Main entry to availdisks. 193fa9e4066Sahrens * 194fa9e4066Sahrens * @return 0 on successful exit, non-zero otherwise 195fa9e4066Sahrens */ 196fa9e4066Sahrens int 197c8e9ed14Stalley main(int argc, char **argv) 198fa9e4066Sahrens { 199c8e9ed14Stalley int error = 0; 200c8e9ed14Stalley int get_pools = 0; 201c8e9ed14Stalley int get_devices = 0; 202fa9e4066Sahrens 203c8e9ed14Stalley /* Examine first arg */ 204c8e9ed14Stalley int c = getopt(argc, argv, CLI_OPTSTRING); 205c8e9ed14Stalley switch (c) { 206c8e9ed14Stalley case CLI_ARG_ALL: 207c8e9ed14Stalley get_devices = 1; 208c8e9ed14Stalley get_pools = 1; 209c8e9ed14Stalley break; 210c8e9ed14Stalley 211c8e9ed14Stalley case CLI_ARG_DEVICES: 212c8e9ed14Stalley get_devices = 1; 213c8e9ed14Stalley break; 214c8e9ed14Stalley 215c8e9ed14Stalley case CLI_ARG_POOLS: 216c8e9ed14Stalley get_pools = 1; 217c8e9ed14Stalley break; 218c8e9ed14Stalley 219c8e9ed14Stalley default: 220c8e9ed14Stalley return (1); 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