]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/compat.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2011 New Dream Network
7 * Copyright (C) 2018 Red Hat, Inc.
9 * This is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License version 2.1, as published by the Free Software
12 * Foundation. See file COPYING.
20 #include <sys/mount.h>
21 #include <sys/param.h>
22 #include <sys/socket.h>
24 #include <sys/types.h>
26 #if defined(__linux__)
30 #include "include/compat.h"
31 #include "include/sock_compat.h"
32 #include "common/safe_io.h"
34 // The type-value for a ZFS FS in fstatfs.
35 #define FS_ZFS_TYPE 0xde
37 // On FreeBSD, ZFS fallocate always fails since it is considered impossible to
38 // reserve space on a COW filesystem. posix_fallocate() returns EINVAL
39 // Linux in this case already emulates the reservation in glibc
40 // In which case it is allocated manually, and still that is not a real guarantee
41 // that a full buffer is allocated on disk, since it could be compressed.
42 // To prevent this the written buffer needs to be loaded with random data.
43 int manual_fallocate(int fd
, off_t offset
, off_t len
) {
44 int r
= lseek(fd
, offset
, SEEK_SET
);
48 // TODO: compressing filesystems would require random data
49 // FIPS zeroization audit 20191115: this memset is not security related.
50 memset(data
, 0x42, sizeof(data
));
51 for (off_t off
= 0; off
< len
; off
+= sizeof(data
)) {
52 if (off
+ static_cast<off_t
>(sizeof(data
)) > len
)
53 r
= safe_write(fd
, data
, len
- off
);
55 r
= safe_write(fd
, data
, sizeof(data
));
63 int on_zfs(int basedir_fd
) {
65 (void)fstatfs(basedir_fd
, &basefs
);
66 return (basefs
.f_type
== FS_ZFS_TYPE
);
69 int ceph_posix_fallocate(int fd
, off_t offset
, off_t len
) {
70 // Return 0 if oke, otherwise errno > 0
72 #ifdef HAVE_POSIX_FALLOCATE
74 return manual_fallocate(fd
, offset
, len
);
76 return posix_fallocate(fd
, offset
, len
);
78 #elif defined(__APPLE__)
80 store
.fst_flags
= F_ALLOCATECONTIG
;
81 store
.fst_posmode
= F_PEOFPOSMODE
;
82 store
.fst_offset
= offset
;
83 store
.fst_length
= len
;
85 int ret
= fcntl(fd
, F_PREALLOCATE
, &store
);
91 return manual_fallocate(fd
, offset
, len
);
95 int pipe_cloexec(int pipefd
[2])
97 #if defined(HAVE_PIPE2)
98 return pipe2(pipefd
, O_CLOEXEC
);
100 if (pipe(pipefd
) == -1)
104 * The old-fashioned, race-condition prone way that we have to fall
105 * back on if pipe2 does not exist.
107 if (fcntl(pipefd
[0], F_SETFD
, FD_CLOEXEC
) < 0) {
111 if (fcntl(pipefd
[1], F_SETFD
, FD_CLOEXEC
) < 0) {
117 int save_errno
= errno
;
118 VOID_TEMP_FAILURE_RETRY(close(pipefd
[0]));
119 VOID_TEMP_FAILURE_RETRY(close(pipefd
[1]));
120 return (errno
= save_errno
, -1);
125 int socket_cloexec(int domain
, int type
, int protocol
)
128 return socket(domain
, type
|SOCK_CLOEXEC
, protocol
);
130 int fd
= socket(domain
, type
, protocol
);
134 if (fcntl(fd
, F_SETFD
, FD_CLOEXEC
) < 0)
139 int save_errno
= errno
;
140 VOID_TEMP_FAILURE_RETRY(close(fd
));
141 return (errno
= save_errno
, -1);
145 int socketpair_cloexec(int domain
, int type
, int protocol
, int sv
[2])
148 return socketpair(domain
, type
|SOCK_CLOEXEC
, protocol
, sv
);
150 int rc
= socketpair(domain
, type
, protocol
, sv
);
154 if (fcntl(sv
[0], F_SETFD
, FD_CLOEXEC
) < 0)
157 if (fcntl(sv
[1], F_SETFD
, FD_CLOEXEC
) < 0)
162 int save_errno
= errno
;
163 VOID_TEMP_FAILURE_RETRY(close(sv
[0]));
164 VOID_TEMP_FAILURE_RETRY(close(sv
[1]));
165 return (errno
= save_errno
, -1);
169 int accept_cloexec(int sockfd
, struct sockaddr
* addr
, socklen_t
* addrlen
)
172 return accept4(sockfd
, addr
, addrlen
, SOCK_CLOEXEC
);
174 int fd
= accept(sockfd
, addr
, addrlen
);
178 if (fcntl(fd
, F_SETFD
, FD_CLOEXEC
) < 0)
183 int save_errno
= errno
;
184 VOID_TEMP_FAILURE_RETRY(close(fd
));
185 return (errno
= save_errno
, -1);
189 #if defined(__FreeBSD__)
190 int sched_setaffinity(pid_t pid
, size_t cpusetsize
,