xref: /illumos-gate/usr/src/uts/common/cpr/cpr_misc.c (revision 3d393ee6c37fa10ac512ed6d36109ad616dc7c1a)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/types.h>
29 #include <sys/errno.h>
30 #include <sys/cpuvar.h>
31 #include <sys/vfs.h>
32 #include <sys/vnode.h>
33 #include <sys/pathname.h>
34 #include <sys/callb.h>
35 #include <sys/fs/ufs_inode.h>
36 #include <vm/anon.h>
37 #include <sys/fs/swapnode.h>	/* for swapfs_minfree */
38 #include <sys/kmem.h>
39 #include <sys/cpr.h>
40 #include <sys/conf.h>
41 #include <sys/machclock.h>
42 
43 /*
44  * CPR miscellaneous support routines
45  */
46 #define	cpr_open(path, mode,  vpp)	(vn_open(path, UIO_SYSSPACE, \
47 		mode, 0600, vpp, CRCREAT, 0))
48 #define	cpr_rdwr(rw, vp, basep, cnt)	(vn_rdwr(rw, vp,  (caddr_t)(basep), \
49 		cnt, 0LL, UIO_SYSSPACE, 0, (rlim64_t)MAXOFF_T, CRED(), \
50 		(ssize_t *)NULL))
51 
52 extern void clkset(time_t);
53 extern cpu_t *i_cpr_bootcpu(void);
54 extern caddr_t i_cpr_map_setup(void);
55 extern void i_cpr_free_memory_resources(void);
56 
57 extern kmutex_t cpr_slock;
58 extern size_t cpr_buf_size;
59 extern char *cpr_buf;
60 extern size_t cpr_pagedata_size;
61 extern char *cpr_pagedata;
62 extern int cpr_bufs_allocated;
63 extern int cpr_bitmaps_allocated;
64 
65 #if defined(__sparc)
66 static struct cprconfig cprconfig;
67 static int cprconfig_loaded = 0;
68 static int cpr_statefile_ok(vnode_t *, int);
69 static int cpr_p_online(cpu_t *, int);
70 static void cpr_save_mp_state(void);
71 #endif
72 
73 int cpr_is_ufs(struct vfs *);
74 int cpr_is_zfs(struct vfs *);
75 
76 char cpr_default_path[] = CPR_DEFAULT;
77 
78 #define	COMPRESS_PERCENT 40	/* approx compression ratio in percent */
79 #define	SIZE_RATE	115	/* increase size by 15% */
80 #define	INTEGRAL	100	/* for integer math */
81 
82 
83 /*
84  * cmn_err() followed by a 1/4 second delay; this gives the
85  * logging service a chance to flush messages and helps avoid
86  * intermixing output from prom_printf().
87  */
88 /*PRINTFLIKE2*/
89 void
90 cpr_err(int ce, const char *fmt, ...)
91 {
92 	va_list adx;
93 
94 	va_start(adx, fmt);
95 	vcmn_err(ce, fmt, adx);
96 	va_end(adx);
97 	drv_usecwait(MICROSEC >> 2);
98 }
99 
100 
101 int
102 cpr_init(int fcn)
103 {
104 	/*
105 	 * Allow only one suspend/resume process.
106 	 */
107 	if (mutex_tryenter(&cpr_slock) == 0)
108 		return (EBUSY);
109 
110 	CPR->c_flags = 0;
111 	CPR->c_substate = 0;
112 	CPR->c_cprboot_magic = 0;
113 	CPR->c_alloc_cnt = 0;
114 
115 	CPR->c_fcn = fcn;
116 	if (fcn == AD_CPR_REUSABLE)
117 		CPR->c_flags |= C_REUSABLE;
118 	else
119 		CPR->c_flags |= C_SUSPENDING;
120 	if (fcn == AD_SUSPEND_TO_RAM || fcn == DEV_SUSPEND_TO_RAM) {
121 		return (0);
122 	}
123 #if defined(__sparc)
124 	if (fcn != AD_CPR_NOCOMPRESS && fcn != AD_CPR_TESTNOZ)
125 		CPR->c_flags |= C_COMPRESSING;
126 	/*
127 	 * reserve CPR_MAXCONTIG virtual pages for cpr_dump()
128 	 */
129 	CPR->c_mapping_area = i_cpr_map_setup();
130 	if (CPR->c_mapping_area == 0) {		/* no space in kernelmap */
131 		cpr_err(CE_CONT, "Unable to alloc from kernelmap.\n");
132 		mutex_exit(&cpr_slock);
133 		return (EAGAIN);
134 	}
135 	if (cpr_debug & CPR_DEBUG3)
136 		cpr_err(CE_CONT, "Reserved virtual range from 0x%p for writing "
137 		    "kas\n", (void *)CPR->c_mapping_area);
138 #endif
139 
140 	return (0);
141 }
142 
143 /*
144  * This routine releases any resources used during the checkpoint.
145  */
146 void
147 cpr_done(void)
148 {
149 	cpr_stat_cleanup();
150 	i_cpr_bitmap_cleanup();
151 
152 	/*
153 	 * Free pages used by cpr buffers.
154 	 */
155 	if (cpr_buf) {
156 		kmem_free(cpr_buf, cpr_buf_size);
157 		cpr_buf = NULL;
158 	}
159 	if (cpr_pagedata) {
160 		kmem_free(cpr_pagedata, cpr_pagedata_size);
161 		cpr_pagedata = NULL;
162 	}
163 
164 	i_cpr_free_memory_resources();
165 	mutex_exit(&cpr_slock);
166 	cpr_err(CE_CONT, "System has been resumed.\n");
167 }
168 
169 
170 #if defined(__sparc)
171 /*
172  * reads config data into cprconfig
173  */
174 static int
175 cpr_get_config(void)
176 {
177 	static char config_path[] = CPR_CONFIG;
178 	struct cprconfig *cf = &cprconfig;
179 	struct vnode *vp;
180 	char *fmt;
181 	int err;
182 
183 	if (cprconfig_loaded)
184 		return (0);
185 
186 	fmt = "cannot %s config file \"%s\", error %d\n";
187 	if (err = vn_open(config_path, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0)) {
188 		cpr_err(CE_CONT, fmt, "open", config_path, err);
189 		return (err);
190 	}
191 
192 	err = cpr_rdwr(UIO_READ, vp, cf, sizeof (*cf));
193 	(void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
194 	VN_RELE(vp);
195 	if (err) {
196 		cpr_err(CE_CONT, fmt, "read", config_path, err);
197 		return (err);
198 	}
199 
200 	if (cf->cf_magic == CPR_CONFIG_MAGIC)
201 		cprconfig_loaded = 1;
202 	else {
203 		cpr_err(CE_CONT, "invalid config file \"%s\", "
204 		    "rerun pmconfig(1M)\n", config_path);
205 		err = EINVAL;
206 	}
207 
208 	return (err);
209 }
210 
211 
212 /*
213  * concat fs and path fields of the cprconfig structure;
214  * returns pointer to the base of static data
215  */
216 static char *
217 cpr_cprconfig_to_path(void)
218 {
219 	static char full_path[MAXNAMELEN];
220 	struct cprconfig *cf = &cprconfig;
221 	char *ptr;
222 
223 	/*
224 	 * build /fs/path without extra '/'
225 	 */
226 	(void) strcpy(full_path, cf->cf_fs);
227 	if (strcmp(cf->cf_fs, "/"))
228 		(void) strcat(full_path, "/");
229 	ptr = cf->cf_path;
230 	if (*ptr == '/')
231 		ptr++;
232 	(void) strcat(full_path, ptr);
233 	return (full_path);
234 }
235 
236 
237 /*
238  * Verify that the information in the configuration file regarding the
239  * location for the statefile is still valid, depending on cf_type.
240  * for CFT_UFS, cf_fs must still be a mounted filesystem, it must be
241  *	mounted on the same device as when pmconfig was last run,
242  *	and the translation of that device to a node in the prom's
243  *	device tree must be the same as when pmconfig was last run.
244  * for CFT_SPEC and CFT_ZVOL, cf_path must be the path to a block
245  *      special file, it must have no file system mounted on it,
246  *	and the translation of that device to a node in the prom's
247  *	device tree must be the same as when pmconfig was last run.
248  */
249 static int
250 cpr_verify_statefile_path(void)
251 {
252 	struct cprconfig *cf = &cprconfig;
253 	static const char long_name[] = "Statefile pathname is too long.\n";
254 	static const char lookup_fmt[] = "Lookup failed for "
255 	    "cpr statefile device %s.\n";
256 	static const char path_chg_fmt[] = "Device path for statefile "
257 	    "has changed from %s to %s.\t%s\n";
258 	static const char rerun[] = "Please rerun pmconfig(1m).";
259 	struct vfs *vfsp = NULL, *vfsp_save = rootvfs;
260 	ufsvfs_t *ufsvfsp = (ufsvfs_t *)rootvfs->vfs_data;
261 	ufsvfs_t *ufsvfsp_save = ufsvfsp;
262 	int error;
263 	struct vnode *vp;
264 	char *slash, *tail, *longest;
265 	char *errstr;
266 	int found = 0;
267 	union {
268 		char un_devpath[OBP_MAXPATHLEN];
269 		char un_sfpath[MAXNAMELEN];
270 	} un;
271 #define	devpath	un.un_devpath
272 #define	sfpath	un.un_sfpath
273 
274 	ASSERT(cprconfig_loaded);
275 	/*
276 	 * We need not worry about locking or the timing of releasing
277 	 * the vnode, since we are single-threaded now.
278 	 */
279 
280 	switch (cf->cf_type) {
281 	case CFT_SPEC:
282 		error = i_devname_to_promname(cf->cf_devfs, devpath,
283 		    OBP_MAXPATHLEN);
284 		if (error || strcmp(devpath, cf->cf_dev_prom)) {
285 			cpr_err(CE_CONT, path_chg_fmt,
286 			    cf->cf_dev_prom, devpath, rerun);
287 			return (error);
288 		}
289 		/*FALLTHROUGH*/
290 	case CFT_ZVOL:
291 		if (strlen(cf->cf_path) > sizeof (sfpath)) {
292 			cpr_err(CE_CONT, long_name);
293 			return (ENAMETOOLONG);
294 		}
295 		if ((error = lookupname(cf->cf_devfs,
296 		    UIO_SYSSPACE, FOLLOW, NULLVPP, &vp)) != 0) {
297 			cpr_err(CE_CONT, lookup_fmt, cf->cf_devfs);
298 			return (error);
299 		}
300 		if (vp->v_type != VBLK)
301 			errstr = "statefile must be a block device";
302 		else if (vfs_devismounted(vp->v_rdev))
303 			errstr = "statefile device must not "
304 			    "have a file system mounted on it";
305 		else if (IS_SWAPVP(vp))
306 			errstr = "statefile device must not "
307 			    "be configured as swap file";
308 		else
309 			errstr = NULL;
310 
311 		VN_RELE(vp);
312 		if (errstr) {
313 			cpr_err(CE_CONT, "%s.\n", errstr);
314 			return (ENOTSUP);
315 		}
316 
317 		return (error);
318 	case CFT_UFS:
319 		break;		/* don't indent all the original code */
320 	default:
321 		cpr_err(CE_PANIC, "invalid cf_type");
322 	}
323 
324 	/*
325 	 * The original code for UFS statefile
326 	 */
327 	if (strlen(cf->cf_fs) + strlen(cf->cf_path) + 2 > sizeof (sfpath)) {
328 		cpr_err(CE_CONT, long_name);
329 		return (ENAMETOOLONG);
330 	}
331 
332 	bzero(sfpath, sizeof (sfpath));
333 	(void) strcpy(sfpath, cpr_cprconfig_to_path());
334 
335 	if (*sfpath != '/') {
336 		cpr_err(CE_CONT, "Statefile pathname %s "
337 		    "must begin with a /\n", sfpath);
338 		return (EINVAL);
339 	}
340 
341 	/*
342 	 * Find the longest prefix of the statefile pathname which
343 	 * is the mountpoint of a filesystem.  This string must
344 	 * match the cf_fs field we read from the config file.  Other-
345 	 * wise the user has changed things without running pmconfig.
346 	 */
347 	tail = longest = sfpath + 1;	/* pt beyond the leading "/" */
348 	while ((slash = strchr(tail, '/')) != NULL) {
349 		*slash = '\0';	  /* temporarily terminate the string */
350 		if ((error = lookupname(sfpath,
351 		    UIO_SYSSPACE, FOLLOW, NULLVPP, &vp)) != 0) {
352 			*slash = '/';
353 			cpr_err(CE_CONT, "A directory in the "
354 			    "statefile path %s was not found.\n", sfpath);
355 			VN_RELE(vp);
356 
357 			return (error);
358 		}
359 
360 		vfs_list_read_lock();
361 		vfsp = rootvfs;
362 		do {
363 			ufsvfsp = (struct ufsvfs *)vfsp->vfs_data;
364 			if (ufsvfsp != NULL && ufsvfsp->vfs_root == vp) {
365 				found = 1;
366 				break;
367 			}
368 			vfsp = vfsp->vfs_next;
369 		} while (vfsp != rootvfs);
370 		vfs_list_unlock();
371 
372 		/*
373 		 * If we have found a filesystem mounted on the current
374 		 * path prefix, remember the end of the string in
375 		 * "longest".  If it happens to be the the exact fs
376 		 * saved in the configuration file, save the current
377 		 * ufsvfsp so we can make additional checks further down.
378 		 */
379 		if (found) {
380 			longest = slash;
381 			if (strcmp(cf->cf_fs, sfpath) == 0) {
382 				ufsvfsp_save = ufsvfsp;
383 				vfsp_save = vfsp;
384 			}
385 			found = 0;
386 		}
387 
388 		VN_RELE(vp);
389 		*slash = '/';
390 		tail = slash + 1;
391 	}
392 	*longest = '\0';
393 	if (cpr_is_ufs(vfsp_save) == 0 || strcmp(cf->cf_fs, sfpath)) {
394 		cpr_err(CE_CONT, "Filesystem containing "
395 		    "the statefile when pmconfig was run (%s) has "
396 		    "changed to %s. %s\n", cf->cf_fs, sfpath, rerun);
397 		return (EINVAL);
398 	}
399 
400 	if ((error = lookupname(cf->cf_devfs,
401 	    UIO_SYSSPACE, FOLLOW, NULLVPP, &vp)) != 0) {
402 		cpr_err(CE_CONT, lookup_fmt, cf->cf_devfs);
403 		return (error);
404 	}
405 
406 	if (ufsvfsp_save->vfs_devvp->v_rdev != vp->v_rdev) {
407 		cpr_err(CE_CONT, "Filesystem containing "
408 		    "statefile no longer mounted on device %s. "
409 		    "See power.conf(4).", cf->cf_devfs);
410 		VN_RELE(vp);
411 		return (ENXIO);
412 	}
413 	VN_RELE(vp);
414 
415 	error = i_devname_to_promname(cf->cf_devfs, devpath, OBP_MAXPATHLEN);
416 	if (error || strcmp(devpath, cf->cf_dev_prom)) {
417 		cpr_err(CE_CONT, path_chg_fmt,
418 		    cf->cf_dev_prom, devpath, rerun);
419 		return (error);
420 	}
421 
422 	return (0);
423 }
424 
425 /*
426  * Make sure that the statefile can be used as a block special statefile
427  * (meaning that is exists and has nothing mounted on it)
428  * Returns errno if not a valid statefile.
429  */
430 int
431 cpr_check_spec_statefile(void)
432 {
433 	int err;
434 
435 	if (err = cpr_get_config())
436 		return (err);
437 	ASSERT(cprconfig.cf_type == CFT_SPEC ||
438 	    cprconfig.cf_type == CFT_ZVOL);
439 
440 	if (cprconfig.cf_devfs == NULL)
441 		return (ENXIO);
442 
443 	return (cpr_verify_statefile_path());
444 
445 }
446 
447 int
448 cpr_alloc_statefile(int alloc_retry)
449 {
450 	register int rc = 0;
451 	char *str;
452 
453 	/*
454 	 * Statefile size validation. If checkpoint the first time, disk blocks
455 	 * allocation will be done; otherwise, just do file size check.
456 	 * if statefile allocation is being retried, C_VP will be inited
457 	 */
458 	if (alloc_retry) {
459 		str = "\n-->Retrying statefile allocation...";
460 		if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG7))
461 			prom_printf(str);
462 		if (C_VP->v_type != VBLK)
463 			(void) VOP_DUMPCTL(C_VP, DUMP_FREE, NULL, NULL);
464 	} else {
465 		/*
466 		 * Open an exiting file for writing, the state file needs to be
467 		 * pre-allocated since we can't and don't want to do allocation
468 		 * during checkpoint (too much of the OS is disabled).
469 		 *    - do a preliminary size checking here, if it is too small,
470 		 *	allocate more space internally and retry.
471 		 *    - check the vp to make sure it's the right type.
472 		 */
473 		char *path = cpr_build_statefile_path();
474 
475 		if (path == NULL)
476 			return (ENXIO);
477 		else if (rc = cpr_verify_statefile_path())
478 			return (rc);
479 
480 		if (rc = vn_open(path, UIO_SYSSPACE,
481 		    FCREAT|FWRITE, 0600, &C_VP, CRCREAT, 0)) {
482 			cpr_err(CE_WARN, "cannot open statefile %s", path);
483 			return (rc);
484 		}
485 	}
486 
487 	/*
488 	 * Only ufs and block special statefiles supported
489 	 */
490 	if (C_VP->v_type != VREG && C_VP->v_type != VBLK) {
491 		cpr_err(CE_CONT,
492 		    "Statefile must be regular file or block special file.");
493 		return (EACCES);
494 	}
495 
496 	if (rc = cpr_statefile_ok(C_VP, alloc_retry))
497 		return (rc);
498 
499 	if (C_VP->v_type != VBLK) {
500 		/*
501 		 * sync out the fs change due to the statefile reservation.
502 		 */
503 		(void) VFS_SYNC(C_VP->v_vfsp, 0, CRED());
504 
505 		/*
506 		 * Validate disk blocks allocation for the state file.
507 		 * Ask the file system prepare itself for the dump operation.
508 		 */
509 		if (rc = VOP_DUMPCTL(C_VP, DUMP_ALLOC, NULL, NULL)) {
510 			cpr_err(CE_CONT, "Error allocating "
511 			    "blocks for cpr statefile.");
512 			return (rc);
513 		}
514 	}
515 	return (0);
516 }
517 
518 
519 /*
520  * Lookup device size and return available space in bytes.
521  * NOTE: Since prop_op(9E) can't tell the difference between a character
522  * and a block reference, it is ok to ask for "Size" instead of "Nblocks".
523  */
524 size_t
525 cpr_get_devsize(dev_t dev)
526 {
527 	size_t bytes = 0;
528 
529 	bytes = cdev_Size(dev);
530 	if (bytes == 0)
531 		bytes = cdev_size(dev);
532 
533 	if (bytes > CPR_SPEC_OFFSET)
534 		bytes -= CPR_SPEC_OFFSET;
535 	else
536 		bytes = 0;
537 
538 	return (bytes);
539 }
540 
541 
542 /*
543  * increase statefile size
544  */
545 static int
546 cpr_grow_statefile(vnode_t *vp, u_longlong_t newsize)
547 {
548 	extern uchar_t cpr_pagecopy[];
549 	struct inode *ip = VTOI(vp);
550 	u_longlong_t offset;
551 	int error, increase;
552 	ssize_t resid;
553 
554 	rw_enter(&ip->i_contents, RW_READER);
555 	increase = (ip->i_size < newsize);
556 	offset = ip->i_size;
557 	rw_exit(&ip->i_contents);
558 
559 	if (increase == 0)
560 		return (0);
561 
562 	/*
563 	 * write to each logical block to reserve disk space
564 	 */
565 	error = 0;
566 	cpr_pagecopy[0] = '1';
567 	for (; offset < newsize; offset += ip->i_fs->fs_bsize) {
568 		if (error = vn_rdwr(UIO_WRITE, vp, (caddr_t)cpr_pagecopy,
569 		    ip->i_fs->fs_bsize, (offset_t)offset, UIO_SYSSPACE, 0,
570 		    (rlim64_t)MAXOFF_T, CRED(), &resid)) {
571 			if (error == ENOSPC) {
572 				cpr_err(CE_WARN, "error %d while reserving "
573 				    "disk space for statefile %s\n"
574 				    "wanted %lld bytes, file is %lld short",
575 				    error, cpr_cprconfig_to_path(),
576 				    newsize, newsize - offset);
577 			}
578 			break;
579 		}
580 	}
581 	return (error);
582 }
583 
584 
585 /*
586  * do a simple estimate of the space needed to hold the statefile
587  * taking compression into account, but be fairly conservative
588  * so we have a better chance of completing; when dump fails,
589  * the retry cost is fairly high.
590  *
591  * Do disk blocks allocation for the state file if no space has
592  * been allocated yet. Since the state file will not be removed,
593  * allocation should only be done once.
594  */
595 static int
596 cpr_statefile_ok(vnode_t *vp, int alloc_retry)
597 {
598 	extern size_t cpr_bitmap_size;
599 	struct inode *ip = VTOI(vp);
600 	const int UCOMP_RATE = 20; /* comp. ratio*10 for user pages */
601 	u_longlong_t size, isize, ksize, raw_data;
602 	char *str, *est_fmt;
603 	size_t space;
604 	int error;
605 
606 	/*
607 	 * number of pages short for swapping.
608 	 */
609 	STAT->cs_nosw_pages = k_anoninfo.ani_mem_resv;
610 	if (STAT->cs_nosw_pages < 0)
611 		STAT->cs_nosw_pages = 0;
612 
613 	str = "cpr_statefile_ok:";
614 
615 	CPR_DEBUG(CPR_DEBUG9, "Phys swap: max=%lu resv=%lu\n",
616 	    k_anoninfo.ani_max, k_anoninfo.ani_phys_resv);
617 	CPR_DEBUG(CPR_DEBUG9, "Mem swap: max=%ld resv=%lu\n",
618 	    MAX(availrmem - swapfs_minfree, 0),
619 	    k_anoninfo.ani_mem_resv);
620 	CPR_DEBUG(CPR_DEBUG9, "Total available swap: %ld\n",
621 	    CURRENT_TOTAL_AVAILABLE_SWAP);
622 
623 	/*
624 	 * try increasing filesize by 15%
625 	 */
626 	if (alloc_retry) {
627 		/*
628 		 * block device doesn't get any bigger
629 		 */
630 		if (vp->v_type == VBLK) {
631 			if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6))
632 				prom_printf(
633 				    "Retry statefile on special file\n");
634 			return (ENOMEM);
635 		} else {
636 			rw_enter(&ip->i_contents, RW_READER);
637 			size = (ip->i_size * SIZE_RATE) / INTEGRAL;
638 			rw_exit(&ip->i_contents);
639 		}
640 		if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6))
641 			prom_printf("Retry statefile size = %lld\n", size);
642 	} else {
643 		u_longlong_t cpd_size;
644 		pgcnt_t npages, nback;
645 		int ndvram;
646 
647 		ndvram = 0;
648 		(void) callb_execute_class(CB_CL_CPR_FB,
649 		    (int)(uintptr_t)&ndvram);
650 		if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6))
651 			prom_printf("ndvram size = %d\n", ndvram);
652 
653 		/*
654 		 * estimate 1 cpd_t for every (CPR_MAXCONTIG / 2) pages
655 		 */
656 		npages = cpr_count_kpages(REGULAR_BITMAP, cpr_nobit);
657 		cpd_size = sizeof (cpd_t) * (npages / (CPR_MAXCONTIG / 2));
658 		raw_data = cpd_size + cpr_bitmap_size;
659 		ksize = ndvram + mmu_ptob(npages);
660 
661 		est_fmt = "%s estimated size with "
662 		    "%scompression %lld, ksize %lld\n";
663 		nback = mmu_ptob(STAT->cs_nosw_pages);
664 		if (CPR->c_flags & C_COMPRESSING) {
665 			size = ((ksize * COMPRESS_PERCENT) / INTEGRAL) +
666 			    raw_data + ((nback * 10) / UCOMP_RATE);
667 			CPR_DEBUG(CPR_DEBUG1, est_fmt, str, "", size, ksize);
668 		} else {
669 			size = ksize + raw_data + nback;
670 			CPR_DEBUG(CPR_DEBUG1, est_fmt, str, "no ",
671 			    size, ksize);
672 		}
673 	}
674 
675 	/*
676 	 * All this is much simpler for a block device
677 	 */
678 	if (vp->v_type == VBLK) {
679 		space = cpr_get_devsize(vp->v_rdev);
680 		if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6))
681 			prom_printf("statefile dev size %lu\n", space);
682 
683 		/*
684 		 * Export the estimated filesize info, this value will be
685 		 * compared before dumping out the statefile in the case of
686 		 * no compression.
687 		 */
688 		STAT->cs_est_statefsz = size;
689 		if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6))
690 			prom_printf("%s Estimated statefile size %llu, "
691 			    "space %lu\n", str, size, space);
692 		if (size > space) {
693 			cpr_err(CE_CONT, "Statefile partition too small.");
694 			return (ENOMEM);
695 		}
696 		return (0);
697 	} else {
698 		if (CPR->c_alloc_cnt++ > C_MAX_ALLOC_RETRY) {
699 			cpr_err(CE_CONT, "Statefile allocation retry failed\n");
700 			return (ENOMEM);
701 		}
702 
703 		/*
704 		 * Estimate space needed for the state file.
705 		 *
706 		 * State file size in bytes:
707 		 * 	kernel size + non-cache pte seg +
708 		 *	bitmap size + cpr state file headers size
709 		 * (round up to fs->fs_bsize)
710 		 */
711 		size = blkroundup(ip->i_fs, size);
712 
713 		/*
714 		 * Export the estimated filesize info, this value will be
715 		 * compared before dumping out the statefile in the case of
716 		 * no compression.
717 		 */
718 		STAT->cs_est_statefsz = size;
719 		error = cpr_grow_statefile(vp, size);
720 		if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6)) {
721 			rw_enter(&ip->i_contents, RW_READER);
722 			isize = ip->i_size;
723 			rw_exit(&ip->i_contents);
724 			prom_printf("%s Estimated statefile size %lld, "
725 			    "i_size %lld\n", str, size, isize);
726 		}
727 
728 		return (error);
729 	}
730 }
731 
732 
733 void
734 cpr_statef_close(void)
735 {
736 	if (C_VP) {
737 		if (!cpr_reusable_mode)
738 			(void) VOP_DUMPCTL(C_VP, DUMP_FREE, NULL, NULL);
739 		(void) VOP_CLOSE(C_VP, FWRITE, 1, (offset_t)0, CRED(), NULL);
740 		VN_RELE(C_VP);
741 		C_VP = 0;
742 	}
743 }
744 
745 
746 /*
747  * open cpr default file and display error
748  */
749 int
750 cpr_open_deffile(int mode, vnode_t **vpp)
751 {
752 	int error;
753 
754 	if (error = cpr_open(cpr_default_path, mode, vpp))
755 		cpr_err(CE_CONT, "cannot open \"%s\", error %d\n",
756 		    cpr_default_path, error);
757 	return (error);
758 }
759 
760 
761 /*
762  * write cdef_t to disk.  This contains the original values of prom
763  * properties that we modify.  We fill in the magic number of the file
764  * here as a signal to the booter code that the state file is valid.
765  * Be sure the file gets synced, since we may be shutting down the OS.
766  */
767 int
768 cpr_write_deffile(cdef_t *cdef)
769 {
770 	struct vnode *vp;
771 	char *str;
772 	int rc;
773 
774 	if (rc = cpr_open_deffile(FCREAT|FWRITE, &vp))
775 		return (rc);
776 
777 	if (rc = cpr_rdwr(UIO_WRITE, vp, cdef, sizeof (*cdef)))
778 		str = "write";
779 	else if (rc = VOP_FSYNC(vp, FSYNC, CRED(), NULL))
780 		str = "fsync";
781 	(void) VOP_CLOSE(vp, FWRITE, 1, (offset_t)0, CRED(), NULL);
782 	VN_RELE(vp);
783 
784 	if (rc) {
785 		cpr_err(CE_WARN, "%s error %d, file \"%s\"",
786 		    str, rc, cpr_default_path);
787 	}
788 	return (rc);
789 }
790 
791 /*
792  * Clear the magic number in the defaults file.  This tells the booter
793  * program that the state file is not current and thus prevents
794  * any attempt to restore from an obsolete state file.
795  */
796 void
797 cpr_clear_definfo(void)
798 {
799 	struct vnode *vp;
800 	cmini_t mini;
801 
802 	if ((CPR->c_cprboot_magic != CPR_DEFAULT_MAGIC) ||
803 	    cpr_open_deffile(FCREAT|FWRITE, &vp))
804 		return;
805 	mini.magic = mini.reusable = 0;
806 	(void) cpr_rdwr(UIO_WRITE, vp, &mini, sizeof (mini));
807 	(void) VOP_CLOSE(vp, FWRITE, 1, (offset_t)0, CRED(), NULL);
808 	VN_RELE(vp);
809 }
810 
811 /*
812  * If the cpr default file is invalid, then we must not be in reusable mode
813  * if it is valid, it tells us our mode
814  */
815 int
816 cpr_get_reusable_mode(void)
817 {
818 	struct vnode *vp;
819 	cmini_t mini;
820 	int rc;
821 
822 	if (cpr_open(cpr_default_path, FREAD, &vp))
823 		return (0);
824 
825 	rc = cpr_rdwr(UIO_READ, vp, &mini, sizeof (mini));
826 	(void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
827 	VN_RELE(vp);
828 	if (rc == 0 && mini.magic == CPR_DEFAULT_MAGIC)
829 		return (mini.reusable);
830 
831 	return (0);
832 }
833 #endif
834 
835 /*
836  * clock/time related routines
837  */
838 static time_t   cpr_time_stamp;
839 
840 
841 void
842 cpr_tod_get(cpr_time_t *ctp)
843 {
844 	timestruc_t ts;
845 
846 	mutex_enter(&tod_lock);
847 	ts = TODOP_GET(tod_ops);
848 	mutex_exit(&tod_lock);
849 	ctp->tv_sec = (time32_t)ts.tv_sec;
850 	ctp->tv_nsec = (int32_t)ts.tv_nsec;
851 }
852 
853 void
854 cpr_tod_fault_reset(void)
855 {
856 	mutex_enter(&tod_lock);
857 	tod_fault_reset();
858 	mutex_exit(&tod_lock);
859 }
860 
861 void
862 cpr_save_time(void)
863 {
864 	cpr_time_stamp = gethrestime_sec();
865 }
866 
867 /*
868  * correct time based on saved time stamp or hardware clock
869  */
870 void
871 cpr_restore_time(void)
872 {
873 	clkset(cpr_time_stamp);
874 }
875 
876 #if defined(__sparc)
877 /*
878  * CPU ONLINE/OFFLINE CODE
879  */
880 int
881 cpr_mp_offline(void)
882 {
883 	cpu_t *cp, *bootcpu;
884 	int rc = 0;
885 	int brought_up_boot = 0;
886 
887 	/*
888 	 * Do nothing for UP.
889 	 */
890 	if (ncpus == 1)
891 		return (0);
892 
893 	mutex_enter(&cpu_lock);
894 
895 	cpr_save_mp_state();
896 
897 	bootcpu = i_cpr_bootcpu();
898 	if (!CPU_ACTIVE(bootcpu)) {
899 		if ((rc = cpr_p_online(bootcpu, CPU_CPR_ONLINE))) {
900 			mutex_exit(&cpu_lock);
901 			return (rc);
902 		}
903 		brought_up_boot = 1;
904 	}
905 
906 	cp = cpu_list;
907 	do {
908 		if (cp == bootcpu)
909 			continue;
910 		if (cp->cpu_flags & CPU_OFFLINE)
911 			continue;
912 		if ((rc = cpr_p_online(cp, CPU_CPR_OFFLINE))) {
913 			mutex_exit(&cpu_lock);
914 			return (rc);
915 		}
916 	} while ((cp = cp->cpu_next) != cpu_list);
917 	if (brought_up_boot && (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6)))
918 		prom_printf("changed cpu %p to state %d\n",
919 		    (void *)bootcpu, CPU_CPR_ONLINE);
920 	mutex_exit(&cpu_lock);
921 
922 	return (rc);
923 }
924 
925 int
926 cpr_mp_online(void)
927 {
928 	cpu_t *cp, *bootcpu = CPU;
929 	int rc = 0;
930 
931 	/*
932 	 * Do nothing for UP.
933 	 */
934 	if (ncpus == 1)
935 		return (0);
936 
937 	/*
938 	 * cpr_save_mp_state() sets CPU_CPR_ONLINE in cpu_cpr_flags
939 	 * to indicate a cpu was online at the time of cpr_suspend();
940 	 * now restart those cpus that were marked as CPU_CPR_ONLINE
941 	 * and actually are offline.
942 	 */
943 	mutex_enter(&cpu_lock);
944 	for (cp = bootcpu->cpu_next; cp != bootcpu; cp = cp->cpu_next) {
945 		/*
946 		 * Clear the CPU_FROZEN flag in all cases.
947 		 */
948 		cp->cpu_flags &= ~CPU_FROZEN;
949 
950 		if (CPU_CPR_IS_OFFLINE(cp))
951 			continue;
952 		if (CPU_ACTIVE(cp))
953 			continue;
954 		if ((rc = cpr_p_online(cp, CPU_CPR_ONLINE))) {
955 			mutex_exit(&cpu_lock);
956 			return (rc);
957 		}
958 	}
959 
960 	/*
961 	 * turn off the boot cpu if it was offlined
962 	 */
963 	if (CPU_CPR_IS_OFFLINE(bootcpu)) {
964 		if ((rc = cpr_p_online(bootcpu, CPU_CPR_OFFLINE))) {
965 			mutex_exit(&cpu_lock);
966 			return (rc);
967 		}
968 	}
969 	mutex_exit(&cpu_lock);
970 	return (0);
971 }
972 
973 static void
974 cpr_save_mp_state(void)
975 {
976 	cpu_t *cp;
977 
978 	ASSERT(MUTEX_HELD(&cpu_lock));
979 
980 	cp = cpu_list;
981 	do {
982 		cp->cpu_cpr_flags &= ~CPU_CPR_ONLINE;
983 		if (CPU_ACTIVE(cp))
984 			CPU_SET_CPR_FLAGS(cp, CPU_CPR_ONLINE);
985 	} while ((cp = cp->cpu_next) != cpu_list);
986 }
987 
988 /*
989  * change cpu to online/offline
990  */
991 static int
992 cpr_p_online(cpu_t *cp, int state)
993 {
994 	int rc;
995 
996 	ASSERT(MUTEX_HELD(&cpu_lock));
997 
998 	switch (state) {
999 	case CPU_CPR_ONLINE:
1000 		rc = cpu_online(cp);
1001 		break;
1002 	case CPU_CPR_OFFLINE:
1003 		rc = cpu_offline(cp, CPU_FORCED);
1004 		break;
1005 	}
1006 	if (rc) {
1007 		cpr_err(CE_WARN, "Failed to change processor %d to "
1008 		    "state %d, (errno %d)", cp->cpu_id, state, rc);
1009 	}
1010 	return (rc);
1011 }
1012 
1013 /*
1014  * Construct the pathname of the state file and return a pointer to
1015  * caller.  Read the config file to get the mount point of the
1016  * filesystem and the pathname within fs.
1017  */
1018 char *
1019 cpr_build_statefile_path(void)
1020 {
1021 	struct cprconfig *cf = &cprconfig;
1022 
1023 	if (cpr_get_config())
1024 		return (NULL);
1025 
1026 	switch (cf->cf_type) {
1027 	case CFT_UFS:
1028 		if (strlen(cf->cf_path) + strlen(cf->cf_fs) >= MAXNAMELEN - 1) {
1029 			cpr_err(CE_CONT, "Statefile path is too long.\n");
1030 			return (NULL);
1031 		}
1032 		return (cpr_cprconfig_to_path());
1033 	case CFT_ZVOL:
1034 		/*FALLTHROUGH*/
1035 	case CFT_SPEC:
1036 		return (cf->cf_devfs);
1037 	default:
1038 		cpr_err(CE_PANIC, "invalid statefile type");
1039 		/*NOTREACHED*/
1040 		return (NULL);
1041 	}
1042 }
1043 
1044 int
1045 cpr_statefile_is_spec(void)
1046 {
1047 	if (cpr_get_config())
1048 		return (0);
1049 	return (cprconfig.cf_type == CFT_SPEC);
1050 }
1051 
1052 char *
1053 cpr_get_statefile_prom_path(void)
1054 {
1055 	struct cprconfig *cf = &cprconfig;
1056 
1057 	ASSERT(cprconfig_loaded);
1058 	ASSERT(cf->cf_magic == CPR_CONFIG_MAGIC);
1059 	ASSERT(cf->cf_type == CFT_SPEC || cf->cf_type == CFT_ZVOL);
1060 	return (cf->cf_dev_prom);
1061 }
1062 
1063 
1064 /*
1065  * XXX The following routines need to be in the vfs source code.
1066  */
1067 
1068 int
1069 cpr_is_ufs(struct vfs *vfsp)
1070 {
1071 	char *fsname;
1072 
1073 	fsname = vfssw[vfsp->vfs_fstype].vsw_name;
1074 	return (strcmp(fsname, "ufs") == 0);
1075 }
1076 
1077 int
1078 cpr_is_zfs(struct vfs *vfsp)
1079 {
1080 	char *fsname;
1081 
1082 	fsname = vfssw[vfsp->vfs_fstype].vsw_name;
1083 	return (strcmp(fsname, "zfs") == 0);
1084 }
1085 
1086 /*
1087  * This is a list of file systems that are allowed to be writeable when a
1088  * reusable statefile checkpoint is taken.  They must not have any state that
1089  * cannot be restored to consistency by simply rebooting using the checkpoint.
1090  * (In contrast to ufs, cachefs and pcfs which have disk state that could get
1091  * out of sync with the in-kernel data).
1092  */
1093 int
1094 cpr_reusable_mount_check(void)
1095 {
1096 	struct vfs *vfsp;
1097 	char *fsname;
1098 	char **cpp;
1099 	static char *cpr_writeok_fss[] = {
1100 		"autofs", "devfs", "fd", "lofs", "mntfs", "namefs", "nfs",
1101 		"proc", "tmpfs", "ctfs", "objfs", "dev", NULL
1102 	};
1103 
1104 	vfs_list_read_lock();
1105 	vfsp = rootvfs;
1106 	do {
1107 		if (vfsp->vfs_flag & VFS_RDONLY) {
1108 			vfsp = vfsp->vfs_next;
1109 			continue;
1110 		}
1111 		fsname = vfssw[vfsp->vfs_fstype].vsw_name;
1112 		for (cpp = cpr_writeok_fss; *cpp; cpp++) {
1113 			if (strcmp(fsname, *cpp) == 0)
1114 				break;
1115 		}
1116 		/*
1117 		 * if the inner loop reached the NULL terminator,
1118 		 * the current fs-type does not match any OK-type
1119 		 */
1120 		if (*cpp == NULL) {
1121 			cpr_err(CE_CONT, "a filesystem of type %s is "
1122 			    "mounted read/write.\nReusable statefile requires "
1123 			    "no writeable filesystem of this type be mounted\n",
1124 			    fsname);
1125 			vfs_list_unlock();
1126 			return (EINVAL);
1127 		}
1128 		vfsp = vfsp->vfs_next;
1129 	} while (vfsp != rootvfs);
1130 	vfs_list_unlock();
1131 	return (0);
1132 }
1133 
1134 /*
1135  * return statefile offset in DEV_BSIZE units
1136  */
1137 int
1138 cpr_statefile_offset(void)
1139 {
1140 	return (cprconfig.cf_type != CFT_UFS ? btod(CPR_SPEC_OFFSET) : 0);
1141 }
1142 
1143 /*
1144  * Force a fresh read of the cprinfo per uadmin 3 call
1145  */
1146 void
1147 cpr_forget_cprconfig(void)
1148 {
1149 	cprconfig_loaded = 0;
1150 }
1151 #endif
1152