7 #ifndef CVMFS_UTIL_PLATFORM_LINUX_H_
8 #define CVMFS_UTIL_PLATFORM_LINUX_H_
10 #include <sys/types.h>
11 #include <sys/xattr.h>
21 #include <sys/mount.h>
22 #include <sys/prctl.h>
23 #include <sys/select.h>
25 #include <sys/utsname.h>
38 #ifdef CVMFS_NAMESPACE_GUARD
39 namespace CVMFS_NAMESPACE_GUARD {
42 #define platform_sighandler_t sighandler_t
45 std::vector<std::string> result;
46 FILE *fmnt = setmntent(
"/proc/mounts",
"r");
47 struct mntent *mntbuf;
48 while ((mntbuf = getmntent(fmnt)) != NULL) {
49 result.push_back(mntbuf->mnt_dir);
57 #define MNT_DETACH 0x00000002
60 struct stat64 mtab_info;
61 int retval = lstat64(_PATH_MOUNTED, &mtab_info);
63 if ((retval == 0) && S_ISREG(mtab_info.st_mode)) {
66 std::string lockfile = std::string(_PATH_MOUNTED) +
".cvmfslock";
67 const int fd_lockfile = open(lockfile.c_str(), O_RDONLY | O_CREAT, 0600);
68 if (fd_lockfile < 0)
return false;
70 while ((flock(fd_lockfile, LOCK_EX | LOCK_NB) != 0) && (timeout > 0)) {
71 if (errno != EWOULDBLOCK) {
75 struct timeval wait_for;
78 select(0, NULL, NULL, NULL, &wait_for);
87 std::string mntnew = std::string(_PATH_MOUNTED) +
".cvmfstmp";
88 FILE *fmntold = setmntent(_PATH_MOUNTED,
"r");
90 flock(fd_lockfile, LOCK_UN);
94 FILE *fmntnew = setmntent(mntnew.c_str(),
"w+");
95 if (!fmntnew && (chmod(mntnew.c_str(), mtab_info.st_mode) != 0) &&
96 (chown(mntnew.c_str(), mtab_info.st_uid, mtab_info.st_gid) != 0)) {
98 flock(fd_lockfile, LOCK_UN);
102 struct mntent *mntbuf;
103 while ((mntbuf = getmntent(fmntold)) != NULL) {
104 if (strcmp(mntbuf->mnt_dir, mountpoint) != 0) {
105 retval = addmntent(fmntnew, mntbuf);
109 unlink(mntnew.c_str());
110 flock(fd_lockfile, LOCK_UN);
118 retval = rename(mntnew.c_str(), _PATH_MOUNTED);
119 flock(fd_lockfile, LOCK_UN);
121 if (retval != 0)
return false;
123 retval = chmod(_PATH_MOUNTED, mtab_info.st_mode);
125 retval = chown(_PATH_MOUNTED, mtab_info.st_uid, mtab_info.st_gid);
131 retval = umount2(mountpoint, flags);
146 return pthread_spin_init(lock, pshared);
150 return pthread_spin_destroy(lock);
154 return pthread_spin_trylock(lock);
158 pthread_spin_unlock(lock);
168 int retval = sigemptyset(&sigset);
170 retval = sigaddset(&sigset, signum);
172 retval = sigwaitinfo(&sigset, NULL);
184 #ifdef PR_SET_PTRACER
188 const int retval =
prctl(PR_SET_PTRACER, pid, 0, 0, 0);
192 return (retval == 0) || (errno == EINVAL);
205 return readdir64(dirp);
211 return stat64(path, buf);
215 return lstat64(path, buf);
219 return fstat64(filedes, buf);
224 std::string *value) {
228 retval = getxattr(path.c_str(), name.c_str(), buffer,
size);
231 buffer = smalloc(size);
232 retval = getxattr(path.c_str(), name.c_str(), buffer,
size);
234 if ((retval < 0) || (retval >
size)) {
239 value->assign(static_cast<const char *>(buffer), size);
249 const std::string &value) {
251 setxattr(path.c_str(), name.c_str(), value.c_str(), value.size(), 0);
256 const std::string &value) {
258 lsetxattr(path.c_str(), name.c_str(), value.c_str(), value.size(), 0);
263 void *value,
size_t size) {
264 return lgetxattr(path, name, value, size);
268 return llistxattr(path, list, size);
272 (void)posix_fadvise(filedes, 0, 0, POSIX_FADV_RANDOM | POSIX_FADV_NOREUSE);
276 return readahead(filedes, 0, static_cast<size_t>(-1));
303 const off_t length) {
304 return posix_fadvise(fd, offset, length, POSIX_FADV_DONTNEED);
308 return "lib" + base_name +
".so";
312 char buf[PATH_MAX + 1];
313 ssize_t ret = readlink(
"/proc/self/exe", buf, PATH_MAX);
316 return std::string(buf);
323 int retval = clock_gettime(clock, &tp);
329 #ifdef CLOCK_MONOTONIC_COARSE
334 return tp.tv_sec + (tp.tv_nsec >= 500000000);
339 return static_cast<uint64_t
>(
static_cast<double>(tp.tv_sec) * 1e9 +
340 static_cast<double>(tp.tv_nsec));
345 return static_cast<uint64_t
>(
static_cast<double>(tp.tv_sec) * 1e9 +
346 static_cast<double>(tp.tv_nsec));
350 return static_cast<uint64_t
>(sysconf(_SC_PHYS_PAGES)) *
351 static_cast<uint64_t>(sysconf(_SC_PAGE_SIZE));
354 #ifdef CVMFS_NAMESPACE_GUARD
358 #endif // CVMFS_UTIL_PLATFORM_LINUX_H_
assert((mem||(size==0))&&"Out Of Memory")