Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/cmd/zed/zed_file.c
48380 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* This file is part of the ZFS Event Daemon (ZED).
4
*
5
* Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).
6
* Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
7
* Refer to the OpenZFS git commit log for authoritative copyright attribution.
8
*
9
* The contents of this file are subject to the terms of the
10
* Common Development and Distribution License Version 1.0 (CDDL-1.0).
11
* You can obtain a copy of the license from the top-level file
12
* "OPENSOLARIS.LICENSE" or at <http://opensource.org/licenses/CDDL-1.0>.
13
* You may not use this file except in compliance with the license.
14
*/
15
16
#include <dirent.h>
17
#include <errno.h>
18
#include <fcntl.h>
19
#include <limits.h>
20
#include <string.h>
21
#include <sys/stat.h>
22
#include <sys/types.h>
23
#include <unistd.h>
24
#include "zed_file.h"
25
#include "zed_log.h"
26
27
/*
28
* Set an exclusive advisory lock on the open file descriptor [fd].
29
* Return 0 on success, 1 if a conflicting lock is held by another process,
30
* or -1 on error (with errno set).
31
*/
32
int
33
zed_file_lock(int fd)
34
{
35
struct flock lock;
36
37
if (fd < 0) {
38
errno = EBADF;
39
return (-1);
40
}
41
lock.l_type = F_WRLCK;
42
lock.l_whence = SEEK_SET;
43
lock.l_start = 0;
44
lock.l_len = 0;
45
46
if (fcntl(fd, F_SETLK, &lock) < 0) {
47
if ((errno == EACCES) || (errno == EAGAIN))
48
return (1);
49
50
return (-1);
51
}
52
return (0);
53
}
54
55
/*
56
* Release an advisory lock held on the open file descriptor [fd].
57
* Return 0 on success, or -1 on error (with errno set).
58
*/
59
int
60
zed_file_unlock(int fd)
61
{
62
struct flock lock;
63
64
if (fd < 0) {
65
errno = EBADF;
66
return (-1);
67
}
68
lock.l_type = F_UNLCK;
69
lock.l_whence = SEEK_SET;
70
lock.l_start = 0;
71
lock.l_len = 0;
72
73
if (fcntl(fd, F_SETLK, &lock) < 0)
74
return (-1);
75
76
return (0);
77
}
78
79
/*
80
* Test whether an exclusive advisory lock could be obtained for the open
81
* file descriptor [fd].
82
* Return 0 if the file is not locked, >0 for the PID of another process
83
* holding a conflicting lock, or -1 on error (with errno set).
84
*/
85
pid_t
86
zed_file_is_locked(int fd)
87
{
88
struct flock lock;
89
90
if (fd < 0) {
91
errno = EBADF;
92
return (-1);
93
}
94
lock.l_type = F_WRLCK;
95
lock.l_whence = SEEK_SET;
96
lock.l_start = 0;
97
lock.l_len = 0;
98
99
if (fcntl(fd, F_GETLK, &lock) < 0)
100
return (-1);
101
102
if (lock.l_type == F_UNLCK)
103
return (0);
104
105
return (lock.l_pid);
106
}
107
108
109
#if __APPLE__
110
#define PROC_SELF_FD "/dev/fd"
111
#else /* Linux-compatible layout */
112
#define PROC_SELF_FD "/proc/self/fd"
113
#endif
114
115
/*
116
* Close all open file descriptors greater than or equal to [lowfd].
117
* Any errors encountered while closing file descriptors are ignored.
118
*/
119
void
120
zed_file_close_from(int lowfd)
121
{
122
int errno_bak = errno;
123
int maxfd = 0;
124
int fd;
125
DIR *fddir;
126
struct dirent *fdent;
127
128
if ((fddir = opendir(PROC_SELF_FD)) != NULL) {
129
while ((fdent = readdir(fddir)) != NULL) {
130
fd = atoi(fdent->d_name);
131
if (fd > maxfd && fd != dirfd(fddir))
132
maxfd = fd;
133
}
134
(void) closedir(fddir);
135
} else {
136
maxfd = sysconf(_SC_OPEN_MAX);
137
}
138
for (fd = lowfd; fd < maxfd; fd++)
139
(void) close(fd);
140
141
errno = errno_bak;
142
}
143
144