Compare commits

...

13 Commits

Author SHA1 Message Date
Jamie Gritton
0e391d97fb MFC zfs/jail: Document the zfs.mount_snapshot parameter in jail(8).
PR:		274263
Differential Revision:	https://reviews.freebsd.org/D45647

(cherry picked from commit 63875db56b)
2024-06-28 12:51:58 -07:00
Jamie Gritton
172fbf12fc MFC zfs/jail: Mark the zfs.mount_snapshot jail parameter as boolean.
PR:		274263
Differential Revision:	https://reviews.freebsd.org/D45647

(cherry picked from commit 9cbf1de7e3)
2024-06-28 12:50:44 -07:00
Alan Somers
5d5082fd98 ctld: plug memory leaks
Reviewed by:	mav
Sponsored by:	Axcient
Reported by:	valgrind
Pull Request:	https://github.com/freebsd/freebsd-src/pull/1288

(cherry picked from commit 2909ddd17c)
2024-06-28 13:35:38 -06:00
Alan Somers
7a8bab3d94 ctladm: don't require the use of "-p" with "port -r"
When removing a port, the ioctl frontend requires the "-p" argument.
But other frontends, like cfiscsi, do not.  So don't require that
argument in the ctladm command.  The frontend driver will report an
error if any required argument is missing.

Sponsored by:	Axcient
Reviewed by:    mav
Pull Request:   https://github.com/freebsd/freebsd-src/pull/1279

(cherry picked from commit edbd489d09)
2024-06-28 13:34:10 -06:00
Alan Somers
259f94f8ab ctladm: better documentation for adding and removing cfiscsi ports
Sponsored by:	Axcient
Reviewed by:    mav
Pull Request:   https://github.com/freebsd/freebsd-src/pull/1279

(cherry picked from commit afecc74cd7)
2024-06-28 13:26:44 -06:00
Alan Somers
1dc90424b2 ctladm: print port number with a succesful "port -c" command
Make "ctladm port -c" print the port number of the newly successful
port.  This way it won't have to be guessed by a subsequent "ctladm
portlist" command.  That means it's safe to use it concurrently with
other ctladm processes.  In particular, this allows the tests to be run
in parallel.

Sponsored by:	Axcient
Reviewed by:    mav
Pull Request:   https://github.com/freebsd/freebsd-src/pull/1279

(cherry picked from commit 591de7534f)
2024-06-28 13:25:54 -06:00
Alan Somers
ab9e5b8659 Add some ATF tests for ctladm
So far only "ctladm port -c" and "ctladm port -r" are covered.

Sponsored by:	Axcient
Reviewed by:	mav
Pull Request:	https://github.com/freebsd/freebsd-src/pull/1279

(cherry picked from commit 9747d11d91)

Fix mtree entry for ctladm tests

Sponsored by:	Axcient

(cherry picked from commit 81ef0a89fc)

ctladm: add a copyright header to the port test

[skip ci]

Reported by:	markj
Sponsored by:	Axcient

(cherry picked from commit a1608e8854)
2024-06-28 13:04:11 -06:00
Alan Somers
4451b1de21 ctladm.8: fix several errors in the "port" section
* Document the "-d" option.
* Add the "-c" and "-r" options to the summary.
* Correct the list of required options.
* Clarify that the "-t" option is only for use with "-o", "-w", and "-W"
* Replace references to the nonexistent "-n" with "-p".

Also, fix a few related error strings in the ctladm command.

Sponsored by:	Axcient
Reviewed by:	jhb
Differential Revision: https://reviews.freebsd.org/D45503

(cherry picked from commit 60107d23d8)
2024-06-28 13:00:41 -06:00
Alan Somers
1cc56f881f mdconfig: fix cleanup in the attach_size_rounddown test
Sponsored by:	Axcient

(cherry picked from commit d1bd097d52)
2024-06-28 12:56:38 -06:00
Alan Somers
43d29dceea vfs_getopt(9): fix typo
[skip ci]

Reported by:	Claudiu <mscotty@protomail.ch>

(cherry picked from commit 3cc1b35bc1)
2024-06-28 12:56:11 -06:00
Alan Somers
af64741bba fusefs: make the tests more robust to changes to maxphys
Remove assumptions in two test cases that maxphys won't be huge.

Reported by:	kib
Sponsored by:	Axcient

(cherry picked from commit b2792a300d)
2024-06-28 12:54:00 -06:00
Gleb Smirnoff
4052c95280 tests/fusefs: fix all tests that depend on kern.maxphys
The tests try to read kern.maxphys sysctl into int value, while
unsigned long is required.  Not sure when this was broken, seems like
since cd85379104.

Reviewed by:		asomers
Differential Revision:	https://reviews.freebsd.org/D45053

