mfi_volume.c (935205e2307611615ed5a7fe0a32b225ffd8c19c) mfi_volume.c (2e5df98a18f21f1e6631e014413e2f8f0f74034a)
1/*-
2 * Copyright (c) 2008, 2009 Yahoo!, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 97 unchanged lines hidden (view full) ---

106 uint8_t mbox[4];
107
108 mbox_store_ldref(mbox, &props->ld);
109 return (mfi_dcmd_command(fd, MFI_DCMD_LD_SET_PROP, props,
110 sizeof(struct mfi_ld_props), mbox, 4, NULL));
111}
112
113static int
1/*-
2 * Copyright (c) 2008, 2009 Yahoo!, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 97 unchanged lines hidden (view full) ---

106 uint8_t mbox[4];
107
108 mbox_store_ldref(mbox, &props->ld);
109 return (mfi_dcmd_command(fd, MFI_DCMD_LD_SET_PROP, props,
110 sizeof(struct mfi_ld_props), mbox, 4, NULL));
111}
112
113static int
114update_cache_policy(int fd, struct mfi_ld_props *props, uint8_t new_policy,
115 uint8_t mask)
114update_cache_policy(int fd, struct mfi_ld_props *old, struct mfi_ld_props *new)
116{
117 int error;
118 uint8_t changes, policy;
119
115{
116 int error;
117 uint8_t changes, policy;
118
120 policy = (props->default_cache_policy & ~mask) | new_policy;
121 if (policy == props->default_cache_policy)
119 if (old->default_cache_policy == new->default_cache_policy &&
120 old->disk_cache_policy == new->disk_cache_policy)
122 return (0);
121 return (0);
123 changes = policy ^ props->default_cache_policy;
122 policy = new->default_cache_policy;
123 changes = policy ^ old->default_cache_policy;
124 if (changes & MR_LD_CACHE_ALLOW_WRITE_CACHE)
125 printf("%s caching of I/O writes\n",
126 policy & MR_LD_CACHE_ALLOW_WRITE_CACHE ? "Enabling" :
127 "Disabling");
128 if (changes & MR_LD_CACHE_ALLOW_READ_CACHE)
129 printf("%s caching of I/O reads\n",
130 policy & MR_LD_CACHE_ALLOW_READ_CACHE ? "Enabling" :
131 "Disabling");

--- 5 unchanged lines hidden (view full) ---

137 printf("Setting read ahead policy to %s\n",
138 policy & MR_LD_CACHE_READ_AHEAD ?
139 (policy & MR_LD_CACHE_READ_ADAPTIVE ?
140 "adaptive" : "always") : "none");
141 if (changes & MR_LD_CACHE_WRITE_CACHE_BAD_BBU)
142 printf("%s write caching with bad BBU\n",
143 policy & MR_LD_CACHE_WRITE_CACHE_BAD_BBU ? "Enabling" :
144 "Disabling");
124 if (changes & MR_LD_CACHE_ALLOW_WRITE_CACHE)
125 printf("%s caching of I/O writes\n",
126 policy & MR_LD_CACHE_ALLOW_WRITE_CACHE ? "Enabling" :
127 "Disabling");
128 if (changes & MR_LD_CACHE_ALLOW_READ_CACHE)
129 printf("%s caching of I/O reads\n",
130 policy & MR_LD_CACHE_ALLOW_READ_CACHE ? "Enabling" :
131 "Disabling");

--- 5 unchanged lines hidden (view full) ---

137 printf("Setting read ahead policy to %s\n",
138 policy & MR_LD_CACHE_READ_AHEAD ?
139 (policy & MR_LD_CACHE_READ_ADAPTIVE ?
140 "adaptive" : "always") : "none");
141 if (changes & MR_LD_CACHE_WRITE_CACHE_BAD_BBU)
142 printf("%s write caching with bad BBU\n",
143 policy & MR_LD_CACHE_WRITE_CACHE_BAD_BBU ? "Enabling" :
144 "Disabling");
145 if (old->disk_cache_policy != new->disk_cache_policy) {
146 switch (new->disk_cache_policy) {
147 case MR_PD_CACHE_ENABLE:
148 printf("Enabling write-cache on physical drives\n");
149 break;
150 case MR_PD_CACHE_DISABLE:
151 printf("Disabling write-cache on physical drives\n");
152 break;
153 case MR_PD_CACHE_UNCHANGED:
154 printf("Using default write-cache setting on physical drives\n");
155 break;
156 }
157 }
145
158
146 props->default_cache_policy = policy;
147 if (mfi_ld_set_props(fd, props) < 0) {
159 if (mfi_ld_set_props(fd, new) < 0) {
148 error = errno;
149 warn("Failed to set volume properties");
150 return (error);
151 }
152 return (0);
153}
154
160 error = errno;
161 warn("Failed to set volume properties");
162 return (error);
163 }
164 return (0);
165}
166
167static void
168stage_cache_setting(struct mfi_ld_props *props, uint8_t new_policy,
169 uint8_t mask)
170{
171
172 props->default_cache_policy &= ~mask;
173 props->default_cache_policy |= new_policy;
174}
175
176/*
177 * Parse a single cache directive modifying the passed in policy.
178 * Returns -1 on a parse error and the number of arguments consumed
179 * on success.
180 */
155static int
181static int
182process_cache_command(int ac, char **av, struct mfi_ld_props *props)
183{
184 uint8_t policy;
185
186 /* I/O cache settings. */
187 if (strcmp(av[0], "all") == 0 || strcmp(av[0], "enable") == 0) {
188 stage_cache_setting(props, MR_LD_CACHE_ALLOW_READ_CACHE |
189 MR_LD_CACHE_ALLOW_WRITE_CACHE,
190 MR_LD_CACHE_ALLOW_READ_CACHE |
191 MR_LD_CACHE_ALLOW_WRITE_CACHE);
192 return (1);
193 }
194 if (strcmp(av[0], "none") == 0 || strcmp(av[0], "disable") == 0) {
195 stage_cache_setting(props, 0, MR_LD_CACHE_ALLOW_READ_CACHE |
196 MR_LD_CACHE_ALLOW_WRITE_CACHE);
197 return (1);
198 }
199 if (strcmp(av[0], "reads") == 0) {
200 stage_cache_setting(props, MR_LD_CACHE_ALLOW_READ_CACHE,
201 MR_LD_CACHE_ALLOW_READ_CACHE |
202 MR_LD_CACHE_ALLOW_WRITE_CACHE);
203 return (1);
204 }
205 if (strcmp(av[0], "writes") == 0) {
206 stage_cache_setting(props, MR_LD_CACHE_ALLOW_WRITE_CACHE,
207 MR_LD_CACHE_ALLOW_READ_CACHE |
208 MR_LD_CACHE_ALLOW_WRITE_CACHE);
209 return (1);
210 }
211
212 /* Write cache behavior. */
213 if (strcmp(av[0], "write-back") == 0) {
214 stage_cache_setting(props, MR_LD_CACHE_WRITE_BACK,
215 MR_LD_CACHE_WRITE_BACK);
216 return (1);
217 }
218 if (strcmp(av[0], "write-through") == 0) {
219 stage_cache_setting(props, 0, MR_LD_CACHE_WRITE_BACK);
220 return (1);
221 }
222 if (strcmp(av[0], "bad-bbu-write-cache") == 0) {
223 if (ac < 2) {
224 warnx("cache: bad BBU setting required");
225 return (-1);
226 }
227 if (strcmp(av[1], "enable") == 0)
228 policy = MR_LD_CACHE_WRITE_CACHE_BAD_BBU;
229 else if (strcmp(av[1], "disable") == 0)
230 policy = 0;
231 else {
232 warnx("cache: invalid bad BBU setting");
233 return (-1);
234 }
235 stage_cache_setting(props, policy,
236 MR_LD_CACHE_WRITE_CACHE_BAD_BBU);
237 return (2);
238 }
239
240 /* Read cache behavior. */
241 if (strcmp(av[0], "read-ahead") == 0) {
242 if (ac < 2) {
243 warnx("cache: read-ahead setting required");
244 return (-1);
245 }
246 if (strcmp(av[1], "none") == 0)
247 policy = 0;
248 else if (strcmp(av[1], "always") == 0)
249 policy = MR_LD_CACHE_READ_AHEAD;
250 else if (strcmp(av[1], "adaptive") == 0)
251 policy = MR_LD_CACHE_READ_AHEAD |
252 MR_LD_CACHE_READ_ADAPTIVE;
253 else {
254 warnx("cache: invalid read-ahead setting");
255 return (-1);
256 }
257 stage_cache_setting(props, policy, MR_LD_CACHE_READ_AHEAD |
258 MR_LD_CACHE_READ_ADAPTIVE);
259 return (2);
260 }
261
262 /* Drive write-cache behavior. */
263 if (strcmp(av[0], "write-cache") == 0) {
264 if (ac < 2) {
265 warnx("cache: write-cache setting required");
266 return (-1);
267 }
268 if (strcmp(av[1], "enable") == 0)
269 props->disk_cache_policy = MR_PD_CACHE_ENABLE;
270 else if (strcmp(av[1], "disable") == 0)
271 props->disk_cache_policy = MR_PD_CACHE_DISABLE;
272 else if (strcmp(av[1], "default") == 0)
273 props->disk_cache_policy = MR_PD_CACHE_UNCHANGED;
274 else {
275 warnx("cache: invalid write-cache setting");
276 return (-1);
277 }
278 return (2);
279 }
280
281 warnx("cache: Invalid command");
282 return (-1);
283}
284
285static int
156volume_cache(int ac, char **av)
157{
286volume_cache(int ac, char **av)
287{
158 struct mfi_ld_props props;
159 int error, fd;
160 uint8_t target_id, policy;
288 struct mfi_ld_props props, new;
289 int error, fd, consumed;
290 uint8_t target_id;
161
162 if (ac < 2) {
163 warnx("cache: volume required");
164 return (EINVAL);
165 }
166
167 fd = mfi_open(mfi_unit);
168 if (fd < 0) {

--- 61 unchanged lines hidden (view full) ---

230 default:
231 printf("??? %d\n", props.disk_cache_policy);
232 break;
233 }
234 if (props.default_cache_policy != props.current_cache_policy)
235 printf("Cache Disabled Due to Dead Battery\n");
236 error = 0;
237 } else {
291
292 if (ac < 2) {
293 warnx("cache: volume required");
294 return (EINVAL);
295 }
296
297 fd = mfi_open(mfi_unit);
298 if (fd < 0) {

--- 61 unchanged lines hidden (view full) ---

360 default:
361 printf("??? %d\n", props.disk_cache_policy);
362 break;
363 }
364 if (props.default_cache_policy != props.current_cache_policy)
365 printf("Cache Disabled Due to Dead Battery\n");
366 error = 0;
367 } else {
238 if (strcmp(av[2], "all") == 0 || strcmp(av[2], "enable") == 0)
239 error = update_cache_policy(fd, &props,
240 MR_LD_CACHE_ALLOW_READ_CACHE |
241 MR_LD_CACHE_ALLOW_WRITE_CACHE,
242 MR_LD_CACHE_ALLOW_READ_CACHE |
243 MR_LD_CACHE_ALLOW_WRITE_CACHE);
244 else if (strcmp(av[2], "none") == 0 ||
245 strcmp(av[2], "disable") == 0)
246 error = update_cache_policy(fd, &props, 0,
247 MR_LD_CACHE_ALLOW_READ_CACHE |
248 MR_LD_CACHE_ALLOW_WRITE_CACHE);
249 else if (strcmp(av[2], "reads") == 0)
250 error = update_cache_policy(fd, &props,
251 MR_LD_CACHE_ALLOW_READ_CACHE,
252 MR_LD_CACHE_ALLOW_READ_CACHE |
253 MR_LD_CACHE_ALLOW_WRITE_CACHE);
254 else if (strcmp(av[2], "writes") == 0)
255 error = update_cache_policy(fd, &props,
256 MR_LD_CACHE_ALLOW_WRITE_CACHE,
257 MR_LD_CACHE_ALLOW_READ_CACHE |
258 MR_LD_CACHE_ALLOW_WRITE_CACHE);
259 else if (strcmp(av[2], "write-back") == 0)
260 error = update_cache_policy(fd, &props,
261 MR_LD_CACHE_WRITE_BACK,
262 MR_LD_CACHE_WRITE_BACK);
263 else if (strcmp(av[2], "write-through") == 0)
264 error = update_cache_policy(fd, &props, 0,
265 MR_LD_CACHE_WRITE_BACK);
266 else if (strcmp(av[2], "read-ahead") == 0) {
267 if (ac < 4) {
268 warnx("cache: read-ahead setting required");
368 new = props;
369 av += 2;
370 ac -= 2;
371 while (ac > 0) {
372 consumed = process_cache_command(ac, av, &new);
373 if (consumed < 0) {
269 close(fd);
270 return (EINVAL);
271 }
374 close(fd);
375 return (EINVAL);
376 }
272 if (strcmp(av[3], "none") == 0)
273 policy = 0;
274 else if (strcmp(av[3], "always") == 0)
275 policy = MR_LD_CACHE_READ_AHEAD;
276 else if (strcmp(av[3], "adaptive") == 0)
277 policy = MR_LD_CACHE_READ_AHEAD |
278 MR_LD_CACHE_READ_ADAPTIVE;
279 else {
280 warnx("cache: invalid read-ahead setting");
281 close(fd);
282 return (EINVAL);
283 }
284 error = update_cache_policy(fd, &props, policy,
285 MR_LD_CACHE_READ_AHEAD |
286 MR_LD_CACHE_READ_ADAPTIVE);
287 } else if (strcmp(av[2], "bad-bbu-write-cache") == 0) {
288 if (ac < 4) {
289 warnx("cache: bad BBU setting required");
290 close(fd);
291 return (EINVAL);
292 }
293 if (strcmp(av[3], "enable") == 0)
294 policy = MR_LD_CACHE_WRITE_CACHE_BAD_BBU;
295 else if (strcmp(av[3], "disable") == 0)
296 policy = 0;
297 else {
298 warnx("cache: invalid bad BBU setting");
299 close(fd);
300 return (EINVAL);
301 }
302 error = update_cache_policy(fd, &props, policy,
303 MR_LD_CACHE_WRITE_CACHE_BAD_BBU);
304 } else if (strcmp(av[2], "write-cache") == 0) {
305 if (ac < 4) {
306 warnx("cache: write-cache setting required");
307 close(fd);
308 return (EINVAL);
309 }
310 if (strcmp(av[3], "enable") == 0)
311 policy = MR_PD_CACHE_ENABLE;
312 else if (strcmp(av[3], "disable") == 0)
313 policy = MR_PD_CACHE_DISABLE;
314 else if (strcmp(av[3], "default") == 0)
315 policy = MR_PD_CACHE_UNCHANGED;
316 else {
317 warnx("cache: invalid write-cache setting");
318 close(fd);
319 return (EINVAL);
320 }
321 error = 0;
322 if (policy != props.disk_cache_policy) {
323 switch (policy) {
324 case MR_PD_CACHE_ENABLE:
325 printf("Enabling write-cache on physical drives\n");
326 break;
327 case MR_PD_CACHE_DISABLE:
328 printf("Disabling write-cache on physical drives\n");
329 break;
330 case MR_PD_CACHE_UNCHANGED:
331 printf("Using default write-cache setting on physical drives\n");
332 break;
333 }
334 props.disk_cache_policy = policy;
335 if (mfi_ld_set_props(fd, &props) < 0) {
336 error = errno;
337 warn("Failed to set volume properties");
338 }
339 }
340 } else {
341 warnx("cache: Invalid command");
342 close(fd);
343 return (EINVAL);
377 av += consumed;
378 ac -= consumed;
344 }
379 }
380 error = update_cache_policy(fd, &props, &new);
345 }
346 close(fd);
347
348 return (error);
349}
350MFI_COMMAND(top, cache, volume_cache);
351
352static int

--- 108 unchanged lines hidden ---
381 }
382 close(fd);
383
384 return (error);
385}
386MFI_COMMAND(top, cache, volume_cache);
387
388static int

--- 108 unchanged lines hidden ---