Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/setlease.c
178616 views
// SPDX-License-Identifier: CDDL-1.01/*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* Common Development and Distribution License (the "License").6* You may not use this file except in compliance with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or https://opensource.org/licenses/CDDL-1.0.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/2122/*23* Copyright (c) 2026, TrueNAS.24*/2526/*27* This is a sanity check test for the F_SETLEASE and F_GETLEASE fcntl() calls.28* We use the generic kernel implementation, but we want to be alerted if it29* ever breaks.30*31* This is not a comprehensive test. It would be nice if it could be!32*/3334#ifndef _GNU_SOURCE35#define _GNU_SOURCE36#endif3738#include <stdio.h>39#include <unistd.h>40#include <stdlib.h>41#include <fcntl.h>42#include <errno.h>43#include <string.h>4445static int46get_lease(int fd) {47int r = fcntl(fd, F_GETLEASE);48if (r < 0) {49perror("fcntl(GETLEASE)");50exit(2);51}52return (r);53}5455static int56set_lease(int fd, int lease) {57return (fcntl(fd, F_SETLEASE, lease) < 0 ? errno : 0);58}5960static const char *lease_str[] = {61[F_RDLCK] = "RDLCK",62[F_WRLCK] = "WRLCK",63[F_UNLCK] = "UNLCK",64};6566static void67assert_lease(int fd, int expect) {68int got = get_lease(fd);69if (got != expect) {70fprintf(stderr, "ASSERT_LEASE: expected %s [%d], got %s [%d]\n",71lease_str[expect], expect, lease_str[got], got);72abort();73}74printf("ok: lease is %s\n", lease_str[got]);75}7677static void78assert_set_lease(int fd, int lease) {79int err = set_lease(fd, lease);80if (err != 0) {81fprintf(stderr, "ASSERT_SET_LEASE: tried %s [%d], error: %s\n",82lease_str[lease], lease, strerror(err));83abort();84}85printf("ok: set lease to %s\n", lease_str[lease]);86}8788int89main(int argc, char **argv)90{91if (argc != 2) {92fprintf(stderr, "usage: %s <filename>\n", argv[0]);93exit(1);94}9596/* create and open file, read+write */97int fd = open(argv[1], O_CREAT|O_RDONLY, S_IRWXU|S_IRWXG|S_IRWXO);98if (fd < 0) {99perror("open");100exit(2);101}102printf("ok: opened file RDONLY\n");103104/* fd starts with no lease */105assert_lease(fd, F_UNLCK);106107/* fd is readonly, so can take read lease */108assert_set_lease(fd, F_RDLCK);109/* confirm read lease */110assert_lease(fd, F_RDLCK);111112/* no other openers, so can take write lease */113assert_set_lease(fd, F_WRLCK);114/* confirm write lease */115assert_lease(fd, F_WRLCK);116117/* release lease */118assert_set_lease(fd, F_UNLCK);119/* confirm lease released */120assert_lease(fd, F_UNLCK);121122close(fd);123124return (0);125}126127128