mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-27 05:21:08 +01:00
Add forwards compatibility for libzfs_core
Unsupported: creation of multiple snapshots including "zfs snapshot -r"
This commit is contained in:
parent
70b0720877
commit
67ebc12d49
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/libzfs_core/; revision=248435
@ -86,6 +86,10 @@
|
|||||||
#include <sys/zfs_ioctl.h>
|
#include <sys/zfs_ioctl.h>
|
||||||
#include <libzfs_compat.h>
|
#include <libzfs_compat.h>
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
extern int zfs_ioctl_version;
|
||||||
|
#endif
|
||||||
|
|
||||||
static int g_fd;
|
static int g_fd;
|
||||||
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static int g_refcount;
|
static int g_refcount;
|
||||||
@ -124,12 +128,24 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
|
|||||||
zfs_cmd_t zc = { 0 };
|
zfs_cmd_t zc = { 0 };
|
||||||
int error = 0;
|
int error = 0;
|
||||||
char *packed;
|
char *packed;
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
nvlist_t *oldsource;
|
||||||
|
#endif
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
ASSERT3S(g_refcount, >, 0);
|
ASSERT3S(g_refcount, >, 0);
|
||||||
|
|
||||||
(void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
|
(void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
if (zfs_ioctl_version < ZFS_IOCVER_LZC) {
|
||||||
|
oldsource = source;
|
||||||
|
error = lzc_compat_pre(&zc, &ioc, &source);
|
||||||
|
if (error)
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
packed = fnvlist_pack(source, &size);
|
packed = fnvlist_pack(source, &size);
|
||||||
zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
|
zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
|
||||||
zc.zc_nvlist_src_size = size;
|
zc.zc_nvlist_src_size = size;
|
||||||
@ -167,14 +183,29 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
if (zfs_ioctl_version < ZFS_IOCVER_LZC)
|
||||||
|
lzc_compat_post(&zc, ioc);
|
||||||
|
#endif
|
||||||
if (zc.zc_nvlist_dst_filled) {
|
if (zc.zc_nvlist_dst_filled) {
|
||||||
*resultp = fnvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst,
|
*resultp = fnvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst,
|
||||||
zc.zc_nvlist_dst_size);
|
zc.zc_nvlist_dst_size);
|
||||||
} else if (resultp != NULL) {
|
} else if (resultp != NULL) {
|
||||||
*resultp = NULL;
|
*resultp = NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
if (zfs_ioctl_version < ZFS_IOCVER_LZC)
|
||||||
|
lzc_compat_outnvl(&zc, ioc, resultp);
|
||||||
|
#endif
|
||||||
out:
|
out:
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
if (zfs_ioctl_version < ZFS_IOCVER_LZC) {
|
||||||
|
if (source != oldsource)
|
||||||
|
nvlist_free(source);
|
||||||
|
source = oldsource;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
fnvlist_pack_free(packed, size);
|
fnvlist_pack_free(packed, size);
|
||||||
free((void *)(uintptr_t)zc.zc_nvlist_dst);
|
free((void *)(uintptr_t)zc.zc_nvlist_dst);
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/fs/zfs.h>
|
#include <sys/fs/zfs.h>
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include "libzfs_core_compat.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* CDDL HEADER START
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the terms of the
|
||||||
|
* Common Development and Distribution License (the "License").
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
*
|
||||||
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
|
* See the License for the specific language governing permissions
|
||||||
|
* and limitations under the License.
|
||||||
|
*
|
||||||
|
* When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
* If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
*
|
||||||
|
* CDDL HEADER END
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/zfs_ioctl.h>
|
||||||
|
#include <libzfs_compat.h>
|
||||||
|
|
||||||
|
extern int zfs_ioctl_version;
|
||||||
|
|
||||||
|
int
|
||||||
|
lzc_compat_pre(zfs_cmd_t *zc, zfs_ioc_t *ioc, nvlist_t **source)
|
||||||
|
{
|
||||||
|
nvlist_t *nvl = NULL;
|
||||||
|
nvpair_t *pair;
|
||||||
|
char *buf;
|
||||||
|
zfs_ioc_t vecnum;
|
||||||
|
uint32_t type32;
|
||||||
|
int error = 0;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
vecnum = *ioc;
|
||||||
|
|
||||||
|
switch (vecnum) {
|
||||||
|
case ZFS_IOC_CREATE:
|
||||||
|
type32 = fnvlist_lookup_int32(*source, "type");
|
||||||
|
zc->zc_objset_type = (uint64_t)type32;
|
||||||
|
nvlist_lookup_nvlist(*source, "props", &nvl);
|
||||||
|
*source = nvl;
|
||||||
|
break;
|
||||||
|
case ZFS_IOC_CLONE:
|
||||||
|
buf = fnvlist_lookup_string(*source, "origin");
|
||||||
|
strlcpy(zc->zc_value, buf, MAXPATHLEN);
|
||||||
|
nvlist_lookup_nvlist(*source, "props", &nvl);
|
||||||
|
*ioc = ZFS_IOC_CREATE;
|
||||||
|
*source = nvl;
|
||||||
|
break;
|
||||||
|
case ZFS_IOC_SNAPSHOT:
|
||||||
|
nvl = fnvlist_lookup_nvlist(*source, "snaps");
|
||||||
|
pair = nvlist_next_nvpair(nvl, NULL);
|
||||||
|
if (pair != NULL) {
|
||||||
|
buf = nvpair_name(pair);
|
||||||
|
pos = strcspn(buf, "@");
|
||||||
|
strlcpy(zc->zc_name, buf, pos + 1);
|
||||||
|
strlcpy(zc->zc_value, buf + pos + 1, MAXPATHLEN);
|
||||||
|
} else
|
||||||
|
error = EOPNOTSUPP;
|
||||||
|
/* old kernel cannot create multiple snapshots */
|
||||||
|
if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
|
||||||
|
error = EOPNOTSUPP;
|
||||||
|
nvlist_free(nvl);
|
||||||
|
nvl = NULL;
|
||||||
|
nvlist_lookup_nvlist(*source, "props", &nvl);
|
||||||
|
*source = nvl;
|
||||||
|
break;
|
||||||
|
case ZFS_IOC_SPACE_SNAPS:
|
||||||
|
buf = fnvlist_lookup_string(*source, "firstsnap");
|
||||||
|
strlcpy(zc->zc_value, buf, MAXPATHLEN);
|
||||||
|
break;
|
||||||
|
case ZFS_IOC_DESTROY_SNAPS:
|
||||||
|
nvl = fnvlist_lookup_nvlist(*source, "snaps");
|
||||||
|
pair = nvlist_next_nvpair(nvl, NULL);
|
||||||
|
if (pair != NULL) {
|
||||||
|
buf = nvpair_name(pair);
|
||||||
|
pos = strcspn(buf, "@");
|
||||||
|
strlcpy(zc->zc_name, buf, pos + 1);
|
||||||
|
}
|
||||||
|
*source = nvl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lzc_compat_post(zfs_cmd_t *zc, const zfs_ioc_t ioc)
|
||||||
|
{
|
||||||
|
if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (ioc) {
|
||||||
|
case ZFS_IOC_CREATE:
|
||||||
|
case ZFS_IOC_CLONE:
|
||||||
|
case ZFS_IOC_SNAPSHOT:
|
||||||
|
case ZFS_IOC_SPACE_SNAPS:
|
||||||
|
case ZFS_IOC_DESTROY_SNAPS:
|
||||||
|
zc->zc_nvlist_dst_filled = B_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lzc_compat_outnvl(zfs_cmd_t *zc, const zfs_ioc_t ioc, nvlist_t **outnvl)
|
||||||
|
{
|
||||||
|
nvlist_t *nvl;
|
||||||
|
|
||||||
|
if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
switch (ioc) {
|
||||||
|
case ZFS_IOC_SPACE_SNAPS:
|
||||||
|
nvl = fnvlist_alloc();
|
||||||
|
fnvlist_add_uint64(nvl, "used", zc->zc_cookie);
|
||||||
|
fnvlist_add_uint64(nvl, "compressed", zc->zc_objset_type);
|
||||||
|
fnvlist_add_uint64(nvl, "uncompressed", zc->zc_perm_action);
|
||||||
|
*outnvl = nvl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* CDDL HEADER START
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the terms of the
|
||||||
|
* Common Development and Distribution License (the "License").
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
*
|
||||||
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
|
* See the License for the specific language governing permissions
|
||||||
|
* and limitations under the License.
|
||||||
|
*
|
||||||
|
* When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
* If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
*
|
||||||
|
* CDDL HEADER END
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013 by Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LIBZFS_CORE_COMPAT_H
|
||||||
|
#define _LIBZFS_CORE_COMPAT_H
|
||||||
|
|
||||||
|
#include <libnvpair.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/fs/zfs.h>
|
||||||
|
#include <sys/zfs_ioctl.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int lzc_compat_pre(zfs_cmd_t *, zfs_ioc_t *, nvlist_t **);
|
||||||
|
void lzc_compat_post(zfs_cmd_t *, const zfs_ioc_t);
|
||||||
|
int lzc_compat_outnvl(zfs_cmd_t *, const zfs_ioc_t, nvlist_t **);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _LIBZFS_CORE_COMPAT_H */
|
@ -9,7 +9,7 @@ LIB= zfs_core
|
|||||||
DPADD= ${LIBNVPAIR}
|
DPADD= ${LIBNVPAIR}
|
||||||
LDADD= -lnvpair
|
LDADD= -lnvpair
|
||||||
|
|
||||||
SRCS= libzfs_core.c
|
SRCS= libzfs_core.c libzfs_core_compat.c
|
||||||
|
|
||||||
WARNS?= 0
|
WARNS?= 0
|
||||||
CSTD= c99
|
CSTD= c99
|
||||||
|
Loading…
Reference in New Issue
Block a user