Path: blob/main/sys/contrib/openzfs/cmd/zed/zed_file.c
48380 views
// SPDX-License-Identifier: CDDL-1.01/*2* This file is part of the ZFS Event Daemon (ZED).3*4* Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).5* Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.6* Refer to the OpenZFS git commit log for authoritative copyright attribution.7*8* The contents of this file are subject to the terms of the9* Common Development and Distribution License Version 1.0 (CDDL-1.0).10* You can obtain a copy of the license from the top-level file11* "OPENSOLARIS.LICENSE" or at <http://opensource.org/licenses/CDDL-1.0>.12* You may not use this file except in compliance with the license.13*/1415#include <dirent.h>16#include <errno.h>17#include <fcntl.h>18#include <limits.h>19#include <string.h>20#include <sys/stat.h>21#include <sys/types.h>22#include <unistd.h>23#include "zed_file.h"24#include "zed_log.h"2526/*27* Set an exclusive advisory lock on the open file descriptor [fd].28* Return 0 on success, 1 if a conflicting lock is held by another process,29* or -1 on error (with errno set).30*/31int32zed_file_lock(int fd)33{34struct flock lock;3536if (fd < 0) {37errno = EBADF;38return (-1);39}40lock.l_type = F_WRLCK;41lock.l_whence = SEEK_SET;42lock.l_start = 0;43lock.l_len = 0;4445if (fcntl(fd, F_SETLK, &lock) < 0) {46if ((errno == EACCES) || (errno == EAGAIN))47return (1);4849return (-1);50}51return (0);52}5354/*55* Release an advisory lock held on the open file descriptor [fd].56* Return 0 on success, or -1 on error (with errno set).57*/58int59zed_file_unlock(int fd)60{61struct flock lock;6263if (fd < 0) {64errno = EBADF;65return (-1);66}67lock.l_type = F_UNLCK;68lock.l_whence = SEEK_SET;69lock.l_start = 0;70lock.l_len = 0;7172if (fcntl(fd, F_SETLK, &lock) < 0)73return (-1);7475return (0);76}7778/*79* Test whether an exclusive advisory lock could be obtained for the open80* file descriptor [fd].81* Return 0 if the file is not locked, >0 for the PID of another process82* holding a conflicting lock, or -1 on error (with errno set).83*/84pid_t85zed_file_is_locked(int fd)86{87struct flock lock;8889if (fd < 0) {90errno = EBADF;91return (-1);92}93lock.l_type = F_WRLCK;94lock.l_whence = SEEK_SET;95lock.l_start = 0;96lock.l_len = 0;9798if (fcntl(fd, F_GETLK, &lock) < 0)99return (-1);100101if (lock.l_type == F_UNLCK)102return (0);103104return (lock.l_pid);105}106107108#if __APPLE__109#define PROC_SELF_FD "/dev/fd"110#else /* Linux-compatible layout */111#define PROC_SELF_FD "/proc/self/fd"112#endif113114/*115* Close all open file descriptors greater than or equal to [lowfd].116* Any errors encountered while closing file descriptors are ignored.117*/118void119zed_file_close_from(int lowfd)120{121int errno_bak = errno;122int maxfd = 0;123int fd;124DIR *fddir;125struct dirent *fdent;126127if ((fddir = opendir(PROC_SELF_FD)) != NULL) {128while ((fdent = readdir(fddir)) != NULL) {129fd = atoi(fdent->d_name);130if (fd > maxfd && fd != dirfd(fddir))131maxfd = fd;132}133(void) closedir(fddir);134} else {135maxfd = sysconf(_SC_OPEN_MAX);136}137for (fd = lowfd; fd < maxfd; fd++)138(void) close(fd);139140errno = errno_bak;141}142143144