(cherry picked from commit e9b411d273)
2024-06-28 12:52:07 -06:00
Alan Somers
51bee6ab65 geli.8: minor proofreading
Sponsored by:	Axcient
Reviewed by:	imp, pauamma (manpages)
Differential Revision: https://reviews.freebsd.org/D44907

(cherry picked from commit c0f02dcd4c)
2024-06-28 12:49:18 -06:00
20 changed files with 537 additions and 61 deletions

View File

@ -1141,6 +1141,8 @@
usr.sbin
chown
..
ctladm
..
daemon
..
etcupdate

View File

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd April 18, 2022
.Dd April 20, 2024
.Dt GELI 8
.Os
.Sh NAME
@ -867,7 +867,7 @@ If set to 0, a CPU-pinned thread will be started for every active CPU.
When set to 1, can speed-up crypto operations by using batching.
Batching reduces the number of interrupts by responding to a group of
crypto requests with one interrupt.
The crypto card and the driver has to support this feature.
The crypto card and the driver have to support this feature.
.It Va kern.geom.eli.key_cache_limit : No 8192
Specifies how many Data Keys to cache.
The default limit
@ -884,7 +884,7 @@ Reports how many times we were looking up a Data Key and it was not in cache.
This sysctl is not updated for providers that need fewer Data Keys than the limit
specified in
.Va kern.geom.eli.key_cache_limit .
.Va kern.geom.eli.unmapped_io
.It Va kern.geom.eli.unmapped_io
Enable support for unmapped I/O buffers, currently implemented only on 64-bit
platforms.
This is an optimization which reduces the overhead of I/O processing.

View File

@ -291,7 +291,7 @@ attach_size_rounddown_body()
-x "mdconfig -r -u ${md#md} -s ${ms2}b"
check_diskinfo "$md" 16384 2 $ss
}
attach_size_rounddown()
attach_size_rounddown_cleanup()
{
cleanup_common
}

View File

@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
.\" DAMAGE.
.\"
.Dd July 31, 2011
.Dd May 19, 2024
.Dt VFS_GETOPT 9
.Os
.Sh NAME
@ -46,7 +46,7 @@
.Fa "struct vfsoptlist *opts" "const char *name" "void **buf" "int *len"
.Fc
.Ft "char *"
.Fn vfs_getops "struct vfsoptlist *opts" "const char *name" "int *error"
.Fn vfs_getopts "struct vfsoptlist *opts" "const char *name" "int *error"
.Ft int
.Fo vfs_flagopt
.Fa "struct vfsoptlist *opts" "const char *name" "uint64_t *flags" "uint64_t flag"
@ -177,7 +177,7 @@ function returns 0 if the option was found; otherwise,
is returned.
.Pp
The
.Fn vfs_getops
.Fn vfs_getopts
function returns the specified option if it is found, and is
.Dv NUL
terminated.

View File

@ -268,7 +268,7 @@ cfi_ioctl_port_remove(struct ctl_req *req)
if (port_id == -1) {
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
"port_id not provided");
"Missing required argument: port_id");
return;
}

View File

@ -2150,17 +2150,24 @@ cfiscsi_ioctl_port_create(struct ctl_req *req)
uint16_t tag;
target = dnvlist_get_string(req->args_nvl, "cfiscsi_target", NULL);
alias = dnvlist_get_string(req->args_nvl, "cfiscsi_target_alias", NULL);
val = dnvlist_get_string(req->args_nvl, "cfiscsi_portal_group_tag",
NULL);
if (target == NULL || val == NULL) {
if (target == NULL) {
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
"Missing required argument");
"Missing required argument: cfiscsi_target");
return;
}
val = dnvlist_get_string(req->args_nvl, "cfiscsi_portal_group_tag",
NULL);
if (val == NULL) {
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
"Missing required argument: cfiscsi_portal_group_tag");
return;
}
alias = dnvlist_get_string(req->args_nvl, "cfiscsi_target_alias", NULL);
tag = strtoul(val, NULL, 0);
ct = cfiscsi_target_find_or_create(&cfiscsi_softc, target, alias, tag);
if (ct == NULL) {
@ -2251,13 +2258,19 @@ cfiscsi_ioctl_port_remove(struct ctl_req *req)
uint16_t tag;
target = dnvlist_get_string(req->args_nvl, "cfiscsi_target", NULL);
val = dnvlist_get_string(req->args_nvl, "cfiscsi_portal_group_tag",
NULL);
if (target == NULL || val == NULL) {
if (target == NULL) {
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
"Missing required argument");
"Missing required argument: cfiscsi_target");
return;
}
val = dnvlist_get_string(req->args_nvl, "cfiscsi_portal_group_tag",
NULL);
if (val == NULL) {
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
"Missing required argument: cfiscsi_portal_group_tag");
return;
}

View File

