1fa9e4066Sahrens /* 2fa9e4066Sahrens * CDDL HEADER START 3fa9e4066Sahrens * 4fa9e4066Sahrens * The contents of this file are subject to the terms of the 5fa9e4066Sahrens * Common Development and Distribution License, Version 1.0 only 6fa9e4066Sahrens * (the "License"). You may not use this file except in compliance 7fa9e4066Sahrens * with the License. 8fa9e4066Sahrens * 9fa9e4066Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10fa9e4066Sahrens * or http://www.opensolaris.org/os/licensing. 11fa9e4066Sahrens * See the License for the specific language governing permissions 12fa9e4066Sahrens * and limitations under the License. 13fa9e4066Sahrens * 14fa9e4066Sahrens * When distributing Covered Code, include this CDDL HEADER in each 15fa9e4066Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16fa9e4066Sahrens * If applicable, add the following below this CDDL HEADER, with the 17fa9e4066Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 18fa9e4066Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 19fa9e4066Sahrens * 20fa9e4066Sahrens * CDDL HEADER END 21fa9e4066Sahrens */ 22fa9e4066Sahrens /* 23fbfd10ffStalley * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24fa9e4066Sahrens * Use is subject to license terms. 25fa9e4066Sahrens */ 26fa9e4066Sahrens 27fa9e4066Sahrens #pragma ident "%Z%%M% %I% %E% SMI" 28fa9e4066Sahrens 29fa9e4066Sahrens #include "availdevs.h" 30fbfd10ffStalley #include <libzfs.h> 31fa9e4066Sahrens #include <libzfs_jni_diskmgt.h> 32c8e9ed14Stalley #include <libzfs_jni_ipool.h> 33fa9e4066Sahrens #include <libxml/parser.h> 34fa9e4066Sahrens 35fa9e4066Sahrens /* 36fa9e4066Sahrens * Function prototypes 37fa9e4066Sahrens */ 38fa9e4066Sahrens 39fa9e4066Sahrens static void handle_error(const char *, va_list); 40*841f46edStalley static void set_uint64_prop(xmlNodePtr, const char *, uint64_t); 41fa9e4066Sahrens static int add_disk_to_xml(dmgt_disk_t *, void *); 42fbfd10ffStalley static int add_pool_to_xml(nvlist_t *, void *); 43fa9e4066Sahrens static xmlDocPtr create_doc(); 44fa9e4066Sahrens int main(); 45fa9e4066Sahrens 46fa9e4066Sahrens /* 47fa9e4066Sahrens * Static functions 48fa9e4066Sahrens */ 49fa9e4066Sahrens 50fa9e4066Sahrens static void 51fa9e4066Sahrens handle_error(const char *fmt, va_list ap) 52fa9e4066Sahrens { 53fa9e4066Sahrens (void) vfprintf(stderr, fmt, ap); 54fa9e4066Sahrens (void) fprintf(stderr, "\n"); 55fa9e4066Sahrens } 56fa9e4066Sahrens 57*841f46edStalley static void 58*841f46edStalley set_uint64_prop(xmlNodePtr node, const char *attr, uint64_t value) 59*841f46edStalley { 60*841f46edStalley static char tmp[64]; 61*841f46edStalley (void) snprintf(tmp, sizeof (tmp), "%llu", value); 62*841f46edStalley xmlSetProp(node, (xmlChar *)attr, (xmlChar *)tmp); 63*841f46edStalley } 64*841f46edStalley 65fa9e4066Sahrens static int 66fa9e4066Sahrens add_disk_to_xml(dmgt_disk_t *dp, void *data) 67fa9e4066Sahrens { 68c8e9ed14Stalley int i; 69fa9e4066Sahrens xmlNodePtr available = *((xmlNodePtr *)data); 70fa9e4066Sahrens 71fa9e4066Sahrens xmlNodePtr disk = xmlNewChild( 72fa9e4066Sahrens available, NULL, (xmlChar *)ELEMENT_DISK, NULL); 73fa9e4066Sahrens xmlSetProp(disk, 74fa9e4066Sahrens (xmlChar *)ATTR_DISK_NAME, (xmlChar *)dp->name); 75*841f46edStalley 76*841f46edStalley set_uint64_prop(disk, ATTR_DISK_SIZE, dp->size); 77fa9e4066Sahrens 78dc307942Stalley xmlSetProp(disk, (xmlChar *)ATTR_DISK_INUSE, (xmlChar *) 79dc307942Stalley (dp->in_use ? VAL_ATTR_TRUE : VAL_ATTR_FALSE)); 80dc307942Stalley 81fa9e4066Sahrens if (dp->aliases != NULL) { 82fa9e4066Sahrens for (i = 0; dp->aliases[i] != NULL; i++) { 83fa9e4066Sahrens xmlNodePtr alias = xmlNewChild( 84fa9e4066Sahrens disk, NULL, (xmlChar *)ELEMENT_ALIAS, NULL); 85fa9e4066Sahrens xmlSetProp(alias, 86fa9e4066Sahrens (xmlChar *)ATTR_ALIAS_NAME, 87fa9e4066Sahrens (xmlChar *)dp->aliases[i]); 88fa9e4066Sahrens } 89fa9e4066Sahrens } 90fa9e4066Sahrens 91fa9e4066Sahrens if (dp->slices != NULL) { 92fa9e4066Sahrens for (i = 0; dp->slices[i] != NULL; i++) { 93fa9e4066Sahrens dmgt_slice_t *sp = dp->slices[i]; 94fa9e4066Sahrens xmlNodePtr slice = xmlNewChild( 95fa9e4066Sahrens disk, NULL, (xmlChar *)ELEMENT_SLICE, NULL); 96fa9e4066Sahrens xmlSetProp(slice, 97fa9e4066Sahrens (xmlChar *)ATTR_SLICE_NAME, (xmlChar *)sp->name); 98fa9e4066Sahrens 99*841f46edStalley set_uint64_prop(slice, ATTR_SLICE_SIZE, sp->size); 100*841f46edStalley set_uint64_prop(slice, ATTR_SLICE_START, sp->start); 101fa9e4066Sahrens 102fa9e4066Sahrens if (sp->used_name != NULL) { 103fa9e4066Sahrens xmlSetProp(slice, 104fa9e4066Sahrens (xmlChar *)ATTR_SLICE_USED_NAME, 105fa9e4066Sahrens (xmlChar *)sp->used_name); 106fa9e4066Sahrens } 107fa9e4066Sahrens 108fa9e4066Sahrens if (sp->used_by != NULL) { 109fa9e4066Sahrens xmlSetProp(slice, (xmlChar *)ATTR_SLICE_USED_BY, 110fa9e4066Sahrens (xmlChar *)sp->used_by); 111fa9e4066Sahrens } 112fa9e4066Sahrens } 113fa9e4066Sahrens } 114fa9e4066Sahrens 115fa9e4066Sahrens return (0); 116fa9e4066Sahrens } 117fa9e4066Sahrens 118c8e9ed14Stalley static int 119fbfd10ffStalley add_pool_to_xml(nvlist_t *config, void *data) 120c8e9ed14Stalley { 121fbfd10ffStalley char *c; 122fbfd10ffStalley char *name; 123fbfd10ffStalley uint64_t guid; 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) || 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( 136fbfd10ffStalley devices, ZPOOL_CONFIG_STATS, (uint64_t **)&vs, &n)) { 137fbfd10ffStalley return (-1); 138c8e9ed14Stalley } 139fbfd10ffStalley 140fbfd10ffStalley pool = xmlNewChild(importable, NULL, (xmlChar *)ELEMENT_POOL, NULL); 141fbfd10ffStalley xmlSetProp(pool, (xmlChar *)ATTR_POOL_NAME, (xmlChar *)name); 142c8e9ed14Stalley 143*841f46edStalley set_uint64_prop(pool, ATTR_POOL_ID, guid); 144*841f46edStalley set_uint64_prop(pool, ATTR_POOL_USED, vs->vs_alloc); 145*841f46edStalley set_uint64_prop(pool, ATTR_POOL_SIZE, vs->vs_space); 146*841f46edStalley set_uint64_prop(pool, ATTR_POOL_REPLACEMENT_SIZE, vs->vs_rsize); 147*841f46edStalley set_uint64_prop(pool, ATTR_POOL_READ_BYTES, 148*841f46edStalley vs->vs_bytes[ZIO_TYPE_READ]); 149*841f46edStalley set_uint64_prop(pool, ATTR_POOL_WRITE_BYTES, 150fbfd10ffStalley vs->vs_bytes[ZIO_TYPE_WRITE]); 151*841f46edStalley set_uint64_prop(pool, ATTR_POOL_READ_OPERATIONS, 152*841f46edStalley vs->vs_ops[ZIO_TYPE_READ]); 153*841f46edStalley set_uint64_prop(pool, ATTR_POOL_WRITE_OPERATIONS, 154*841f46edStalley vs->vs_ops[ZIO_TYPE_WRITE]); 155*841f46edStalley set_uint64_prop(pool, ATTR_POOL_READ_ERRORS, vs->vs_read_errors); 156*841f46edStalley set_uint64_prop(pool, ATTR_POOL_WRITE_ERRORS, vs->vs_write_errors); 157*841f46edStalley set_uint64_prop(pool, ATTR_POOL_CHECKSUM_ERRORS, 158*841f46edStalley vs->vs_checksum_errors); 159fbfd10ffStalley 160fbfd10ffStalley xmlSetProp(pool, (xmlChar *)ATTR_DEVICE_STATE, 161fbfd10ffStalley (xmlChar *)zjni_vdev_state_to_str(vs->vs_state)); 162fbfd10ffStalley 163fbfd10ffStalley xmlSetProp(pool, (xmlChar *)ATTR_DEVICE_STATUS, 164fbfd10ffStalley (xmlChar *)zjni_vdev_aux_to_str(vs->vs_aux)); 165fbfd10ffStalley 166fbfd10ffStalley xmlSetProp(pool, (xmlChar *)ATTR_POOL_STATE, 167fbfd10ffStalley (xmlChar *)zjni_pool_state_to_str(state)); 168fbfd10ffStalley 169fbfd10ffStalley xmlSetProp(pool, (xmlChar *)ATTR_POOL_STATUS, (xmlChar *) 170fbfd10ffStalley zjni_pool_status_to_str(zpool_import_status(config, &c))); 171fbfd10ffStalley 172c8e9ed14Stalley return (0); 173c8e9ed14Stalley } 174c8e9ed14Stalley 175fa9e4066Sahrens static xmlDocPtr 176fa9e4066Sahrens create_doc(void) 177fa9e4066Sahrens { 178fa9e4066Sahrens /* Create the XML document */ 179fa9e4066Sahrens xmlDocPtr doc = xmlNewDoc((xmlChar *)"1.0"); 180fa9e4066Sahrens 181fa9e4066Sahrens /* Create the root node */ 182fa9e4066Sahrens xmlNodePtr root = xmlNewDocNode( 183fa9e4066Sahrens doc, NULL, (xmlChar *)ELEMENT_ROOT, NULL); 184fa9e4066Sahrens xmlAddChild((xmlNodePtr) doc, (xmlNodePtr)root); 185fa9e4066Sahrens 186fa9e4066Sahrens return (doc); 187fa9e4066Sahrens } 188fa9e4066Sahrens 189fa9e4066Sahrens /* 190fa9e4066Sahrens * Main entry to availdisks. 191fa9e4066Sahrens * 192fa9e4066Sahrens * @return 0 on successful exit, non-zero otherwise 193fa9e4066Sahrens */ 194fa9e4066Sahrens int 195c8e9ed14Stalley main(int argc, char **argv) 196fa9e4066Sahrens { 197c8e9ed14Stalley int error = 0; 198c8e9ed14Stalley int get_pools = 0; 199c8e9ed14Stalley int get_devices = 0; 200fa9e4066Sahrens 201c8e9ed14Stalley /* Examine first arg */ 202c8e9ed14Stalley int c = getopt(argc, argv, CLI_OPTSTRING); 203c8e9ed14Stalley switch (c) { 204c8e9ed14Stalley case CLI_ARG_ALL: 205c8e9ed14Stalley get_devices = 1; 206c8e9ed14Stalley get_pools = 1; 207c8e9ed14Stalley break; 208c8e9ed14Stalley 209c8e9ed14Stalley case CLI_ARG_DEVICES: 210c8e9ed14Stalley get_devices = 1; 211c8e9ed14Stalley break; 212c8e9ed14Stalley 213c8e9ed14Stalley case CLI_ARG_POOLS: 214c8e9ed14Stalley get_pools = 1; 215c8e9ed14Stalley break; 216c8e9ed14Stalley 217c8e9ed14Stalley default: 218c8e9ed14Stalley return (1); 219c8e9ed14Stalley break; 220c8e9ed14Stalley } 221c8e9ed14Stalley 222c8e9ed14Stalley argc -= optind; 223c8e9ed14Stalley argv += optind; 224c8e9ed14Stalley 225c8e9ed14Stalley if (get_pools || get_devices) { 226c8e9ed14Stalley xmlDocPtr doc = create_doc(); 227c8e9ed14Stalley xmlNodePtr root = xmlDocGetRootElement(doc); 228c8e9ed14Stalley 229c8e9ed14Stalley if (get_devices) { 230c8e9ed14Stalley /* Create the available node */ 231c8e9ed14Stalley xmlNodePtr available = xmlNewChild(root, NULL, 232c8e9ed14Stalley (xmlChar *)ELEMENT_AVAILABLE, NULL); 233c8e9ed14Stalley 234c8e9ed14Stalley /* libzfs_jni_diskmgt.o error handler */ 235fa9e4066Sahrens dmgt_set_error_handler(handle_error); 236fa9e4066Sahrens 237c8e9ed14Stalley error = dmgt_avail_disk_iter( 238c8e9ed14Stalley add_disk_to_xml, &available); 239c8e9ed14Stalley } 240fa9e4066Sahrens 241c8e9ed14Stalley if (get_pools && !error) { 242c8e9ed14Stalley /* Create the importable node */ 243c8e9ed14Stalley xmlNodePtr importable = xmlNewChild(root, NULL, 244c8e9ed14Stalley (xmlChar *)ELEMENT_IMPORTABLE, NULL); 245c8e9ed14Stalley 246c8e9ed14Stalley error = zjni_ipool_iter( 247c8e9ed14Stalley argc, argv, add_pool_to_xml, &importable); 248c8e9ed14Stalley } 249c8e9ed14Stalley 250fa9e4066Sahrens if (!error) { 251fa9e4066Sahrens /* Print out XML */ 252fa9e4066Sahrens xmlDocFormatDump(stdout, doc, 1); 253fa9e4066Sahrens } 254fa9e4066Sahrens 255fa9e4066Sahrens xmlFreeDoc(doc); 256c8e9ed14Stalley } 257fa9e4066Sahrens 258fa9e4066Sahrens return (error != 0); 259fa9e4066Sahrens } 260