4998 add libdiskmgt spec as block comment
[unleashed.git] / usr / src / lib / libdiskmgt / common / libdiskmgt.h
blob2c42f6e8cc6cb9bb11395e2cf86d67746becbd7a
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
27 #ifndef _LIBDISKMGT_H
28 #define _LIBDISKMGT_H
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
34 #include <libnvpair.h>
35 #include <sys/swap.h>
39 * Disk Management Library
41 * This library provides a common way to gather information about a system's
42 * disks, controllers, and related components.
45 * THREADS
46 * -------
48 * In general all of the functions are thread safe, however there are some
49 * specific considerations for getting events. The dm_get_event function may
50 * block the calling thread if no event is currently available. If another
51 * thread calls dm_get_event while a thread is already blocked in this function,
52 * the second thread will also block. When an event arrives and multiple
53 * threads are waiting for events, it is undefined which thread will be
54 * unblocked and receive the event. If a callback is used for handling events,
55 * this is equivalent to the dm_get_event function, so mixing callbacks and
56 * dm_get_event is also nondeterministic.
59 * ERRORS
60 * ------
62 * In general all of the functions take an errno pointer. This is an integer
63 * that will contain 0 if the function succeeded or contains an errno (see
64 * errno.h) if there was an error. If the function returns some data, that
65 * return data will generally be null if an error occured (see the API comment
66 * for the specific function for details). Many of the functions take a
67 * descriptor and provide more information for that descriptor. These functions
68 * may return an error if the object was removed between the call which obtained
69 * the descriptor and the call to get more information about the object (errno
70 * will be ENODEV). Only a few of the possible errno values will be returned;
71 * typically:
72 * EPERM not super-user
73 * ENOMEM not enough memory
74 * ENODEV no such device
75 * EINVAL invalid argument
76 * ENOENT no event queue has been created
78 * Many of the functions require the application to be running as root in order
79 * to get complete information. EPERM will be returned if the application is
80 * not running as root. However, not all of the functions have this requirement
81 * (i.e. event handling).
83 * It is possible for the system to run out of memory while receiving events.
84 * Since event receipt is asyncronous from the dm_get_event call there may not
85 * be a thread waiting when the event occurs and ENOMEM is detected. In this
86 * case the event will be lost. The first call to dm_get_event following this
87 * condition will immediately return ENOMEM, even if events are queued.
88 * Subsequent calls can return events. The dm_get_event call will clear the
89 * pending ENOMEM condition. There is no way to know how many events were lost
90 * when this situation occurs. If a thread is waiting when the event arrives
91 * and the ENOMEM condition occurs, the call will also return with ENOMEM.
92 * There is no way to determine if the system ran out of memory before the
93 * dm_get_event call or while the thread was blocked in the dm_get_event call
94 * since both conditions cause dm_get_event to return ENOMEM.
97 * MEMORY MANAGEMENT
98 * -----------------
100 * Most of the functions that return data are returning memory that has been
101 * allocated and must be freed by the application when no longer needed. The
102 * application should call the proper free function to free the memory. Most of
103 * the functions return either a nvlist or an array of descriptors. The normal
104 * nvlist function (nvlist_free; see libnvpair(3LIB)) can be used to free the
105 * simple nvlists. Other functions are provided to free the more complex data
106 * structures.
108 * The following list shows the functions that return allocated memory and the
109 * corresponding function to free the memory:
110 * dm_get_descriptors dm_free_descriptors
111 * dm_get_associated_descriptors dm_free_descriptors
112 * dm_get_descriptor_by_name dm_free_descriptor
113 * dm_get_name dm_free_name
114 * dm_get_attributes nvlist_free
115 * dm_get_stats nvlist_free
116 * dm_get_event nvlist_free
119 * EVENTS
120 * ------
122 * Event information is returned as a nvlist. It may be possible to return more
123 * information about events over time, especially information about what has
124 * changed. However, that may not always be the case, so by using an nvlist we
125 * have a very generic event indication. At a minimum the event will return the
126 * name of the device, the type of device (see dm_desc_type_t) and the type of
127 * event. The event type is a string which can currently be; add, remove,
128 * change.
130 * If a drive goes up or down this could be returned as event type "change".
131 * The application could get the drive information to see that the "status"
132 * attribute has changed value (ideally the event would include an attribute
133 * with the name of the changed attribute as the value). Although the API can
134 * return events for all drive related changes, events will not necessarily be
135 * delivered for all changes unless the system generates those events.
138 * Controller/HBAs
139 * ---------------
141 * In general the API means "the parent node of the drive in the device tree"
142 * where the word "controller" is used. This can actually be either the HBA or
143 * the drive controller depending on the type of the drive.
145 * Drives can be connected to their controller(s) in three different ways:
146 * single controller
147 * multiple controllers
148 * multiple controllers with mpxio
149 * These cases will lead to different information being available for the
150 * configuration. The two interesting cases are multi-path with and without
151 * mpxio. With mpxio the drive will have a unique name and a single controller
152 * (scsi_vhci). The physical controllers, the paths to the drive, can be
153 * obtained by calling dm_get_associated_descriptors with a drive descriptor and
154 * a type of DM_PATH. This will only return these physical paths when MPXIO, or
155 * possibly some future similar feature, is controlling the drive.
157 * Without mpxio the drive does not have a unique public name (in all cases the
158 * alias(es) of the drive can be determined by calling
159 * dm_get_associated_descriptors to get the DM_ALIAS descriptors. There will be
160 * more than one controller returned from dm_get_associated_descriptors when
161 * called with a type of DM_CONTROLLER. The controllers for each of the aliases
162 * will be returned in the same order as the aliases descriptors. For example,
163 * a drive with two paths has the aliases c5t3d2 and c7t1d0. There will be two
164 * controllers returned; the first corresponds to c5 and the second corresponds
165 * to c7.
167 * In the multi-path, non-mpxio case the drive has more than one alias.
168 * Although most of the drive attributes are represented on the drive (see
169 * dm_get_attributes) there can be some different attributes for the different
170 * aliases for the drive. Use dm_get_associated_descriptors to get the DM_ALIAS
171 * descriptors which can then be used to obtain these attributes. Use of this
172 * algorithm is not restricted to the multi-path, non-mpxio case. For example,
173 * it can be used to get the target/lun for a SCSI drive with a single path.
177 * Holds all the data regarding the device.
178 * Private to libdiskmgt. Must use dm_xxx functions to set/get data.
180 typedef uint64_t dm_descriptor_t;
182 typedef enum {
183 DM_WHO_MKFS = 0,
184 DM_WHO_ZPOOL,
185 DM_WHO_ZPOOL_FORCE,
186 DM_WHO_FORMAT,
187 DM_WHO_SWAP,
188 DM_WHO_DUMP,
189 DM_WHO_ZPOOL_SPARE
190 } dm_who_type_t;
193 * The API uses a "descriptor" to identify the managed objects such as drives,
194 * controllers, media, slices, partitions, paths and buses. The descriptors are
195 * opaque and are only returned or used as parameters to the other functions in
196 * the API. The descriptor definition is a typedef to dm_descriptor_t.
198 * Applications call either the dm_get_descriptors or
199 * dm_get_associated_descriptors function to obtain a list of descriptors of a
200 * specific type. The application specifies the desired type from the following
201 * enumeration:
203 typedef enum {
204 DM_DRIVE = 0,
205 DM_CONTROLLER,
206 DM_MEDIA,
207 DM_SLICE,
208 DM_PARTITION,
209 DM_PATH,
210 DM_ALIAS,
211 DM_BUS
212 } dm_desc_type_t;
215 * These descriptors are associated with each other in the following way:
217 * alias partition
218 * _ \ / |
219 * / \ \ / |
220 * \ / \ / |
221 * bus --- controller --- drive --- media |
222 * | / \ |
223 * | / \ |
224 * | / \ |
225 * path slice
227 * The dm_get_associated_descriptors function can be used get the descriptors
228 * associated with a given descriptor. The dm_get_associated_types function can
229 * be used to find the types that can be associated with a given type.
231 * The attributes and values for these objects are described using a list of
232 * name/value pairs (see libnvpair(3LIB) and the specific comments for each
233 * function in the API section of this document).
235 * Drives and media have a type which are defined as the following enumerations.
236 * There could be additional types added to these enumerations as new drive and
237 * media types are supported by the system.
240 typedef enum {
241 DM_DT_UNKNOWN = 0,
242 DM_DT_FIXED,
243 DM_DT_ZIP,
244 DM_DT_JAZ,
245 DM_DT_FLOPPY,
246 DM_DT_MO_ERASABLE,
247 DM_DT_MO_WRITEONCE,
248 DM_DT_AS_MO,
249 DM_DT_CDROM,
250 DM_DT_CDR,
251 DM_DT_CDRW,
252 DM_DT_DVDROM,
253 DM_DT_DVDR,
254 DM_DT_DVDRAM,
255 DM_DT_DVDRW,
256 DM_DT_DDCDROM,
257 DM_DT_DDCDR,
258 DM_DT_DDCDRW
259 } dm_drive_type_t;
261 typedef enum {
262 DM_MT_UNKNOWN = 0,
263 DM_MT_FIXED,
264 DM_MT_FLOPPY,
265 DM_MT_CDROM,
266 DM_MT_ZIP,
267 DM_MT_JAZ,
268 DM_MT_CDR,
269 DM_MT_CDRW,
270 DM_MT_DVDROM,
271 DM_MT_DVDR,
272 DM_MT_DVDRAM,
273 DM_MT_MO_ERASABLE,
274 DM_MT_MO_WRITEONCE,
275 DM_MT_AS_MO
276 } dm_media_type_t;
278 #define DM_FILTER_END -1
281 * The dm_get_stats function takes a stat_type argument for the specific sample
282 * to get for the descriptor. The following enums specify the drive and slice
283 * stat types.
285 /* drive stat name */
286 typedef enum {
287 DM_DRV_STAT_PERFORMANCE = 0,
288 DM_DRV_STAT_DIAGNOSTIC,
289 DM_DRV_STAT_TEMPERATURE
290 } dm_drive_stat_t;
292 /* slice stat name */
293 typedef enum {
294 DM_SLICE_STAT_USE = 0
295 } dm_slice_stat_t;
297 /* partition type */
298 typedef enum {
299 DM_PRIMARY = 0,
300 DM_EXTENDED,
301 DM_LOGICAL
302 } dm_partition_type_t;
304 /* attribute definitions */
306 /* drive */
307 #define DM_DISK_UP 1
308 #define DM_DISK_DOWN 0
310 #define DM_CLUSTERED "clustered"
311 #define DM_DRVTYPE "drvtype"
312 #define DM_FAILING "failing"
313 #define DM_LOADED "loaded" /* also in media */
314 #define DM_NDNRERRS "ndevice_not_ready_errors"
315 #define DM_NBYTESREAD "nbytes_read"
316 #define DM_NBYTESWRITTEN "nbytes_written"
317 #define DM_NHARDERRS "nhard_errors"
318 #define DM_NILLREQERRS "nillegal_req_errors"
319 #define DM_NMEDIAERRS "nmedia_errors"
320 #define DM_NNODEVERRS "nno_dev_errors"
321 #define DM_NREADOPS "nread_ops"
322 #define DM_NRECOVERRS "nrecoverable_errors"
323 #define DM_NSOFTERRS "nsoft_errors"
324 #define DM_NTRANSERRS "ntransport_errors"
325 #define DM_NWRITEOPS "nwrite_ops"
326 #define DM_OPATH "opath"
327 #define DM_PRODUCT_ID "product_id"
328 #define DM_REMOVABLE "removable" /* also in media */
329 #define DM_RPM "rpm"
330 #define DM_SOLIDSTATE "solid_state"
331 #define DM_STATUS "status"
332 #define DM_SYNC_SPEED "sync_speed"
333 #define DM_TEMPERATURE "temperature"
334 #define DM_VENDOR_ID "vendor_id"
335 #define DM_WIDE "wide" /* also on controller */
336 #define DM_WWN "wwn"
338 /* bus */
339 #define DM_BTYPE "btype"
340 #define DM_CLOCK "clock" /* also on controller */
341 #define DM_PNAME "pname"
343 /* controller */
344 #define DM_FAST "fast"
345 #define DM_FAST20 "fast20"
346 #define DM_FAST40 "fast40"
347 #define DM_FAST80 "fast80"
348 #define DM_MULTIPLEX "multiplex"
349 #define DM_PATH_STATE "path_state"
351 #define DM_CTYPE_ATA "ata"
352 #define DM_CTYPE_SCSI "scsi"
353 #define DM_CTYPE_FIBRE "fibre channel"
354 #define DM_CTYPE_USB "usb"
355 #define DM_CTYPE_UNKNOWN "unknown"
357 /* media */
358 #define DM_BLOCKSIZE "blocksize"
359 #define DM_FDISK "fdisk"
360 #define DM_MTYPE "mtype"
361 #define DM_NACTUALCYLINDERS "nactual_cylinders"
362 #define DM_NALTCYLINDERS "nalt_cylinders"
363 #define DM_NCYLINDERS "ncylinders"
364 #define DM_NHEADS "nheads"
365 #define DM_NPHYSCYLINDERS "nphys_cylinders"
366 #define DM_NSECTORS "nsectors" /* also in partition */
367 #define DM_SIZE "size" /* also in slice */
368 #define DM_NACCESSIBLE "naccessible"
369 #define DM_LABEL "label"
371 /* partition */
372 #define DM_BCYL "bcyl"
373 #define DM_BHEAD "bhead"
374 #define DM_BOOTID "bootid"
375 #define DM_BSECT "bsect"
376 #define DM_ECYL "ecyl"
377 #define DM_EHEAD "ehead"
378 #define DM_ESECT "esect"
379 #define DM_PTYPE "ptype" /* this references the partition id */
380 #define DM_PARTITION_TYPE "part_type" /* primary, extended, logical */
381 #define DM_RELSECT "relsect"
383 /* slice */
384 #define DM_DEVICEID "deviceid"
385 #define DM_DEVT "devt"
386 #define DM_INDEX "index"
387 #define DM_EFI_NAME "name"
388 #define DM_MOUNTPOINT "mountpoint"
389 #define DM_LOCALNAME "localname"
390 #define DM_START "start"
391 #define DM_TAG "tag"
392 #define DM_FLAG "flag"
393 #define DM_EFI "efi" /* also on media */
394 #define DM_USED_BY "used_by"
395 #define DM_USED_NAME "used_name"
396 #define DM_USE_MOUNT "mount"
397 #define DM_USE_SVM "svm"
398 #define DM_USE_LU "lu"
399 #define DM_USE_DUMP "dump"
400 #define DM_USE_VXVM "vxvm"
401 #define DM_USE_FS "fs"
402 #define DM_USE_VFSTAB "vfstab"
403 #define DM_USE_EXPORTED_ZPOOL "exported_zpool"
404 #define DM_USE_ACTIVE_ZPOOL "active_zpool"
405 #define DM_USE_SPARE_ZPOOL "spare_zpool"
406 #define DM_USE_L2CACHE_ZPOOL "l2cache_zpool"
408 /* event */
409 #define DM_EV_NAME "name"
410 #define DM_EV_DTYPE "edtype"
411 #define DM_EV_TYPE "evtype"
412 #define DM_EV_TADD "add"
413 #define DM_EV_TREMOVE "remove"
414 #define DM_EV_TCHANGE "change"
416 /* findisks */
417 #define DM_CTYPE "ctype"
418 #define DM_LUN "lun"
419 #define DM_TARGET "target"
421 #define NOINUSE_SET getenv("NOINUSE_CHECK") != NULL
423 void dm_free_descriptors(dm_descriptor_t *desc_list);
424 void dm_free_descriptor(dm_descriptor_t desc);
425 void dm_free_name(char *name);
426 void dm_free_swapentries(swaptbl_t *);
428 dm_descriptor_t *dm_get_descriptors(dm_desc_type_t type, int filter[],
429 int *errp);
430 dm_descriptor_t *dm_get_associated_descriptors(dm_descriptor_t desc,
431 dm_desc_type_t type, int *errp);
432 dm_desc_type_t *dm_get_associated_types(dm_desc_type_t type);
433 dm_descriptor_t dm_get_descriptor_by_name(dm_desc_type_t desc_type,
434 char *name, int *errp);
435 char *dm_get_name(dm_descriptor_t desc, int *errp);
436 dm_desc_type_t dm_get_type(dm_descriptor_t desc);
437 nvlist_t *dm_get_attributes(dm_descriptor_t desc, int *errp);
438 nvlist_t *dm_get_stats(dm_descriptor_t desc, int stat_type,
439 int *errp);
440 void dm_init_event_queue(void(*callback)(nvlist_t *, int),
441 int *errp);
442 nvlist_t *dm_get_event(int *errp);
443 void dm_get_slices(char *drive, dm_descriptor_t **slices,
444 int *errp);
445 void dm_get_slice_stats(char *slice, nvlist_t **dev_stats,
446 int *errp);
447 int dm_get_swapentries(swaptbl_t **, int *);
448 void dm_get_usage_string(char *who, char *data, char **msg);
449 int dm_inuse(char *dev_name, char **msg, dm_who_type_t who,
450 int *errp);
451 int dm_inuse_swap(const char *dev_name, int *errp);
452 int dm_isoverlapping(char *dev_name, char **msg, int *errp);
454 #ifdef __cplusplus
456 #endif
458 #endif /* _LIBDISKMGT_H */