@ -102,7 +102,7 @@ static struct zfs_jailparam zfs_jailparam0 = {
static int zfs_jailparam_slot;
SYSCTL_JAIL_PARAM_SYS_NODE(zfs, CTLFLAG_RW, "Jail ZFS parameters");
SYSCTL_JAIL_PARAM(_zfs, mount_snapshot, CTLTYPE_INT | CTLFLAG_RW, "I",
SYSCTL_JAIL_PARAM(_zfs, mount_snapshot, CTLTYPE_INT | CTLFLAG_RW, "B",
"Allow mounting snapshots in the .zfs directory for unjailed datasets");
SYSCTL_NODE(_vfs_zfs, OID_AUTO, version, CTLFLAG_RD, 0, "ZFS versions");

View File

@ -77,8 +77,6 @@ class BmapEof: public Bmap, public WithParamInterface<int> {};
/*
* Test FUSE_BMAP
* XXX The FUSE protocol does not include the runp and runb variables, so those
* must be guessed in-kernel.
*/
TEST_F(Bmap, bmap)
{
@ -105,8 +103,19 @@ TEST_F(Bmap, bmap)
arg.runb = -1;
ASSERT_EQ(0, ioctl(fd, FIOBMAP2, &arg)) << strerror(errno);
EXPECT_EQ(arg.bn, pbn);
EXPECT_EQ(arg.runp, m_maxphys / m_maxbcachebuf - 1);
EXPECT_EQ(arg.runb, m_maxphys / m_maxbcachebuf - 1);
/*
* XXX The FUSE protocol does not include the runp and runb variables,
* so those must be guessed in-kernel. There's no "right" answer, so
* just check that they're within reasonable limits.
*/
EXPECT_LE(arg.runb, lbn);
EXPECT_LE((unsigned long)arg.runb, m_maxreadahead / m_maxbcachebuf);
EXPECT_LE((unsigned long)arg.runb, m_maxphys / m_maxbcachebuf);
EXPECT_GT(arg.runb, 0);
EXPECT_LE(arg.runp, filesize / m_maxbcachebuf - lbn);
EXPECT_LE((unsigned long)arg.runp, m_maxreadahead / m_maxbcachebuf);
EXPECT_LE((unsigned long)arg.runp, m_maxphys / m_maxbcachebuf);
EXPECT_GT(arg.runp, 0);
leak(fd);
}
@ -142,7 +151,7 @@ TEST_F(Bmap, default_)
arg.runb = -1;
ASSERT_EQ(0, ioctl(fd, FIOBMAP2, &arg)) << strerror(errno);
EXPECT_EQ(arg.bn, 0);
EXPECT_EQ(arg.runp, m_maxphys / m_maxbcachebuf - 1);
EXPECT_EQ((unsigned long )arg.runp, m_maxphys / m_maxbcachebuf - 1);
EXPECT_EQ(arg.runb, 0);
/* In the middle */
@ -152,8 +161,8 @@ TEST_F(Bmap, default_)
arg.runb = -1;
ASSERT_EQ(0, ioctl(fd, FIOBMAP2, &arg)) << strerror(errno);
EXPECT_EQ(arg.bn, lbn * m_maxbcachebuf / DEV_BSIZE);
EXPECT_EQ(arg.runp, m_maxphys / m_maxbcachebuf - 1);
EXPECT_EQ(arg.runb, m_maxphys / m_maxbcachebuf - 1);
EXPECT_EQ((unsigned long )arg.runp, m_maxphys / m_maxbcachebuf - 1);
EXPECT_EQ((unsigned long )arg.runb, m_maxphys / m_maxbcachebuf - 1);
/* Last block */
lbn = filesize / m_maxbcachebuf - 1;
@ -163,7 +172,7 @@ TEST_F(Bmap, default_)
ASSERT_EQ(0, ioctl(fd, FIOBMAP2, &arg)) << strerror(errno);
EXPECT_EQ(arg.bn, lbn * m_maxbcachebuf / DEV_BSIZE);
EXPECT_EQ(arg.runp, 0);
EXPECT_EQ(arg.runb, m_maxphys / m_maxbcachebuf - 1);
EXPECT_EQ((unsigned long )arg.runb, m_maxphys / m_maxbcachebuf - 1);
leak(fd);
}

View File

@ -1339,7 +1339,7 @@ TEST_P(ReadAhead, readahead) {
expect_open(ino, 0, 1);
maxcontig = m_noclusterr ? m_maxbcachebuf :
m_maxbcachebuf + m_maxreadahead;
clustersize = MIN(maxcontig, m_maxphys);
clustersize = MIN((unsigned long )maxcontig, m_maxphys);
for (offs = 0; offs < bufsize; offs += clustersize) {
len = std::min((size_t)clustersize, (size_t)(filesize - offs));
expect_read(ino, offs, len, len, contents + offs);

View File

@ -130,8 +130,7 @@ class FuseEnv: public Environment {
void FuseTest::SetUp() {
const char *maxbcachebuf_node = "vfs.maxbcachebuf";
const char *maxphys_node = "kern.maxphys";
int val = 0;
size_t size = sizeof(val);
size_t size;
/*
* XXX check_environment should be called from FuseEnv::SetUp, but
@ -141,12 +140,12 @@ void FuseTest::SetUp() {
if (IsSkipped())
return;
ASSERT_EQ(0, sysctlbyname(maxbcachebuf_node, &val, &size, NULL, 0))
size = sizeof(m_maxbcachebuf);
ASSERT_EQ(0, sysctlbyname(maxbcachebuf_node, &m_maxbcachebuf, &size,
NULL, 0)) << strerror(errno);
size = sizeof(m_maxphys);
ASSERT_EQ(0, sysctlbyname(maxphys_node, &m_maxphys, &size, NULL, 0))
<< strerror(errno);
m_maxbcachebuf = val;
ASSERT_EQ(0, sysctlbyname(maxphys_node, &val, &size, NULL, 0))
<< strerror(errno);
m_maxphys = val;
/*
* Set the default max_write to a distinct value from MAXPHYS to catch
* bugs that confuse the two.

View File

@ -77,7 +77,7 @@ class FuseTest : public ::testing::Test {
public:
int m_maxbcachebuf;
int m_maxphys;
unsigned long m_maxphys;
FuseTest():
m_maxreadahead(0),

View File

@ -179,12 +179,12 @@ class WriteCluster: public WriteBack {
public:
virtual void SetUp() {
m_async = true;
m_maxwrite = 1 << 25; // Anything larger than MAXPHYS will suffice
m_maxwrite = UINT32_MAX; // Anything larger than MAXPHYS will suffice
WriteBack::SetUp();
if (m_maxphys < 2 * DFLTPHYS)
GTEST_SKIP() << "MAXPHYS must be at least twice DFLTPHYS"
<< " for this test";
if (m_maxphys < 2 * m_maxbcachebuf)
if (m_maxphys < 2 * (unsigned long )m_maxbcachebuf)
GTEST_SKIP() << "MAXPHYS must be at least twice maxbcachebuf"
<< " for this test";
}
@ -860,7 +860,8 @@ TEST_F(WriteMaxWrite, write)
ssize_t halfbufsize, bufsize;
halfbufsize = m_mock->m_maxwrite;
if (halfbufsize >= m_maxbcachebuf || halfbufsize >= m_maxphys)
if (halfbufsize >= m_maxbcachebuf ||
(unsigned long )halfbufsize >= m_maxphys)
GTEST_SKIP() << "Must lower m_maxwrite for this test";
bufsize = halfbufsize * 2;
contents = new int[bufsize / sizeof(int)];

View File

@ -23,4 +23,7 @@ MAN= ctladm.8
CFLAGS+= -DWANT_ISCSI
.endif
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View File

@ -35,7 +35,7 @@
.\"
.\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
.\"
.Dd December 27, 2023
.Dd June 6, 2024
.Dt CTLADM 8
.Os
.Sh NAME
@ -162,10 +162,11 @@
.Nm
.Ic port
.Op Fl c
.Op Fl d Ar driver
.Op Fl o Ar on|off
.Op Fl w Ar wwpn
.Op Fl W Ar wwnn
.Op Fl O Ar pp|vp
.Op Fl O Ar name=value
.Op Fl p Ar targ_port
.Op Fl r
.Op Fl t Ar fe_type
@ -591,6 +592,10 @@ The serial number is returned when the error is injected.
Perform one of several CTL frontend port operations.
Either get a list of frontend ports
.Pq Fl l ,
create a new frontend port
.Pq Fl c ,
destroy a frontend port
.Pq Fl r ,
turn one or more frontends on
or off
.Pq Fl o Ar on|off ,
@ -600,6 +605,8 @@ or World Wide Port Name
.Pq Fl W Ar wwpn
for a given port.
One of
.Fl c ,
.Fl r ,
.Fl l ,
.Fl o ,
or
@ -611,22 +618,62 @@ The WWNN and WWPN may both be specified at the same time, but cannot be
combined with enabling/disabling or listing ports.
.Bl -tag -width 12n
.It Fl c
Create new frontend port using free pp and vp=0.
Create new frontend port.
.It Fl d Ar driver
Specify the name of the frontend driver used by the
.Pq Fl c
or
.Pq Fl r
subcommands.
Valid driver names include
.Dq ioctl ,
.Dq iscsi ,
and
.Dq nvmf ,
but more can be added by external kernel modules.
.It Fl o Ar on|off
Turn the specified CTL frontend ports on or off.
If no port number or port type is specified, all ports are turned on or
off.
.It Fl O Ar pp|vp
Specify generic options on the ioctl frontend port.
At present, only pp and vp port numbers can be set.
The list of recognized options is driver-dependent.
The
.Dq ioctl
driver recognizes
.Dq pp
and
.Dq vp .
The
.Dq iscsi
driver recongizes
.Dq cfiscsi_portal_group_tag ,
.Dq cfiscsi_target ,
and
.Dq cfiscsi_target_alias .
The
.Dq nvmf
driver recognizes
.Dq subnqn ,
.Dq portid ,
.Dq max_io_qsize ,
.Dq enable_timeout ,
.Dq ioccsz ,
.Dq nn ,
and
.Dq serial .
.It Fl p Ar targ_port
Specify the frontend port number.
The port numbers can be found in the frontend port list.
.It Fl r
Remove port specified with
.Pq Fl p Ar targ_port .
Remove a port.
.It Fl t Ar fe_type
Specify the frontend type.
Specify the frontend type used by the
.Pq Fl o ,
.Pq Fl w ,
and
.Pq Fl W
subcommands.
Currently defined port types are
.Dq fc
(Fibre Channel),
@ -640,7 +687,7 @@ and
.It Fl w Ar wwnn
Set the World Wide Node Name for the given port.
The
.Fl n
.Fl p
argument must be specified, since this is only possible to implement on a
single port.
As a general rule, the WWNN should be the same across all ports on the
@ -648,7 +695,7 @@ system.
.It Fl W Ar wwpn
Set the World Wide Port Name for the given port.
The
.Fl n
.Fl p
argument must be specified, since this is only possible to implement on a
single port.
As a general rule, the WWPN must be different for every port in the system.

View File

@ -392,7 +392,9 @@ static struct ctladm_opts cctl_fe_table[] = {
static int
cctl_port(int fd, int argc, char **argv, char *combinedopt)
{
char result_buf[1024];
int c;
uint64_t created_port = -1;
int32_t targ_port = -1;
int retval = 0;
int wwnn_set = 0, wwpn_set = 0;
@ -541,7 +543,7 @@ cctl_port(int fd, int argc, char **argv, char *combinedopt)
* we'll throw an error, since that only works on one port at a time.
*/
if ((port_type != CTL_PORT_NONE) && (targ_port != -1)) {
warnx("%s: can only specify one of -t or -n", __func__);
warnx("%s: can only specify one of -t or -p", __func__);
retval = 1;
goto bailout;
} else if ((targ_port == -1) && (port_type == CTL_PORT_NONE))
@ -573,20 +575,18 @@ cctl_port(int fd, int argc, char **argv, char *combinedopt)
break;
}
case CCTL_PORT_MODE_REMOVE:
if (targ_port == -1) {
warnx("%s: -r requires -p", __func__);
retval = 1;
goto bailout;
}
/* FALLTHROUGH */
case CCTL_PORT_MODE_CREATE: {
bzero(&req, sizeof(req));
strlcpy(req.driver, driver, sizeof(req.driver));
req.result = result_buf;
req.result_len = sizeof(result_buf);
if (port_mode == CCTL_PORT_MODE_REMOVE) {
req.reqtype = CTL_REQ_REMOVE;
nvlist_add_stringf(option_list, "port_id", "%d",
targ_port);
if (targ_port != -1)
nvlist_add_stringf(option_list, "port_id", "%d",
targ_port);
} else
req.reqtype = CTL_REQ_CREATE;
@ -614,6 +614,20 @@ cctl_port(int fd, int argc, char **argv, char *combinedopt)
warnx("warning: %s", req.error_str);
break;
case CTL_LUN_OK:
if (port_mode == CCTL_PORT_MODE_CREATE) {
req.result_nvl = nvlist_unpack(result_buf, req.result_len, 0);
if (req.result_nvl == NULL) {
warnx("error unpacking result nvlist");
break;
}
created_port = nvlist_get_number(req.result_nvl, "port_id");
printf("Port created successfully\n"
"frontend: %s\n"
"port: %ju\n", driver,
(uintmax_t) created_port);
nvlist_destroy(req.result_nvl);
} else
printf("Port destroyed successfully\n");
break;
default:
warnx("unknown status: %d", req.status);
@ -625,7 +639,7 @@ cctl_port(int fd, int argc, char **argv, char *combinedopt)
}
case CCTL_PORT_MODE_SET:
if (targ_port == -1) {
warnx("%s: -w and -W require -n", __func__);
warnx("%s: -w and -W require -p", __func__);
retval = 1;
goto bailout;
}
@ -674,7 +688,8 @@ cctl_port(int fd, int argc, char **argv, char *combinedopt)
return (retval);
bailout_badarg:
warnx("%s: only one of -l, -o or -w/-W may be specified", __func__);
warnx("%s: only one of -c, -r, -l, -o or -w/-W may be specified",
__func__);
return (1);
}

View File

@ -0,0 +1,6 @@
PACKAGE= tests
ATF_TESTS_SH= port
.include <bsd.test.mk>

View File

@ -0,0 +1,336 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2024 Axcient
# 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 DOCUMENTATION 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.
# Things that aren't tested due to lack of kernel support:
# * Creating camsim ports
# * Creating tpc ports
# * Creating camtgt ports
# * Creating umass ports
# TODO
# * Creating nvmf ports
# * Creating ha ports
# * Creating fc ports
# The PGTAG can be any 16-bit number. The only constraint is that each
# PGTAG,TARGET pair must be globally unique.
PGTAG=30257
load_cfiscsi() {
if ! kldstat -q -m cfiscsi; then
kldload cfiscsi || atf_skip "could not load cfscsi kernel mod"
fi
}
skip_if_ctld() {
if service ctld onestatus > /dev/null; then
# If ctld is running on this server, let's not interfere.
atf_skip "Cannot run this test while ctld is running"
fi
}
cleanup() {
driver=$1
if [ -e port-create.txt ]; then
case "$driver" in
"ioctl")
PORTNUM=`awk '/port:/ {print $2}' port-create.txt`
ctladm port -r -d $driver -p $PORTNUM
;;
"iscsi")
TARGET=`awk '/target:/ {print $2}' port-create.txt`
ctladm port -r -d $driver -p "$PORTNUM" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target=$TARGET
;;
esac
fi
}
atf_test_case create_ioctl cleanup
create_ioctl_head()
{
atf_set "descr" "ctladm can create a new ioctl port"
atf_set "require.user" "root"
}
create_ioctl_body()
{
skip_if_ctld
atf_check -o save:port-create.txt ctladm port -c -d "ioctl"
atf_check egrep -q "Port created successfully" port-create.txt
atf_check egrep -q "frontend: *ioctl" port-create.txt
atf_check egrep -q "port: *[0-9]+" port-create.txt
portnum=`awk '/port:/ {print $2}' port-create.txt`
atf_check -o save:portlist.txt ctladm portlist -qf ioctl
atf_check egrep -q "$portnum *YES *ioctl *ioctl" portlist.txt
}
create_ioctl_cleanup()
{
cleanup ioctl
}
atf_test_case remove_ioctl_without_required_args cleanup
remove_ioctl_without_required_args_head()
{
atf_set "descr" "ctladm will gracefully fail to remove an ioctl target if required arguments are missing"
atf_set "require.user" "root"
}
remove_ioctl_without_required_args_body()
{
skip_if_ctld
atf_check -o save:port-create.txt ctladm port -c -d "ioctl"
atf_check egrep -q "Port created successfully" port-create.txt
atf_check -s exit:1 -e match:"Missing required argument: port_id" ctladm port -r -d "ioctl"
}
remove_ioctl_without_required_args_cleanup()
{
cleanup ioctl
}
atf_test_case create_iscsi cleanup
create_iscsi_head()
{
atf_set "descr" "ctladm can create a new iscsi port"
atf_set "require.user" "root"
}
create_iscsi_body()
{
skip_if_ctld
load_cfiscsi
TARGET=iqn.2018-10.myhost.create_iscsi
atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET"
echo "target: $TARGET" >> port-create.txt
atf_check egrep -q "Port created successfully" port-create.txt
atf_check egrep -q "frontend: *iscsi" port-create.txt
atf_check egrep -q "port: *[0-9]+" port-create.txt
atf_check -o save:portlist.txt ctladm portlist -qf iscsi
# Unlike the ioctl driver, the iscsi driver creates ports in a disabled
# state, so the port's lunmap may be set before enabling it.
atf_check egrep -q "$portnum *NO *iscsi *iscsi.*$TARGET" portlist.txt
}
create_iscsi_cleanup()
{
cleanup iscsi
}
atf_test_case create_iscsi_alias cleanup
create_iscsi_alias_head()
{
atf_set "descr" "ctladm can create a new iscsi port with a target alias"
atf_set "require.user" "root"
}
create_iscsi_alias_body()
{
skip_if_ctld
load_cfiscsi
TARGET=iqn.2018-10.myhost.create_iscsi_alias
ALIAS="foobar"
atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET" -O cfiscsi_target_alias="$ALIAS"
echo "target: $TARGET" >> port-create.txt
atf_check egrep -q "Port created successfully" port-create.txt
atf_check egrep -q "frontend: *iscsi" port-create.txt
atf_check egrep -q "port: *[0-9]+" port-create.txt
atf_check -o save:portlist.txt ctladm portlist -qvf iscsi
atf_check egrep -q "cfiscsi_target_alias=$ALIAS" portlist.txt
}
create_iscsi_alias_cleanup()
{
cleanup iscsi
}
atf_test_case create_iscsi_without_required_args
create_iscsi_without_required_args_head()
{
atf_set "descr" "ctladm will gracefully fail to create an iSCSI target if required arguments are missing"
atf_set "require.user" "root"
}
create_iscsi_without_required_args_body()
{
skip_if_ctld
load_cfiscsi
TARGET=iqn.2018-10.myhost.create_iscsi
atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_target" ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG
atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_portal_group_tag" ctladm port -c -d "iscsi" -O cfiscsi_target=$TARGET
}
atf_test_case create_ioctl_options cleanup
create_ioctl_options_head()
{
atf_set "descr" "ctladm can set options when creating a new ioctl port"
atf_set "require.user" "root"
}
create_ioctl_options_body()
{
skip_if_ctld
atf_check -o save:port-create.txt ctladm port -c -d "ioctl" -O pp=101 -O vp=102
atf_check egrep -q "Port created successfully" port-create.txt
atf_check egrep -q "frontend: *ioctl" port-create.txt
atf_check egrep -q "port: *[0-9]+" port-create.txt
portnum=`awk '/port:/ {print $2}' port-create.txt`
atf_check -o save:portlist.txt ctladm portlist -qf ioctl
if ! egrep -q '101[[:space:]]+102' portlist.txt; then
ctladm portlist
atf_fail "Did not create the port with the specified options"
fi
}
create_ioctl_options_cleanup()
{
cleanup ioctl
}
atf_test_case disable_ioctl cleanup
disable_ioctl_head()
{
atf_set "descr" "ctladm can disable an ioctl port"
atf_set "require.user" "root"
}
disable_ioctl_body()
{
skip_if_ctld
atf_check -o save:port-create.txt ctladm port -c -d "ioctl"
portnum=`awk '/port:/ {print $2}' port-create.txt`
atf_check -o save:portlist.txt ctladm portlist -qf ioctl
atf_check -o ignore ctladm port -o off -p $portnum
atf_check -o match:"^$portnum *NO" ctladm portlist -qf ioctl
}
disable_ioctl_cleanup()
{
cleanup ioctl
}
atf_test_case enable_ioctl cleanup
enable_ioctl_head()
{
atf_set "descr" "ctladm can enable an ioctl port"
atf_set "require.user" "root"
}
enable_ioctl_body()
{
skip_if_ctld
atf_check -o save:port-create.txt ctladm port -c -d "ioctl"
portnum=`awk '/port:/ {print $2}' port-create.txt`
atf_check -o save:portlist.txt ctladm portlist -qf ioctl
atf_check -o ignore ctladm port -o off -p $portnum
atf_check -o ignore ctladm port -o on -p $portnum
atf_check -o match:"^$portnum *YES" ctladm portlist -qf ioctl
}
enable_ioctl_cleanup()
{
cleanup ioctl
}
atf_test_case remove_ioctl
remove_ioctl_head()
{
atf_set "descr" "ctladm can remove an ioctl port"
atf_set "require.user" "root"
}
remove_ioctl_body()
{
skip_if_ctld
# Specify exact pp and vp to make the post-removal portlist check
# unambiguous
atf_check -o save:port-create.txt ctladm port -c -d "ioctl" -O pp=10001 -O vp=10002
portnum=`awk '/port:/ {print $2}' port-create.txt`
atf_check -o save:portlist.txt ctladm portlist -qf ioctl
atf_check -o inline:"Port destroyed successfully\n" ctladm port -r -d ioctl -p $portnum
# Check that the port was removed. A new port may have been added with
# the same ID, so match against the pp and vp numbers, too.
if ctladm portlist -qf ioctl | egrep -q "^${portnum} .*10001 *10002"; then
ctladm portlist -qf ioctl
atf_fail "port was not removed"
fi
}
atf_test_case remove_iscsi
remove_iscsi_head()
{
atf_set "descr" "ctladm can remove an iscsi port"
atf_set "require.user" "root"
}
remove_iscsi_body()
{
skip_if_ctld
load_cfiscsi
TARGET=iqn.2018-10.myhost.remove_iscsi
atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET"
portnum=`awk '/port:/ {print $2}' port-create.txt`
atf_check -o save:portlist.txt ctladm portlist -qf iscsi
atf_check -o inline:"Port destroyed successfully\n" ctladm port -r -d iscsi -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET"
# Check that the port was removed. A new port may have been added with
# the same ID, so match against the target and tag, too.
PGTAGHEX=0x7631 # PGTAG in hex
if ctladm portlist -qf iscsi | egrep -q "^${portnum} .*$PGTAG +[0-9]+ +$TARGET,t,$PGTAGHEX"; then
ctladm portlist -qf iscsi
atf_fail "port was not removed"
fi
}
atf_test_case remove_iscsi_without_required_args cleanup
remove_iscsi_without_required_args_head()
{
atf_set "descr" "ctladm will gracefully fail to remove an iSCSI target if required arguments are missing"
atf_set "require.user" "root"
}
remove_iscsi_without_required_args_body()
{
skip_if_ctld
load_cfiscsi
TARGET=iqn.2018-10.myhost.remove_iscsi_without_required_args
atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET"
echo "target: $TARGET" >> port-create.txt
atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_portal_group_tag" ctladm port -r -d iscsi -O cfiscsi_target="$TARGET"
atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_target" ctladm port -r -d iscsi -O cfiscsi_portal_group_tag=$PGTAG
}
remove_iscsi_without_required_args_cleanup()
{
cleanup iscsi
}
atf_init_test_cases()
{
atf_add_test_case create_ioctl
atf_add_test_case create_iscsi
atf_add_test_case create_iscsi_without_required_args
atf_add_test_case create_iscsi_alias
atf_add_test_case create_ioctl_options
atf_add_test_case disable_ioctl
atf_add_test_case enable_ioctl
atf_add_test_case remove_ioctl
atf_add_test_case remove_ioctl_without_required_args
atf_add_test_case remove_iscsi
atf_add_test_case remove_iscsi_without_required_args
}

View File

@ -2874,6 +2874,7 @@ main(int argc, char **argv)
error = conf_apply(oldconf, newconf);
if (error != 0)
log_warnx("failed to apply configuration");
conf_delete(newconf);
conf_delete(oldconf);
oldconf = NULL;

View File

@ -615,6 +615,22 @@ conf_new_from_kernel(void)
}
cp->p_ctl_port = port->port_id;
}
while ((port = STAILQ_FIRST(&devlist.port_list))) {
struct cctl_lun_nv *nv;
STAILQ_REMOVE_HEAD(&devlist.port_list, links);
free(port->port_frontend);
free(port->port_name);
free(port->cfiscsi_target);
free(port->ctld_portal_group_name);
while ((nv = STAILQ_FIRST(&port->attr_list))) {
STAILQ_REMOVE_HEAD(&port->attr_list, links);
free(nv->value);
free(nv->name);
free(nv);
}
free(port);
}
free(name);
STAILQ_FOREACH(lun, &devlist.lun_list, links) {
@ -665,6 +681,18 @@ conf_new_from_kernel(void)
cl->l_name);
}
}
while ((lun = STAILQ_FIRST(&devlist.lun_list))) {
struct cctl_lun_nv *nv;
STAILQ_REMOVE_HEAD(&devlist.lun_list, links);
while ((nv = STAILQ_FIRST(&lun->attr_list))) {
STAILQ_REMOVE_HEAD(&lun->attr_list, links);
free(nv->value);
free(nv->name);
free(nv);
}
free(lun);
}
return (conf);
}
@ -742,12 +770,14 @@ kernel_lun_add(struct lun *lun)
req.args = nvlist_pack(req.args_nvl, &req.args_len);
if (req.args == NULL) {
nvlist_destroy(req.args_nvl);
log_warn("error packing nvlist");
return (1);
}
}
error = ioctl(ctl_fd, CTL_LUN_REQ, &req);
free(req.args);
nvlist_destroy(req.args_nvl);
if (error != 0) {
@ -825,12 +855,14 @@ kernel_lun_modify(struct lun *lun)
req.args = nvlist_pack(req.args_nvl, &req.args_len);
if (req.args == NULL) {
nvlist_destroy(req.args_nvl);
log_warn("error packing nvlist");
return (1);
}
}
error = ioctl(ctl_fd, CTL_LUN_REQ, &req);
free(req.args);
nvlist_destroy(req.args_nvl);
if (error != 0) {
@ -1053,6 +1085,7 @@ kernel_port_add(struct port *port)
req.args = nvlist_pack(req.args_nvl, &req.args_len);
if (req.args == NULL) {
nvlist_destroy(req.args_nvl);
log_warn("error packing nvlist");
return (1);
}
@ -1060,6 +1093,7 @@ kernel_port_add(struct port *port)
req.result = result_buf;
req.result_len = sizeof(result_buf);
error = ioctl(ctl_fd, CTL_PORT_REQ, &req);
free(req.args);
nvlist_destroy(req.args_nvl);
if (error != 0) {
@ -1203,11 +1237,13 @@ kernel_port_remove(struct port *port)
req.args = nvlist_pack(req.args_nvl, &req.args_len);
if (req.args == NULL) {
nvlist_destroy(req.args_nvl);
log_warn("error packing nvlist");
return (1);
}
error = ioctl(ctl_fd, CTL_PORT_REQ, &req);
free(req.args);
nvlist_destroy(req.args_nvl);
if (error != 0) {

View File

@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd March 12, 2023
.Dd June 24, 2024
.Dt JAIL 8
.Os
.Sh NAME
@ -757,7 +757,15 @@ the jail cannot perform any sysvmsg-related system calls.
.It Va sysvsem, sysvshm
Allow access to SYSV IPC semaphore and shared memory primitives, in the
same manner as
.Va sysvmsg.
.Va sysvmsg .
.It Va zfs.mount_snapshot
Allow jailed users to access the contents of ZFS snapshots under the
filesystem's
.Pa .zfs
directory.
If
.Va allow.mount.zfs
is set, the snapshots may also be mounted.
.El
.Pp
There are pseudo-parameters that are not passed to the kernel, but are