ZTS: Add additional exceptions
[zfs.git] / cmd / zed / zed_file.c
blobb62f68b2610f59975d0cbf540ab70b5c41160428
1 /*
2 * This file is part of the ZFS Event Daemon (ZED).
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.
8 * The contents of this file are subject to the terms of the
9 * Common Development and Distribution License Version 1.0 (CDDL-1.0).
10 * You can obtain a copy of the license from the top-level file
11 * "OPENSOLARIS.LICENSE" or at <http://opensource.org/licenses/CDDL-1.0>.
12 * You may not use this file except in compliance with the license.
15 #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"
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).
31 int
32 zed_file_lock(int fd)
34 struct flock lock;
36 if (fd < 0) {
37 errno = EBADF;
38 return (-1);
40 lock.l_type = F_WRLCK;
41 lock.l_whence = SEEK_SET;
42 lock.l_start = 0;
43 lock.l_len = 0;
45 if (fcntl(fd, F_SETLK, &lock) < 0) {
46 if ((errno == EACCES) || (errno == EAGAIN))
47 return (1);
49 return (-1);
51 return (0);
55 * Release an advisory lock held on the open file descriptor [fd].
56 * Return 0 on success, or -1 on error (with errno set).
58 int
59 zed_file_unlock(int fd)
61 struct flock lock;
63 if (fd < 0) {
64 errno = EBADF;
65 return (-1);
67 lock.l_type = F_UNLCK;
68 lock.l_whence = SEEK_SET;
69 lock.l_start = 0;
70 lock.l_len = 0;
72 if (fcntl(fd, F_SETLK, &lock) < 0)
73 return (-1);
75 return (0);
79 * Test whether an exclusive advisory lock could be obtained for the open
80 * file descriptor [fd].
81 * Return 0 if the file is not locked, >0 for the PID of another process
82 * holding a conflicting lock, or -1 on error (with errno set).
84 pid_t
85 zed_file_is_locked(int fd)
87 struct flock lock;
89 if (fd < 0) {
90 errno = EBADF;
91 return (-1);
93 lock.l_type = F_WRLCK;
94 lock.l_whence = SEEK_SET;
95 lock.l_start = 0;
96 lock.l_len = 0;
98 if (fcntl(fd, F_GETLK, &lock) < 0)
99 return (-1);
101 if (lock.l_type == F_UNLCK)
102 return (0);
104 return (lock.l_pid);
108 #if __APPLE__
109 #define PROC_SELF_FD "/dev/fd"
110 #else /* Linux-compatible layout */
111 #define PROC_SELF_FD "/proc/self/fd"
112 #endif
115 * Close all open file descriptors greater than or equal to [lowfd].
116 * Any errors encountered while closing file descriptors are ignored.
118 void
119 zed_file_close_from(int lowfd)
121 int errno_bak = errno;
122 int maxfd = 0;
123 int fd;
124 DIR *fddir;
125 struct dirent *fdent;
127 if ((fddir = opendir(PROC_SELF_FD)) != NULL) {
128 while ((fdent = readdir(fddir)) != NULL) {
129 fd = atoi(fdent->d_name);
130 if (fd > maxfd && fd != dirfd(fddir))
131 maxfd = fd;
133 (void) closedir(fddir);
134 } else {
135 maxfd = sysconf(_SC_OPEN_MAX);
137 for (fd = lowfd; fd < maxfd; fd++)
138 (void) close(fd);
140 errno = errno_bak;