/* * Make sure that the statefile can be used as a block special statefile * (meaning that is exists and has nothing mounted on it) * Returns errno if not a valid statefile. */ int cpr_check_spec_statefile(void) { int err; if (err = cpr_get_config()) return (err); ASSERT(cprconfig.cf_type == CFT_SPEC); if (cprconfig.cf_devfs == NULL) return (ENXIO); return (cpr_verify_statefile_path()); }
int cpr_alloc_statefile(int alloc_retry) { register int rc = 0; char *str; /* * Statefile size validation. If checkpoint the first time, disk blocks * allocation will be done; otherwise, just do file size check. * if statefile allocation is being retried, C_VP will be inited */ if (alloc_retry) { str = "\n-->Retrying statefile allocation..."; if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG7)) prom_printf(str); if (C_VP->v_type != VBLK) (void) VOP_DUMPCTL(C_VP, DUMP_FREE, NULL, NULL); } else { /* * Open an exiting file for writing, the state file needs to be * pre-allocated since we can't and don't want to do allocation * during checkpoint (too much of the OS is disabled). * - do a preliminary size checking here, if it is too small, * allocate more space internally and retry. * - check the vp to make sure it's the right type. */ char *path = cpr_build_statefile_path(); if (path == NULL) return (ENXIO); else if (rc = cpr_verify_statefile_path()) return (rc); if (rc = vn_open(path, UIO_SYSSPACE, FCREAT|FWRITE, 0600, &C_VP, CRCREAT, 0)) { cpr_err(CE_WARN, "cannot open statefile %s", path); return (rc); } } /* * Only ufs and block special statefiles supported */ if (C_VP->v_type != VREG && C_VP->v_type != VBLK) { cpr_err(CE_CONT, "Statefile must be regular file or block special file."); return (EACCES); } if (rc = cpr_statefile_ok(C_VP, alloc_retry)) return (rc); if (C_VP->v_type != VBLK) { /* * sync out the fs change due to the statefile reservation. */ (void) VFS_SYNC(C_VP->v_vfsp, 0, CRED()); /* * Validate disk blocks allocation for the state file. * Ask the file system prepare itself for the dump operation. */ if (rc = VOP_DUMPCTL(C_VP, DUMP_ALLOC, NULL, NULL)) { cpr_err(CE_CONT, "Error allocating " "blocks for cpr statefile."); return (rc); } } return (0); }