1308089Savg/*- 2308089Savg * Copyright (c) 2016 Andriy Gapon <avg@FreeBSD.org> 3308089Savg * All rights reserved. 4308089Savg * 5308089Savg * Redistribution and use in source and binary forms, with or without 6308089Savg * modification, are permitted provided that the following conditions 7308089Savg * are met: 8308089Savg * 1. Redistributions of source code must retain the above copyright 9308089Savg * notice, this list of conditions and the following disclaimer. 10308089Savg * 2. Redistributions in binary form must reproduce the above copyright 11308089Savg * notice, this list of conditions and the following disclaimer in the 12308089Savg * documentation and/or other materials provided with the distribution. 13308089Savg * 14308089Savg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15308089Savg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16308089Savg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17308089Savg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18308089Savg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19308089Savg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20308089Savg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21308089Savg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22308089Savg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23308089Savg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24308089Savg */ 25308089Savg 26308089Savg#include <sys/cdefs.h> 27308089Savg__FBSDID("$FreeBSD: stable/11/sbin/zfsbootcfg/zfsbootcfg.c 308089 2016-10-29 14:09:32Z avg $"); 28308089Savg 29308089Savg#include <sys/types.h> 30308089Savg#include <errno.h> 31308089Savg#include <limits.h> 32308089Savg#include <inttypes.h> 33308089Savg#include <stdio.h> 34308089Savg#include <stdlib.h> 35308089Savg#include <string.h> 36308089Savg#include <kenv.h> 37308089Savg 38308089Savg#include <libzfs.h> 39308089Savg 40308089Savg/* Keep in sync with zfsboot.c. */ 41308089Savg#define MAX_COMMAND_LEN 512 42308089Savg 43308089Savgint main(int argc, const char * const *argv) 44308089Savg{ 45308089Savg char buf[32]; 46308089Savg libzfs_handle_t *hdl; 47308089Savg uint64_t pool_guid; 48308089Savg uint64_t vdev_guid; 49308089Savg int zfs_fd; 50308089Savg int len; 51308089Savg 52308089Savg if (argc != 2) { 53308089Savg fprintf(stderr, "usage: zfsbootcfg <boot.config(5) options>\n"); 54308089Savg return (1); 55308089Savg } 56308089Savg 57308089Savg len = strlen(argv[1]); 58308089Savg if (len >= MAX_COMMAND_LEN) { 59308089Savg fprintf(stderr, "options string is too long\n"); 60308089Savg return (1); 61308089Savg } 62308089Savg 63308089Savg if (kenv(KENV_GET, "vfs.zfs.boot.primary_pool", buf, sizeof(buf)) <= 0) { 64308089Savg perror("can't get vfs.zfs.boot.primary_pool"); 65308089Savg return (1); 66308089Savg } 67308089Savg pool_guid = strtoumax(buf, NULL, 10); 68308089Savg if (pool_guid == 0) { 69308089Savg perror("can't parse vfs.zfs.boot.primary_pool"); 70308089Savg return (1); 71308089Savg } 72308089Savg 73308089Savg if (kenv(KENV_GET, "vfs.zfs.boot.primary_vdev", buf, sizeof(buf)) <= 0) { 74308089Savg perror("can't get vfs.zfs.boot.primary_vdev"); 75308089Savg return (1); 76308089Savg } 77308089Savg vdev_guid = strtoumax(buf, NULL, 10); 78308089Savg if (vdev_guid == 0) { 79308089Savg perror("can't parse vfs.zfs.boot.primary_vdev"); 80308089Savg return (1); 81308089Savg } 82308089Savg 83308089Savg if ((hdl = libzfs_init()) == NULL) { 84308089Savg (void) fprintf(stderr, "internal error: failed to " 85308089Savg "initialize ZFS library\n"); 86308089Savg return (1); 87308089Savg } 88308089Savg 89308089Savg if (zpool_nextboot(hdl, pool_guid, vdev_guid, argv[1]) != 0) { 90308089Savg perror("ZFS_IOC_NEXTBOOT failed"); 91308089Savg libzfs_fini(hdl); 92308089Savg return (1); 93308089Savg } 94308089Savg 95308089Savg libzfs_fini(hdl); 96308089Savg printf("zfs next boot options are successfully written\n"); 97308089Savg return (0); 98308089Savg} 99