#include <sys/syscall.h>
#include <sys/time.h>
#include <signal.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
#ifdef MT
#include <pthread.h>
#endif
pid_t pid =syscall(SYS_gettid);
uint64_t loops;
uint64_t threshold=1000/(1 + portno_end - portno_start);
-
+
XSEGLOG2(&lc, D, "thread %u\n", (unsigned int) (t- peer->thread));
XSEGLOG2(&lc, I, "Thread %u has tid %u.\n", (unsigned int) (t- peer->thread), pid);
xseg_cancel_wait(xseg, peer->portno_start);
XSEGLOG2(&lc, I, "Thread %u woke up\n", (unsigned int) (t- peer->thread));
}
+ wake_up_next_thread(peer);
return NULL;
}
uint64_t threshold=1000/(1 + portno_end - portno_start);
pid_t pid =syscall(SYS_gettid);
uint64_t loops;
-
+
XSEGLOG2(&lc, I, "Peer has tid %u.\n", pid);
xseg_init_local_signal(xseg, peer->portno_start);
for (;!(isTerminate() && xq_count(&peer->free_reqs) == peer->nr_ops);) {
peer->portno_end= (xport) portno_end;
port = xseg_bind_port(peer->xseg, peer->portno_start, NULL);
if (!port){
- printf("cannot bind to port %ld\n", peer->portno_start);
+ printf("cannot bind to port %u\n", (unsigned int) peer->portno_start);
return NULL;
}
struct xseg_port *tmp;
tmp = xseg_bind_port(peer->xseg, p, (void *)xseg_get_signal_desc(peer->xseg, port));
if (!tmp){
- printf("cannot bind to port %ld\n", p);
+ printf("cannot bind to port %u\n", (unsigned int) p);
return NULL;
}
}
return peer;
}
+int pidfile_remove(char *path, int fd)
+{
+ close(fd);
+ return (unlink(path));
+}
+
+int pidfile_write(int pid_fd)
+{
+ char buf[16];
+ snprintf(buf, sizeof(buf), "%ld", syscall(SYS_gettid));
+ buf[15] = 0;
+
+ lseek(pid_fd, 0, SEEK_SET);
+ int ret = write(pid_fd, buf, strlen(buf));
+ return ret;
+}
+
+int pidfile_read(char *path, pid_t *pid)
+{
+ char buf[16], *endptr;
+ *pid = 0;
+
+ int fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return -1;
+ int ret = read(fd, buf, 15);
+ buf[15]=0;
+ close(fd);
+ if (ret < 0)
+ return -1;
+ else{
+ *pid = strtol(buf, &endptr, 10);
+ if (endptr != &buf[ret]){
+ *pid = 0;
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int pidfile_open(char *path, pid_t *old_pid)
+{
+ //nfs version > 3
+ int fd = open(path, O_CREAT|O_EXCL|O_WRONLY);
+ if (fd < 0){
+ if (errno == -EEXIST)
+ pidfile_read(path, old_pid);
+ }
+ return fd;
+}
int main(int argc, char *argv[])
{
struct peerd *peer = NULL;
//parse args
char *spec = "";
- int i, r;
+ int i, r, daemonize = 0;
long portno_start = -1, portno_end = -1, portno = -1;
//set defaults here
uint32_t nr_ops = 16;
unsigned int debug_level = 0;
uint32_t defer_portno = NoPort;
char *logfile = NULL;
+ char *pidfile = NULL;
+ pid_t old_pid;
+ int pid_fd = -1;
//capture here -g spec, -n nr_ops, -p portno, -t nr_threads -v verbose level
// -dp xseg_portno to defer blocking requests
// -l log file ?
//TODO print messages on arg parsing error
-
+ //TODO string checking
+
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-g") && i + 1 < argc) {
spec = argv[i+1];
i += 1;
continue;
}
-
+
if (!strcmp(argv[i], "-ep") && i + 1 < argc) {
portno_end = strtoul(argv[i+1], NULL, 10);
i += 1;
i += 1;
continue;
}
+ if (!strcmp(argv[i], "-d")) {
+ daemonize = 1;
+ continue;
+ }
+ if (!strcmp(argv[i], "--pidfile") && i + 1 < argc ) {
+ pidfile = argv[i+1];
+ i += 1;
+ continue;
+ }
}
- init_logctx(&lc, argv[0], debug_level, logfile);
+ r = init_logctx(&lc, argv[0], debug_level, logfile);
+ if (r < 0){
+ XSEGLOG("Cannot initialize logging to logfile");
+ return -1;
+ }
+ //hack
+ if (logfile){
+ dup2(fileno(lc.logfile), 1);
+ dup2(fileno(lc.logfile), 2);
+ }
XSEGLOG2(&lc, D, "Main thread has tid %ld.\n", syscall(SYS_gettid));
-
+
+ if (pidfile){
+ pid_fd = pidfile_open(pidfile, &old_pid);
+ if (pid_fd < 0) {
+ if (old_pid) {
+ XSEGLOG2(&lc, E, "Daemon already running, pid: %d.", old_pid);
+ } else {
+ XSEGLOG2(&lc, E, "Cannot open or create pidfile");
+ }
+ return -1;
+ }
+ }
+
+ if (daemonize){
+ if (daemon(0, 1) < 0){
+ XSEGLOG2(&lc, E, "Cannot daemonize");
+ r = -1;
+ goto out;
+ }
+ }
+
+ pidfile_write(pid_fd);
+
//TODO perform argument sanity checks
verbose = debug_level;
if (portno != -1) {
setup_signals();
//TODO err check
peer = peerd_init(nr_ops, spec, portno_start, portno_end, nr_threads, defer_portno);
- if (!peer)
- return -1;
+ if (!peer){
+ r = -1;
+ goto out;
+ }
r = custom_peer_init(peer, argc, argv);
if (r < 0)
- return -1;
+ goto out;
#ifdef MT
peerd_start_threads(peer);
#endif
#ifdef ST_THREADS
st_thread_t st = st_thread_create(peerd_loop, peer, 1, 0);
- return st_thread_join(st, NULL);
+ r = st_thread_join(st, NULL);
#else
- return peerd_loop(peer);
+ r = peerd_loop(peer);
#endif
+out:
+ if (pid_fd > 0)
+ pidfile_remove(pidfile, pid_fd);
+ return r;
}