aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <mszeredi@suse.cz>2013-07-25 17:58:48 +0200
committerGravatar Miklos Szeredi <mszeredi@suse.cz>2013-07-25 17:58:48 +0200
commit3c3f03b81f3027ef0a25bd790605265b384b93c1 (patch)
treebf3dd9c26414cb7f97f090cbc2a61062824566b2 /util
parent0cb2db32e73cb06716ea797374c42e99d782643b (diff)
ulockmgr: strip ulockmgr support from this source package
Distribute ulockmgr separately. It is not needed for the building of libfuse, only fusexmp_fh. Check ulockmgr library in ./configure and if not disable remote-lock suport in fusexmp_fh.
Diffstat (limited to 'util')
-rw-r--r--util/.gitignore1
-rw-r--r--util/Makefile.am6
-rw-r--r--util/ulockmgr_server.c426
3 files changed, 1 insertions, 432 deletions
diff --git a/util/.gitignore b/util/.gitignore
index 4a58d8e..961b59b 100644
--- a/util/.gitignore
+++ b/util/.gitignore
@@ -1,5 +1,4 @@
fusermount
-ulockmgr_server
fuse_ioslave
mount.fuse
mount_util.c
diff --git a/util/Makefile.am b/util/Makefile.am
index e77782b..a489d28 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
-bin_PROGRAMS = fusermount ulockmgr_server
+bin_PROGRAMS = fusermount
noinst_PROGRAMS = mount.fuse
# we re-use mount_util.c from the library, but do want to keep ourself
@@ -15,10 +15,6 @@ mount_util.c: $(top_srcdir)/lib/mount_util.c
mount_fuse_SOURCES = mount.fuse.c
-ulockmgr_server_SOURCES = ulockmgr_server.c
-ulockmgr_server_CPPFLAGS = -D_REENTRANT
-ulockmgr_server_LDFLAGS = -pthread
-
install-exec-hook:
-chmod u+s $(DESTDIR)$(bindir)/fusermount
@if test ! -e $(DESTDIR)/dev/fuse; then \
diff --git a/util/ulockmgr_server.c b/util/ulockmgr_server.c
deleted file mode 100644
index 09972ce..0000000
--- a/util/ulockmgr_server.c
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- ulockmgr_server: Userspace Lock Manager Server
- Copyright (C) 2006 Miklos Szeredi <miklos@szeredi.hu>
-
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
-*/
-
-/* #define DEBUG 1 */
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-
-struct message {
- unsigned intr : 1;
- unsigned nofd : 1;
- pthread_t thr;
- int cmd;
- int fd;
- struct flock lock;
- int error;
-};
-
-struct fd_store {
- struct fd_store *next;
- int fd;
- int origfd;
- int inuse;
-};
-
-struct owner {
- struct fd_store *fds;
- pthread_mutex_t lock;
-};
-
-struct req_data {
- struct owner *o;
- int cfd;
- struct fd_store *f;
- struct message msg;
-};
-
-#define MAX_SEND_FDS 2
-
-static int receive_message(int sock, void *buf, size_t buflen, int *fdp,
- int *numfds)
-{
- struct msghdr msg;
- struct iovec iov;
- size_t ccmsg[CMSG_SPACE(sizeof(int) * MAX_SEND_FDS) / sizeof(size_t)];
- struct cmsghdr *cmsg;
- int res;
- int i;
-
- assert(*numfds <= MAX_SEND_FDS);
- iov.iov_base = buf;
- iov.iov_len = buflen;
-
- memset(&msg, 0, sizeof(msg));
- memset(ccmsg, -1, sizeof(ccmsg));
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = ccmsg;
- msg.msg_controllen = sizeof(ccmsg);
-
- res = recvmsg(sock, &msg, MSG_WAITALL);
- if (!res) {
- /* retry on zero return, see do_recv() in ulockmgr.c */
- res = recvmsg(sock, &msg, MSG_WAITALL);
- if (!res)
- return 0;
- }
- if (res == -1) {
- perror("ulockmgr_server: recvmsg");
- return -1;
- }
- if ((size_t) res != buflen) {
- fprintf(stderr, "ulockmgr_server: short message received\n");
- return -1;
- }
-
- cmsg = CMSG_FIRSTHDR(&msg);
- if (cmsg) {
- if (!cmsg->cmsg_type == SCM_RIGHTS) {
- fprintf(stderr,
- "ulockmgr_server: unknown control message %d\n",
- cmsg->cmsg_type);
- return -1;
- }
- memcpy(fdp, CMSG_DATA(cmsg), sizeof(int) * *numfds);
- if (msg.msg_flags & MSG_CTRUNC) {
- fprintf(stderr,
- "ulockmgr_server: control message truncated\n");
- for (i = 0; i < *numfds; i++)
- close(fdp[i]);
- *numfds = 0;
- }
- } else {
- if (msg.msg_flags & MSG_CTRUNC) {
- fprintf(stderr,
- "ulockmgr_server: control message truncated(*)\n");
-
- /* There's a bug in the Linux kernel, that if
- not all file descriptors were allocated,
- then the cmsg header is not filled in */
- cmsg = (struct cmsghdr *) ccmsg;
- memcpy(fdp, CMSG_DATA(cmsg), sizeof(int) * *numfds);
- for (i = 0; i < *numfds; i++)
- close(fdp[i]);
- }
- *numfds = 0;
- }
- return res;
-}
-
-static int closefrom(int minfd)
-{
- DIR *dir = opendir("/proc/self/fd");
- if (dir) {
- int dfd = dirfd(dir);
- struct dirent *ent;
- while ((ent = readdir(dir))) {
- char *end;
- int fd = strtol(ent->d_name, &end, 10);
- if (ent->d_name[0] && !end[0] && fd >= minfd &&
- fd != dfd)
- close(fd);
- }
- closedir(dir);
- }
- return 0;
-}
-
-static void send_reply(int cfd, struct message *msg)
-{
- int res = send(cfd, msg, sizeof(struct message), MSG_NOSIGNAL);
- if (res == -1)
- perror("ulockmgr_server: sending reply");
-#ifdef DEBUG
- fprintf(stderr, "ulockmgr_server: error: %i\n", msg->error);
-#endif
-}
-
-static void *process_request(void *d_)
-{
- struct req_data *d = d_;
- int res;
-
- assert(d->msg.cmd == F_SETLKW);
- res = fcntl(d->f->fd, F_SETLK, &d->msg.lock);
- if (res == -1 && errno == EAGAIN) {
- d->msg.error = EAGAIN;
- d->msg.thr = pthread_self();
- send_reply(d->cfd, &d->msg);
- res = fcntl(d->f->fd, F_SETLKW, &d->msg.lock);
- }
- d->msg.error = (res == -1) ? errno : 0;
- pthread_mutex_lock(&d->o->lock);
- d->f->inuse--;
- pthread_mutex_unlock(&d->o->lock);
- send_reply(d->cfd, &d->msg);
- close(d->cfd);
- free(d);
-
- return NULL;
-}
-
-static void process_message(struct owner *o, struct message *msg, int cfd,
- int fd)
-{
- struct fd_store *f = NULL;
- struct fd_store *newf = NULL;
- struct fd_store **fp;
- struct req_data *d;
- pthread_t tid;
- int res;
-
-#ifdef DEBUG
- fprintf(stderr, "ulockmgr_server: %i %i %i %lli %lli\n",
- msg->cmd, msg->lock.l_type, msg->lock.l_whence,
- msg->lock.l_start, msg->lock.l_len);
-#endif
-
- if (msg->cmd == F_SETLK && msg->lock.l_type == F_UNLCK &&
- msg->lock.l_start == 0 && msg->lock.l_len == 0) {
- for (fp = &o->fds; *fp;) {
- f = *fp;
- if (f->origfd == msg->fd && !f->inuse) {
- close(f->fd);
- *fp = f->next;
- free(f);
- } else
- fp = &f->next;
- }
- if (!msg->nofd)
- close(fd);
-
- msg->error = 0;
- send_reply(cfd, msg);
- close(cfd);
- return;
- }
-
- if (msg->nofd) {
- for (fp = &o->fds; *fp; fp = &(*fp)->next) {
- f = *fp;
- if (f->origfd == msg->fd)
- break;
- }
- if (!*fp) {
- fprintf(stderr, "ulockmgr_server: fd %i not found\n",
- msg->fd);
- msg->error = EIO;
- send_reply(cfd, msg);
- close(cfd);
- return;
- }
- } else {
- newf = f = malloc(sizeof(struct fd_store));
- if (!f) {
- msg->error = ENOLCK;
- send_reply(cfd, msg);
- close(cfd);
- return;
- }
-
- f->fd = fd;
- f->origfd = msg->fd;
- f->inuse = 0;
- }
-
- if (msg->cmd == F_GETLK || msg->cmd == F_SETLK ||
- msg->lock.l_type == F_UNLCK) {
- res = fcntl(f->fd, msg->cmd, &msg->lock);
- msg->error = (res == -1) ? errno : 0;
- send_reply(cfd, msg);
- close(cfd);
- if (newf) {
- newf->next = o->fds;
- o->fds = newf;
- }
- return;
- }
-
- d = malloc(sizeof(struct req_data));
- if (!d) {
- msg->error = ENOLCK;
- send_reply(cfd, msg);
- close(cfd);
- free(newf);
- return;
- }
-
- f->inuse++;
- d->o = o;
- d->cfd = cfd;
- d->f = f;
- d->msg = *msg;
- res = pthread_create(&tid, NULL, process_request, d);
- if (res) {
- msg->error = ENOLCK;
- send_reply(cfd, msg);
- close(cfd);
- free(d);
- f->inuse--;
- free(newf);
- return;
- }
-
- if (newf) {
- newf->next = o->fds;
- o->fds = newf;
- }
- pthread_detach(tid);
-}
-
-static void sigusr1_handler(int sig)
-{
- (void) sig;
- /* Nothing to do */
-}
-
-static void process_owner(int cfd)
-{
- struct owner o;
- struct sigaction sa;
-
- memset(&sa, 0, sizeof(struct sigaction));
- sa.sa_handler = sigusr1_handler;
- sigemptyset(&sa.sa_mask);
-
- if (sigaction(SIGUSR1, &sa, NULL) == -1) {
- perror("ulockmgr_server: cannot set sigusr1 signal handler");
- exit(1);
- }
-
- memset(&o, 0, sizeof(struct owner));
- pthread_mutex_init(&o.lock, NULL);
- while (1) {
- struct message msg;
- int rfds[2];
- int res;
- int numfds = 2;
-
- res = receive_message(cfd, &msg, sizeof(msg), rfds, &numfds);
- if (!res)
- break;
- if (res == -1)
- exit(1);
-
- if (msg.intr) {
- if (numfds != 0)
- fprintf(stderr,
- "ulockmgr_server: too many fds for intr\n");
- pthread_kill(msg.thr, SIGUSR1);
- } else {
- if (numfds != 2)
- continue;
-
- pthread_mutex_lock(&o.lock);
- process_message(&o, &msg, rfds[0], rfds[1]);
- pthread_mutex_unlock(&o.lock);
- }
- }
- if (o.fds)
- fprintf(stderr,
- "ulockmgr_server: open file descriptors on exit\n");
-}
-
-int main(int argc, char *argv[])
-{
- int nullfd;
- char *end;
- int cfd;
- sigset_t empty;
-
- if (argc != 2 || !argv[1][0])
- goto out_inval;
-
- cfd = strtol(argv[1], &end, 10);
- if (*end)
- goto out_inval;
-
- /* demonize current process */
- switch(fork()) {
- case -1:
- perror("ulockmgr_server: fork");
- exit(1);
- case 0:
- break;
- default:
- _exit(0);
- }
-
- if (setsid() == -1) {
- perror("ulockmgr_server: setsid");
- exit(1);
- }
-
- (void) chdir("/");
-
- sigemptyset(&empty);
- sigprocmask(SIG_SETMASK, &empty, NULL);
-
- if (dup2(cfd, 4) == -1) {
- perror("ulockmgr_server: dup2");
- exit(1);
- }
- cfd = 4;
- nullfd = open("/dev/null", O_RDWR);
- if (nullfd >= 0) {
- dup2(nullfd, 0);
- dup2(nullfd, 1);
- }
- close(3);
- closefrom(5);
- while (1) {
- char c;
- int sock;
- int pid;
- int numfds = 1;
- int res = receive_message(cfd, &c, sizeof(c), &sock, &numfds);
- if (!res)
- break;
- if (res == -1)
- exit(1);
- assert(numfds == 1);
-
- pid = fork();
- if (pid == -1) {
- perror("ulockmgr_server: fork");
- close(sock);
- continue;
- }
- if (pid == 0) {
- close(cfd);
- pid = fork();
- if (pid == -1) {
- perror("ulockmgr_server: fork");
- _exit(1);
- }
- if (pid == 0)
- process_owner(sock);
- _exit(0);
- }
- waitpid(pid, NULL, 0);
- close(sock);
- }
- return 0;
-
-out_inval:
- fprintf(stderr, "%s should be started by libulockmgr\n", argv[0]);
- return 1;
-}