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]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2019 Joyent, Inc.
28 #include <sys/types.h>
29 #include <sys/errno.h>
30 #include <sys/cpuvar.h>
32 #include <sys/vnode.h>
33 #include <sys/pathname.h>
34 #include <sys/callb.h>
35 #include <sys/fs/ufs_inode.h>
37 #include <sys/fs/swapnode.h> /* for swapfs_minfree */
41 #include <sys/machclock.h>
44 * CPR miscellaneous support routines
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(), \
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);
57 extern kmutex_t cpr_slock
;
58 extern size_t cpr_buf_size
;
60 extern size_t cpr_pagedata_size
;
61 extern char *cpr_pagedata
;
62 extern int cpr_bufs_allocated
;
63 extern int cpr_bitmaps_allocated
;
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);
73 int cpr_is_ufs(struct vfs
*);
74 int cpr_is_zfs(struct vfs
*);
76 char cpr_default_path
[] = CPR_DEFAULT
;
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 */
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().
90 cpr_err(int ce
, const char *fmt
, ...)
95 vcmn_err(ce
, fmt
, adx
);
97 drv_usecwait(MICROSEC
>> 2);
105 * Allow only one suspend/resume process.
107 if (mutex_tryenter(&cpr_slock
) == 0)
112 CPR
->c_cprboot_magic
= 0;
113 CPR
->c_alloc_cnt
= 0;
116 if (fcn
== AD_CPR_REUSABLE
)
117 CPR
->c_flags
|= C_REUSABLE
;
119 CPR
->c_flags
|= C_SUSPENDING
;
120 if (fcn
== AD_SUSPEND_TO_RAM
|| fcn
== DEV_SUSPEND_TO_RAM
) {
124 if (fcn
!= AD_CPR_NOCOMPRESS
&& fcn
!= AD_CPR_TESTNOZ
)
125 CPR
->c_flags
|= C_COMPRESSING
;
127 * reserve CPR_MAXCONTIG virtual pages for cpr_dump()
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
);
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
);
144 * This routine releases any resources used during the checkpoint.
150 i_cpr_bitmap_cleanup();
153 * Free pages used by cpr buffers.
156 kmem_free(cpr_buf
, cpr_buf_size
);
160 kmem_free(cpr_pagedata
, cpr_pagedata_size
);
164 i_cpr_free_memory_resources();
165 mutex_exit(&cpr_slock
);
166 cpr_err(CE_CONT
, "System has been resumed.\n");
172 * reads config data into cprconfig
177 static char config_path
[] = CPR_CONFIG
;
178 struct cprconfig
*cf
= &cprconfig
;
183 if (cprconfig_loaded
)
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
);
192 err
= cpr_rdwr(UIO_READ
, vp
, cf
, sizeof (*cf
));
193 (void) VOP_CLOSE(vp
, FREAD
, 1, (offset_t
)0, CRED(), NULL
);
196 cpr_err(CE_CONT
, fmt
, "read", config_path
, err
);
200 if (cf
->cf_magic
== CPR_CONFIG_MAGIC
)
201 cprconfig_loaded
= 1;
203 cpr_err(CE_CONT
, "invalid config file \"%s\", "
204 "rerun pmconfig(8)\n", config_path
);
213 * concat fs and path fields of the cprconfig structure;
214 * returns pointer to the base of static data
217 cpr_cprconfig_to_path(void)
219 static char full_path
[MAXNAMELEN
];
220 struct cprconfig
*cf
= &cprconfig
;
224 * build /fs/path without extra '/'
226 (void) strcpy(full_path
, cf
->cf_fs
);
227 if (strcmp(cf
->cf_fs
, "/"))
228 (void) strcat(full_path
, "/");
232 (void) strcat(full_path
, ptr
);
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.
250 cpr_verify_statefile_path(void)
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(8).";
259 struct vfs
*vfsp
= NULL
, *vfsp_save
= rootvfs
;
260 ufsvfs_t
*ufsvfsp
= (ufsvfs_t
*)rootvfs
->vfs_data
;
261 ufsvfs_t
*ufsvfsp_save
= ufsvfsp
;
264 char *slash
, *tail
, *longest
;
268 char un_devpath
[OBP_MAXPATHLEN
];
269 char un_sfpath
[MAXNAMELEN
];
271 #define devpath un.un_devpath
272 #define sfpath un.un_sfpath
274 ASSERT(cprconfig_loaded
);
276 * We need not worry about locking or the timing of releasing
277 * the vnode, since we are single-threaded now.
280 switch (cf
->cf_type
) {
282 error
= i_devname_to_promname(cf
->cf_devfs
, devpath
,
284 if (error
|| strcmp(devpath
, cf
->cf_dev_prom
)) {
285 cpr_err(CE_CONT
, path_chg_fmt
,
286 cf
->cf_dev_prom
, devpath
, rerun
);
291 if (strlen(cf
->cf_path
) > sizeof (sfpath
)) {
292 cpr_err(CE_CONT
, long_name
);
293 return (ENAMETOOLONG
);
295 if ((error
= lookupname(cf
->cf_devfs
,
296 UIO_SYSSPACE
, FOLLOW
, NULLVPP
, &vp
)) != 0) {
297 cpr_err(CE_CONT
, lookup_fmt
, cf
->cf_devfs
);
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";
313 cpr_err(CE_CONT
, "%s.\n", errstr
);
319 break; /* don't indent all the original code */
321 cpr_err(CE_PANIC
, "invalid cf_type");
325 * The original code for UFS statefile
327 if (strlen(cf
->cf_fs
) + strlen(cf
->cf_path
) + 2 > sizeof (sfpath
)) {
328 cpr_err(CE_CONT
, long_name
);
329 return (ENAMETOOLONG
);
332 bzero(sfpath
, sizeof (sfpath
));
333 (void) strcpy(sfpath
, cpr_cprconfig_to_path());
335 if (*sfpath
!= '/') {
336 cpr_err(CE_CONT
, "Statefile pathname %s "
337 "must begin with a /\n", sfpath
);
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.
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) {
353 cpr_err(CE_CONT
, "A directory in the "
354 "statefile path %s was not found.\n", sfpath
);
360 vfs_list_read_lock();
363 ufsvfsp
= (struct ufsvfs
*)vfsp
->vfs_data
;
364 if (ufsvfsp
!= NULL
&& ufsvfsp
->vfs_root
== vp
) {
368 vfsp
= vfsp
->vfs_next
;
369 } while (vfsp
!= rootvfs
);
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.
381 if (strcmp(cf
->cf_fs
, sfpath
) == 0) {
382 ufsvfsp_save
= ufsvfsp
;
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
);
400 if ((error
= lookupname(cf
->cf_devfs
,
401 UIO_SYSSPACE
, FOLLOW
, NULLVPP
, &vp
)) != 0) {
402 cpr_err(CE_CONT
, lookup_fmt
, cf
->cf_devfs
);
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(5).", cf
->cf_devfs
);
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
);
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.
431 cpr_check_spec_statefile(void)
435 if (err
= cpr_get_config())
437 ASSERT(cprconfig
.cf_type
== CFT_SPEC
||
438 cprconfig
.cf_type
== CFT_ZVOL
);
440 if (cprconfig
.cf_devfs
== NULL
)
443 return (cpr_verify_statefile_path());
448 cpr_alloc_statefile(int alloc_retry
)
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
459 str
= "\n-->Retrying statefile allocation...";
460 if (cpr_debug
& (CPR_DEBUG1
| CPR_DEBUG7
))
462 if (C_VP
->v_type
!= VBLK
)
463 (void) VOP_DUMPCTL(C_VP
, DUMP_FREE
, NULL
, NULL
);
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.
473 char *path
= cpr_build_statefile_path();
477 else if (rc
= cpr_verify_statefile_path())
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
);
488 * Only ufs and block special statefiles supported
490 if (C_VP
->v_type
!= VREG
&& C_VP
->v_type
!= VBLK
) {
492 "Statefile must be regular file or block special file.");
496 if (rc
= cpr_statefile_ok(C_VP
, alloc_retry
))
499 if (C_VP
->v_type
!= VBLK
) {
501 * sync out the fs change due to the statefile reservation.
503 (void) VFS_SYNC(C_VP
->v_vfsp
, 0, CRED());
506 * Validate disk blocks allocation for the state file.
507 * Ask the file system prepare itself for the dump operation.
509 if (rc
= VOP_DUMPCTL(C_VP
, DUMP_ALLOC
, NULL
, NULL
)) {
510 cpr_err(CE_CONT
, "Error allocating "
511 "blocks for cpr statefile.");
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".
525 cpr_get_devsize(dev_t dev
)
529 bytes
= cdev_Size(dev
);
531 bytes
= cdev_size(dev
);
533 if (bytes
> CPR_SPEC_OFFSET
)
534 bytes
-= CPR_SPEC_OFFSET
;
543 * increase statefile size
546 cpr_grow_statefile(vnode_t
*vp
, u_longlong_t newsize
)
548 extern uchar_t cpr_pagecopy
[];
549 struct inode
*ip
= VTOI(vp
);
554 rw_enter(&ip
->i_contents
, RW_READER
);
555 increase
= (ip
->i_size
< newsize
);
557 rw_exit(&ip
->i_contents
);
563 * write to each logical block to reserve disk space
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
);
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.
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.
596 cpr_statefile_ok(vnode_t
*vp
, int alloc_retry
)
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
;
607 * number of pages short for swapping.
609 STAT
->cs_nosw_pages
= k_anoninfo
.ani_mem_resv
;
610 if (STAT
->cs_nosw_pages
< 0)
611 STAT
->cs_nosw_pages
= 0;
613 str
= "cpr_statefile_ok:";
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
);
624 * try increasing filesize by 15%
628 * block device doesn't get any bigger
630 if (vp
->v_type
== VBLK
) {
631 if (cpr_debug
& (CPR_DEBUG1
| CPR_DEBUG6
))
633 "Retry statefile on special file\n");
636 rw_enter(&ip
->i_contents
, RW_READER
);
637 size
= (ip
->i_size
* SIZE_RATE
) / INTEGRAL
;
638 rw_exit(&ip
->i_contents
);
640 if (cpr_debug
& (CPR_DEBUG1
| CPR_DEBUG6
))
641 prom_printf("Retry statefile size = %lld\n", size
);
643 u_longlong_t cpd_size
;
644 pgcnt_t npages
, nback
;
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
);
654 * estimate 1 cpd_t for every (CPR_MAXCONTIG / 2) pages
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
);
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
);
669 size
= ksize
+ raw_data
+ nback
;
670 CPR_DEBUG(CPR_DEBUG1
, est_fmt
, str
, "no ",
676 * All this is much simpler for a block device
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
);
684 * Export the estimated filesize info, this value will be
685 * compared before dumping out the statefile in the case of
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
);
693 cpr_err(CE_CONT
, "Statefile partition too small.");
698 if (CPR
->c_alloc_cnt
++ > C_MAX_ALLOC_RETRY
) {
699 cpr_err(CE_CONT
, "Statefile allocation retry failed\n");
704 * Estimate space needed for the state file.
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)
711 size
= blkroundup(ip
->i_fs
, size
);
714 * Export the estimated filesize info, this value will be
715 * compared before dumping out the statefile in the case of
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
);
723 rw_exit(&ip
->i_contents
);
724 prom_printf("%s Estimated statefile size %lld, "
725 "i_size %lld\n", str
, size
, isize
);
734 cpr_statef_close(void)
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
);
747 * open cpr default file and display error
750 cpr_open_deffile(int mode
, vnode_t
**vpp
)
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
);
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.
768 cpr_write_deffile(cdef_t
*cdef
)
774 if (rc
= cpr_open_deffile(FCREAT
|FWRITE
, &vp
))
777 if (rc
= cpr_rdwr(UIO_WRITE
, vp
, cdef
, sizeof (*cdef
)))
779 else if (rc
= VOP_FSYNC(vp
, FSYNC
, CRED(), NULL
))
781 (void) VOP_CLOSE(vp
, FWRITE
, 1, (offset_t
)0, CRED(), NULL
);
785 cpr_err(CE_WARN
, "%s error %d, file \"%s\"",
786 str
, rc
, cpr_default_path
);
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.
797 cpr_clear_definfo(void)
802 if ((CPR
->c_cprboot_magic
!= CPR_DEFAULT_MAGIC
) ||
803 cpr_open_deffile(FCREAT
|FWRITE
, &vp
))
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
);
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
816 cpr_get_reusable_mode(void)
822 if (cpr_open(cpr_default_path
, FREAD
, &vp
))
825 rc
= cpr_rdwr(UIO_READ
, vp
, &mini
, sizeof (mini
));
826 (void) VOP_CLOSE(vp
, FREAD
, 1, (offset_t
)0, CRED(), NULL
);
828 if (rc
== 0 && mini
.magic
== CPR_DEFAULT_MAGIC
)
829 return (mini
.reusable
);
836 * clock/time related routines
838 static time_t cpr_time_stamp
;
842 cpr_tod_get(cpr_time_t
*ctp
)
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
;
854 cpr_tod_status_set(int tod_flag
)
856 mutex_enter(&tod_lock
);
857 tod_status_set(tod_flag
);
858 mutex_exit(&tod_lock
);
864 cpr_time_stamp
= gethrestime_sec();
868 * correct time based on saved time stamp or hardware clock
871 cpr_restore_time(void)
873 clkset(cpr_time_stamp
);
878 * CPU ONLINE/OFFLINE CODE
885 int brought_up_boot
= 0;
893 mutex_enter(&cpu_lock
);
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
);
910 if (cp
->cpu_flags
& CPU_OFFLINE
)
912 if ((rc
= cpr_p_online(cp
, CPU_CPR_OFFLINE
))) {
913 mutex_exit(&cpu_lock
);
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
);
928 cpu_t
*cp
, *bootcpu
= CPU
;
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.
943 mutex_enter(&cpu_lock
);
944 for (cp
= bootcpu
->cpu_next
; cp
!= bootcpu
; cp
= cp
->cpu_next
) {
946 * Clear the CPU_FROZEN flag in all cases.
948 cp
->cpu_flags
&= ~CPU_FROZEN
;
950 if (CPU_CPR_IS_OFFLINE(cp
))
954 if ((rc
= cpr_p_online(cp
, CPU_CPR_ONLINE
))) {
955 mutex_exit(&cpu_lock
);
961 * turn off the boot cpu if it was offlined
963 if (CPU_CPR_IS_OFFLINE(bootcpu
)) {
964 if ((rc
= cpr_p_online(bootcpu
, CPU_CPR_OFFLINE
))) {
965 mutex_exit(&cpu_lock
);
969 mutex_exit(&cpu_lock
);
974 cpr_save_mp_state(void)
978 ASSERT(MUTEX_HELD(&cpu_lock
));
982 cp
->cpu_cpr_flags
&= ~CPU_CPR_ONLINE
;
984 CPU_SET_CPR_FLAGS(cp
, CPU_CPR_ONLINE
);
985 } while ((cp
= cp
->cpu_next
) != cpu_list
);
989 * change cpu to online/offline
992 cpr_p_online(cpu_t
*cp
, int state
)
996 ASSERT(MUTEX_HELD(&cpu_lock
));
1000 rc
= cpu_online(cp
, 0);
1002 case CPU_CPR_OFFLINE
:
1003 rc
= cpu_offline(cp
, CPU_FORCED
);
1007 cpr_err(CE_WARN
, "Failed to change processor %d to "
1008 "state %d, (errno %d)", cp
->cpu_id
, state
, rc
);
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.
1019 cpr_build_statefile_path(void)
1021 struct cprconfig
*cf
= &cprconfig
;
1023 if (cpr_get_config())
1026 switch (cf
->cf_type
) {
1028 if (strlen(cf
->cf_path
) + strlen(cf
->cf_fs
) >= MAXNAMELEN
- 1) {
1029 cpr_err(CE_CONT
, "Statefile path is too long.\n");
1032 return (cpr_cprconfig_to_path());
1036 return (cf
->cf_devfs
);
1038 cpr_err(CE_PANIC
, "invalid statefile type");
1045 cpr_statefile_is_spec(void)
1047 if (cpr_get_config())
1049 return (cprconfig
.cf_type
== CFT_SPEC
);
1053 cpr_get_statefile_prom_path(void)
1055 struct cprconfig
*cf
= &cprconfig
;
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
);
1065 * XXX The following routines need to be in the vfs source code.
1069 cpr_is_ufs(struct vfs
*vfsp
)
1073 fsname
= vfssw
[vfsp
->vfs_fstype
].vsw_name
;
1074 return (strcmp(fsname
, "ufs") == 0);
1078 cpr_is_zfs(struct vfs
*vfsp
)
1082 fsname
= vfssw
[vfsp
->vfs_fstype
].vsw_name
;
1083 return (strcmp(fsname
, "zfs") == 0);
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 and pcfs which have disk state that could get
1091 * out of sync with the in-kernel data).
1094 cpr_reusable_mount_check(void)
1099 static char *cpr_writeok_fss
[] = {
1100 "autofs", "devfs", "fd", "lofs", "mntfs", "namefs", "nfs",
1101 "proc", "tmpfs", "ctfs", "objfs", "dev", NULL
1104 vfs_list_read_lock();
1107 if (vfsp
->vfs_flag
& VFS_RDONLY
) {
1108 vfsp
= vfsp
->vfs_next
;
1111 fsname
= vfssw
[vfsp
->vfs_fstype
].vsw_name
;
1112 for (cpp
= cpr_writeok_fss
; *cpp
; cpp
++) {
1113 if (strcmp(fsname
, *cpp
) == 0)
1117 * if the inner loop reached the NULL terminator,
1118 * the current fs-type does not match any OK-type
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",
1128 vfsp
= vfsp
->vfs_next
;
1129 } while (vfsp
!= rootvfs
);
1135 * return statefile offset in DEV_BSIZE units
1138 cpr_statefile_offset(void)
1140 return (cprconfig
.cf_type
!= CFT_UFS
? btod(CPR_SPEC_OFFSET
) : 0);
1144 * Force a fresh read of the cprinfo per uadmin 3 call
1147 cpr_forget_cprconfig(void)
1149 cprconfig_loaded
= 0;