static void fs_remount_simple(const char *path, OPERATION op) {
	EUID_ASSERT();
	assert(path);

	// open path without following symbolic links
	int fd = safer_openat(-1, path, O_PATH|O_NOFOLLOW|O_CLOEXEC);
	if (fd < 0)
		goto out;

	struct stat s;
	if (fstat(fd, &s) < 0) {
		// fstat can fail with EACCES if path is a FUSE mount,
		// mounted without 'allow_root' or 'allow_other'
		if (errno != EACCES)
			errExit("fstat");
		close(fd);
		goto out;
	}
	// get mount flags
	struct statvfs buf;
	if (fstatvfs(fd, &buf) < 0) {
		close(fd);
		goto out;
	}
	unsigned long flags = buf.f_flag;

	// read-write option
	if (op == MOUNT_RDWR || op == MOUNT_RDWR_NOCHECK) {
		// nothing to do if there is no read-only flag
		if ((flags & MS_RDONLY) == 0) {
			close(fd);
			return;
		}
		// allow only user owned directories, except the user is root
		if (op != MOUNT_RDWR_NOCHECK && getuid() != 0 && s.st_uid != getuid()) {
			fwarning("you are not allowed to change %s to read-write\n", path);
			close(fd);
			return;
		}
		flags &= ~MS_RDONLY;
	}
	// noexec option
	else if (op == MOUNT_NOEXEC) {
		// nothing to do if path is mounted noexec already
		if ((flags & (MS_NOEXEC|MS_NODEV|MS_NOSUID)) == (MS_NOEXEC|MS_NODEV|MS_NOSUID)) {
			close(fd);
			return;
		}
		flags |= MS_NOEXEC|MS_NODEV|MS_NOSUID;
	}
	// read-only option
	else if (op == MOUNT_READONLY) {
		// nothing to do if path is mounted read-only already
		if ((flags & MS_RDONLY) == MS_RDONLY) {
			close(fd);
			return;
		}
		flags |= MS_RDONLY;
	}
	else
		assert(0);

	if (arg_debug)
		printf("Mounting %s %s\n", opstr[op], path);

	// make path a mount point:
	// mount --bind path path
	EUID_ROOT();
	int err = bind_mount_by_fd(fd, fd);
	EUID_USER();
	if (err) {
		close(fd);
		goto out;
	}

	// remount the mount point
	// need to open path again
	int fd2 = safer_openat(-1, path, O_PATH|O_NOFOLLOW|O_CLOEXEC);
	close(fd); // earliest timepoint to close fd
	if (fd2 < 0)
		goto out;

	// device and inode number should be the same
	struct stat s2;
	if (fstat(fd2, &s2) < 0)
		errExit("fstat");
	if (s.st_dev != s2.st_dev || s.st_ino != s2.st_ino)
		errLogExit("invalid %s mount", opstr[op]);

	EUID_ROOT();
	err = remount_by_fd(fd2, flags);
	EUID_USER();
	close(fd2);
	if (err)
		goto out;

	// run a sanity check on /proc/self/mountinfo and confirm that target of the last
	// mount operation was path; if there are other mount points contained inside path,
	// one of those will show up as target of the last mount operation instead
	MountData *mptr = get_last_mount();
	size_t len = strlen(path);
	if ((strncmp(mptr->dir, path, len) != 0 ||
	   (*(mptr->dir + len) != '\0' && *(mptr->dir + len) != '/'))
	   && strcmp(path, "/") != 0) // support read-only=/
		errLogExit("invalid %s mount", opstr[op]);

	fs_logger2(opstr[op], path);
	return;

out:
	fwarning("not remounting %s\n", path);
}
static void fs_remount_simple(const char *path, OPERATION op) {
	EUID_ASSERT();
	assert(path);

	 
	int fd = safer_openat(-1, path, O_PATH|O_NOFOLLOW|O_CLOEXEC);
	if (fd < 0)
		goto out;

	struct stat s;
	if (fstat(fd, &s) < 0) {
		 
		 
		if (errno != EACCES)
			errExit("fstat");
		close(fd);
		goto out;
	}
	 
	struct statvfs buf;
	if (fstatvfs(fd, &buf) < 0) {
		close(fd);
		goto out;
	}
	unsigned long flags = buf.f_flag;

	 
	if (op == MOUNT_RDWR || op == MOUNT_RDWR_NOCHECK) {
		 
		if ((flags & MS_RDONLY) == 0) {
			close(fd);
			return;
		}
		 
		if (op != MOUNT_RDWR_NOCHECK && getuid() != 0 && s.st_uid != getuid()) {
			fwarning("you are not allowed to change %s to read-write\n", path);
			close(fd);
			return;
		}
		flags &= ~MS_RDONLY;
	}
	 
	else if (op == MOUNT_NOEXEC) {
		 
		if ((flags & (MS_NOEXEC|MS_NODEV|MS_NOSUID)) == (MS_NOEXEC|MS_NODEV|MS_NOSUID)) {
			close(fd);
			return;
		}
		flags |= MS_NOEXEC|MS_NODEV|MS_NOSUID;
	}
	 
	else if (op == MOUNT_READONLY) {
		 
		if ((flags & MS_RDONLY) == MS_RDONLY) {
			close(fd);
			return;
		}
		flags |= MS_RDONLY;
	}
	else
		assert(0);

	if (arg_debug)
		printf("Mounting %s %s\n", opstr[op], path);

	 
	 
	EUID_ROOT();
	int err = bind_mount_by_fd(fd, fd);
	EUID_USER();
	if (err) {
		close(fd);
		goto out;
	}

	 
	 
	int fd2 = safer_openat(-1, path, O_PATH|O_NOFOLLOW|O_CLOEXEC);
	close(fd);  
	if (fd2 < 0)
		goto out;

	 
	struct stat s2;
	if (fstat(fd2, &s2) < 0)
		errExit("fstat");
	if (s.st_dev != s2.st_dev || s.st_ino != s2.st_ino)
		errLogExit("invalid %s mount", opstr[op]);

	EUID_ROOT();
	err = remount_by_fd(fd2, flags);
	EUID_USER();
	close(fd2);
	if (err)
		goto out;

	 
	 
	 
	MountData *mptr = get_last_mount();
	size_t len = strlen(path);
	if ((strncmp(mptr->dir, path, len) != 0 ||
	   (*(mptr->dir + len) != '\0' && *(mptr->dir + len) != '/'))
	   && strcmp(path, "/") != 0)  
		errLogExit("invalid %s mount", opstr[op]);

	fs_logger2(opstr[op], path);
	return;

out:
	fwarning("not remounting %s\n", path);
}