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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <sys/ksynch.h>
28 #include <sys/cmn_err.h>
29 #include <sys/errno.h>
30 #include <sys/kmem.h>
31 #include <sys/cred.h>
32 #include <sys/buf.h>
33 #include <sys/ddi.h>
34 #include <sys/nsc_thread.h>
35
36
37 #include "sd_bcache.h"
38 #include "sd_trace.h"
39 #include "sd_io.h"
40 #include "sd_bio.h"
41 #include "sd_ft.h"
42 #include "sd_misc.h"
43 #include "sd_pcu.h"
44
45 /*
46 * PCU (aka UPS) handling -
47 */
48 #define bitmap_next cc_dirty_link
49 #define bitmap_tail cc_dirty_next
50
51 #define anon_next cc_dirty_link
52 #define anon_tail cc_dirty_next
53 #define anon_data cc_data
54
55 struct bitmap {
56 _sd_cctl_t *bmps;
57 int bmaps_per_block;
58 int inuse; /* In use in the _last_ block */
59 };
60
61 #define SDBC_PCU_MAXSWAPIL 3 /* Watch for 5 fields in ioctl arg. */
62
63 struct swapfiles {
64 int nswpf; /* Number of filenames */
65 int colsize; /* In cache blocks */
66 char *names[SDBC_PCU_MAXSWAPIL];
67 };
68
69 static void _sdbc_pcu_cleanup(struct swapfiles *);
70
71 /*
72 * Forward declare functions containing 64-bit argument types to enforce
73 * type-checking.
74 */
75 static int add_bitmap_entry(struct bitmap *bmp, _sd_bitmap_t bits, int any_fail,
76 nsc_off_t fba_num);
77 static int flush_bitmap_list(struct bitmap *bmp, dev_t dev, nsc_off_t *blkno);
78 static int flush_centry_list(_sd_cd_info_t *cdi, _sd_cctl_t *dirty, dev_t dev,
79 nsc_off_t *blkno, int failed, struct bitmap *bmaps);
80 static int flush_hdr(_sd_cctl_t *hdr, dev_t dev, nsc_off_t blkno);
81 static int flush_anon_list(_sd_cctl_t *anon_list, dev_t dev, nsc_off_t *blkno);
82 static void sdbc_anon_copy(caddr_t src, nsc_size_t len, _sd_cctl_t *dest,
83 nsc_off_t dest_off);
84 static void sdbc_anon_get(_sd_cctl_t *src, nsc_off_t src_off, caddr_t dest,
85 nsc_size_t len);
86 static _sd_cctl_t *sdbc_get_anon_list(nsc_size_t bytes);
87
88 static int got_hint; /* did we capture hint at power_lost */
89 static unsigned int wrthru_hint; /* saved hint at power_lost */
90 static int saw_power_lost;
91
92 char _sdbc_shutdown_in_progress;
93 static struct swapfiles swfs;
94
95 /*
96 * sdbc_get_anon_list - allocate a set of anonymous cache block
97 * entries that can pretend to be a single blocks of data holding
98 * a virtual character array holding "bytes" entries.
99 *
100 * returns - the cache block heading the chain.
101 */
102 static _sd_cctl_t *
sdbc_get_anon_list(nsc_size_t bytes)103 sdbc_get_anon_list(nsc_size_t bytes)
104 {
105 _sd_cctl_t *list, *prev;
106 nsc_size_t i, blks;
107
108 prev = NULL;
109 blks = (bytes + CACHE_BLOCK_SIZE - 1) / CACHE_BLOCK_SIZE;
110 for (i = 0; i < blks; i++) {
111
112 list = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
113 bzero(list->cc_data, CACHE_BLOCK_SIZE);
114 list->anon_next = prev;
115 prev = list;
116 };
117
118 return (list);
119 }
120
121 /*
122 * sdbc_anon_get - gets "len" bytes of data virtual character array represented
123 * by "src" begining at index "dest_off" and copy to buffer "dest".
124 *
125 * dest - pointer to our virtual array (chain of cache blocks).
126 * dest_off - first location to copy data to.
127 * src - pointer to data to copy
128 * len - the number of bytes of data to copy
129 *
130 */
131 static void
sdbc_anon_get(_sd_cctl_t * src,nsc_off_t src_off,caddr_t dest,nsc_size_t len)132 sdbc_anon_get(_sd_cctl_t *src, nsc_off_t src_off, caddr_t dest, nsc_size_t len)
133 {
134 nsc_size_t i;
135 nsc_size_t nlen;
136 nsc_off_t blk_start, blk_end;
137
138 if (len == 0)
139 return;
140
141 blk_start = src_off / CACHE_BLOCK_SIZE;
142 blk_end = (src_off + len) / CACHE_BLOCK_SIZE;
143
144 for (i = 0; i < blk_start; i++) {
145 src = src->anon_next;
146 src_off -= CACHE_BLOCK_SIZE;
147 }
148
149 nlen = min(len, CACHE_BLOCK_SIZE - src_off);
150 bcopy(&src->anon_data[src_off], dest, (size_t)nlen);
151
152 for (i = 1; i < blk_end - blk_start; i++) {
153 bcopy(src->anon_data, &dest[nlen], (size_t)CACHE_BLOCK_SIZE);
154 nlen += CACHE_BLOCK_SIZE;
155 src = src->anon_next;
156 }
157 if (nlen != len) {
158 bcopy(src->anon_data, &dest[nlen], (size_t)(len - nlen));
159 }
160 }
161
162 /*
163 * sdbc_anon_copy - copies "len" bytes of data from "src" to the
164 * virtual character array represented by "dest" begining at index
165 * "dest_off".
166 *
167 * src - pointer to data to copy
168 * len - the number of bytes of data to copy
169 * dest - pointer to our virtual array (chain of cache blocks).
170 * dest_off - first location to copy data to.
171 *
172 */
173 static void
sdbc_anon_copy(caddr_t src,nsc_size_t len,_sd_cctl_t * dest,nsc_off_t dest_off)174 sdbc_anon_copy(caddr_t src, nsc_size_t len, _sd_cctl_t *dest,
175 nsc_off_t dest_off)
176 {
177 nsc_size_t i;
178 nsc_size_t nlen;
179 nsc_off_t blk_start, blk_end;
180
181 if (len == 0)
182 return;
183
184 blk_start = dest_off / CACHE_BLOCK_SIZE;
185 blk_end = (dest_off + len) / CACHE_BLOCK_SIZE;
186
187 for (i = 0; i < blk_start; i++) {
188 dest = dest->anon_next;
189 dest_off -= CACHE_BLOCK_SIZE;
190 }
191
192 nlen = min(len, CACHE_BLOCK_SIZE - dest_off);
193 bcopy(src, &dest->anon_data[dest_off], (size_t)nlen);
194
195 for (i = 1; i < blk_end - blk_start; i++) {
196 bcopy(&src[nlen], dest->anon_data, (size_t)CACHE_BLOCK_SIZE);
197 nlen += CACHE_BLOCK_SIZE;
198 dest = dest->anon_next;
199 }
200 if (nlen != len) {
201 bcopy(&src[nlen], dest->anon_data, (size_t)(len - nlen));
202 }
203 }
204
205 /*
206 * flush_anon_list - flush a chain of anonymous cache blocks
207 * to the state file. Anonymous chains of cache blocks represent
208 * virtual arrays for the state flushing code and can contain
209 * various types of data.
210 *
211 * anon_list - chain of cache blocks to flush.
212 *
213 * dev - the state file device
214 *
215 * blkno - on input the cache block number to begin writing at.
216 * On exit the next cache block number following the data
217 * just written.
218 *
219 * returns - 0 on success, error number on failure.
220 */
221 static int
flush_anon_list(_sd_cctl_t * anon_list,dev_t dev,nsc_off_t * blkno)222 flush_anon_list(_sd_cctl_t *anon_list,
223 dev_t dev,
224 nsc_off_t *blkno)
225 {
226 struct buf *bp;
227 int rc;
228 _sd_cctl_t *prev;
229 nsc_size_t bcnt;
230
231 if (anon_list == NULL)
232 return (0);
233
234 bcnt = 0;
235 do {
236 bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(*blkno),
237 BLK_TO_FBA_NUM(1), 0);
238 sd_add_fba(bp, &anon_list->cc_addr, 0, BLK_FBAS);
239 rc = sd_start_io(bp, NULL, NULL, 0);
240 (*blkno)++;
241
242 /*
243 * A failure here is death. This is harsh but not sure
244 * what else to do
245 */
246
247 if (rc != NSC_DONE)
248 return (rc);
249 bcnt++;
250
251 prev = anon_list;
252 anon_list = anon_list->anon_next;
253 _sd_centry_release(prev);
254
255 } while (anon_list);
256
257 cmn_err(CE_CONT, "sdbc(flush_anon_list) %" NSC_SZFMT "\n", bcnt);
258 return (0);
259
260 }
261
262 /*
263 * start_bitmap_list - allocate an anonymous cache block entry
264 * to anchor a chain of cache blocks representing a virtual
265 * array of bitmap entries.
266 *
267 * returns - the cache block heading the chain.
268 */
269 static void
start_bitmap_list(struct bitmap * bmp,int bpb)270 start_bitmap_list(struct bitmap *bmp, int bpb)
271 {
272 _sd_cctl_t *list;
273
274 list = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
275 bzero(list->cc_data, CACHE_BLOCK_SIZE);
276 list->bitmap_next = NULL;
277 list->bitmap_tail = list;
278
279 bmp->bmps = list;
280 bmp->inuse = 0;
281 bmp->bmaps_per_block = bpb;
282 }
283
284 /*
285 * add_bitmap_entry - Add a bitmap entry to the chain of bitmap
286 * entries we are creating for cd's entry in the state file.
287 *
288 * Bitmaps are stored in a chain of anonymous cache blocks. Each
289 * cache block can hold bmaps_per_block in it. As each block is
290 * filled a new block is added to the tail of the chain.
291 *
292 * list - the chain of cache blocks containing the bitmaps.
293 * bits - the bitmap entry to add.
294 * any_fail - flag saying whether the data corresponding to this
295 * bitmap entry had previously failed going to disk.
296 * fba_num - FBA number corresponding to the entry.
297 *
298 * returns - 0 on success, error number on failure.
299 */
300 static int
add_bitmap_entry(struct bitmap * bmp,_sd_bitmap_t bits,int any_fail,nsc_off_t fba_num)301 add_bitmap_entry(struct bitmap *bmp,
302 _sd_bitmap_t bits, int any_fail, nsc_off_t fba_num)
303 {
304 sdbc_pwf_bitmap_t *bmap;
305 _sd_cctl_t *list = bmp->bmps;
306 int i;
307
308 bmap = (sdbc_pwf_bitmap_t *)list->bitmap_tail->cc_data;
309 if (bmp->inuse == bmp->bmaps_per_block) {
310 _sd_cctl_t *nlist;
311
312 nlist = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
313 bzero(nlist->cc_data, CACHE_BLOCK_SIZE);
314 nlist->bitmap_next = NULL;
315 nlist->bitmap_tail = NULL;
316 list->bitmap_tail->bitmap_next = nlist;
317 list->bitmap_tail = nlist;
318 bmp->inuse = 0;
319 }
320 i = bmp->inuse++;
321 bmap->bitmaps[i].fba_num = fba_num;
322 bmap->bitmaps[i].dirty = bits;
323 bmap->bitmaps[i].errs = (char)any_fail;
324
325 return (0);
326 }
327
328 /*
329 * flush_bitmap_list - flush a chain of anonymous cache blocks
330 * containing the dirty/valid bitmaps for a set of cache blocks.
331 *
332 * b_list - the chain of bitmap data.
333 * dev - the state file device.
334 * blkno - on input the cache block number to begin writing at.
335 * On exit the next cache block number following the data
336 * just written.
337 *
338 * returns - 0 on success, error number on failure.
339 */
340 static int
flush_bitmap_list(struct bitmap * bmp,dev_t dev,nsc_off_t * blkno)341 flush_bitmap_list(struct bitmap *bmp, dev_t dev, nsc_off_t *blkno)
342 {
343 _sd_cctl_t *b_list;
344 struct buf *bp;
345 int rc;
346 _sd_cctl_t *prev;
347 int bcnt = 0; /* P3 temp */
348
349 if ((b_list = bmp->bmps) == NULL)
350 return (0);
351
352 do {
353 bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(*blkno),
354 BLK_TO_FBA_NUM(1), 0);
355 sd_add_fba(bp, &b_list->cc_addr, 0, BLK_FBAS);
356 rc = sd_start_io(bp, NULL, NULL, 0);
357 (*blkno)++;
358
359 /*
360 * A failure here is death. This is harsh but not sure
361 * what else to do
362 */
363
364 if (rc != NSC_DONE)
365 return (rc);
366 bcnt++;
367
368 prev = b_list;
369 b_list = b_list->bitmap_next;
370 _sd_centry_release(prev);
371
372 } while (b_list);
373 cmn_err(CE_CONT, "sdbc(flush_bitmap_list) %d\n", bcnt); /* P3 */
374
375 return (0);
376
377 }
378
379 /*
380 * flush_centry_list - flush a chain of cache blocks for the
381 * cache descriptor described by "cdi" to the state file.
382 * In addition the bitmaps describing the validity and dirty
383 * state of each entry are captured to the bitmap chain.
384 *
385 * cdi - pointer to description of the cd we are writing.
386 * dirty - chain of dirty cache blocks to flush (linked
387 * by dirty_next (sequential) and dirty_link (disjoint).
388 *
389 * dev - the state file device.
390 *
391 * blkno - on input the cache block number to begin writing at.
392 * On exit the next cache block number following the data
393 * just written.
394 *
395 * failed - a flag noting whether these blocks had already
396 * been attempted to write to their true destination and
397 * failed. (i.e. is the chain from fail_head).
398 *
399 * bmaps - a chain of anonymous cache blocks containing all
400 * the dirty/valid bitmaps for the cache blocks we write.
401 *
402 * returns - 0 on success, error number on failure.
403 */
404 static int
flush_centry_list(_sd_cd_info_t * cdi,_sd_cctl_t * dirty,dev_t dev,nsc_off_t * blkno,int failed,struct bitmap * bmaps)405 flush_centry_list(_sd_cd_info_t *cdi,
406 _sd_cctl_t *dirty,
407 dev_t dev,
408 nsc_off_t *blkno,
409 int failed,
410 struct bitmap *bmaps)
411 {
412 _sd_cctl_t *cc_ent;
413 nsc_size_t count; /* count of cache blocks in a sequential chain */
414 struct buf *bp;
415 int rc;
416 int bcnt = 0;
417
418 if (dirty == NULL)
419 return (0);
420
421 mutex_enter(&cdi->cd_lock);
422
423 do {
424 /*
425 * each cache block is written to the disk regardless of its
426 * valid/dirty masks.
427 */
428 count = 0;
429 cc_ent = dirty;
430 do {
431 count++;
432 cc_ent = cc_ent->cc_dirty_next;
433 } while (cc_ent);
434
435 bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(*blkno),
436 BLK_TO_FBA_NUM(count), 0);
437
438 cc_ent = dirty;
439 do {
440 sd_add_fba(bp, &cc_ent->cc_addr, 0, BLK_FBAS);
441 rc = add_bitmap_entry(bmaps,
442 cc_ent->cc_dirty | cc_ent->cc_toflush, failed,
443 BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)));
444 if (rc)
445 return (rc);
446 cc_ent = cc_ent->cc_dirty_next;
447 } while (cc_ent);
448
449 *blkno += count;
450 rc = sd_start_io(bp, NULL, NULL, 0);
451
452 /*
453 * A failure here is death. This is harsh but not sure
454 * what else to do
455 */
456
457 if (rc != NSC_DONE)
458 return (rc);
459 bcnt += count;
460
461 dirty = dirty->cc_dirty_link;
462 } while (dirty);
463 cmn_err(CE_CONT, "sdbc(flush_centry_list) %d\n", bcnt); /* P3 */
464
465 mutex_exit(&cdi->cd_lock);
466 return (0);
467 }
468
469 /*
470 * flush_hdr - Flush the state file header to the disk partition
471 * "dev" at FBA "blkno". Return the result of the i/o operation.
472 * hdr - a cache block containing the header.
473 * dev - the state file device.
474 * blkno - cache block position to write the header.
475 *
476 * returns - 0 on success, error number on failure.
477 */
478 static int
flush_hdr(_sd_cctl_t * hdr,dev_t dev,nsc_off_t blkno)479 flush_hdr(_sd_cctl_t *hdr, dev_t dev, nsc_off_t blkno)
480 {
481 struct buf *bp;
482 int rc;
483
484 bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(blkno), BLK_TO_FBA_NUM(1), 0);
485 sd_add_fba(bp, &hdr->cc_addr, 0, BLK_FBAS);
486 rc = sd_start_io(bp, NULL, NULL, 0);
487 _sd_centry_release(hdr);
488 return (rc);
489
490 }
491
492 /*
493 * _sdbc_power_flush - flushd the state of sdbc to the state "file"
494 * on the system disk. All dirty blocks (in progress, unscheduled,
495 * failed) are written along with the bitmap for each block. The
496 * data is written using normal sdbc i/o via anonymous cache blocks.
497 * This is done to simplify the job here (and to limit memory
498 * requests) at the expense of making the recovery programs more
499 * complex. Since recovery is done at user level this seems to be
500 * a good trade off.
501 *
502 * Returns: 0 on success, error number on failure.
503 */
504 static int
_sdbc_power_flush(void)505 _sdbc_power_flush(void)
506 {
507 _sd_cctl_t *name_pool;
508 int string_size;
509
510 sdbc_pwf_hdr_t *hdr;
511 _sd_cctl_t *hdrblk;
512
513 struct bitmap bmap;
514
515 _sd_cd_info_t *cdi;
516 int open_files;
517 _sd_cctl_t *file_pool;
518 sdbc_pwf_desc_t current;
519
520 nsc_fd_t *state_fd;
521 dev_t state_rdev;
522 int devmaj, devmin;
523 nsc_off_t blkno;
524 long len;
525 long total_len;
526 int pending;
527 int rc = 0;
528
529 /*
530 * Force wrthru just in case SLM software didn't really send us a
531 * warning. (Also makes for easier testing)
532 */
533 (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
534 /* disable all (dangerous) cache entry points */
535
536 cmn_err(CE_CONT, "sdbc(sdbc_power_flush) hint set..\n"); /* P3 */
537
538 _sdbc_shutdown_in_progress = 1;
539
540 #if 0
541 if (sdbc_io && (rc = nsc_unregister_io(sdbc_io, NSC_PCATCH)) != 0) {
542 /*
543 * this is bad, in theory we could just busy-out all our
544 * interfaces and continue.
545 */
546 cmn_err(CE_WARN,
547 "sdbc(_sdbc_power_flush) couldn't unregister i/o %d", rc);
548 return (rc);
549 }
550
551 sdbc_io = NULL;
552 #endif
553
554 /* wait for all i/o to finish/timeout ? */
555
556 if ((pending = _sdbc_wait_pending()) != 0)
557 cmn_err(CE_NOTE, "sdbc(_sdbc_power_flush) %d I/Os were"
558 " pending at power shutdown", pending);
559
560 cmn_err(CE_CONT, "sdbc(sdbc_power_flush) over pending\n"); /* P3 */
561
562 /* prevent any further async flushing */
563
564 _sdbc_flush_deconfigure();
565
566 /*
567 * At this point no higher level clients should be able to get thru.
568 * Failover i/o from the other node is our only other concern as
569 * far as disturbing the state of sdbc.
570 */
571
572 /* figure out the names for the string pool */
573
574 string_size = 0;
575 open_files = 0;
576 cdi = _sd_cache_files;
577 do {
578
579 if (cdi->cd_info == NULL)
580 continue;
581 if (cdi->cd_info->sh_alloc == 0)
582 continue;
583 open_files++;
584 string_size += strlen(cdi->cd_info->sh_filename) + 1;
585 } while (++cdi != &_sd_cache_files[sdbc_max_devs]);
586
587 if (open_files == 0) {
588 return (0);
589 }
590
591 hdrblk = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
592 bzero(hdrblk->cc_data, CACHE_BLOCK_SIZE);
593 hdr = (sdbc_pwf_hdr_t *)hdrblk->cc_data;
594 hdr->magic = SDBC_PWF_MAGIC;
595 hdr->alignment = CACHE_BLOCK_SIZE;
596 hdr->cd_count = open_files;
597 /* XXX bmap_size is redundant */
598 hdr->bmap_size = CACHE_BLOCK_SIZE / sizeof (sdbc_pwf_bitmap_t);
599
600 name_pool = sdbc_get_anon_list(string_size);
601 file_pool = sdbc_get_anon_list(sizeof (sdbc_pwf_desc_t) * open_files);
602
603 open_files = 0;
604 cdi = _sd_cache_files;
605 total_len = 0;
606 do {
607
608 if (cdi->cd_info == NULL)
609 continue;
610 if (cdi->cd_info->sh_alloc == 0)
611 continue;
612
613 len = strlen(cdi->cd_info->sh_filename) + 1;
614
615 /* copy the name to string pool */
616 sdbc_anon_copy(cdi->cd_info->sh_filename,
617 len, name_pool, total_len);
618
619 bzero(¤t, sizeof (current));
620 current.name = total_len;
621 sdbc_anon_copy((caddr_t)¤t, sizeof (current), file_pool,
622 open_files * sizeof (sdbc_pwf_desc_t));
623
624 open_files++;
625 total_len += len;
626
627 } while (++cdi != &_sd_cache_files[sdbc_max_devs]);
628
629 /* flush dirty data */
630
631 if (swfs.nswpf == 0 || swfs.names[0] == NULL) {
632 cmn_err(CE_WARN, "sdbc(_sdbc_power_flush): State file"
633 " is not configured");
634 rc = ENODEV;
635 goto cleanup;
636 }
637
638 if (!(state_fd =
639 nsc_open(swfs.names[0], NSC_DEVICE, NULL, NULL, &rc)) ||
640 !nsc_getval(state_fd, "DevMaj", (int *)&devmaj) ||
641 !nsc_getval(state_fd, "DevMin", (int *)&devmin)) {
642 if (state_fd) {
643 (void) nsc_close(state_fd);
644 }
645 /*
646 * We are hosed big time. We can't get device to write the
647 * state file opened.
648 */
649 cmn_err(CE_WARN, "sdbc(_sdbc_power_flush): Couldn't "
650 "open %s for saved state file", swfs.names[0]);
651 rc = EIO;
652 goto cleanup;
653 }
654
655 state_rdev = makedevice(devmaj, devmin);
656
657 blkno = 1;
658
659 hdr->string_pool = blkno;
660 rc = flush_anon_list(name_pool, state_rdev, &blkno);
661
662 hdr->descriptor_pool = blkno;
663 rc = flush_anon_list(file_pool, state_rdev, &blkno);
664
665 /*
666 * iterate across all devices, flushing the data and collecting bitmaps
667 */
668
669 open_files = 0;
670 for (cdi = _sd_cache_files;
671 cdi != &_sd_cache_files[sdbc_max_devs]; cdi++) {
672 nsc_off_t blk2;
673 nsc_off_t fp_off;
674
675 if (cdi->cd_info == NULL)
676 continue;
677 if (cdi->cd_info->sh_alloc == 0)
678 continue;
679
680 /* retrieve the file description so we can update it */
681 fp_off = (open_files++) * sizeof (sdbc_pwf_desc_t);
682 sdbc_anon_get(file_pool, fp_off,
683 (caddr_t)¤t, sizeof (current));
684
685 current.blocks = blkno;
686
687 if (cdi->cd_io_head) {
688 /*
689 * Need to wait for this to timeout?
690 * Seems like worst case we just write the data twice
691 * so we should be ok.
692 */
693 /*EMPTY*/
694 ;
695 }
696
697 start_bitmap_list(&bmap, hdr->bmap_size);
698
699 /* Flush the enqueued dirty data blocks */
700
701 (void) flush_centry_list(cdi, cdi->cd_dirty_head, state_rdev,
702 &blkno, 0, &bmap);
703 cdi->cd_dirty_head = NULL;
704 cdi->cd_dirty_tail = NULL;
705
706 /* Flush the failed dirty data blocks */
707
708 (void) flush_centry_list(cdi, cdi->cd_fail_head, state_rdev,
709 &blkno, 1, &bmap);
710 cdi->cd_fail_head = NULL;
711
712 /*
713 * Flush the in progress dirty data blocks. These really should
714 * really be null by now. Worst case we write the data again
715 * on recovery as we know the dirty masks won't change since
716 * flusher is stopped.
717 */
718
719 (void) flush_centry_list(cdi, cdi->cd_io_head, state_rdev,
720 &blkno, 0, &bmap);
721 cdi->cd_io_head = NULL;
722 cdi->cd_io_tail = NULL;
723
724 current.bitmaps = blkno;
725 current.nblocks = blkno - current.blocks;
726
727 (void) flush_bitmap_list(&bmap, state_rdev, &blkno);
728
729 /* update the current cd's file description */
730 sdbc_anon_copy((caddr_t)¤t, sizeof (current), file_pool,
731 fp_off);
732
733 blk2 = hdr->descriptor_pool;
734 rc = flush_anon_list(file_pool, state_rdev, &blk2);
735 }
736
737 #if !defined(_SunOS_5_6)
738 hdr->dump_time = ddi_get_time();
739 #else
740 hdr->dump_time = hrestime.tv_sec;
741 #endif
742 /* write the header at front and back */
743 (void) flush_hdr(hdrblk, state_rdev, blkno);
744 (void) flush_hdr(hdrblk, state_rdev, 0L);
745
746 /* P3 */
747 cmn_err(CE_CONT, "sdbc(sdbc_power_flush) %" NSC_SZFMT " total\n",
748 blkno);
749
750 cleanup:
751 ;
752 return (rc);
753
754 }
755
756 /*
757 * _sdbc_power_lost - System is running on UPS power we have "rideout"
758 * minutes of power left prior to shutdown. Get into a state where we
759 * will be ready should we need to shutdown.
760 *
761 * ARGUMENTS:
762 * rideout - minutes of power left prior to shutdown.
763 */
764 void
_sdbc_power_lost(int rideout)765 _sdbc_power_lost(int rideout)
766 {
767 cmn_err(CE_WARN, "sdbc(_sdbc_power_lost) battery time "
768 "remaining %d minute(s)", rideout);
769
770 got_hint = 1;
771 if (_sd_get_node_hint(&wrthru_hint))
772 got_hint = 0;
773
774 cmn_err(CE_WARN, "sdbc(_sdbc_power_lost) got hint %d "
775 "hint 0x%x", got_hint, wrthru_hint);
776
777 (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
778 saw_power_lost = 1;
779 }
780
781 /*
782 * _sdbc_power_ok - System is back running on mains power after
783 * seeing a power fail. Return to normal power up operation.
784 *
785 */
786 void
_sdbc_power_ok(void)787 _sdbc_power_ok(void)
788 {
789 cmn_err(CE_WARN, "sdbc(_sdbc_power_ok) power ok");
790 if (saw_power_lost && got_hint) {
791 /*
792 * In theory we have a race here between _sdbc_power_lost
793 * and here. However it is expected that power ioctls that
794 * cause these to be generated are sequential in nature
795 * so there is no race.
796 */
797 saw_power_lost = 0;
798 if (wrthru_hint & _SD_WRTHRU_MASK)
799 (void) _sd_set_node_hint(wrthru_hint & _SD_WRTHRU_MASK);
800 else
801 (void) _sd_clear_node_hint(_SD_WRTHRU_MASK);
802 }
803 }
804
805 /*
806 * _sdbc_power_down - System is running on UPS power and we must stop
807 * operation as the machine is now going down. Schedule a shutdown
808 * thread.
809 *
810 * When we return all cache activity will be blocked.
811 */
812 void
_sdbc_power_down(void)813 _sdbc_power_down(void)
814 {
815 cmn_err(CE_WARN, "sdbc(_sdbc_power_down) powering down...");
816 (void) _sdbc_power_flush();
817 }
818
819 /*
820 * Configure safe store from the general cache configuration ioctl.
821 */
822 int
_sdbc_pcu_config(int namec,char ** namev)823 _sdbc_pcu_config(int namec, char **namev)
824 {
825 int i;
826
827 if (swfs.nswpf != 0) {
828 /*
829 * This should not happen because cache protects itself
830 * from double configuration in sd_conf.c.
831 */
832 cmn_err(CE_CONT, "sdbc(_sdbc_pcu_config) double "
833 "configuration of Safe Store\n");
834 return (EINVAL);
835 }
836 swfs.colsize = 32; /* No way to configure in the general ioctl */
837
838 for (i = 0; i < namec; i++) {
839 if ((swfs.names[i] = kmem_alloc(strlen(namev[i])+1,
840 KM_NOSLEEP)) == NULL) {
841 _sdbc_pcu_cleanup(&swfs);
842 return (ENOMEM);
843 }
844 swfs.nswpf++;
845 (void) strcpy(swfs.names[i], namev[i]);
846 }
847
848 return (0);
849 }
850
851 /*
852 */
853 void
_sdbc_pcu_unload()854 _sdbc_pcu_unload()
855 {
856 _sdbc_pcu_cleanup(&swfs);
857 }
858
859 /*
860 * Destructor for struct swapfiles.
861 */
862 static void
_sdbc_pcu_cleanup(struct swapfiles * swp)863 _sdbc_pcu_cleanup(struct swapfiles *swp)
864 {
865 int i;
866 char *s;
867
868 for (i = 0; i < swp->nswpf; i++) {
869 if ((s = swp->names[i]) != NULL)
870 kmem_free(s, strlen(s)+1);
871 swp->names[i] = NULL;
872 }
873 swp->nswpf = 0;
874 }
875