aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMariusz Zaborski <oshogbo@FreeBSD.org>2020-08-18 19:48:04 +0000
committerMariusz Zaborski <oshogbo@FreeBSD.org>2020-08-18 19:48:04 +0000
commit277f38abffc6a8160b5044128b5b2c620fbb970c (patch)
tree3bab41fe37fb14ef05b8dfb2b0b1235a2a47ffce /sys
parentad7a0eb189e2aba52f2dcc6b47642a84365b90dd (diff)
downloadsrc-277f38abffc6a8160b5044128b5b2c620fbb970c.tar.gz
src-277f38abffc6a8160b5044128b5b2c620fbb970c.zip
zfs: add an option to the bootloader to rewind the ZFS checkpoint
The checkpoints are another way of keeping the state of ZFS. During the rewind, the pool has to be exported. This makes checkpoints unusable when using ZFS as root. Add the option to rewind the ZFS checkpoint at the boot time. If checkpoint exists, a new option for rewinding a checkpoint will appear in the bootloader menu. We fully support boot environments. If the rewind option is selected, the boot loader will show a list of boot environments that existed before the checkpoint. Reviewed by: tsoome, allanjude, kevans (ok with high-level overview) Differential Revision: https://reviews.freebsd.org/D24920
Notes
Notes: svn path=/head/; revision=364355
Diffstat (limited to 'sys')
-rw-r--r--sys/cddl/boot/zfs/zfsimpl.h10
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c5
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c16
4 files changed, 28 insertions, 5 deletions
diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h
index 9ad244d083b9..6a6331450e8b 100644
--- a/sys/cddl/boot/zfs/zfsimpl.h
+++ b/sys/cddl/boot/zfs/zfsimpl.h
@@ -1351,6 +1351,7 @@ typedef struct dsl_dataset_phys {
#define DMU_POOL_REMOVING "com.delphix:removing"
#define DMU_POOL_OBSOLETE_BPOBJ "com.delphix:obsolete_bpobj"
#define DMU_POOL_CONDENSING_INDIRECT "com.delphix:condensing_indirect"
+#define DMU_POOL_ZPOOL_CHECKPOINT "com.delphix:zpool_checkpoint"
#define ZAP_MAGIC 0x2F52AB2ABULL
@@ -1814,12 +1815,17 @@ typedef struct spa {
char *spa_name; /* pool name */
uint64_t spa_guid; /* pool guid */
uint64_t spa_txg; /* most recent transaction */
- struct uberblock spa_uberblock; /* best uberblock so far */
+ struct uberblock *spa_uberblock; /* best uberblock so far */
vdev_t *spa_root_vdev; /* toplevel vdev container */
- objset_phys_t spa_mos; /* MOS for this pool */
+ objset_phys_t *spa_mos; /* MOS for this pool */
zio_cksum_salt_t spa_cksum_salt; /* secret salt for cksum */
void *spa_cksum_tmpls[ZIO_CHECKSUM_FUNCTIONS];
boolean_t spa_with_log; /* this pool has log */
+
+ struct uberblock spa_uberblock_master; /* best uberblock so far */
+ objset_phys_t spa_mos_master; /* MOS for this pool */
+ struct uberblock spa_uberblock_checkpoint; /* checkpoint uberblock */
+ objset_phys_t spa_mos_checkpoint; /* Checkpoint MOS */
} spa_t;
/* IO related arguments. */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
index 1012f1908d02..65ae7904047b 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
@@ -5719,7 +5719,7 @@ spa_generate_rootconf(const char *name)
}
int
-spa_import_rootpool(const char *name)
+spa_import_rootpool(const char *name, bool checkpointrewind)
{
spa_t *spa;
vdev_t *rvd, *bvd, *avd = NULL;
@@ -5778,6 +5778,9 @@ spa_import_rootpool(const char *name)
}
spa->spa_is_root = B_TRUE;
spa->spa_import_flags = ZFS_IMPORT_VERBATIM;
+ if (checkpointrewind) {
+ spa->spa_import_flags |= ZFS_IMPORT_CHECKPOINT;
+ }
/*
* Build up a vdev tree based on the boot device's label config.
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h
index 925358febd7c..5bdc4feb3d5e 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h
@@ -643,7 +643,7 @@ extern int spa_create(const char *pool, nvlist_t *config, nvlist_t *props,
#ifdef illumos
extern int spa_import_rootpool(char *devpath, char *devid);
#else
-extern int spa_import_rootpool(const char *name);
+extern int spa_import_rootpool(const char *name, bool checkpointrewind);
#endif
extern int spa_import(const char *pool, nvlist_t *config, nvlist_t *props,
uint64_t flags);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index fb6a40ac49b4..1ce186d0862e 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -1783,6 +1783,18 @@ getpoolname(const char *osname, char *poolname)
return (0);
}
+static void
+fetch_osname_options(char *name, bool *checkpointrewind)
+{
+
+ if (name[0] == '!') {
+ *checkpointrewind = true;
+ memmove(name, name + 1, strlen(name));
+ } else {
+ *checkpointrewind = false;
+ }
+}
+
/*ARGSUSED*/
static int
zfs_mount(vfs_t *vfsp)
@@ -1793,6 +1805,7 @@ zfs_mount(vfs_t *vfsp)
char *osname;
int error = 0;
int canwrite;
+ bool checkpointrewind;
#ifdef illumos
if (mvp->v_type != VDIR)
@@ -1836,6 +1849,7 @@ zfs_mount(vfs_t *vfsp)
secpolicy_fs_mount_clearopts(cr, vfsp);
}
#endif /* illumos */
+ fetch_osname_options(osname, &checkpointrewind);
/*
* Check for mount privilege?
@@ -1921,7 +1935,7 @@ zfs_mount(vfs_t *vfsp)
error = getpoolname(osname, pname);
if (error == 0)
- error = spa_import_rootpool(pname);
+ error = spa_import_rootpool(pname, checkpointrewind);
if (error)
goto out;
}