diff options
author | avg <avg@FreeBSD.org> | 2016-11-21 10:14:36 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2016-11-21 10:14:36 +0000 |
commit | 127d4fb179cbcc20d23d875bd762df151f4095fd (patch) | |
tree | cbc4adadf658bd1b64df474a818bfbd0d8d00cc7 /sbin | |
parent | f40dc50ad2f89e81e3e36797a4771a529126b76c (diff) | |
download | FreeBSD-src-127d4fb179cbcc20d23d875bd762df151f4095fd.zip FreeBSD-src-127d4fb179cbcc20d23d875bd762df151f4095fd.tar.gz |
MFC r308089: zfsbootcfg: a simple tool to set next boot (one time)
options for zfsboot
There is a branch-specific change in sbin/zfsbootcfg/Makefile because of
LIBADD vs LDADD/DPADD.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/Makefile | 1 | ||||
-rw-r--r-- | sbin/zfsbootcfg/Makefile | 33 | ||||
-rw-r--r-- | sbin/zfsbootcfg/zfsbootcfg.8 | 112 | ||||
-rw-r--r-- | sbin/zfsbootcfg/zfsbootcfg.c | 98 |
4 files changed, 244 insertions, 0 deletions
diff --git a/sbin/Makefile b/sbin/Makefile index 3c24934..460c767 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -73,6 +73,7 @@ SUBDIR=adjkerntz \ .if ${MK_ATM} != "no" SUBDIR+= atm .endif +SUBDIR.${MK_ZFS}+= zfsbootcfg .if ${MK_CCD} != "no" SUBDIR+= ccdconfig diff --git a/sbin/zfsbootcfg/Makefile b/sbin/zfsbootcfg/Makefile new file mode 100644 index 0000000..563c48e --- /dev/null +++ b/sbin/zfsbootcfg/Makefile @@ -0,0 +1,33 @@ +# @(#)Makefile 8.4 (Berkeley) 6/22/95 +# $FreeBSD$ + +PROG= zfsbootcfg +WARNS?= 1 +MAN= zfsbootcfg.8 + +DPADD+=${LIBZFS} +DPADD+=${LIBNVPAIR} +DPADD+=${LIBUMEM} +DPADD+=${LIBUUTIL} +DPADD+=${LIBGEOM} + +LDADD+=-lzfs +LDADD+=-lnvpair +LDADD+=-lumem +LDADD+=-luutil +LDADD+=-lgeom + +CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include +CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs/common +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs_core/common +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair +CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris +CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs +CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head + +CFLAGS+= -DNEED_SOLARIS_BOOLEAN + +.include <bsd.prog.mk> diff --git a/sbin/zfsbootcfg/zfsbootcfg.8 b/sbin/zfsbootcfg/zfsbootcfg.8 new file mode 100644 index 0000000..aa6201d --- /dev/null +++ b/sbin/zfsbootcfg/zfsbootcfg.8 @@ -0,0 +1,112 @@ +.\" Copyright (c) 2016 Andriy Gapon +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd October 12, 2016 +.Dt ZFSBOOTCFG 8 +.Os +.Sh NAME +.Nm zfsbootcfg +.Nd "specify zfsboot options for the next boot" +.Sh SYNOPSIS +.Nm +.Ao Ar options Ac +.Sh DESCRIPTION +.Nm +is used to set +.Xr boot.config 5 Ns -style +options to be used by +.Xr zfsboot 8 +or +.Xr gptzfsboot 8 +the next time the machine is booted. +Once +.Xr zfsboot 8 +or +.Xr gptzfsboot 8 +reads the information, it is deleted. +If booting fails, the machine automatically reverts to the previous +boot configuration. +The information is stored in a special reserved area of a ZFS pool. +.Xr zfsboot 8 +or +.Xr gptzfsboot 8 +read the boot option information from the first disk found in the first +ZFS pool found. +.Sh ENVIRONMENT +.Bl -tag -width vfs.zfs.boot.primary_pool -compact +.It Ev vfs.zfs.boot.primary_pool +The +.Xr kenv 1 +variable that identifies a pool for which the options are written. +.It Ev vfs.zfs.boot.primary_vdev +The +.Xr kenv 1 +variable that identifies a disk within the pool where the options +are written. +.El +.Sh EXAMPLES +Try to boot to a new +.Em boot environment +without changing the +.Cm bootfs +property of a pool: +.Pp +.Dl "zfsbootcfg ""zfs:tank/ROOT/newbe:"" +.Pp +To clear the boot options: +.Pp +.Dl "zfsbootcfg """" +.Sh SEE ALSO +.Xr boot.config 5 , +.Xr gptzfsboot 8 , +.Xr zfsboot 8 +.Sh HISTORY +.Nm +appeared in +.Fx 12.0 . +.Sh AUTHORS +This manual page was written by +.An Andriy Gapon Aq Mt avg@FreeBSD.org . +.Sh CAVEATS +At the moment, +.Nm +uses the +.Ev vfs.zfs.boot.primary_pool +and +.Ev vfs.zfs.boot.primary_vdev +.Xr kenv 1 +variables to determine a ZFS pool and a disk in it where the options +are to be stored. +The variables are set by the ZFS boot chain, so there is an assumption +that the same boot disk is going to be used for the next reboot. +There is no +.Nm +option to specify a different pool or a different disk. +.Pp +.Nm +should be extended to install new +.Xr zfsboot 8 +blocks in a ZFS pool. diff --git a/sbin/zfsbootcfg/zfsbootcfg.c b/sbin/zfsbootcfg/zfsbootcfg.c new file mode 100644 index 0000000..096f1a4 --- /dev/null +++ b/sbin/zfsbootcfg/zfsbootcfg.c @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 2016 Andriy Gapon <avg@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <errno.h> +#include <limits.h> +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <kenv.h> + +#include <libzfs.h> + +/* Keep in sync with zfsboot.c. */ +#define MAX_COMMAND_LEN 512 + +int main(int argc, const char * const *argv) +{ + char buf[32]; + libzfs_handle_t *hdl; + uint64_t pool_guid; + uint64_t vdev_guid; + int zfs_fd; + int len; + + if (argc != 2) { + fprintf(stderr, "usage: zfsbootcfg <boot.config(5) options>\n"); + return (1); + } + + len = strlen(argv[1]); + if (len >= MAX_COMMAND_LEN) { + fprintf(stderr, "options string is too long\n"); + return (1); + } + + if (kenv(KENV_GET, "vfs.zfs.boot.primary_pool", buf, sizeof(buf)) <= 0) { + perror("can't get vfs.zfs.boot.primary_pool"); + return (1); + } + pool_guid = strtoumax(buf, NULL, 10); + if (pool_guid == 0) { + perror("can't parse vfs.zfs.boot.primary_pool"); + return (1); + } + + if (kenv(KENV_GET, "vfs.zfs.boot.primary_vdev", buf, sizeof(buf)) <= 0) { + perror("can't get vfs.zfs.boot.primary_vdev"); + return (1); + } + vdev_guid = strtoumax(buf, NULL, 10); + if (vdev_guid == 0) { + perror("can't parse vfs.zfs.boot.primary_vdev"); + return (1); + } + + if ((hdl = libzfs_init()) == NULL) { + (void) fprintf(stderr, "internal error: failed to " + "initialize ZFS library\n"); + return (1); + } + + if (zpool_nextboot(hdl, pool_guid, vdev_guid, argv[1]) != 0) { + perror("ZFS_IOC_NEXTBOOT failed"); + libzfs_fini(hdl); + return (1); + } + + libzfs_fini(hdl); + printf("zfs next boot options are successfully written\n"); + return (0); +} |