2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A * Handle initialization of the suspend subsystem. This includes setting 2N/A * platform default values for the suspend-enable property and creating 2N/A * Initialize any suspend facilities for this machine if needed or configured. 2N/A * Retrieve all of the SMF properties to see if suspend-enabled is 2N/A * already configured in SMF. If it is, then the service has been 2N/A * started before and no re-setting of the default is required. 2N/A * An error occurred reading from SMF. Pass the error up 2N/A * to the caller to process. 2N/A * The suspend-enable property is not yet initialized. 2N/A * Since this implies that suspend is not enabled, 2N/A * there is nothing left to do here, so return failure. 2N/A /* Recurse to find the value of the property */ 2N/A /* Things to run if suspend is enabled */ 2N/A * Update the cprconfig file or create if it does not 2N/A * If we get here, always return success, as we have done 2N/A * what is needed to "initialize" suspend. 2N/A * returns B_TRUE if the slice is good (e.g. does not start at block 2N/A * zero, or a string describing the error if it doesn't 2N/A /* convert from dsk to rdsk */ 2N/A *
err =
"could not open '%s'\n";
2N/A * we got a slice number; now check the block 2N/A * number where the slice starts 2N/A *
err =
"using '%s' would clobber the disk label\n";
2N/A /* EFI slices don't clobber the disk label */ 2N/A *
err =
"could not read partition table from '%s'\n";
2N/A * This should go in a header file, but for now it is private, so leave 2N/A * These describe the parent pathname to block disk devices used 2N/A * for the statefile. As there is no API for acquiring them, we 2N/A * define them here so that they are easily identified should they 2N/A * need to be updated. 2N/A * Get and verify the device for saving a statefile. 2N/A * If there is not a defined property, choose the ZFS dump device. 2N/A * First see if we have a property that specifies the 2N/A * statefile path. If any attempt to find it via SMF 2N/A * fails, fallback to the "default" path of the ZFS dump 2N/A /* Get the property defining the statefile path */ 2N/A * We have a property, so now extract the value 2N/A * Define the "default" statefile. 2N/A * Note that this suffers from the same problem as 2N/A * get_cpr_config_path(), in that it uses a copy of 2N/A * a private interface to get the pool name. 2N/A * Technically, we have free'd the stuff at fp, but that 2N/A * is OK, as we don't expect to use the data, but only know 2N/A * that we found data. 2N/A /* Couldn't find pool, return. */ 2N/A /* If we still cannot find a path, return. */ 2N/A * Statefile must exist before it can be used here. 2N/A * If not a block device, return. 2N/A * If not a good "slice", return. 2N/A * OK, we have a block device, and we know it is valid, 2N/A * so identify the prom device 2N/A * If the path is *not* a zvol, it will be treated as a 2N/A "%s could not convert to prom name: %s\n",
2N/A * Should be ZFS, get the underlying device. 2N/A * If anything fails, just return as we haven't yet 2N/A * filled in any config file entries. 2N/A * Note that we don't really care about the vdev on 2N/A * x86 platforms, but this code does give us the 2N/A * oppertunity to validate the zvol. 2N/A "%s could not convert to prom name: %s\n",
2N/A * By virtue of arriving here, we have identified and validated 2N/A * the statefile path. All that remains is to stuff it in the 2N/A * last two config file entries. 2N/A * Update or create cpr_config file. 2N/A * A note on the use of dirname and the strings we use to get it. 2N/A * dirname(3c) usually manipulates the string that is passed in, 2N/A * such that the original string is not usable unless it was 2N/A * dup'd or copied before. The exception, is if a NULL is passed, 2N/A * and then we get get a new string that is ".". So we must 2N/A * always check the return value, and if we care about the original 2N/A * string, we must dup it before calling dirname. 2N/A "%s cpr_config directory unknown or invalid\n",
2N/A * If the confdir doesn't exist, it needs to be created, 2N/A * unless the parent doesn't exist, and then we bail. 2N/A * cpr_config directory doesn't exist. If the parent does, 2N/A * set it up so that cpr_conf_dir can be created a little 2N/A * further down. Otherwise, return an error. 2N/A * We already know that cpr_conf_dir properly started 2N/A * with '/', so the copy should as well, and we don't 2N/A * need to test for it. However, if the parent is 2N/A * just '/', this is an error. 2N/A "%s cpr_config parent directory missing\n",
2N/A * Create the cpr_config directory if we have determined it is missing 2N/A "%s conf directory %s missing\n",
2N/A /* Is there an existing cpr_config */ 2N/A /* Use it to initially populate cprconfig struct. */ 2N/A "%s: %s is corrupted, regenerating.\n",
2N/A /* Always make sure the magic number is correct. */ 2N/A * Fetch the statefile path for this platform, and populate 2N/A * the cpr config struct. 2N/A * Effectively, we always want a fresh file, so create it if 2N/A * it doesn't exist, and truncate it if it does. 2N/A "%s error writing \"%s\", %s\\n",
2N/A * Find the path to the cpr_config file. 2N/A /* On Sparc, this is easy, as it (currently) must be CPR_CONFIG */ 2N/A /* On others, we need to find the pool the root is running. */ 2N/A /* Clear and add the leading '/' to the pool pathname. */ 2N/A * We have identified the mounted pool, extract everything 2N/A * up to "/ROOT" from it. 2N/A * Convert a Unix device to a prom device and save on success, 2N/A "%s cannot open \"%s\", %s.\n",
2N/A "%s cannot convert \"%s\" to prom device\n",
2N/A * Function: be_get_ds_from_dir_callback 2N/A * Description: This is a callback function used to iterate all datasets 2N/A * to find the one that is currently mounted at the directory 2N/A * being searched for. If matched, the name of the dataset is 2N/A * returned in heap storage, so the caller is responsible for 2N/A * zhp - zfs_handle_t pointer to current dataset being processed. 2N/A * data - dir_data_t pointer providing name of directory being 2N/A * 1 - This dataset is mounted at directory being searched for. 2N/A * 0 - This dataset is not mounted at directory being searched for. 2N/A * Function: be_get_ds_from_dir(char *dir) 2N/A * Description: Given a directory path, find the underlying dataset mounted 2N/A * at that directory path if there is one. The returned name 2N/A * is allocated in heap storage, so the caller is responsible 2N/A * dir - char pointer of directory to find. 2N/A * NULL - if directory is not mounted from a dataset. 2N/A * name of dataset mounted at dir. 2N/A * Semi-private (library wide use only) 2N/A * This is what I need to find the root pool from a mounted root dir. 2N/A /* Make sure length of dir is within the max length */ 2N/A /* Resolve dir in case its lofs mounted */