4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012 Milan Jurik. All rights reserved.
27 #include "availdevs.h"
29 #include <libzfs_jni_diskmgt.h>
30 #include <libzfs_jni_ipool.h>
31 #include <libxml/parser.h>
37 static void handle_error(const char *, va_list);
38 static void set_uint64_prop(xmlNodePtr
, const char *, uint64_t);
39 static int add_disk_to_xml(dmgt_disk_t
*, void *);
40 static int add_pool_to_xml(nvlist_t
*, void *);
41 static xmlDocPtr
create_doc();
49 handle_error(const char *fmt
, va_list ap
)
51 (void) vfprintf(stderr
, fmt
, ap
);
52 (void) fprintf(stderr
, "\n");
56 set_uint64_prop(xmlNodePtr node
, const char *attr
, uint64_t value
)
59 (void) snprintf(tmp
, sizeof (tmp
), "%llu", value
);
60 (void) xmlSetProp(node
, (xmlChar
*)attr
, (xmlChar
*)tmp
);
64 add_disk_to_xml(dmgt_disk_t
*dp
, void *data
)
67 xmlNodePtr available
= *((xmlNodePtr
*)data
);
69 xmlNodePtr disk
= xmlNewChild(
70 available
, NULL
, (xmlChar
*)ELEMENT_DISK
, NULL
);
71 (void) xmlSetProp(disk
,
72 (xmlChar
*)ATTR_DISK_NAME
, (xmlChar
*)dp
->name
);
74 set_uint64_prop(disk
, ATTR_DISK_SIZE
, dp
->size
);
76 (void) xmlSetProp(disk
, (xmlChar
*)ATTR_DISK_INUSE
, (xmlChar
*)
77 (dp
->in_use
? VAL_ATTR_TRUE
: VAL_ATTR_FALSE
));
79 if (dp
->aliases
!= NULL
) {
80 for (i
= 0; dp
->aliases
[i
] != NULL
; i
++) {
81 xmlNodePtr alias
= xmlNewChild(
82 disk
, NULL
, (xmlChar
*)ELEMENT_ALIAS
, NULL
);
83 (void) xmlSetProp(alias
,
84 (xmlChar
*)ATTR_ALIAS_NAME
,
85 (xmlChar
*)dp
->aliases
[i
]);
89 if (dp
->slices
!= NULL
) {
90 for (i
= 0; dp
->slices
[i
] != NULL
; i
++) {
91 dmgt_slice_t
*sp
= dp
->slices
[i
];
92 xmlNodePtr slice
= xmlNewChild(
93 disk
, NULL
, (xmlChar
*)ELEMENT_SLICE
, NULL
);
94 (void) xmlSetProp(slice
,
95 (xmlChar
*)ATTR_SLICE_NAME
, (xmlChar
*)sp
->name
);
97 set_uint64_prop(slice
, ATTR_SLICE_SIZE
, sp
->size
);
98 set_uint64_prop(slice
, ATTR_SLICE_START
, sp
->start
);
100 if (sp
->used_name
!= NULL
) {
101 (void) xmlSetProp(slice
,
102 (xmlChar
*)ATTR_SLICE_USED_NAME
,
103 (xmlChar
*)sp
->used_name
);
106 if (sp
->used_by
!= NULL
) {
107 (void) xmlSetProp(slice
,
108 (xmlChar
*)ATTR_SLICE_USED_BY
,
109 (xmlChar
*)sp
->used_by
);
118 add_pool_to_xml(nvlist_t
*config
, void *data
)
129 xmlNodePtr importable
= *((xmlNodePtr
*)data
);
131 if (nvlist_lookup_string(config
, ZPOOL_CONFIG_POOL_NAME
, &name
) ||
132 nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_GUID
, &guid
) ||
133 nvlist_lookup_uint64(config
, ZPOOL_CONFIG_VERSION
, &version
) ||
134 nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_STATE
, &state
) ||
135 nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
, &devices
) ||
136 nvlist_lookup_uint64_array(
137 devices
, ZPOOL_CONFIG_VDEV_STATS
, (uint64_t **)&vs
, &n
)) {
141 pool
= xmlNewChild(importable
, NULL
, (xmlChar
*)ELEMENT_POOL
, NULL
);
142 (void) xmlSetProp(pool
, (xmlChar
*)ATTR_POOL_NAME
, (xmlChar
*)name
);
144 set_uint64_prop(pool
, ATTR_POOL_ID
, guid
);
145 set_uint64_prop(pool
, ATTR_POOL_VERSION
, version
);
146 set_uint64_prop(pool
, ATTR_POOL_USED
, vs
->vs_alloc
);
147 set_uint64_prop(pool
, ATTR_POOL_SIZE
, vs
->vs_space
);
148 set_uint64_prop(pool
, ATTR_POOL_REPLACEMENT_SIZE
, vs
->vs_rsize
);
149 set_uint64_prop(pool
, ATTR_POOL_READ_BYTES
,
150 vs
->vs_bytes
[ZIO_TYPE_READ
]);
151 set_uint64_prop(pool
, ATTR_POOL_WRITE_BYTES
,
152 vs
->vs_bytes
[ZIO_TYPE_WRITE
]);
153 set_uint64_prop(pool
, ATTR_POOL_READ_OPERATIONS
,
154 vs
->vs_ops
[ZIO_TYPE_READ
]);
155 set_uint64_prop(pool
, ATTR_POOL_WRITE_OPERATIONS
,
156 vs
->vs_ops
[ZIO_TYPE_WRITE
]);
157 set_uint64_prop(pool
, ATTR_POOL_READ_ERRORS
, vs
->vs_read_errors
);
158 set_uint64_prop(pool
, ATTR_POOL_WRITE_ERRORS
, vs
->vs_write_errors
);
159 set_uint64_prop(pool
, ATTR_POOL_CHECKSUM_ERRORS
,
160 vs
->vs_checksum_errors
);
162 (void) xmlSetProp(pool
, (xmlChar
*)ATTR_DEVICE_STATE
,
163 (xmlChar
*)zjni_vdev_state_to_str(vs
->vs_state
));
165 (void) xmlSetProp(pool
, (xmlChar
*)ATTR_DEVICE_STATUS
,
166 (xmlChar
*)zjni_vdev_aux_to_str(vs
->vs_aux
));
168 (void) xmlSetProp(pool
, (xmlChar
*)ATTR_POOL_STATE
,
169 (xmlChar
*)zjni_pool_state_to_str(state
));
171 (void) xmlSetProp(pool
, (xmlChar
*)ATTR_POOL_STATUS
, (xmlChar
*)
172 zjni_pool_status_to_str(zpool_import_status(config
, &c
)));
180 /* Create the XML document */
181 xmlDocPtr doc
= xmlNewDoc((xmlChar
*)"1.0");
183 /* Create the root node */
184 xmlNodePtr root
= xmlNewDocNode(
185 doc
, NULL
, (xmlChar
*)ELEMENT_ROOT
, NULL
);
186 (void) xmlAddChild((xmlNodePtr
) doc
, (xmlNodePtr
)root
);
192 * Main entry to availdisks.
194 * @return 0 on successful exit, non-zero otherwise
197 main(int argc
, char **argv
)
203 /* Examine first arg */
204 int c
= getopt(argc
, argv
, CLI_OPTSTRING
);
211 case CLI_ARG_DEVICES
:
226 if (get_pools
|| get_devices
) {
227 xmlDocPtr doc
= create_doc();
228 xmlNodePtr root
= xmlDocGetRootElement(doc
);
231 /* Create the available node */
232 xmlNodePtr available
= xmlNewChild(root
, NULL
,
233 (xmlChar
*)ELEMENT_AVAILABLE
, NULL
);
235 /* libzfs_jni_diskmgt.o error handler */
236 dmgt_set_error_handler(handle_error
);
238 error
= dmgt_avail_disk_iter(
239 add_disk_to_xml
, &available
);
242 if (get_pools
&& !error
) {
243 /* Create the importable node */
244 xmlNodePtr importable
= xmlNewChild(root
, NULL
,
245 (xmlChar
*)ELEMENT_IMPORTABLE
, NULL
);
247 error
= zjni_ipool_iter(
248 argc
, argv
, add_pool_to_xml
, &importable
);
253 (void) xmlDocFormatDump(stdout
, doc
, 1);