|
|
@@ -20,7 +20,7 @@ |
|
|
*/ |
|
|
|
|
|
/* |
|
|
* Copyright (c) 2012, 2017 by Delphix. All rights reserved. |
|
|
* Copyright (c) 2012, 2018 by Delphix. All rights reserved. |
|
|
* Copyright (c) 2013 Steven Hartland. All rights reserved. |
|
|
* Copyright (c) 2017 Datto Inc. |
|
|
* Copyright 2017 RackTop Systems. |
|
|
@@ -78,6 +78,9 @@ |
|
|
#include <unistd.h> |
|
|
#include <stdlib.h> |
|
|
#include <string.h> |
|
|
#ifdef ZFS_DEBUG |
|
|
#include <stdio.h> |
|
|
#endif |
|
|
#include <errno.h> |
|
|
#include <fcntl.h> |
|
|
#include <pthread.h> |
|
|
@@ -91,6 +94,42 @@ static int g_fd = -1; |
|
|
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; |
|
|
static int g_refcount; |
|
|
|
|
|
#ifdef ZFS_DEBUG |
|
|
static zfs_ioc_t fail_ioc_cmd; |
|
|
static zfs_errno_t fail_ioc_err; |
|
|
|
|
|
static void |
|
|
libzfs_core_debug_ioc(void) |
|
|
{ |
|
|
/* |
|
|
* To test running newer user space binaries with kernel's |
|
|
* that don't yet support an ioctl or a new ioctl arg we |
|
|
* provide an override to intentionally fail an ioctl. |
|
|
* |
|
|
* USAGE: |
|
|
* The override variable, ZFS_IOC_TEST, is of the form "cmd:err" |
|
|
* |
|
|
* For example, to fail a ZFS_IOC_POOL_CHECKPOINT with a |
|
|
* ZFS_ERR_IOC_CMD_UNAVAIL, the string would be "0x5a4d:1029" |
|
|
* |
|
|
* $ sudo sh -c "ZFS_IOC_TEST=0x5a4d:1029 zpool checkpoint tank" |
|
|
* cannot checkpoint 'tank': the loaded zfs module does not support |
|
|
* this operation. A reboot may be required to enable this operation. |
|
|
*/ |
|
|
if (fail_ioc_cmd == 0) { |
|
|
char *ioc_test = getenv("ZFS_IOC_TEST"); |
|
|
unsigned int ioc_num = 0, ioc_err = 0; |
|
|
|
|
|
if (ioc_test != NULL && |
|
|
sscanf(ioc_test, "%i:%i", &ioc_num, &ioc_err) == 2 && |
|
|
ioc_num < ZFS_IOC_LAST) { |
|
|
fail_ioc_cmd = ioc_num; |
|
|
fail_ioc_err = ioc_err; |
|
|
} |
|
|
} |
|
|
} |
|
|
#endif |
|
|
|
|
|
int |
|
|
libzfs_core_init(void) |
|
|
{ |
|
|
@@ -103,6 +142,10 @@ libzfs_core_init(void) |
|
|
} |
|
|
} |
|
|
g_refcount++; |
|
|
|
|
|
#ifdef ZFS_DEBUG |
|
|
libzfs_core_debug_ioc(); |
|
|
#endif |
|
|
(void) pthread_mutex_unlock(&g_lock); |
|
|
return (0); |
|
|
} |
|
|
@@ -135,6 +178,11 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name, |
|
|
ASSERT3S(g_refcount, >, 0); |
|
|
VERIFY3S(g_fd, !=, -1); |
|
|
|
|
|
#ifdef ZFS_DEBUG |
|
|
if (ioc == fail_ioc_cmd) |
|
|
return (fail_ioc_err); |
|
|
#endif |
|
|
|
|
|
if (name != NULL) |
|
|
(void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name)); |
|
|
|
|
|
|