mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-25 02:49:32 +03:00
Improve handling of filesystem versions
Change mount code to diagnose filesystem versions that are not supported by the current implementation. Change upgrade code to do likewise and refuse to upgrade a pool if any filesystems on it are a version which is not supported by the current implementation. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Dan Swartzendruber <dswartz@druber.com> Closes: #2616
This commit is contained in:
parent
bcd9624d0f
commit
287be44f53
@ -363,6 +363,7 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
zfs_handle_t *zhp;
|
zfs_handle_t *zhp;
|
||||||
char prop[ZFS_MAXPROPLEN];
|
char prop[ZFS_MAXPROPLEN];
|
||||||
|
uint64_t zfs_version = 0;
|
||||||
char mntopts[MNT_LINE_MAX] = { '\0' };
|
char mntopts[MNT_LINE_MAX] = { '\0' };
|
||||||
char badopt[MNT_LINE_MAX] = { '\0' };
|
char badopt[MNT_LINE_MAX] = { '\0' };
|
||||||
char mtabopt[MNT_LINE_MAX] = { '\0' };
|
char mtabopt[MNT_LINE_MAX] = { '\0' };
|
||||||
@ -515,6 +516,18 @@ main(int argc, char **argv)
|
|||||||
(void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, prop,
|
(void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, prop,
|
||||||
sizeof (prop), NULL, NULL, 0, B_FALSE);
|
sizeof (prop), NULL, NULL, 0, B_FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fetch the max supported zfs version in case we get ENOTSUP
|
||||||
|
* back from the mount command, since we need the zfs handle
|
||||||
|
* to do so.
|
||||||
|
*/
|
||||||
|
zfs_version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
|
||||||
|
if (zfs_version == 0) {
|
||||||
|
fprintf(stderr, gettext("unable to fetch "
|
||||||
|
"ZFS version for filesystem '%s'\n"), dataset);
|
||||||
|
return (MOUNT_SYSERR);
|
||||||
|
}
|
||||||
|
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
libzfs_fini(g_zfs);
|
libzfs_fini(g_zfs);
|
||||||
|
|
||||||
@ -551,22 +564,36 @@ main(int argc, char **argv)
|
|||||||
if (!fake) {
|
if (!fake) {
|
||||||
error = mount(dataset, mntpoint, MNTTYPE_ZFS,
|
error = mount(dataset, mntpoint, MNTTYPE_ZFS,
|
||||||
mntflags, mntopts);
|
mntflags, mntopts);
|
||||||
if (error) {
|
}
|
||||||
switch (errno) {
|
|
||||||
case ENOENT:
|
if (error) {
|
||||||
(void) fprintf(stderr, gettext("mount point "
|
switch (errno) {
|
||||||
"'%s' does not exist\n"), mntpoint);
|
case ENOENT:
|
||||||
return (MOUNT_SYSERR);
|
(void) fprintf(stderr, gettext("mount point "
|
||||||
case EBUSY:
|
"'%s' does not exist\n"), mntpoint);
|
||||||
(void) fprintf(stderr, gettext("filesystem "
|
return (MOUNT_SYSERR);
|
||||||
"'%s' is already mounted\n"), dataset);
|
case EBUSY:
|
||||||
return (MOUNT_BUSY);
|
(void) fprintf(stderr, gettext("filesystem "
|
||||||
default:
|
"'%s' is already mounted\n"), dataset);
|
||||||
(void) fprintf(stderr, gettext("filesystem "
|
return (MOUNT_BUSY);
|
||||||
"'%s' can not be mounted due to error "
|
case ENOTSUP:
|
||||||
"%d\n"), dataset, errno);
|
if (zfs_version > ZPL_VERSION) {
|
||||||
return (MOUNT_USAGE);
|
(void) fprintf(stderr,
|
||||||
|
gettext("filesystem '%s' (v%d) is not "
|
||||||
|
"supported by this implementation of "
|
||||||
|
"ZFS (max v%d).\n"), dataset,
|
||||||
|
(int) zfs_version, (int) ZPL_VERSION);
|
||||||
|
} else {
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
gettext("filesystem '%s' mount "
|
||||||
|
"failed for unknown reason.\n"), dataset);
|
||||||
}
|
}
|
||||||
|
return (MOUNT_SYSERR);
|
||||||
|
default:
|
||||||
|
(void) fprintf(stderr, gettext("filesystem "
|
||||||
|
"'%s' can not be mounted due to error "
|
||||||
|
"%d\n"), dataset, errno);
|
||||||
|
return (MOUNT_USAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4601,12 +4601,33 @@ typedef struct upgrade_cbdata {
|
|||||||
char **cb_argv;
|
char **cb_argv;
|
||||||
} upgrade_cbdata_t;
|
} upgrade_cbdata_t;
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_unsupp_fs(zfs_handle_t *zhp, void *unsupp_fs)
|
||||||
|
{
|
||||||
|
int zfs_version = (int) zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
|
||||||
|
int *count = (int *)unsupp_fs;
|
||||||
|
|
||||||
|
if (zfs_version > ZPL_VERSION) {
|
||||||
|
(void) printf(gettext("%s (v%d) is not supported by this "
|
||||||
|
"implementation of ZFS.\n"),
|
||||||
|
zfs_get_name(zhp), zfs_version);
|
||||||
|
(*count)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
zfs_iter_filesystems(zhp, check_unsupp_fs, unsupp_fs);
|
||||||
|
|
||||||
|
zfs_close(zhp);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
upgrade_version(zpool_handle_t *zhp, uint64_t version)
|
upgrade_version(zpool_handle_t *zhp, uint64_t version)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
nvlist_t *config;
|
nvlist_t *config;
|
||||||
uint64_t oldversion;
|
uint64_t oldversion;
|
||||||
|
int unsupp_fs = 0;
|
||||||
|
|
||||||
config = zpool_get_config(zhp, NULL);
|
config = zpool_get_config(zhp, NULL);
|
||||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
|
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
|
||||||
@ -4615,6 +4636,17 @@ upgrade_version(zpool_handle_t *zhp, uint64_t version)
|
|||||||
assert(SPA_VERSION_IS_SUPPORTED(oldversion));
|
assert(SPA_VERSION_IS_SUPPORTED(oldversion));
|
||||||
assert(oldversion < version);
|
assert(oldversion < version);
|
||||||
|
|
||||||
|
ret = zfs_iter_root(zpool_get_handle(zhp), check_unsupp_fs, &unsupp_fs);
|
||||||
|
if (ret != 0)
|
||||||
|
return (ret);
|
||||||
|
|
||||||
|
if (unsupp_fs) {
|
||||||
|
(void) printf(gettext("Upgrade not performed due to %d "
|
||||||
|
"unsupported filesystems (max v%d).\n"),
|
||||||
|
unsupp_fs, (int) ZPL_VERSION);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
ret = zpool_upgrade(zhp, version);
|
ret = zpool_upgrade(zhp, version);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return (ret);
|
return (ret);
|
||||||
|
@ -679,12 +679,7 @@ zfs_sb_create(const char *osname, zfs_sb_t **zsbp)
|
|||||||
error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zsb->z_version);
|
error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zsb->z_version);
|
||||||
if (error) {
|
if (error) {
|
||||||
goto out;
|
goto out;
|
||||||
} else if (zsb->z_version >
|
} else if (zsb->z_version > ZPL_VERSION) {
|
||||||
zfs_zpl_version_map(spa_version(dmu_objset_spa(os)))) {
|
|
||||||
(void) printk("Can't mount a version %lld file system "
|
|
||||||
"on a version %lld pool\n. Pool must be upgraded to mount "
|
|
||||||
"this file system.", (u_longlong_t)zsb->z_version,
|
|
||||||
(u_longlong_t)spa_version(dmu_objset_spa(os)));
|
|
||||||
error = SET_ERROR(ENOTSUP);
|
error = SET_ERROR(ENOTSUP);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user