mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	zed: implement close_from() in terms of /proc/self/fd, if available
/dev/fd on Darwin
Consider the following strace output:
  prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, rlim_max=1024*1024}) = 0
Yes, that is well over a million file descriptors!
This reduces the ZED start-up time from "at least a second" to
"instantaneous", and, under strace, from "don't even try" to "usable"
by simple virtue of doing five syscalls instead of over a million;
in most cases the main loop does nothing
Recent Linuxes (5.8+) have close_range(2) for this, but that's an
overoptimisation (and libcs don't have wrappers for it yet)
This is also run by the ZEDLET pre-exec. Compare:
  Finished "all-syslog.sh" eid=13 pid=6717 time=1.027100s exit=0
  Finished "history_event-zfs-list-cacher.sh" eid=13 pid=6718 time=1.046923s exit=0
to
  Finished "all-syslog.sh" eid=12 pid=4834 time=0.001836s exit=0
  Finished "history_event-zfs-list-cacher.sh" eid=12 pid=4835 time=0.001346s exit=0
lol
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #11834
			
			
This commit is contained in:
		
							parent
							
								
									b73e40a5ad
								
							
						
					
					
						commit
						0a51083e39
					
				| @ -12,6 +12,7 @@ | |||||||
|  * You may not use this file except in compliance with the license. |  * You may not use this file except in compliance with the license. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include <dirent.h> | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
| #include <limits.h> | #include <limits.h> | ||||||
| @ -160,6 +161,13 @@ zed_file_is_locked(int fd) | |||||||
| 	return (lock.l_pid); | 	return (lock.l_pid); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | #if __APPLE__ | ||||||
|  | #define	PROC_SELF_FD "/dev/fd" | ||||||
|  | #else /* Linux-compatible layout */ | ||||||
|  | #define	PROC_SELF_FD "/proc/self/fd" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Close all open file descriptors greater than or equal to [lowfd]. |  * Close all open file descriptors greater than or equal to [lowfd]. | ||||||
|  * Any errors encountered while closing file descriptors are ignored. |  * Any errors encountered while closing file descriptors are ignored. | ||||||
| @ -167,17 +175,23 @@ zed_file_is_locked(int fd) | |||||||
| void | void | ||||||
| zed_file_close_from(int lowfd) | zed_file_close_from(int lowfd) | ||||||
| { | { | ||||||
| 	const int maxfd_def = 256; | 	static const int maxfd_def = 256; | ||||||
| 	int errno_bak; | 	int errno_bak = errno; | ||||||
| 	struct rlimit rl; | 	struct rlimit rl; | ||||||
| 	int maxfd; | 	int maxfd = 0; | ||||||
| 	int fd; | 	int fd; | ||||||
|  | 	DIR *fddir; | ||||||
|  | 	struct dirent *fdent; | ||||||
| 
 | 
 | ||||||
| 	errno_bak = errno; | 	if ((fddir = opendir(PROC_SELF_FD)) != NULL) { | ||||||
| 
 | 		while ((fdent = readdir(fddir)) != NULL) { | ||||||
| 	if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { | 			fd = atoi(fdent->d_name); | ||||||
| 		maxfd = maxfd_def; | 			if (fd > maxfd && fd != dirfd(fddir)) | ||||||
| 	} else if (rl.rlim_max == RLIM_INFINITY) { | 				maxfd = fd; | ||||||
|  | 		} | ||||||
|  | 		(void) closedir(fddir); | ||||||
|  | 	} else if (getrlimit(RLIMIT_NOFILE, &rl) < 0 || | ||||||
|  | 	    rl.rlim_max == RLIM_INFINITY) { | ||||||
| 		maxfd = maxfd_def; | 		maxfd = maxfd_def; | ||||||
| 	} else { | 	} else { | ||||||
| 		maxfd = rl.rlim_max; | 		maxfd = rl.rlim_max; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 наб
						наб