Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/setlease.c
178616 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* CDDL HEADER START
4
*
5
* The contents of this file are subject to the terms of the
6
* Common Development and Distribution License (the "License").
7
* You may not use this file except in compliance with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or https://opensource.org/licenses/CDDL-1.0.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
23
/*
24
* Copyright (c) 2026, TrueNAS.
25
*/
26
27
/*
28
* This is a sanity check test for the F_SETLEASE and F_GETLEASE fcntl() calls.
29
* We use the generic kernel implementation, but we want to be alerted if it
30
* ever breaks.
31
*
32
* This is not a comprehensive test. It would be nice if it could be!
33
*/
34
35
#ifndef _GNU_SOURCE
36
#define _GNU_SOURCE
37
#endif
38
39
#include <stdio.h>
40
#include <unistd.h>
41
#include <stdlib.h>
42
#include <fcntl.h>
43
#include <errno.h>
44
#include <string.h>
45
46
static int
47
get_lease(int fd) {
48
int r = fcntl(fd, F_GETLEASE);
49
if (r < 0) {
50
perror("fcntl(GETLEASE)");
51
exit(2);
52
}
53
return (r);
54
}
55
56
static int
57
set_lease(int fd, int lease) {
58
return (fcntl(fd, F_SETLEASE, lease) < 0 ? errno : 0);
59
}
60
61
static const char *lease_str[] = {
62
[F_RDLCK] = "RDLCK",
63
[F_WRLCK] = "WRLCK",
64
[F_UNLCK] = "UNLCK",
65
};
66
67
static void
68
assert_lease(int fd, int expect) {
69
int got = get_lease(fd);
70
if (got != expect) {
71
fprintf(stderr, "ASSERT_LEASE: expected %s [%d], got %s [%d]\n",
72
lease_str[expect], expect, lease_str[got], got);
73
abort();
74
}
75
printf("ok: lease is %s\n", lease_str[got]);
76
}
77
78
static void
79
assert_set_lease(int fd, int lease) {
80
int err = set_lease(fd, lease);
81
if (err != 0) {
82
fprintf(stderr, "ASSERT_SET_LEASE: tried %s [%d], error: %s\n",
83
lease_str[lease], lease, strerror(err));
84
abort();
85
}
86
printf("ok: set lease to %s\n", lease_str[lease]);
87
}
88
89
int
90
main(int argc, char **argv)
91
{
92
if (argc != 2) {
93
fprintf(stderr, "usage: %s <filename>\n", argv[0]);
94
exit(1);
95
}
96
97
/* create and open file, read+write */
98
int fd = open(argv[1], O_CREAT|O_RDONLY, S_IRWXU|S_IRWXG|S_IRWXO);
99
if (fd < 0) {
100
perror("open");
101
exit(2);
102
}
103
printf("ok: opened file RDONLY\n");
104
105
/* fd starts with no lease */
106
assert_lease(fd, F_UNLCK);
107
108
/* fd is readonly, so can take read lease */
109
assert_set_lease(fd, F_RDLCK);
110
/* confirm read lease */
111
assert_lease(fd, F_RDLCK);
112
113
/* no other openers, so can take write lease */
114
assert_set_lease(fd, F_WRLCK);
115
/* confirm write lease */
116
assert_lease(fd, F_WRLCK);
117
118
/* release lease */
119
assert_set_lease(fd, F_UNLCK);
120
/* confirm lease released */
121
assert_lease(fd, F_UNLCK);
122
123
close(fd);
124
125
return (0);
126
}
127
128