f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * CDDL HEADER START
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The contents of this file are subject to the terms of the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Common Development and Distribution License (the "License").
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * You may not use this file except in compliance with the License.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * or http://www.opensolaris.org/os/licensing.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * See the License for the specific language governing permissions
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * and limitations under the License.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * When distributing Covered Code, include this CDDL HEADER in each
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If applicable, add the following below this CDDL HEADER, with the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * fields enclosed by brackets "[]" replaced with your own identifying
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * information: Portions Copyright [yyyy] [name of copyright owner]
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * CDDL HEADER END
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * Copyright 2016 Toomas Soome <tsoome@me.com>
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens * Copyright (c) 2015 by Delphix. All rights reserved.
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin */
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * System includes
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <assert.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <errno.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <libgen.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <libintl.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <libnvpair.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <libzfs.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <libgen.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <stdio.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <stdlib.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <string.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <sys/stat.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <sys/types.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <sys/vfstab.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <sys/param.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <sys/systeminfo.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <ctype.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <time.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <unistd.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <fcntl.h>
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin#include <deflt.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <wait.h>
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin#include <libdevinfo.h>
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin#include <libgen.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <libbe.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <libbe_priv.h>
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome#include <boot_utils.h>
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome#include <ficl.h>
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome#include <ficlplatform/emu.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Private function prototypes */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic int update_dataset(char *, int, char *, char *, char *);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic int _update_vfstab(char *, char *, char *, char *, be_fs_list_data_t *);
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Ereminstatic int be_open_menu(char *, char *, FILE **, char *, boolean_t);
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Ereminstatic int be_create_menu(char *, char *, FILE **, char *);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic char *be_get_auto_name(char *, char *, boolean_t);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Global error printing
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseboolean_t do_print = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Private datatypes
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassetypedef struct zone_be_name_cb_data {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *base_be_name;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int num;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse} zone_be_name_cb_data_t;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ******************************************************************** */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Public Functions */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ******************************************************************** */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome/*
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * Callback for ficl to suppress all output from ficl, as we do not
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * want to confuse user with messages from ficl, and we are only
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * checking results from function calls.
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome */
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome/*ARGSUSED*/
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soomestatic void
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas SoomeficlSuppressTextOutput(ficlCallback *cb, char *text)
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome{
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome /* This function is intentionally doing nothing. */
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome}
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome/*
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * Function: be_get_boot_args
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * Description: Returns the fast boot argument string for enumerated BE.
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * Parameters:
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * fbarg - pointer to argument string.
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * entry - index of BE.
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * Returns:
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * fast boot argument string.
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * Scope:
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * Public
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome */
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soomeint
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soomebe_get_boot_args(char **fbarg, int entry)
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome{
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_node_list_t *node, *be_nodes = NULL;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_transaction_data_t bt = {0};
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome char *mountpoint = NULL;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome boolean_t be_mounted = B_FALSE;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome int ret = BE_SUCCESS;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome int index;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ficlVm *vm;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome *fbarg = NULL;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (!be_zfs_init())
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome return (BE_ERR_INIT);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome /*
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * need pool name, menu.lst has entries from our pool only
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome */
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = be_find_current_be(&bt);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (ret != BE_SUCCESS) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_zfs_fini();
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome return (ret);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome /*
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * be_get_boot_args() is for loader, fail with grub will trigger
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * normal boot.
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome */
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (be_has_grub()) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = BE_ERR_INIT;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome goto done;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = _be_list(NULL, &be_nodes);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (ret != BE_SUCCESS)
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome goto done;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome /*
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * iterate through be_nodes,
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * if entry == -1, stop if be_active_on_boot,
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * else stop if index == entry.
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome */
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome index = 0;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome for (node = be_nodes; node != NULL; node = node->be_next_node) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (strcmp(node->be_rpool, bt.obe_zpool) != 0)
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome continue;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (entry == BE_ENTRY_DEFAULT &&
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome node->be_active_on_boot == B_TRUE)
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome break;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (index == entry)
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome break;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome index++;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (node == NULL) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_free_list(be_nodes);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = BE_ERR_NOENT;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome goto done;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome /* try to mount inactive be */
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (node->be_active == B_FALSE) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = _be_mount(node->be_node_name, &mountpoint,
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome BE_MOUNT_FLAG_NO_ZONES);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (ret != BE_SUCCESS && ret != BE_ERR_MOUNTED) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_free_list(be_nodes);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome goto done;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome } else
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_mounted = B_TRUE;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome vm = bf_init("", ficlSuppressTextOutput);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (vm != NULL) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome /*
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * zfs MAXNAMELEN is 256, so we need to pick buf large enough
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * to contain such names.
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome */
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome char buf[MAXNAMELEN * 2];
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome char *kernel_options = NULL;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome char *kernel = NULL;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome char *tmp;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome zpool_handle_t *zph;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome /*
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * just try to interpret following words. on error
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome * we will be missing kernelname, and will get out.
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome */
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome (void) snprintf(buf, sizeof (buf), "set currdev=zfs:%s:",
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome node->be_root_ds);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = ficlVmEvaluate(vm, buf);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_print_err(gettext("be_get_boot_args: error "
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome "interpreting boot config: %d\n"), ret);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome bf_fini();
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = BE_ERR_NO_MENU;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome goto cleanup;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome (void) snprintf(buf, sizeof (buf),
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome "include /boot/forth/loader.4th");
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = ficlVmEvaluate(vm, buf);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_print_err(gettext("be_get_boot_args: error "
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome "interpreting boot config: %d\n"), ret);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome bf_fini();
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = BE_ERR_NO_MENU;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome goto cleanup;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome (void) snprintf(buf, sizeof (buf), "start");
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = ficlVmEvaluate(vm, buf);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_print_err(gettext("be_get_boot_args: error "
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome "interpreting boot config: %d\n"), ret);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome bf_fini();
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = BE_ERR_NO_MENU;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome goto cleanup;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome (void) snprintf(buf, sizeof (buf), "boot");
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = ficlVmEvaluate(vm, buf);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome bf_fini();
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_print_err(gettext("be_get_boot_args: error "
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome "interpreting boot config: %d\n"), ret);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = BE_ERR_NO_MENU;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome goto cleanup;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome kernel_options = getenv("boot-args");
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome kernel = getenv("kernelname");
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (kernel == NULL) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_print_err(gettext("be_get_boot_args: no kernel\n"));
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = BE_ERR_NOENT;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome goto cleanup;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if ((zph = zpool_open(g_zfs, node->be_rpool)) == NULL) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_print_err(gettext("be_get_boot_args: failed to "
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome "open root pool (%s): %s\n"), node->be_rpool,
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome libzfs_error_description(g_zfs));
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = zfs_err_to_be_err(g_zfs);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome goto cleanup;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = zpool_get_physpath(zph, buf, sizeof (buf));
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome zpool_close(zph);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (ret != 0) {
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_print_err(gettext("be_get_boot_args: failed to "
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome "get physpath\n"));
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome goto cleanup;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome }
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome /* zpool_get_physpath() can return space separated list */
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome tmp = buf;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome tmp = strsep(&tmp, " ");
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (kernel_options == NULL || *kernel_options == '\0')
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome (void) asprintf(fbarg, "/ %s "
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome "-B zfs-bootfs=%s,bootpath=\"%s\"\n", kernel,
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome node->be_root_ds, tmp);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome else
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome (void) asprintf(fbarg, "/ %s %s "
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome "-B zfs-bootfs=%s,bootpath=\"%s\"\n", kernel,
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome kernel_options, node->be_root_ds, tmp);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (fbarg == NULL)
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = BE_ERR_NOMEM;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome else
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = 0;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome } else
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome ret = BE_ERR_NOMEM;
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soomecleanup:
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome if (be_mounted == B_TRUE)
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome (void) _be_unmount(node->be_node_name, BE_UNMOUNT_FLAG_FORCE);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_free_list(be_nodes);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soomedone:
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome free(mountpoint);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome free(bt.obe_name);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome free(bt.obe_root_ds);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome free(bt.obe_zpool);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome free(bt.obe_snap_name);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome free(bt.obe_altroot);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome be_zfs_fini();
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome return (ret);
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome}
f5e5a2c4965aa1013184568ca3140cdcba93e44bToomas Soome
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_max_avail
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Returns the available size for the zfs dataset passed in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * dataset - The dataset we want to get the available space for.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * ret - The available size will be returned in this.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The error returned by the zfs get property function.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Public
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_max_avail(char *dataset, uint64_t *ret)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zfs_handle_t *zhp;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Initialize libzfs handle */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!be_zfs_init())
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_INIT);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (zhp == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The zfs_open failed return an error
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = zfs_err_to_be_err(g_zfs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = be_maxsize_avail(zhp, ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_zfs_fini();
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: libbe_print_errors
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Turns on/off error output for the library.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameter:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * set_do_print - Boolean that turns library error
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * printing on or off.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * None
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Public;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasselibbe_print_errors(boolean_t set_do_print)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse do_print = set_do_print;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ******************************************************************** */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Semi-Private Functions */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ******************************************************************** */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_zfs_init
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Initializes the libary global libzfs handle.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * None
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_TRUE - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_FALSE - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseboolean_t
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_zfs_init(void)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_zfs_fini();
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((g_zfs = libzfs_init()) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_zfs_init: failed to initialize ZFS "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "library\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_TRUE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_zfs_fini
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Closes the library global libzfs handle if it currently open.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameter:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * None
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * None
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_zfs_fini(void)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (g_zfs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse libzfs_fini(g_zfs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse g_zfs = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin/*
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin * Function: be_get_defaults
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin * Description: Open defaults and gets be default paramets
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin * Parameters:
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin * defaults - be defaults struct
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin * Returns:
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin * None
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin * Scope:
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin * Semi-private (library wide use only)
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin */
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Ereminvoid
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Ereminbe_get_defaults(struct be_defaults *defaults)
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin{
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin void *defp;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome defaults->be_deflt_grub = B_FALSE;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin defaults->be_deflt_rpool_container = B_FALSE;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin defaults->be_deflt_bename_starts_with[0] = '\0';
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if ((defp = defopen_r(BE_DEFAULTS)) != NULL) {
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin const char *res = defread_r(BE_DFLT_BENAME_STARTS, defp);
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome if (res != NULL && res[0] != '\0') {
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin (void) strlcpy(defaults->be_deflt_bename_starts_with,
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens res, ZFS_MAX_DATASET_NAME_LEN);
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin defaults->be_deflt_rpool_container = B_TRUE;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin }
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome if (be_is_isa("i386")) {
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome res = defread_r(BE_DFLT_BE_HAS_GRUB, defp);
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome if (res != NULL && res[0] != '\0') {
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome if (strcasecmp(res, "true") == 0)
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome defaults->be_deflt_grub = B_TRUE;
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome }
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome }
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin defclose_r(defp);
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin }
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin}
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_make_root_ds
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Generate string for BE's root dataset given the pool
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * it lives in and the BE name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * zpool - pointer zpool name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_name - pointer to BE name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_root_ds - pointer to buffer to return BE root dataset in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_root_ds_size - size of be_root_ds
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * None
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_make_root_ds(const char *zpool, const char *be_name, char *be_root_ds,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int be_root_ds_size)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin struct be_defaults be_defaults;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin be_get_defaults(&be_defaults);
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin char *root_ds = NULL;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin if (getzoneid() == GLOBAL_ZONEID) {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin if (be_defaults.be_deflt_rpool_container) {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin (void) snprintf(be_root_ds, be_root_ds_size,
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin "%s/%s", zpool, be_name);
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin } else {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin (void) snprintf(be_root_ds, be_root_ds_size,
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin "%s/%s/%s", zpool, BE_CONTAINER_DS_NAME, be_name);
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin }
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin } else {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin /*
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin * In non-global zone we can use path from mounted root dataset
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin * to generate BE's root dataset string.
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin */
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin if ((root_ds = be_get_ds_from_dir("/")) != NULL) {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin (void) snprintf(be_root_ds, be_root_ds_size, "%s/%s",
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin dirname(root_ds), be_name);
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin } else {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin be_print_err(gettext("be_make_root_ds: zone root "
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin "dataset is not mounted\n"));
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin return;
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin }
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_make_container_ds
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Generate string for the BE container dataset given a pool name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * zpool - pointer zpool name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * container_ds - pointer to buffer to return BE container
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * dataset in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * container_ds_size - size of container_ds
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * None
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_make_container_ds(const char *zpool, char *container_ds,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int container_ds_size)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin struct be_defaults be_defaults;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin be_get_defaults(&be_defaults);
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin char *root_ds = NULL;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin if (getzoneid() == GLOBAL_ZONEID) {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin if (be_defaults.be_deflt_rpool_container) {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin (void) snprintf(container_ds, container_ds_size,
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin "%s", zpool);
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin } else {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin (void) snprintf(container_ds, container_ds_size,
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin "%s/%s", zpool, BE_CONTAINER_DS_NAME);
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin }
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin } else {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin if ((root_ds = be_get_ds_from_dir("/")) != NULL) {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin (void) strlcpy(container_ds, dirname(root_ds),
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin container_ds_size);
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin } else {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin be_print_err(gettext("be_make_container_ds: zone root "
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin "dataset is not mounted\n"));
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin return;
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin }
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_make_name_from_ds
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function takes a dataset name and strips off the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE container dataset portion from the beginning. The
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * returned name is allocated in heap storage, so the caller
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * is responsible for freeing it.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * dataset - dataset to get name from.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * rc_loc - dataset underwhich the root container dataset lives.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * name of dataset relative to BE container dataset.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * NULL if dataset is not under a BE root dataset.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-primate (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassechar *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_make_name_from_ds(const char *dataset, char *rc_loc)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens char ds[ZFS_MAX_DATASET_NAME_LEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tok = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *name = NULL;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin struct be_defaults be_defaults;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin int rlen = strlen(rc_loc);
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin be_get_defaults(&be_defaults);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * First token is the location of where the root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * lives; it must match rc_loc.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if (strncmp(dataset, rc_loc, rlen) == 0 && dataset[rlen] == '/')
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin (void) strlcpy(ds, dataset + rlen + 1, sizeof (ds));
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if (be_defaults.be_deflt_rpool_container) {
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if ((name = strdup(ds)) == NULL) {
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin be_print_err(gettext("be_make_name_from_ds: "
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin "memory allocation failed\n"));
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin return (NULL);
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin }
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin } else {
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin /* Second token must be BE container dataset name */
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if ((tok = strtok(ds, "/")) == NULL ||
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin strcmp(tok, BE_CONTAINER_DS_NAME) != 0)
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin /* Return the remaining token if one exists */
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if ((tok = strtok(NULL, "")) == NULL)
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if ((name = strdup(tok)) == NULL) {
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin be_print_err(gettext("be_make_name_from_ds: "
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin "memory allocation failed\n"));
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin return (NULL);
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_maxsize_avail
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Returns the available size for the zfs handle passed in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * zhp - A pointer to the open zfs handle.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * ret - The available size will be returned in this.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The error returned by the zfs get property function.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_maxsize_avail(zfs_handle_t *zhp, uint64_t *ret)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return ((*ret = zfs_prop_get_int(zhp, ZFS_PROP_AVAILABLE)));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_append_menu
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Appends an entry for a BE into the menu.lst.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_name - pointer to name of BE to add boot menu entry for.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_root_pool - pointer to name of pool BE lives in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * boot_pool - Used if the pool containing the grub menu is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * different than the one contaiing the BE. This
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * will normally be NULL.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_orig_root_ds - The root dataset for the BE. This is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * used to check to see if an entry already exists
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * for this BE.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * description - pointer to description of BE to be added in
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the title line for this BEs entry.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_append_menu(char *be_name, char *be_root_pool, char *boot_pool,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *be_orig_root_ds, char *description)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zfs_handle_t *zhp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char menu_file[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char be_root_ds[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char line[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char temp_line[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char title[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *entries[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tmp_entries[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *pool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *ptmp_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *orig_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t found_be = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t found_orig_be = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t found_title = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t pool_mounted = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t collect_lines = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *menu_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = 0, ret = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int i, num_tmp_lines = 0, num_lines = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_name == NULL || be_root_pool == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_INVAL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (boot_pool == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boot_pool = be_root_pool;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((zhp = zfs_open(g_zfs, be_root_pool, ZFS_TYPE_DATASET)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_append_menu: failed to open "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "pool dataset for %s: %s\n"), be_root_pool,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse libzfs_error_description(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (zfs_err_to_be_err(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if the pool's dataset is mounted. If it isn't we'll
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * attempt to mount it.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((ret = be_mount_pool(zhp, &ptmp_mntpnt, &orig_mntpnt,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse &pool_mounted)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_append_menu: pool dataset "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "(%s) could not be mounted\n"), be_root_pool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Get the mountpoint for the root pool dataset.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!zfs_is_mounted(zhp, &pool_mntpnt)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_append_menu: pool "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "dataset (%s) is not mounted. Can't set "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "the default BE in the grub menu.\n"), be_root_pool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NO_MENU;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if this system supports grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_has_grub()) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(menu_file, sizeof (menu_file),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "%s%s", pool_mntpnt, BE_GRUB_MENU);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(menu_file, sizeof (menu_file),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "%s%s", pool_mntpnt, BE_SPARC_MENU);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_make_root_ds(be_root_pool, be_name, be_root_ds, sizeof (be_root_ds));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Iterate through menu first to make sure the BE doesn't already
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * have an entry in the menu.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Additionally while iterating through the menu, if we have an
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * original root dataset for a BE we're cloning from, we need to keep
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * track of that BE's menu entry. We will then use the lines from
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * that entry to create the entry for the new BE.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if ((ret = be_open_menu(be_root_pool, menu_file,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse &menu_fp, "r", B_TRUE)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (menu_fp == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NO_MENU;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(pool_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse pool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (fgets(line, BUFSIZ, menu_fp)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tok = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(temp_line, line, BUFSIZ);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tok = strtok(line, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tok == NULL || tok[0] == '#') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (strcmp(tok, "title") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse collect_lines = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((tok = strtok(NULL, "\n")) == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(title, "", sizeof (title));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(title, tok, sizeof (title));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse found_title = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (num_tmp_lines != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i < num_tmp_lines; i++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(tmp_entries[i]);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_entries[i] = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_tmp_lines = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (strcmp(tok, "bootfs") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *bootfs = strtok(NULL, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse found_title = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (bootfs == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(bootfs, be_root_ds) == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse found_be = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_orig_root_ds != NULL &&
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strcmp(bootfs, be_orig_root_ds) == 0 &&
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse !found_orig_be) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char str[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse found_orig_be = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_lines = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Store the new title line
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(str, BUFSIZ, "title %s\n",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse description ? description : be_name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse entries[num_lines] = strdup(str);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_lines++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If there are any lines between the title
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * and the bootfs line store these. Also
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * free the temporary lines.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i < num_tmp_lines; i++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse entries[num_lines] = tmp_entries[i];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_entries[i] = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_lines++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_tmp_lines = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Store the new bootfs line.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(str, BUFSIZ, "bootfs %s\n",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_root_ds);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse entries[num_lines] = strdup(str);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_lines++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse collect_lines = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (found_orig_be && collect_lines) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * get the rest of the lines for the original BE and
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * store them.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strstr(line, BE_GRUB_COMMENT) != NULL ||
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strstr(line, "BOOTADM") != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
e77c795bcbe51aebd7579fe13cbf2a6d56eca47fGarrett D'Amore if (strcmp(tok, "splashimage") == 0) {
e77c795bcbe51aebd7579fe13cbf2a6d56eca47fGarrett D'Amore entries[num_lines] =
e77c795bcbe51aebd7579fe13cbf2a6d56eca47fGarrett D'Amore strdup("splashimage "
e77c795bcbe51aebd7579fe13cbf2a6d56eca47fGarrett D'Amore "/boot/splashimage.xpm\n");
e77c795bcbe51aebd7579fe13cbf2a6d56eca47fGarrett D'Amore } else {
e77c795bcbe51aebd7579fe13cbf2a6d56eca47fGarrett D'Amore entries[num_lines] = strdup(temp_line);
e77c795bcbe51aebd7579fe13cbf2a6d56eca47fGarrett D'Amore }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_lines++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (found_title && !found_orig_be) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_entries[num_tmp_lines] = strdup(temp_line);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_tmp_lines++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (found_be) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If an entry for this BE was already in the menu, then if
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * that entry's title matches what we would have put in
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * return success. Otherwise return failure.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *new_title = description ? description : be_name;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(title, new_title) == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_remove_menu(be_name, be_root_pool,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boot_pool) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_append_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "Failed to remove existing unusable "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "entry '%s' in boot menu.\n"), be_name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_BE_EXISTS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Append BE entry to the end of the file */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse menu_fp = fopen(menu_file, "a+");
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (menu_fp == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_append_menu: failed "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "to open menu.lst file %s\n"), menu_file);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (found_orig_be) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * write out all the stored lines
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i < num_lines; i++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fprintf(menu_fp, "%s", entries[i]);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(entries[i]);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_lines = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if this system supports grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_has_grub())
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fprintf(menu_fp, "%s\n", BE_GRUB_COMMENT);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fprintf(menu_fp, "title %s\n",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse description ? description : be_name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fprintf(menu_fp, "bootfs %s\n", be_root_ds);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if this system supports grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_has_grub()) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fprintf(menu_fp, "kernel$ "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "/platform/i86pc/kernel/$ISADIR/unix -B "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "$ZFS-BOOTFS\n");
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fprintf(menu_fp, "module$ "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "/platform/i86pc/$ISADIR/boot_archive\n");
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fprintf(menu_fp, "%s\n", BE_GRUB_COMMENT);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassecleanup:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (pool_mounted) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = be_unmount_pool(zhp, ptmp_mntpnt, orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ret == BE_SUCCESS)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = err;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(ptmp_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (num_tmp_lines > 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i < num_tmp_lines; i++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(tmp_entries[i]);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_entries[i] = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (num_lines > 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i < num_lines; i++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(entries[i]);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse entries[i] = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_remove_menu
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Removes a BE's entry from a menu.lst file.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_name - the name of BE whose entry is to be removed from
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the menu.lst file.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_root_pool - the pool that be_name lives in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * boot_pool - the pool where the BE is, if different than
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the pool containing the boot menu. If this is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * NULL it will be set to be_root_pool.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_remove_menu(char *be_name, char *be_root_pool, char *boot_pool)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zfs_handle_t *zhp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char be_root_ds[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char **buffer = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char menu_buf[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char menu[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *pool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *ptmp_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *orig_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tmp_menu = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *menu_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *tmp_menu_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct stat sb;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int ret = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int i;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int fd;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int nlines = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int default_entry = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int entry_cnt = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int entry_del = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int num_entry_del = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int tmp_menu_len = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t write = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t do_buffer = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t pool_mounted = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (boot_pool == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boot_pool = be_root_pool;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get name of BE's root dataset */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_make_root_ds(be_root_pool, be_name, be_root_ds, sizeof (be_root_ds));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get handle to pool dataset */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((zhp = zfs_open(g_zfs, be_root_pool, ZFS_TYPE_DATASET)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to open pool dataset for %s: %s"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_root_pool, libzfs_error_description(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (zfs_err_to_be_err(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if the pool's dataset is mounted. If it isn't we'll
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * attempt to mount it.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((ret = be_mount_pool(zhp, &ptmp_mntpnt, &orig_mntpnt,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse &pool_mounted)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: pool dataset "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "(%s) could not be mounted\n"), be_root_pool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Get the mountpoint for the root pool dataset.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!zfs_is_mounted(zhp, &pool_mntpnt)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: pool "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "dataset (%s) is not mounted. Can't set "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "the default BE in the grub menu.\n"), be_root_pool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NO_MENU;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get path to boot menu */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(menu, pool_mntpnt, sizeof (menu));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if this system supports grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_has_grub())
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(menu, BE_GRUB_MENU, sizeof (menu));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(menu, BE_SPARC_MENU, sizeof (menu));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get handle to boot menu file */
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if ((ret = be_open_menu(be_root_pool, menu, &menu_fp, "r",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse B_TRUE)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (menu_fp == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NO_MENU;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(pool_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse pool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Grab the stats of the original menu file */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (stat(menu, &sb) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to stat file %s: %s\n"), menu, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Create a tmp file for the modified menu.lst */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_menu_len = strlen(menu) + 7;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((tmp_menu = (char *)malloc(tmp_menu_len)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: malloc failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) memset(tmp_menu, 0, tmp_menu_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(tmp_menu, menu, tmp_menu_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(tmp_menu, "XXXXXX", tmp_menu_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((fd = mkstemp(tmp_menu)) == -1) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: mkstemp failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(tmp_menu);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_menu = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((tmp_menu_fp = fdopen(fd, "w")) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "could not open tmp file for write: %s\n"), strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) close(fd);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (fgets(menu_buf, BUFSIZ, menu_fp)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char tline [BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tok = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(tline, menu_buf, sizeof (tline));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Tokenize line */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tok = strtok(tline, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tok == NULL || tok[0] == '#') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Found empty line or comment line */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (do_buffer) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Buffer this line */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((buffer = (char **)realloc(buffer,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof (char *)*(nlines + 1))) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((buffer[nlines++] = strdup(menu_buf))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (write || strncmp(menu_buf, BE_GRUB_COMMENT,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strlen(BE_GRUB_COMMENT)) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Write this line out */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(menu_buf, tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (strcmp(tok, "default") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Record what 'default' is set to because we might
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * need to adjust this upon deleting an entry.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tok = strtok(NULL, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tok != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse default_entry = atoi(tok);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(menu_buf, tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (strcmp(tok, "title") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If we've reached a 'title' line and do_buffer is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * is true, that means we've just buffered an entire
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * entry without finding a 'bootfs' directive. We
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * need to write that entry out and keep searching.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (do_buffer) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i < nlines; i++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(buffer[i], tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(buffer[i]);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(buffer);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse buffer = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse nlines = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Turn writing off and buffering on, and increment
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * our entry counter.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse write = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse do_buffer = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse entry_cnt++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Buffer this 'title' line */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((buffer = (char **)realloc(buffer,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof (char *)*(nlines + 1))) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((buffer[nlines++] = strdup(menu_buf)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (strcmp(tok, "bootfs") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *bootfs = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Found a 'bootfs' line. See if it matches the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE we're looking for.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((bootfs = strtok(NULL, BE_WHITE_SPACE)) == NULL ||
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strcmp(bootfs, be_root_ds) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Either there's nothing after the 'bootfs'
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * or this is not the BE we're looking for,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * write out the line(s) we've buffered since
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * finding the title.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i < nlines; i++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(buffer[i], tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(buffer[i]);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(buffer);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse buffer = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse nlines = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Turn writing back on, and turn off buffering
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * since this isn't the entry we're looking
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * for.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse write = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse do_buffer = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Write this 'bootfs' line out. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(menu_buf, tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Found the entry we're looking for.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Record its entry number, increment the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * number of entries we've deleted, and turn
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * writing off. Also, throw away the lines
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * we've buffered for this entry so far, we
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * don't need them.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse entry_del = entry_cnt - 1;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_entry_del++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse write = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse do_buffer = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i < nlines; i++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(buffer[i]);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(buffer);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse buffer = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse nlines = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (do_buffer) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Buffer this line */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((buffer = (char **)realloc(buffer,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof (char *)*(nlines + 1))) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((buffer[nlines++] = strdup(menu_buf))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (write) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Write this line out */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(menu_buf, tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse menu_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_menu_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Copy the modified menu.lst into place */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (rename(tmp_menu, menu) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to rename file %s to %s: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_menu, menu, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(tmp_menu);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_menu = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If we've removed an entry, see if we need to
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * adjust the default value in the menu.lst. If the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * entry we've deleted comes before the default entry
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * we need to adjust the default value accordingly.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_has_grub is used here to check to see if this system
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * supports grub.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_has_grub() && num_entry_del > 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (entry_del <= default_entry) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse default_entry = default_entry - num_entry_del;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (default_entry < 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse default_entry = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Adjust the default value by rewriting the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * menu.lst file. This may be overkill, but to
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * preserve the location of the 'default' entry
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * in the file, we need to do this.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get handle to boot menu file */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((menu_fp = fopen(menu, "r")) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to open menu.lst (%s): %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse menu, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Create a tmp file for the modified menu.lst */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_menu_len = strlen(menu) + 7;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((tmp_menu = (char *)malloc(tmp_menu_len))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "malloc failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) memset(tmp_menu, 0, tmp_menu_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(tmp_menu, menu, tmp_menu_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(tmp_menu, "XXXXXX", tmp_menu_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((fd = mkstemp(tmp_menu)) == -1) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "mkstemp failed: %s\n"), strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(tmp_menu);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_menu = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((tmp_menu_fp = fdopen(fd, "w")) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "could not open tmp file for write: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) close(fd);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (fgets(menu_buf, BUFSIZ, menu_fp)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char tline [BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tok = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(tline, menu_buf, sizeof (tline));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Tokenize line */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tok = strtok(tline, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tok == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Found empty line, write it out */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(menu_buf, tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (strcmp(tok, "default") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Found the default line, adjust it */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(tline, sizeof (tline),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "default %d\n", default_entry);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(tline, tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Pass through all other lines */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(menu_buf, tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse menu_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_menu_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Copy the modified menu.lst into place */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (rename(tmp_menu, menu) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to rename file %s to %s: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_menu, menu, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(tmp_menu);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_menu = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Set the perms and ownership of the updated file */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (chmod(menu, sb.st_mode) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to chmod %s: %s\n"), menu, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (chown(menu, sb.st_uid, sb.st_gid) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_remove_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to chown %s: %s\n"), menu, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassecleanup:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (pool_mounted) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = be_unmount_pool(zhp, ptmp_mntpnt, orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ret == BE_SUCCESS)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = err;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(ptmp_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(buffer);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (menu_fp != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tmp_menu_fp != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(tmp_menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tmp_menu != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) unlink(tmp_menu);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(tmp_menu);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_default_grub_bootfs
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function returns the dataset in the default entry of
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the grub menu. If no default entry is found with a valid bootfs
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * entry NULL is returned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_root_pool - This is the name of the root pool where the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * grub menu can be found.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * def_bootfs - This is used to pass back the bootfs string. On
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * error NULL is returned here.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Success - BE_SUCCESS is returned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Failure - a be_errno_t is returned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_default_grub_bootfs(const char *be_root_pool, char **def_bootfs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zfs_handle_t *zhp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char grub_file[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *menu_fp;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char line[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *pool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *ptmp_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *orig_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int default_entry = 0, entries = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int found_default = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int ret = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t pool_mounted = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse errno = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if this system supports grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!be_has_grub()) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_default_grub_bootfs: operation "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "not supported on this architecture\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NOTSUP);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *def_bootfs = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get handle to pool dataset */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((zhp = zfs_open(g_zfs, be_root_pool, ZFS_TYPE_DATASET)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_default_grub_bootfs: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to open pool dataset for %s: %s"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_root_pool, libzfs_error_description(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (zfs_err_to_be_err(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if the pool's dataset is mounted. If it isn't we'll
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * attempt to mount it.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((ret = be_mount_pool(zhp, &ptmp_mntpnt, &orig_mntpnt,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse &pool_mounted)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_default_grub_bootfs: pool dataset "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "(%s) could not be mounted\n"), be_root_pool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Get the mountpoint for the root pool dataset.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!zfs_is_mounted(zhp, &pool_mntpnt)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_default_grub_bootfs: failed "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "to get mount point for the root pool. Can't set "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "the default BE in the grub menu.\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NO_MENU;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(grub_file, MAXPATHLEN, "%s%s",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse pool_mntpnt, BE_GRUB_MENU);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if ((ret = be_open_menu((char *)be_root_pool, grub_file,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse &menu_fp, "r", B_FALSE)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (menu_fp == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NO_MENU;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(pool_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse pool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (fgets(line, BUFSIZ, menu_fp)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tok = strtok(line, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tok != NULL && tok[0] != '#') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!found_default) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(tok, "default") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tok = strtok(NULL, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tok != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse default_entry = atoi(tok);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rewind(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse found_default = 1;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(tok, "title") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse entries++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (default_entry == entries - 1) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(tok, "bootfs") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tok = strtok(NULL, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tok == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((*def_bootfs = strdup(tok)) !=
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext(
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "be_default_grub_bootfs: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "memory allocation failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (default_entry < entries - 1) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * no bootfs entry for the default entry.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassecleanup:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (pool_mounted) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = be_unmount_pool(zhp, ptmp_mntpnt, orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ret == BE_SUCCESS)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = err;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(ptmp_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_change_grub_default
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function takes two parameters. These are the name of
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the BE we want to have as the default booted in the grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * menu and the root pool where the path to the grub menu exists.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The code takes this and finds the BE's entry in the grub menu
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * and changes the default entry to point to that entry in the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * list.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_name - This is the name of the BE wanted as the default
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * for the next boot.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_root_pool - This is the name of the root pool where the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * grub menu can be found.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_change_grub_default(char *be_name, char *be_root_pool)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zfs_handle_t *zhp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char grub_file[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *temp_grub;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *pool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *ptmp_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *orig_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char line[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char temp_line[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char be_root_ds[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *grub_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *temp_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct stat sb;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int temp_grub_len = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int fd, entries = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int ret = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t found_default = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t pool_mounted = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse errno = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if this system supports grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!be_has_grub()) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: operation "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "not supported on this architecture\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NOTSUP);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Generate string for BE's root dataset */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_make_root_ds(be_root_pool, be_name, be_root_ds, sizeof (be_root_ds));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get handle to pool dataset */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((zhp = zfs_open(g_zfs, be_root_pool, ZFS_TYPE_DATASET)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to open pool dataset for %s: %s"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_root_pool, libzfs_error_description(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (zfs_err_to_be_err(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if the pool's dataset is mounted. If it isn't we'll
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * attempt to mount it.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((ret = be_mount_pool(zhp, &ptmp_mntpnt, &orig_mntpnt,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse &pool_mounted)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: pool dataset "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "(%s) could not be mounted\n"), be_root_pool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Get the mountpoint for the root pool dataset.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!zfs_is_mounted(zhp, &pool_mntpnt)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: pool "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "dataset (%s) is not mounted. Can't set "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "the default BE in the grub menu.\n"), be_root_pool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NO_MENU;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(grub_file, MAXPATHLEN, "%s%s",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse pool_mntpnt, BE_GRUB_MENU);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if ((ret = be_open_menu(be_root_pool, grub_file,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse &grub_fp, "r+", B_TRUE)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (grub_fp == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NO_MENU;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(pool_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse pool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Grab the stats of the original menu file */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (stat(grub_file, &sb) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to stat file %s: %s\n"), grub_file, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Create a tmp file for the modified menu.lst */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse temp_grub_len = strlen(grub_file) + 7;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((temp_grub = (char *)malloc(temp_grub_len)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "malloc failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) memset(temp_grub, 0, temp_grub_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(temp_grub, grub_file, temp_grub_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(temp_grub, "XXXXXX", temp_grub_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((fd = mkstemp(temp_grub)) == -1) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "mkstemp failed: %s\n"), strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(temp_grub);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse temp_grub = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((temp_fp = fdopen(fd, "w")) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to open %s file: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse temp_grub, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) close(fd);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (fgets(line, BUFSIZ, grub_fp)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tok = strtok(line, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tok == NULL || tok[0] == '#') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (strcmp(tok, "title") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse entries++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (strcmp(tok, "bootfs") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *bootfs = strtok(NULL, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (bootfs == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(bootfs, be_root_ds) == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse found_default = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!found_default) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: failed "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "to find entry for %s in the grub menu\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_BE_NOENT;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rewind(grub_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (fgets(line, BUFSIZ, grub_fp)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tok = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strncpy(temp_line, line, BUFSIZ);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((tok = strtok(temp_line, BE_WHITE_SPACE)) != NULL &&
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strcmp(tok, "default") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(temp_line, BUFSIZ, "default %d\n",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse entries - 1 >= 0 ? entries - 1 : 0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(temp_line, temp_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(line, temp_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(grub_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse grub_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(temp_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse temp_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (rename(temp_grub, grub_file) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to rename file %s to %s: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse temp_grub, grub_file, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(temp_grub);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse temp_grub = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Set the perms and ownership of the updated file */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (chmod(grub_file, sb.st_mode) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to chmod %s: %s\n"), grub_file, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (chown(grub_file, sb.st_uid, sb.st_gid) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_change_grub_default: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to chown %s: %s\n"), grub_file, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassecleanup:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (pool_mounted) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = be_unmount_pool(zhp, ptmp_mntpnt, orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ret == BE_SUCCESS)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = err;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(ptmp_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (grub_fp != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(grub_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (temp_fp != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(temp_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (temp_grub != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) unlink(temp_grub);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(temp_grub);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_update_menu
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function is used by be_rename to change the BE name in
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * an existing entry in the grub menu to the new name of the BE.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_orig_name - the original name of the BE
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_new_name - the new name the BE is being renameed to.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_root_pool - The pool which contains the grub menu
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * boot_pool - the pool where the BE is, if different than
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the pool containing the boot menu. If this is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * NULL it will be set to be_root_pool.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_update_menu(char *be_orig_name, char *be_new_name, char *be_root_pool,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *boot_pool)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zfs_handle_t *zhp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char menu_file[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char be_root_ds[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char be_new_root_ds[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char line[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *pool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *ptmp_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *orig_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *temp_menu = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *menu_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *new_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct stat sb;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int temp_menu_len = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int tmp_fd;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int ret = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t pool_mounted = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse errno = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (boot_pool == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boot_pool = be_root_pool;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((zhp = zfs_open(g_zfs, be_root_pool, ZFS_TYPE_DATASET)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_menu: failed to open "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "pool dataset for %s: %s\n"), be_root_pool,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse libzfs_error_description(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (zfs_err_to_be_err(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if the pool's dataset is mounted. If it isn't we'll
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * attempt to mount it.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((ret = be_mount_pool(zhp, &ptmp_mntpnt, &orig_mntpnt,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse &pool_mounted)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_menu: pool dataset "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "(%s) could not be mounted\n"), be_root_pool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Get the mountpoint for the root pool dataset.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!zfs_is_mounted(zhp, &pool_mntpnt)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_menu: failed "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "to get mount point for the root pool. Can't set "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "the default BE in the grub menu.\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NO_MENU;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if this system supports grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_has_grub()) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(menu_file, sizeof (menu_file),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "%s%s", pool_mntpnt, BE_GRUB_MENU);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(menu_file, sizeof (menu_file),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "%s%s", pool_mntpnt, BE_SPARC_MENU);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_make_root_ds(be_root_pool, be_orig_name, be_root_ds,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof (be_root_ds));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_make_root_ds(be_root_pool, be_new_name, be_new_root_ds,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof (be_new_root_ds));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if ((ret = be_open_menu(be_root_pool, menu_file,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse &menu_fp, "r", B_TRUE)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (menu_fp == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NO_MENU;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(pool_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse pool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Grab the stat of the original menu file */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (stat(menu_file, &sb) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to stat file %s: %s\n"), menu_file, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Create tmp file for modified menu.lst */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse temp_menu_len = strlen(menu_file) + 7;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((temp_menu = (char *)malloc(temp_menu_len))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "malloc failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) memset(temp_menu, 0, temp_menu_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(temp_menu, menu_file, temp_menu_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(temp_menu, "XXXXXX", temp_menu_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((tmp_fd = mkstemp(temp_menu)) == -1) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "mkstemp failed: %s\n"), strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(temp_menu);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((new_fp = fdopen(tmp_fd, "w")) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "fdopen failed: %s\n"), strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) close(tmp_fd);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(temp_menu);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (fgets(line, BUFSIZ, menu_fp)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char tline[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char new_line[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *c = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(tline, line, sizeof (tline));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Tokenize line */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c = strtok(tline, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (c == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Found empty line, write it out. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(line, new_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (c[0] == '#') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Found a comment line, write it out. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(line, new_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (strcmp(c, "title") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *name = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *desc = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Found a 'title' line, parse out BE name or
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the description.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse name = strtok(NULL, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (name == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Nothing after 'title', just push
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * this line through
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(line, new_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Grab the remainder of the title which
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * could be a multi worded description
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse desc = strtok(NULL, "\n");
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(name, be_orig_name) == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The first token of the title is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the old BE name, replace it with
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the new one, and write it out
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * along with the remainder of
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * description if there is one.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (desc) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(new_line,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof (new_line),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "title %s %s\n",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_new_name, desc);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(new_line,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof (new_line),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "title %s\n", be_new_name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(new_line, new_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(line, new_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (strcmp(c, "bootfs") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Found a 'bootfs' line, parse out the BE root
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * dataset value.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *root_ds = strtok(NULL, BE_WHITE_SPACE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (root_ds == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Nothing after 'bootfs', just push
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * this line through
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(line, new_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If this bootfs is the one we're renaming,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * write out the new root dataset value
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(root_ds, be_root_ds) == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(new_line,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof (new_line), "bootfs %s\n",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_new_root_ds);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(new_line, new_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(line, new_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Found some other line we don't care
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * about, write it out.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(line, new_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(new_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) close(tmp_fd);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (rename(temp_menu, menu_file) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to rename file %s to %s: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse temp_menu, menu_file, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(temp_menu);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Set the perms and ownership of the updated file */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (chmod(menu_file, sb.st_mode) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to chmod %s: %s\n"), menu_file, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (chown(menu_file, sb.st_uid, sb.st_gid) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_menu: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to chown %s: %s\n"), menu_file, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassecleanup:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (pool_mounted) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = be_unmount_pool(zhp, ptmp_mntpnt, orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ret == BE_SUCCESS)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = err;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(ptmp_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_has_menu_entry
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Checks to see if the BEs root dataset has an entry in the grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * menu.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_dataset - The root dataset of the BE
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_root_pool - The pool which contains the boot menu
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * entry - A pointer the the entry number of the BE if found.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_TRUE - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_FALSE - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseboolean_t
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_has_menu_entry(char *be_dataset, char *be_root_pool, int *entry)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zfs_handle_t *zhp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char menu_file[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *menu_fp;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char line[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *last;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *rpool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *ptmp_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *orig_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int ent_num = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t ret = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t pool_mounted = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if this system supports grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((zhp = zfs_open(g_zfs, be_root_pool, ZFS_TYPE_DATASET)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_has_menu_entry: failed to open "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "pool dataset for %s: %s\n"), be_root_pool,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse libzfs_error_description(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if the pool's dataset is mounted. If it isn't we'll
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * attempt to mount it.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_mount_pool(zhp, &ptmp_mntpnt, &orig_mntpnt,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse &pool_mounted) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_has_menu_entry: pool dataset "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "(%s) could not be mounted\n"), be_root_pool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Get the mountpoint for the root pool dataset.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!zfs_is_mounted(zhp, &rpool_mntpnt)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_has_menu_entry: pool "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "dataset (%s) is not mounted. Can't set "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "the default BE in the grub menu.\n"), be_root_pool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_has_grub()) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(menu_file, MAXPATHLEN, "/%s%s",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rpool_mntpnt, BE_GRUB_MENU);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(menu_file, MAXPATHLEN, "/%s%s",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rpool_mntpnt, BE_SPARC_MENU);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if (be_open_menu(be_root_pool, menu_file, &menu_fp, "r",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse B_FALSE) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (menu_fp == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(rpool_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rpool_mntpnt = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (fgets(line, BUFSIZ, menu_fp)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tok = strtok_r(line, BE_WHITE_SPACE, &last);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tok != NULL && tok[0] != '#') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(tok, "bootfs") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tok = strtok_r(last, BE_WHITE_SPACE, &last);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tok != NULL && strcmp(tok,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_dataset) == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The entry number needs to be
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * decremented here because the title
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * will always be the first line for
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * an entry. Because of this we'll
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * always be off by one entry when we
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * check for bootfs.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *entry = ent_num - 1;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (strcmp(tok, "title") == 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ent_num++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassecleanup:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (pool_mounted) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) be_unmount_pool(zhp, ptmp_mntpnt, orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(orig_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(ptmp_mntpnt);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(menu_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_update_vfstab
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function digs into a BE's vfstab and updates all
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * entries with file systems listed in be_fs_list_data_t.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The entry's root container dataset and be_name will be
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * updated with the parameters passed in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_name - name of BE to update
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * old_rc_loc - dataset under which the root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * of the old BE resides in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * new_rc_loc - dataset under which the root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * of the new BE resides in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * fld - be_fs_list_data_t pointer providing the list of
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * file systems to look for in vfstab.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * mountpoint - directory of where BE is currently mounted.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If NULL, then BE is not currently mounted.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_update_vfstab(char *be_name, char *old_rc_loc, char *new_rc_loc,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_fs_list_data_t *fld, char *mountpoint)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tmp_mountpoint = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char alt_vfstab[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int ret = BE_SUCCESS, err = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (fld == NULL || fld->fs_list == NULL || fld->fs_num == 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_SUCCESS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* If BE not already mounted, mount the BE */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (mountpoint == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((ret = _be_mount(be_name, &tmp_mountpoint,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse BE_MOUNT_FLAG_NO_ZONES)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to mount BE (%s)\n"), be_name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_mountpoint = mountpoint;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get string for vfstab in the mounted BE. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(alt_vfstab, sizeof (alt_vfstab), "%s/etc/vfstab",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_mountpoint);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Update the vfstab */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = _update_vfstab(alt_vfstab, be_name, old_rc_loc, new_rc_loc,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse fld);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Unmount BE if we mounted it */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (mountpoint == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((err = _be_unmount(be_name, 0)) == BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Remove temporary mountpoint */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) rmdir(tmp_mountpoint);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to unmount BE %s mounted at %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_name, tmp_mountpoint);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ret == BE_SUCCESS)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = err;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(tmp_mountpoint);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_update_zone_vfstab
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function digs into a zone BE's vfstab and updates all
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * entries with file systems listed in be_fs_list_data_t.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The entry's root container dataset and be_name will be
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * updated with the parameters passed in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * zhp - zfs_handle_t pointer to zone root dataset.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_name - name of zone BE to update
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * old_rc_loc - dataset under which the root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * of the old zone BE resides in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * new_rc_loc - dataset under which the root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * of the new zone BE resides in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * fld - be_fs_list_data_t pointer providing the list of
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * file systems to look for in vfstab.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_update_zone_vfstab(zfs_handle_t *zhp, char *be_name, char *old_rc_loc,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *new_rc_loc, be_fs_list_data_t *fld)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_mount_data_t md = { 0 };
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_unmount_data_t ud = { 0 };
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char alt_vfstab[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t mounted_here = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int ret = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If zone root not already mounted, mount it at a
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * temporary location.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!zfs_is_mounted(zhp, &md.altroot)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Generate temporary mountpoint to mount zone root */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((ret = be_make_tmp_mountpoint(&md.altroot)) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_zone_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to make temporary mountpoint to "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "mount zone root\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_mount_zone_root(zhp, &md) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_zone_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to mount zone root %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zfs_get_name(zhp));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(md.altroot);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_MOUNT_ZONEROOT);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse mounted_here = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get string from vfstab in the mounted zone BE */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(alt_vfstab, sizeof (alt_vfstab), "%s/etc/vfstab",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse md.altroot);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Update the vfstab */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = _update_vfstab(alt_vfstab, be_name, old_rc_loc, new_rc_loc,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse fld);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Unmount zone root if we mounted it */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (mounted_here) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ud.force = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_unmount_zone_root(zhp, &ud) == BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Remove the temporary mountpoint */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) rmdir(md.altroot);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_update_zone_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to unmount zone root %s from %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zfs_get_name(zhp), md.altroot);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ret == 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_UMOUNT_ZONEROOT;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(md.altroot);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_auto_snap_name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Generate an auto snapshot name constructed based on the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * current date and time. The auto snapshot name is of the form:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * <date>-<time>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * where <date> is in ISO standard format, so the resultant name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * is of the form:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * %Y-%m-%d-%H:%M:%S
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * None
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Success - pointer to auto generated snapshot name. The name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * is allocated in heap storage so the caller is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * responsible for free'ing the name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Failure - NULL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassechar *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_auto_snap_name(void)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse time_t utc_tm = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct tm *gmt_tm = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char gmt_time_str[64];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *auto_snap_name = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (time(&utc_tm) == -1) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_auto_snap_name: time() failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((gmt_tm = gmtime(&utc_tm)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_auto_snap_name: gmtime() failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strftime(gmt_time_str, sizeof (gmt_time_str), "%F-%T", gmt_tm);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((auto_snap_name = strdup(gmt_time_str)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_auto_snap_name: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "memory allocation failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (auto_snap_name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_auto_be_name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Generate an auto BE name constructed based on the BE name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * of the original BE being cloned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * obe_name - name of the original BE being cloned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Success - pointer to auto generated BE name. The name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * is allocated in heap storage so the caller is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * responsible for free'ing the name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Failure - NULL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassechar *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_auto_be_name(char *obe_name)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (be_get_auto_name(obe_name, NULL, B_FALSE));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_auto_zone_be_name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Generate an auto BE name for a zone constructed based on
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the BE name of the original zone BE being cloned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * container_ds - container dataset for the zone.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * zbe_name - name of the original zone BE being cloned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Success - pointer to auto generated BE name. The name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * is allocated in heap storage so the caller is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * responsible for free'ing the name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Failure - NULL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassechar *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_auto_zone_be_name(char *container_ds, char *zbe_name)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (be_get_auto_name(zbe_name, container_ds, B_TRUE));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_valid_be_name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Validates a BE name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_name - name of BE to validate
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_TRUE - be_name is valid
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_FALSE - be_name is invalid
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseboolean_t
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_valid_be_name(const char *be_name)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse const char *c = NULL;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin struct be_defaults be_defaults;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_name == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin be_get_defaults(&be_defaults);
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * A BE name must not be a multi-level dataset name. We also check
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * that it does not contain the ' ' and '%' characters. The ' ' is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * a valid character for datasets, however we don't allow that in a
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE name. The '%' is invalid, but zfs_name_valid() allows it for
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * internal reasons, so we explicitly check for it here.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c = be_name;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (*c != '\0' && *c != '/' && *c != ' ' && *c != '%')
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (*c != '\0')
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The BE name must comply with a zfs dataset filesystem. We also
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * verify its length to be < BE_NAME_MAX_LEN.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!zfs_name_valid(be_name, ZFS_TYPE_FILESYSTEM) ||
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strlen(be_name) > BE_NAME_MAX_LEN)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if (be_defaults.be_deflt_bename_starts_with[0] != '\0' &&
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin strstr(be_name, be_defaults.be_deflt_bename_starts_with) == NULL) {
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin return (B_FALSE);
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin }
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_TRUE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_valid_auto_snap_name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function checks that a snapshot name is a valid auto
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * generated snapshot name. A valid auto generated snapshot
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * name is of the form:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * %Y-%m-%d-%H:%M:%S
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * An older form of the auto generated snapshot name also
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * included the snapshot's BE cleanup policy and a reserved
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * field. Those names will also be verified by this function.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Examples of valid auto snapshot names are:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * 2008-03-31-18:41:30
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * 2008-03-31-22:17:24
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * <policy>:-:2008:04-05-09:12:55
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * <policy>:-:2008:04-06-15:34:12
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * name - name of the snapshot to be validated.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_TRUE - the name is a valid auto snapshot name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_FALSE - the name is not a valid auto snapshot name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseboolean_t
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_valid_auto_snap_name(char *name)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct tm gmt_tm;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *policy = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *reserved = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *date = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *c = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Validate the snapshot name by converting it into utc time */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strptime(name, "%Y-%m-%d-%T", &gmt_tm) != NULL &&
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (mktime(&gmt_tm) != -1)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_TRUE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Validate the snapshot name against the older form of an
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * auto generated snapshot name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse policy = strdup(name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Get the first field from the snapshot name,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * which is the BE policy
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c = strchr(policy, ':');
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (c == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(policy);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c[0] = '\0';
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Validate the policy name */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!valid_be_policy(policy)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(policy);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get the next field, which is the reserved field. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (c[1] == NULL || c[1] == '\0') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(policy);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse reserved = c+1;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c = strchr(reserved, ':');
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (c == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(policy);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c[0] = '\0';
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Validate the reserved field */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(reserved, "-") != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(policy);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* The remaining string should be the date field */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (c[1] == NULL || c[1] == '\0') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(policy);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse date = c+1;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Validate the date string by converting it into utc time */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strptime(date, "%Y-%m-%d-%T", &gmt_tm) == NULL ||
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (mktime(&gmt_tm) == -1)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_valid_auto_snap_name: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "invalid auto snapshot name\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(policy);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(policy);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_TRUE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_default_policy
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Temporary hardcoded policy support. This function returns
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the default policy type to be used to create a BE or a BE
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * snapshot.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * None
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Name of default BE policy.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassechar *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_default_policy(void)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_PLCY_STATIC);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: valid_be_policy
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Temporary hardcoded policy support. This function valids
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * whether a policy is a valid known policy or not.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Paramters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * policy - name of policy to validate.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_TRUE - policy is a valid.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_FALSE - policy is invalid.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseboolean_t
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevalid_be_policy(char *policy)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (policy == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(policy, BE_PLCY_STATIC) == 0 ||
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strcmp(policy, BE_PLCY_VOLATILE) == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_TRUE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (B_FALSE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_print_err
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function prints out error messages if do_print is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * set to B_TRUE or if the BE_PRINT_ERR environment variable
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * is set to true.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Paramters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * prnt_str - the string we wish to print and any arguments
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * for the format of that string.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * void
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_print_err(char *prnt_str, ...)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse va_list ap;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char buf[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *env_buf;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse static boolean_t env_checked = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!env_checked) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((env_buf = getenv("BE_PRINT_ERR")) != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcasecmp(env_buf, "true") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse do_print = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse env_checked = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (do_print) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse va_start(ap, prnt_str);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* LINTED variable format specifier */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) vsnprintf(buf, BUFSIZ, prnt_str, ap);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(buf, stderr);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse va_end(ap);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_find_current_be
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Find the currently "active" BE. Fill in the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * passed in be_transaction_data_t reference with the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * active BE's data.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Paramters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * none
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errnot_t - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Notes:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The caller is responsible for initializing the libzfs handle
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * and freeing the memory used by the active be_name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_find_current_be(be_transaction_data_t *bt)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int zret;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((zret = zpool_iter(g_zfs, be_zpool_find_current_be_callback,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bt)) == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_find_current_be: failed to "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "find current BE name\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_BE_NOENT);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (zret < 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_find_current_be: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "zpool_iter failed: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse libzfs_error_description(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (zfs_err_to_be_err(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_SUCCESS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_zpool_find_current_be_callback
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Callback function used to iterate through all existing pools
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * to find the BE that is the currently booted BE.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * zlp - zpool_handle_t pointer to the current pool being
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * looked at.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * data - be_transaction_data_t pointer.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Upon successfully finding the current BE, the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * obe_zpool member of this parameter is set to the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * pool it is found in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Return:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * 1 - Found current BE in this pool.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * 0 - Did not find current BE in this pool.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_zpool_find_current_be_callback(zpool_handle_t *zlp, void *data)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_transaction_data_t *bt = data;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zfs_handle_t *zhp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse const char *zpool = zpool_get_name(zlp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char be_container_ds[MAXPATHLEN];
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin char *zpath = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Generate string for BE container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin if (getzoneid() != GLOBAL_ZONEID) {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin if ((zpath = be_get_ds_from_dir("/")) != NULL) {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin (void) strlcpy(be_container_ds, dirname(zpath),
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin sizeof (be_container_ds));
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin } else {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin be_print_err(gettext(
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin "be_zpool_find_current_be_callback: "
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin "zone root dataset is not mounted\n"));
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin return (0);
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin }
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin } else {
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin be_make_container_ds(zpool, be_container_ds,
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin sizeof (be_container_ds));
7e0e2549bfaa531aff576083ab0c07f84fa8fb27Alexander Eremin }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check if a BE container dataset exists in this pool.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!zfs_dataset_exists(g_zfs, be_container_ds, ZFS_TYPE_FILESYSTEM)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zpool_close(zlp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Get handle to this zpool's BE container dataset.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((zhp = zfs_open(g_zfs, be_container_ds, ZFS_TYPE_FILESYSTEM)) ==
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_zpool_find_current_be_callback: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to open BE container dataset (%s)\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_container_ds);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zpool_close(zlp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Iterate through all potential BEs in this zpool
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (zfs_iter_filesystems(zhp, be_zfs_find_current_be_callback, bt)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Found current BE dataset; set obe_zpool
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((bt->obe_zpool = strdup(zpool)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext(
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "be_zpool_find_current_be_callback: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "memory allocation failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zpool_close(zlp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zpool_close(zlp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (1);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zpool_close(zlp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_zfs_find_current_be_callback
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Callback function used to iterate through all BEs in a
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * pool to find the BE that is the currently booted BE.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * zhp - zfs_handle_t pointer to current filesystem being checked.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * data - be_transaction-data_t pointer
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Upon successfully finding the current BE, the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * obe_name and obe_root_ds members of this parameter
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * are set to the BE name and BE's root dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * respectively.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Return:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * 1 - Found current BE.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * 0 - Did not find current BE.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_zfs_find_current_be_callback(zfs_handle_t *zhp, void *data)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_transaction_data_t *bt = data;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *mp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check if dataset is mounted, and if so where.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (zfs_is_mounted(zhp, &mp)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If mounted at root, set obe_root_ds and obe_name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (mp != NULL && strcmp(mp, "/") == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(mp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((bt->obe_root_ds = strdup(zfs_get_name(zhp)))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext(
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "be_zfs_find_current_be_callback: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "memory allocation failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((bt->obe_name = strdup(basename(bt->obe_root_ds)))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext(
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "be_zfs_find_current_be_callback: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "memory allocation failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (1);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(mp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ZFS_CLOSE(zhp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_check_be_roots_callback
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function checks whether or not the dataset name passed
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * is hierachically located under the BE root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * for this pool.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * zlp - zpool_handle_t pointer to current pool being processed.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * data - name of dataset to check
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * 0 - dataset is not in this pool's BE root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * 1 - dataset is in this pool's BE root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_check_be_roots_callback(zpool_handle_t *zlp, void *data)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse const char *zpool = zpool_get_name(zlp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *ds = data;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char be_container_ds[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Generate string for this pool's BE root container dataset */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_make_container_ds(zpool, be_container_ds, sizeof (be_container_ds));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If dataset lives under the BE root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * of this pool, return failure.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strncmp(be_container_ds, ds, strlen(be_container_ds)) == 0 &&
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ds[strlen(be_container_ds)] == '/') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zpool_close(zlp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (1);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse zpool_close(zlp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: zfs_err_to_be_err
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function takes the error stored in the libzfs handle
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * and maps it to an be_errno_t. If there are no matching
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t's then BE_ERR_ZFS is returned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Paramters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * zfsh - The libzfs handle containing the error we're looking up.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassezfs_err_to_be_err(libzfs_handle_t *zfsh)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = libzfs_errno(zfsh);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse switch (err) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case 0:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_SUCCESS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_PERM:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_PERM);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_INTR:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_INTR);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_NOENT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NOENT);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_NOSPC:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NOSPC);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_MOUNTFAILED:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_MOUNT);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_UMOUNTFAILED:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_UMOUNT);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_EXISTS:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_BE_EXISTS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_BUSY:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_DEV_BUSY);
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson case EZFS_POOLREADONLY:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_ROFS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_NAMETOOLONG:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NAMETOOLONG);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_NODEVICE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NODEV);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_POOL_INVALARG:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_INVAL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_PROPTYPE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_INVALPROP);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_BADTYPE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_DSTYPE);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_PROPNONINHERIT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NONINHERIT);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_PROPREADONLY:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_READONLYPROP);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_RESILVERING:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_POOLUNAVAIL:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_UNAVAIL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EZFS_DSREADONLY:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_READONLYDS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse default:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_ZFS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: errno_to_be_err
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function takes an errno and maps it to an be_errno_t.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If there are no matching be_errno_t's then BE_ERR_UNKNOWN is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * returned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Paramters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * err - The errno we're compairing against.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseerrno_to_be_err(int err)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse switch (err) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EPERM:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_PERM);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EACCES:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_ACCESS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case ECANCELED:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_CANCELED);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EINTR:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_INTR);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case ENOENT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NOENT);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case ENOSPC:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EDQUOT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NOSPC);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EEXIST:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_BE_EXISTS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EBUSY:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_BUSY);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EROFS:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_ROFS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case ENAMETOOLONG:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NAMETOOLONG);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case ENXIO:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NXIO);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EINVAL:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_INVAL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case EFAULT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_FAULT);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse default:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_UNKNOWN);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_err_to_str
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function takes a be_errno_t and maps it to a message.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If there are no matching be_errno_t's then NULL is returned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Paramters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t - The be_errno_t we're mapping.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * string or NULL if the error code is not known.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassechar *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_err_to_str(int err)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse switch (err) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_ACCESS:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Permission denied."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_ACTIVATE_CURR:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Activation of current BE failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_AUTONAME:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Auto naming failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_BE_NOENT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("No such BE."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_BUSY:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Mount busy."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_DEV_BUSY:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Device busy."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_CANCELED:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Operation canceled."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_CLONE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("BE clone failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_COPY:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("BE copy failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_CREATDS:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Dataset creation failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_CURR_BE_NOT_FOUND:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Can't find current BE."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_DESTROY:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Failed to destroy BE or snapshot."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_DESTROY_CURR_BE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Cannot destroy current BE."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_DEMOTE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("BE demotion failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_DSTYPE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Invalid dataset type."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_BE_EXISTS:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("BE exists."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_INIT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("be_zfs_init failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_INTR:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Interupted system call."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_INVAL:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Invalid argument."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_INVALPROP:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Invalid property for dataset."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_INVALMOUNTPOINT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Unexpected mountpoint."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_MOUNT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Mount failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_MOUNTED:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Already mounted."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NAMETOOLONG:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("name > BUFSIZ."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NOENT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Doesn't exist."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_POOL_NOENT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("No such pool."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NODEV:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("No such device."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NOTMOUNTED:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("File system not mounted."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NOMEM:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Not enough memory."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NONINHERIT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext(
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "Property is not inheritable for the BE dataset."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NXIO:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("No such device or address."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NOSPC:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("No space on device."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NOTSUP:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Operation not supported."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_OPEN:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Open failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_PERM:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Not owner."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_UNAVAIL:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("The BE is currently unavailable."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_PROMOTE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("BE promotion failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_ROFS:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Read only file system."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_READONLYDS:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Read only dataset."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_READONLYPROP:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Read only property."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_RENAME_ACTIVE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Renaming the active BE is not supported."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_SS_EXISTS:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Snapshot exists."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_SS_NOENT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("No such snapshot."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_UMOUNT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Unmount failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_UMOUNT_CURR_BE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Can't unmount the current BE."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_UMOUNT_SHARED:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Unmount of a shared File System failed."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_FAULT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Bad address."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_UNKNOWN:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Unknown error."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_ZFS:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("ZFS returned an error."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_GEN_UUID:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Failed to generate uuid."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_PARSE_UUID:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Failed to parse uuid."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NO_UUID:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("No uuid"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_ZONE_NO_PARENTBE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("No parent uuid"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_ZONE_MULTIPLE_ACTIVE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Multiple active zone roots"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_ZONE_NO_ACTIVE_ROOT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("No active zone root"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_ZONE_ROOT_NOT_LEGACY:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Zone root not legacy"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_MOUNT_ZONEROOT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Failed to mount a zone root."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_UMOUNT_ZONEROOT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Failed to unmount a zone root."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NO_MOUNTED_ZONE:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Zone is not mounted"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_ZONES_UNMOUNT:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Unable to unmount a zone BE."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_NO_MENU:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Missing boot menu file."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_BAD_MENU_PATH:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Invalid path for menu.lst file"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_ZONE_SS_EXISTS:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Zone snapshot exists."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_BOOTFILE_INST:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Error installing boot files."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case BE_ERR_EXTCMD:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (gettext("Error running an external command."));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse default:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_has_grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Boolean function indicating whether the current system
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * uses grub.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Return: B_FALSE - the system does not have grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_TRUE - the system does have grub.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseboolean_t
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_has_grub(void)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome static struct be_defaults be_defaults;
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome static boolean_t be_deflts_set = B_FALSE;
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome /* Cache the defaults, because be_has_grub is used often. */
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome if (be_deflts_set == B_FALSE) {
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome be_get_defaults(&be_defaults);
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome be_deflts_set = B_TRUE;
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome }
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome
fa0c327afe484fa5ff164fb81ff93715dd6573f8Toomas Soome return (be_defaults.be_deflt_grub);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_is_isa
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Boolean function indicating whether the instruction set
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * architecture of the executing system matches the name provided.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The string must match a system defined architecture (e.g.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * "i386", "sparc") and is case sensitive.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters: name - string representing the name of instruction set
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * architecture being tested
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns: B_FALSE - the system instruction set architecture is different
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * from the one specified
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * B_TRUE - the system instruction set architecture is the same
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * as the one specified
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseboolean_t
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_is_isa(char *name)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return ((strcmp((char *)be_get_default_isa(), name) == 0));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_get_default_isa
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns the default instruction set architecture of the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * machine it is executed on. (eg. sparc, i386, ...)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * NOTE: SYS_INST environment variable may override default
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * return value
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * none
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * NULL - the architecture returned by sysinfo() was too
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * long for local variables
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * char * - pointer to a string containing the default
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * implementation
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassechar *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_get_default_isa(void)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int i;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *envp;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse static char default_inst[ARCH_LENGTH] = "";
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (default_inst[0] == '\0') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((envp = getenv("SYS_INST")) != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((int)strlen(envp) >= ARCH_LENGTH)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strcpy(default_inst, envp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse i = sysinfo(SI_ARCHITECTURE, default_inst, ARCH_LENGTH);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (i < 0 || i > ARCH_LENGTH)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (default_inst);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome/*
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * Function: be_get_platform
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * Description:
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * Returns the platfom name
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * Parameters:
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * none
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * Returns:
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * NULL - the platform name returned by sysinfo() was too
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * long for local variables
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * char * - pointer to a string containing the platform name
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * Scope:
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * Semi-private (library wide use only)
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome */
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soomechar *
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soomebe_get_platform(void)
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome{
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome int i;
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome static char default_inst[ARCH_LENGTH] = "";
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome if (default_inst[0] == '\0') {
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome i = sysinfo(SI_PLATFORM, default_inst, ARCH_LENGTH);
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome if (i < 0 || i > ARCH_LENGTH)
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome return (NULL);
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome }
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome return (default_inst);
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome}
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_run_cmd
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Runs a command in a separate subprocess. Splits out stdout from stderr
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * and sends each to its own buffer. Buffers must be pre-allocated and
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * passed in as arguments. Buffer sizes are also passed in as arguments.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Notes / caveats:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * - Command being run is assumed to not have any stdout or stderr
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * redirection.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * - Commands which emit total stderr output of greater than PIPE_BUF
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * bytes can hang. For such commands, a different implementation
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * which uses poll(2) must be used.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * - stdout_buf can be NULL. In this case, stdout_bufsize is ignored, and
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the stream which would have gone to it is sent to the bit
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * bucket.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * - stderr_buf cannot be NULL.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * - Only subprocess errors are appended to the stderr_buf. Errors
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * running the command are reported through be_print_err().
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * - Data which would overflow its respective buffer is sent to the bit
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * bucket.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * command: command to run. Assumed not to have embedded stdout
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * or stderr redirection. May have stdin redirection,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * however.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * stderr_buf: buffer returning subprocess stderr data. Errors
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * reported by this function are reported through
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_print_err().
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * stderr_bufsize: size of stderr_buf
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * stdout_buf: buffer returning subprocess stdout data.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * stdout_bufsize: size of stdout_buf
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - The command ran successfully without returning
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * errors.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_ERR_EXTCMD
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * - The command could not be run.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * - The command terminated with error status.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * - There were errors extracting or returning subprocess
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * data.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_ERR_NOMEM - The command exceeds the command buffer size.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_ERR_INVAL - An invalid argument was specified.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Semi-private (library wide use only)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_run_cmd(char *command, char *stderr_buf, int stderr_bufsize,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *stdout_buf, int stdout_bufsize)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *temp_filename = strdup(tmpnam(NULL));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *stdout_str = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *stderr_str = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char cmdline[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char oneline[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int exit_status;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int rval = BE_SUCCESS;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((command == NULL) || (stderr_buf == NULL) ||
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (stderr_bufsize <= 0) || (stdout_bufsize < 0) ||
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ((stdout_buf != NULL) ^ (stdout_bufsize != 0))) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_INVAL);
2b66e65286e123b22eb83c96426eafe5b3ddccd3Toomas Soome }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Set up command so popen returns stderr, not stdout */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (snprintf(cmdline, BUFSIZ, "%s 2> %s", command,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse temp_filename) >= BUFSIZ) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rval = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Set up the fifo that will make stderr available. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (mkfifo(temp_filename, 0600) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) be_print_err(gettext("be_run_cmd: mkfifo: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strerror(errno));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rval = BE_ERR_EXTCMD;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((stdout_str = popen(cmdline, "r")) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) be_print_err(gettext("be_run_cmd: popen: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strerror(errno));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rval = BE_ERR_EXTCMD;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((stderr_str = fopen(temp_filename, "r")) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) be_print_err(gettext("be_run_cmd: fopen: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strerror(errno));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) pclose(stdout_str);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rval = BE_ERR_EXTCMD;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Read stdout first, as it usually outputs more than stderr. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse oneline[BUFSIZ-1] = '\0';
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (fgets(oneline, BUFSIZ-1, stdout_str) != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (stdout_str != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(stdout_buf, oneline, stdout_bufsize);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (fgets(oneline, BUFSIZ-1, stderr_str) != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(stderr_buf, oneline, stderr_bufsize);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Close pipe, get exit status. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((exit_status = pclose(stdout_str)) == -1) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) be_print_err(gettext("be_run_cmd: pclose: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strerror(errno));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rval = BE_ERR_EXTCMD;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (WIFEXITED(exit_status)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse exit_status = (int)((char)WEXITSTATUS(exit_status));
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome /*
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * error code BC_NOUPDT means more recent version
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome * is installed
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome */
a63c99a2145c99a38d5ff19422b132400428ed9dToomas Soome if (exit_status != BC_SUCCESS && exit_status != BC_NOUPDT) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(oneline, BUFSIZ, gettext("be_run_cmd: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "command terminated with error status: %d\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse exit_status);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(stderr_buf, oneline, stderr_bufsize);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rval = BE_ERR_EXTCMD;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(oneline, BUFSIZ, gettext("be_run_cmd: command "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "terminated on signal: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strsignal(WTERMSIG(exit_status)));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(stderr_buf, oneline, stderr_bufsize);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rval = BE_ERR_EXTCMD;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassecleanup:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) unlink(temp_filename);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) free(temp_filename);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (rval);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ******************************************************************** */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Private Functions */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ******************************************************************** */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: update_dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function takes a dataset name and replaces the zpool
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * and be_name components of the dataset with the new be_name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * zpool passed in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * dataset - name of dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * dataset_len - lenth of buffer in which dataset is passed in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_name - name of new BE name to update to.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * old_rc_loc - dataset under which the root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * for the old BE lives.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * new_rc_loc - dataset under which the root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * for the new BE lives.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Private
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic int
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseupdate_dataset(char *dataset, int dataset_len, char *be_name,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *old_rc_loc, char *new_rc_loc)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *ds = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *sub_ds = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Tear off the BE container dataset */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((ds = be_make_name_from_ds(dataset, old_rc_loc)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_INVAL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get dataset name relative to BE root, if there is one */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sub_ds = strchr(ds, '/');
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Generate the BE root dataset name */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_make_root_ds(new_rc_loc, be_name, dataset, dataset_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* If a subordinate dataset name was found, append it */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (sub_ds != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(dataset, sub_ds, dataset_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(ds);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_SUCCESS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: _update_vfstab
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: This function updates a vfstab file to reflect the new
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * root container dataset location and be_name for all
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * entries listed in the be_fs_list_data_t structure passed in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * vfstab - vfstab file to modify
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_name - name of BE to update.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * old_rc_loc - dataset under which the root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * of the old BE resides in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * new_rc_loc - dataset under which the root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * of the new BE resides in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * fld - be_fs_list_data_t pointer providing the list of
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * file systems to look for in vfstab.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Private
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic int
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse_update_vfstab(char *vfstab, char *be_name, char *old_rc_loc,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *new_rc_loc, be_fs_list_data_t *fld)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct vfstab vp;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *tmp_vfstab = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char comments_buf[BUFSIZ];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *comments = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *vfs_ents = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *tfile = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct stat sb;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char dev[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *c;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int fd;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int ret = BE_SUCCESS, err = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int i;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int tmp_vfstab_len = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse errno = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Open vfstab for reading twice. First is for comments,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * second is for actual entries.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((comments = fopen(vfstab, "r")) == NULL ||
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (vfs_ents = fopen(vfstab, "r")) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to open vfstab (%s): %s\n"), vfstab,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Grab the stats of the original vfstab file */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (stat(vfstab, &sb) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to stat file %s: %s\n"), vfstab,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Create tmp file for modified vfstab */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((tmp_vfstab = (char *)malloc(strlen(vfstab) + 7))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "malloc failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = BE_ERR_NOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tmp_vfstab_len = strlen(vfstab) + 7;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) memset(tmp_vfstab, 0, tmp_vfstab_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(tmp_vfstab, vfstab, tmp_vfstab_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcat(tmp_vfstab, "XXXXXX", tmp_vfstab_len);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((fd = mkstemp(tmp_vfstab)) == -1) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "mkstemp failed: %s\n"), strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((tfile = fdopen(fd, "w")) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "could not open file for write\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) close(fd);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (fgets(comments_buf, BUFSIZ, comments)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (c = comments_buf; *c != '\0' && isspace(*c); c++)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (*c == '\0') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (*c == '#') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If line is a comment line, just put
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * it through to the tmp vfstab.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fputs(comments_buf, tfile);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Else line is a vfstab entry, grab it
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * into a vfstab struct.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (getvfsent(vfs_ents, &vp) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "getvfsent failed: %s\n"), strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (vp.vfs_special == NULL || vp.vfs_mountp == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) putvfsent(tfile, &vp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If the entry is one of the entries in the list
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * of file systems to update, modify it's device
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * field to be correct for this BE.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i < fld->fs_num; i++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(vp.vfs_special, fld->fs_list[i])
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Found entry that needs an update.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Replace the root container dataset
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * location and be_name in the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * entry's device.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(dev, vp.vfs_special,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof (dev));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((ret = update_dataset(dev,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof (dev), be_name, old_rc_loc,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse new_rc_loc)) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse gettext("_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "Failed to update device "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "field for vfstab entry "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "%s\n"), fld->fs_list[i]);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse vp.vfs_special = dev;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Put entry through to tmp vfstab */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) putvfsent(tfile, &vp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(comments);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse comments = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(vfs_ents);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse vfs_ents = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(tfile);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse tfile = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Copy tmp vfstab into place */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (rename(tmp_vfstab, vfstab) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to rename file %s to %s: %s\n"), tmp_vfstab,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse vfstab, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Set the perms and ownership of the updated file */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (chmod(vfstab, sb.st_mode) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to chmod %s: %s\n"), vfstab, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (chown(vfstab, sb.st_uid, sb.st_gid) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("_update_vfstab: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "failed to chown %s: %s\n"), vfstab, strerror(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = errno_to_be_err(err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse goto cleanup;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassecleanup:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (comments != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(comments);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (vfs_ents != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(vfs_ents);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) unlink(tmp_vfstab);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) free(tmp_vfstab);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (tfile != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(tfile);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ret);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_get_auto_name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description: Generate an auto name constructed based on the BE name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * of the original BE or zone BE being cloned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * obe_name - name of the original BE or zone BE being cloned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * container_ds - container dataset for the zone.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Note: if zone_be is false this should be
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * NULL.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * zone_be - flag that indicates if we are operating on a zone BE.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Success - pointer to auto generated BE name. The name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * is allocated in heap storage so the caller is
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * responsible for free'ing the name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Failure - NULL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Private
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic char *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_get_auto_name(char *obe_name, char *be_container_ds, boolean_t zone_be)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_node_list_t *be_nodes = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_node_list_t *cur_be = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char auto_be_name[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char base_be_name[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char cur_be_name[MAXPATHLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *num_str = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *c = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int num = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int cur_num = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse errno = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check if obe_name is already in an auto BE name format.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If it is, then strip off the increment number to get the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * base name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(base_be_name, obe_name, sizeof (base_be_name));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((num_str = strrchr(base_be_name, BE_AUTO_NAME_DELIM))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Make sure remaining string is all digits */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c = num_str + 1;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (c[0] != '\0' && isdigit(c[0]))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If we're now at the end of the string strip off the
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * increment number.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (c[0] == '\0')
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_str[0] = '\0';
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (zone_be) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_container_ds == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_get_zone_be_list(obe_name, be_container_ds,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse &be_nodes) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_get_auto_name: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "be_get_zone_be_list failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (_be_list(NULL, &be_nodes) != BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_get_auto_name: be_list failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (cur_be = be_nodes; cur_be != NULL; cur_be = cur_be->be_next_node) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strlcpy(cur_be_name, cur_be->be_node_name,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof (cur_be_name));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* If cur_be_name doesn't match at least base be name, skip. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strncmp(cur_be_name, base_be_name, strlen(base_be_name))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse != 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Get the string following the base be name */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_str = cur_be_name + strlen(base_be_name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If nothing follows the base be name, this cur_be_name
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * is the BE named with the base be name, skip.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (num_str == NULL || num_str[0] == '\0')
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Remove the name delimiter. If its not there,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * cur_be_name isn't part of this BE name stream, skip.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (num_str[0] == BE_AUTO_NAME_DELIM)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num_str++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Make sure remaining string is all digits */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c = num_str;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (c[0] != '\0' && isdigit(c[0]))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (c[0] != '\0')
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Convert the number string to an int */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse cur_num = atoi(num_str);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If failed to convert the string, skip it. If its too
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * long to be converted to an int, we wouldn't auto generate
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * this number anyway so there couldn't be a conflict.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * We treat it as a manually created BE name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (cur_num == 0 && errno == EINVAL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Compare current number to current max number,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * take higher of the two.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (cur_num > num)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num = cur_num;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Store off a copy of 'num' incase we need it later. If incrementing
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * 'num' causes it to roll over, this means 'num' is the largest
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * positive int possible; we'll need it later in the loop to determine
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * if we've exhausted all possible increment numbers. We store it in
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * 'cur_num'.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse cur_num = num;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* Increment 'num' to get new auto BE name number */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (++num <= 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int ret = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Since incrementing 'num' caused it to rollover, start
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * over at 0 and find the first available number.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (num = 0; num < cur_num; num++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(cur_be_name, sizeof (cur_be_name),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "%s%c%d", base_be_name, BE_AUTO_NAME_DELIM, num);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ret = zpool_iter(g_zfs, be_exists_callback,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse cur_be_name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ret == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE name doesn't exist, break out
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * to use 'num'.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (ret == 1) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /* BE name exists, continue looking */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_get_auto_name: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "zpool_iter failed: %s\n"),
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse libzfs_error_description(g_zfs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_free_list(be_nodes);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If 'num' equals 'cur_num', we've exhausted all possible
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * auto BE names for this base BE name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (num == cur_num) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_get_auto_name: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "No more available auto BE names for base "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "BE name %s\n"), base_be_name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_free_list(be_nodes);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_free_list(be_nodes);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Generate string for auto BE name.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) snprintf(auto_be_name, sizeof (auto_be_name), "%s%c%d",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse base_be_name, BE_AUTO_NAME_DELIM, num);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((c = strdup(auto_be_name)) == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_get_auto_name: "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "memory allocation failed\n"));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (c);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin/*
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin * Function: be_get_console_prop
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin * Description: Determine console device.
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin * Returns:
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin * Success - pointer to console setting.
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin * Failure - NULL
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin * Scope:
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin * Private
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin */
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Ereminstatic char *
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Ereminbe_get_console_prop(void)
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin{
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin di_node_t dn;
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin char *console = NULL;
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin if ((dn = di_init("/", DINFOPROP)) == DI_NODE_NIL) {
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin be_print_err(gettext("be_get_console_prop: "
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin "di_init() failed\n"));
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin return (NULL);
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin }
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin if (di_prop_lookup_strings(DDI_DEV_T_ANY, dn,
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin "console", &console) != -1) {
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin di_fini(dn);
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin return (console);
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin }
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin if (console == NULL) {
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin if (di_prop_lookup_strings(DDI_DEV_T_ANY, dn,
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin "output-device", &console) != -1) {
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin di_fini(dn);
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin if (strncmp(console, "screen", strlen("screen")) == 0)
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin console = BE_DEFAULT_CONSOLE;
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin }
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin }
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin /*
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin * Default console to text
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin */
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin if (console == NULL) {
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin console = BE_DEFAULT_CONSOLE;
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin }
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin return (console);
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin}
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_create_menu
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * This function is used if no menu.lst file exists. In
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * this case a new file is created and if needed default
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * lines are added to the file.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * pool - The name of the pool the menu.lst file is on
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * menu_file - The name of the file we're creating.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * menu_fp - A pointer to the file pointer of the file we
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * created. This is also used to pass back the file
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * pointer to the newly created file.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * mode - the original mode used for the failed attempt to
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * non-existent file.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Private
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic int
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_create_menu(
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *pool,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *menu_file,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE **menu_fp,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *mode)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_node_list_t *be_nodes = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *menu_path = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *be_rpool = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *be_name = NULL;
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin char *console = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse errno = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (menu_file == NULL || menu_fp == NULL || mode == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_INVAL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse menu_path = strdup(menu_file);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (menu_path == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NOMEM);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) dirname(menu_path);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (*menu_path == '.') {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(menu_path);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_BAD_MENU_PATH);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (mkdirp(menu_path,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1 &&
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse errno != EEXIST) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(menu_path);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_create_menu: Failed to create the %s "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "directory: %s\n"), menu_path, strerror(errno));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (errno_to_be_err(errno));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse free(menu_path);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if this system supports grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_has_grub()) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The grub menu is missing so we need to create it
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * and fill in the first few lines.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin FILE *temp_fp = fopen(menu_file, "a+");
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin if (temp_fp == NULL) {
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin *menu_fp = NULL;
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin return (errno_to_be_err(errno));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin if ((console = be_get_console_prop()) != NULL) {
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin /*
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin * If console is redirected to serial line,
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin * GRUB splash screen will not be enabled.
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin */
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin if (strncmp(console, "text", strlen("text")) == 0 ||
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin strncmp(console, "graphics",
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin strlen("graphics")) == 0) {
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin (void) fprintf(temp_fp, "%s\n", BE_GRUB_SPLASH);
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin (void) fprintf(temp_fp, "%s\n",
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin BE_GRUB_FOREGROUND);
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin (void) fprintf(temp_fp, "%s\n",
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin BE_GRUB_BACKGROUND);
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin (void) fprintf(temp_fp, "%s\n",
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin BE_GRUB_DEFAULT);
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin } else {
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin be_print_err(gettext("be_create_menu: "
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin "console on serial line, "
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin "GRUB splash image will be disabled\n"));
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin }
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin }
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin (void) fprintf(temp_fp, "timeout 30\n");
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin (void) fclose(temp_fp);
6b1d07a45d9af0029b8def806dc241c96c57435bAlexander Eremin
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * The menu file doesn't exist so we need to create a
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * blank file.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE *temp_fp = fopen(menu_file, "w+");
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (temp_fp == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *menu_fp = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (errno_to_be_err(errno));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) fclose(temp_fp);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Now we need to add all the BE's back into the the file.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (_be_list(NULL, &be_nodes) == BE_SUCCESS) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while (be_nodes != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strcmp(pool, be_nodes->be_rpool) == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) be_append_menu(be_nodes->be_node_name,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_nodes->be_rpool, NULL, NULL, NULL);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_nodes->be_active_on_boot) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_rpool = strdup(be_nodes->be_rpool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_name = strdup(be_nodes->be_node_name);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_nodes = be_nodes->be_next_node;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_free_list(be_nodes);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Check to see if this system supports grub
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (be_has_grub()) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = be_change_grub_default(be_name, be_rpool);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (err != BE_SUCCESS)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *menu_fp = fopen(menu_file, mode);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (*menu_fp == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (errno_to_be_err(errno));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_SUCCESS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Function: be_open_menu
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Description:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * This function is used it open the menu.lst file. If this
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * file does not exist be_create_menu is called to create it
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * and the open file pointer is returned. If the file does
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * exist it is simply opened using the mode passed in.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Parameters:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * pool - The name of the pool the menu.lst file is on
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * menu_file - The name of the file we're opening.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * menu_fp - A pointer to the file pointer of the file we're
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * opening. This is also used to pass back the file
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * pointer.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * mode - the original mode to be used for opening the menu.lst
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * file.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * create_menu - If this is true and the menu.lst file does not
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * exist we will attempt to re-create it. However
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * if it's false the error returned from the fopen
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * will be returned.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Returns:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * BE_SUCCESS - Success
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * be_errno_t - Failure
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Scope:
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Private
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic int
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassebe_open_menu(
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *pool,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *menu_file,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FILE **menu_fp,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *mode,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t create_menu)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse boolean_t set_print = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *menu_fp = fopen(menu_file, mode);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = errno;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (*menu_fp == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (err == ENOENT && create_menu) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_open_menu: menu.lst "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "file %s does not exist,\n"), menu_file);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (!do_print) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse set_print = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse do_print = B_TRUE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("WARNING: menu.lst "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "file %s does not exist,\n generating "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "a new menu.lst file\n"), menu_file);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (set_print)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse do_print = B_FALSE;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = 0;
de1ab35c09a8c3ae1b531c0a613d2cc1c61cee9dAlexander Eremin if ((err = be_create_menu(pool, menu_file,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse menu_fp, mode)) == ENOENT)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NO_MENU);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse else if (err != BE_SUCCESS)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (err);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse else if (*menu_fp == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NO_MENU);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse be_print_err(gettext("be_open_menu: failed "
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse "to open menu.lst file %s\n"), menu_file);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (err == ENOENT)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_ERR_NO_MENU);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (errno_to_be_err(err));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (BE_SUCCESS);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}