1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_MD_NOTIFY_H 28 #define _SYS_MD_NOTIFY_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <sys/lvm/mdvar.h> 33 #include <sys/proc.h> 34 #include <sys/lvm/md_mirror_shared.h> 35 #include <sys/time.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 #define MD_EVENT_ID (0xda1eab1e) 42 #define MD_ALLSETS ((ulong_t)0xffffffff) 43 #define MD_ALLDEVS ((ulong_t)0xffffffff) 44 #define MD_NOTIFY_HALT_TRIES (4) 45 #define MD_NOTIFY_NAME_SIZE (64) 46 #define MD_NOTIFY_REVISION 1 47 48 /* mdn_flags bits in struct md_event_queue */ 49 50 #define MD_EVENT_QUEUE_DESTROY (0x00000001) 51 #define MD_EVENT_QUEUE_INVALID (0x00000002) 52 #define MD_EVENT_QUEUE_PERM (0x00000004) /* do not delete when proc dies */ 53 #define MD_EVENT_QUEUE_FULL (0x00000008) 54 55 typedef enum md_event_type { 56 57 EQ_EMPTY = 0, 58 59 /* Configuration Changes */ 60 EQ_CREATE = 1, 61 EQ_DELETE, 62 EQ_ADD, 63 EQ_REMOVE, 64 EQ_REPLACE, 65 EQ_GROW, 66 EQ_RENAME_SRC, 67 EQ_RENAME_DST, 68 69 EQ_MEDIATOR_ADD, 70 EQ_MEDIATOR_DELETE, 71 EQ_HOST_ADD, 72 EQ_HOST_DELETE, 73 EQ_DRIVE_ADD, 74 EQ_DRIVE_DELETE, 75 76 /* State Changes */ 77 EQ_INIT_START = 0x00000400, 78 EQ_INIT_FAILED, 79 EQ_INIT_FATAL, 80 EQ_INIT_SUCCESS, 81 EQ_IOERR, 82 EQ_ERRED, 83 EQ_LASTERRED, 84 EQ_OK, 85 EQ_ENABLE, 86 EQ_RESYNC_START, 87 EQ_RESYNC_FAILED, 88 EQ_RESYNC_SUCCESS, /* resync has succeeded */ 89 EQ_RESYNC_DONE, /* resync completed */ 90 EQ_HOTSPARED, /* hot spare aquired for use */ 91 EQ_HS_FREED, /* hotspare no longer in use */ 92 EQ_HS_CHANGED, /* change of metadevice hotspare pool */ 93 EQ_TAKEOVER, 94 EQ_RELEASE, 95 EQ_OPEN_FAIL, 96 EQ_OFFLINE, 97 EQ_ONLINE, 98 EQ_DETACH, 99 EQ_DETACHING, 100 EQ_ATTACH, 101 EQ_ATTACHING, 102 EQ_CHANGE, 103 EQ_EXCHANGE, 104 EQ_REGEN_START, 105 EQ_REGEN_DONE, 106 EQ_REGEN_FAILED, 107 108 /* User defined event */ 109 EQ_USER = 0x00100000, 110 111 /* Notify Specfic */ 112 EQ_NOTIFY_LOST, 113 EQ_LAST } 114 md_event_type_t; 115 116 typedef enum md_event_cmds { 117 EQ_NONE = 0x00000000, 118 EQ_ON = 0x00000001, 119 EQ_OFF = 0x00000002, 120 EQ_GET_NOWAIT = 0x00000010, 121 EQ_GET_WAIT = 0x00000040, 122 EQ_PUT = 0x00000020, 123 124 EQ_ALLVALID = 0x00000073 125 }md_event_cmds_t; 126 127 typedef enum md_tags { 128 TAG_EMPTY, 129 TAG_METADEVICE, 130 TAG_REPLICA, 131 TAG_HSP, 132 TAG_HS, 133 TAG_SET, 134 TAG_DRIVE, 135 TAG_HOST, 136 TAG_MEDIATOR, 137 TAG_UNK, 138 TAG_LAST 139 } md_tags_t; 140 141 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 142 #pragma pack(4) 143 #endif 144 typedef struct md_event_ioctl { 145 MD_DRIVER 146 md_error_t mde; /* error return */ 147 uint_t mdn_magic; /* magic number for structure */ 148 int mdn_rev; /* revision number */ 149 char mdn_name[MD_NOTIFY_NAME_SIZE]; 150 /* queue name */ 151 int mdn_flags; /* ioctl flags */ 152 md_event_cmds_t mdn_cmd; /* command value */ 153 md_tags_t mdn_tag; /* object tag */ 154 set_t mdn_set; /* set number */ 155 md_dev64_t mdn_dev; /* device event occurred on */ 156 md_event_type_t mdn_event; /* event */ 157 u_longlong_t mdn_user; /* user defined event */ 158 md_timeval32_t mdn_time; /* time stamp of event */ 159 } md_event_ioctl_t; 160 161 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 162 #pragma pack() 163 #endif 164 165 /* ioctl flags */ 166 #define EQ_Q_PERM (0x00000001) /* do not delete when proc dies */ 167 168 #define EQ_Q_ALLVALID (0x00000001) /* all valid notify ioctl flags */ 169 170 typedef enum notify_cmds_t 171 { EQ_LIST_ADD = 1, EQ_LIST_DELETE } 172 notify_cmds_t; 173 174 typedef struct notify { 175 notify_cmds_t mdn_cmd; /* list function (add/delete) */ 176 md_tags_t mdn_tag; /* type of object */ 177 set_t mdn_set; /* set where event occurred */ 178 md_dev64_t mdn_dev; /* device that event occurred on */ 179 md_event_type_t mdn_event; /* event */ 180 }notify_t; 181 182 183 #ifdef _KERNEL 184 185 #define NOTIFY_MD(tag, set, dev, event) \ 186 (void) md_notify_interface(EQ_PUT, (tag), (set), (dev), (event)) 187 188 #define SE_NOTIFY(se_class, se_subclass, tag, set, dev) \ 189 svm_gen_sysevent((se_class), (se_subclass), (tag), (set), (dev)) 190 191 typedef struct md_event { 192 struct md_event *mdn_next; /* pointer to next element */ 193 md_tags_t mdn_tag; /* object type */ 194 set_t mdn_set; /* set where event occurred */ 195 md_dev64_t mdn_dev; /* device that event occurred on */ 196 md_event_type_t mdn_event; /* event */ 197 u_longlong_t mdn_user; /* user defined event */ 198 struct timeval mdn_time; /* time stamp of event */ 199 }md_event_t; 200 201 typedef struct md_event_queue { 202 struct md_event_queue *mdn_nextq; /* next event queue */ 203 char mdn_name[MD_NOTIFY_NAME_SIZE]; 204 /* queue name */ 205 int mdn_flags; /* queue flags */ 206 pid_t mdn_pid; /* pid that created the queue */ 207 proc_t *mdn_proc; /* process that created the queue */ 208 uid_t mdn_uid; /* uid of queue creator */ 209 size_t mdn_size; /* size of the queue in elements */ 210 md_event_t *mdn_front; /* front element in queue */ 211 md_event_t *mdn_tail; /* last element of queue */ 212 int mdn_waiting; /* number of process waiting */ 213 kcondvar_t mdn_cv; /* waiting condition varaible */ 214 } md_event_queue_t; 215 216 /* 217 * The remainder of this file defines items that are used for testing 218 * md_notify. 219 */ 220 221 /* 222 * Named services for testing 223 */ 224 225 #define MD_NOTIFY_REAP_OFF "notify turn reap off" 226 #define MD_NOTIFY_REAP_ON "notify turn reap on" 227 #define MD_NOTIFY_TEST_STATS "notify test statistics" 228 229 /* 230 * The MD_NOTIFY_TEST_STATS named service can be invoked to get md_notify 231 * to set the values of this structure. The md_tnotify module uses this 232 * structure. 233 */ 234 235 typedef struct md_notify_stats { 236 kmutex_t *mds_eventq_mx; /* Address of mutex protecting */ 237 /* event queue. */ 238 int mds_max_queue; /* Max. # events in notify queue. */ 239 int mds_reap; /* events since last reap. */ 240 int mds_reap_count; /* # events between reaps. */ 241 int mds_reap_off; /* non-zero -> reaping is off. */ 242 } md_notify_stats_t; 243 244 #endif /* _KERNEL */ 245 246 #ifdef __cplusplus 247 } 248 #endif 249 250 #endif /* _SYS_MD_NOTIFY_H */ 251