示例#1
0
int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
		     struct file_lock *fl)
{
	struct dlm_ls *ls;
	struct plock_op *op;
	int rv;

	ls = dlm_find_lockspace_local(lockspace);
	if (!ls)
		return -EINVAL;

	op = kzalloc(sizeof(*op), GFP_NOFS);
	if (!op) {
		rv = -ENOMEM;
		goto out;
	}

	if (posix_lock_file_wait(file, fl) < 0)
		log_error(ls, "dlm_posix_unlock: vfs unlock error %llx",
			  (unsigned long long)number);

	op->info.optype		= DLM_PLOCK_OP_UNLOCK;
	op->info.pid		= fl->fl_pid;
	op->info.fsid		= ls->ls_global_id;
	op->info.number		= number;
	op->info.start		= fl->fl_start;
	op->info.end		= fl->fl_end;
	if (fl->fl_lmops && fl->fl_lmops->lm_grant)
		op->info.owner	= (__u64) fl->fl_pid;
	else
		op->info.owner	= (__u64)(long) fl->fl_owner;

	if (fl->fl_flags & FL_CLOSE) {
		op->info.flags |= DLM_PLOCK_FL_CLOSE;
		send_op(op);
		rv = 0;
		goto out;
	}

	send_op(op);
	wait_event(recv_wq, (op->done != 0));

	spin_lock(&ops_lock);
	if (!list_empty(&op->list)) {
		log_error(ls, "dlm_posix_unlock: op on list %llx",
			  (unsigned long long)number);
		list_del(&op->list);
	}
	spin_unlock(&ops_lock);

	rv = op->info.rv;

	if (rv == -ENOENT)
		rv = 0;

	kfree(op);
out:
	dlm_put_lockspace(ls);
	return rv;
}
示例#2
0
文件: conn_sock.c 项目: nigaky/tp
/* client side */
void run_client(void)
{
	int op_fd;
	int nr_threads;
	pthread_t *p;
	long i;

	op_fd = init_op_sock_client();

	nr_threads = 2;

	p = malloc(sizeof(pthread_t) * nr_threads);
	if (!p) {
		perror("malloc");
		exit(1);
	}

	send_op(nr_threads, op_fd);

	/* create server worker */
	for (i=0;i<nr_threads;i++) {
		pthread_create(&p[i], NULL, client_work, (void *)i);
	}

	/* wait for client workers */
	for (i=0;i<nr_threads;i++) {
		pthread_join(p[i], NULL);
	}

	send_op(-1, op_fd);
}
示例#3
0
/* Send single-valued operand */
bool send_as_operand(dword_t dest, word_t val) {
    chunk_ptr oper = msg_new_operand(dest, 1 + OPER_HEADER_CNT);
    chunk_insert_word(oper, val, 0 + OPER_HEADER_CNT);
    bool ok = send_op(oper);
    chunk_free(oper);
    return ok;
}
示例#4
0
/* Send a command to howm and wait for its reply. */
int main(int argc, char *argv[])
{
	int ret, ch, type = 0;

	if (argc < 2)
		usage();

	while ((ch = getopt(argc, argv, "vcfo")) != -1 && !type) {
		switch (ch) {
		case 'c':
			type = MSG_CONFIG;
			break;
		case 'f':
			type = MSG_FUNCTION;
			break;
		case 'o':
			type = MSG_OP_HELPER;
			break;
		case 'v':
			printf("%s\n", VERSION);
			exit(EXIT_SUCCESS);
		default:
			usage();
		}
	}

	if (!type || (type == MSG_OP_HELPER && argc < 5))
		usage();

	argc -= 2;
	argv += 2;

	ret = type == MSG_OP_HELPER ? send_op(argv)
					: send_command(argc, argv, type);

	if (ret == -1)
		perror("Failed to send data");

	if (ret != IPC_ERR_NONE)
		return EXIT_FAILURE;

	return EXIT_SUCCESS;
}
示例#5
0
int gdlm_plock(void *lockspace, struct lm_lockname *name,
	       struct file *file, int cmd, struct file_lock *fl)
{
	struct gdlm_ls *ls = lockspace;
	struct plock_op *op;
	int rv;

	op = kzalloc(sizeof(*op), GFP_KERNEL);
	if (!op)
		return -ENOMEM;

	op->info.optype		= GDLM_PLOCK_OP_LOCK;
	op->info.pid		= fl->fl_pid;
	op->info.ex		= (fl->fl_type == F_WRLCK);
	op->info.wait		= IS_SETLKW(cmd);
	op->info.fsid		= ls->id;
	op->info.number		= name->ln_number;
	op->info.start		= fl->fl_start;
	op->info.end		= fl->fl_end;
	op->info.owner		= (__u64)(long) fl->fl_owner;

	send_op(op);
	wait_event(recv_wq, (op->done != 0));

	spin_lock(&ops_lock);
	if (!list_empty(&op->list)) {
		printk(KERN_INFO "plock op on list\n");
		list_del(&op->list);
	}
	spin_unlock(&ops_lock);

	rv = op->info.rv;

	if (!rv) {
		if (posix_lock_file_wait(file, fl) < 0)
			log_error("gdlm_plock: vfs lock error %x,%llx",
				  name->ln_type,
				  (unsigned long long)name->ln_number);
	}

	kfree(op);
	return rv;
}
示例#6
0
int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
		   struct file *file, struct file_lock *fl)
{
	struct gdlm_ls *ls = lockspace;
	struct plock_op *op;
	int rv;

	op = kzalloc(sizeof(*op), GFP_KERNEL);
	if (!op)
		return -ENOMEM;

	op->info.optype		= GDLM_PLOCK_OP_GET;
	op->info.pid		= fl->fl_pid;
	op->info.ex		= (fl->fl_type == F_WRLCK);
	op->info.fsid		= ls->id;
	op->info.number		= name->ln_number;
	op->info.start		= fl->fl_start;
	op->info.end		= fl->fl_end;

	send_op(op);
	wait_event(recv_wq, (op->done != 0));

	spin_lock(&ops_lock);
	if (!list_empty(&op->list)) {
		printk(KERN_INFO "plock_get op on list\n");
		list_del(&op->list);
	}
	spin_unlock(&ops_lock);

	rv = op->info.rv;

	if (rv == 0)
		fl->fl_type = F_UNLCK;
	else if (rv > 0) {
		fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
		fl->fl_pid = op->info.pid;
		fl->fl_start = op->info.start;
		fl->fl_end = op->info.end;
	}

	kfree(op);
	return rv;
}
示例#7
0
    void connect() {
      if (socket_error || !socket->is_open()) {
        boost::asio::ip::tcp::resolver::query query(host, std::to_string(port));
        boost::asio::connect(*socket, asio_resolver.resolve(query));

        boost::asio::ip::tcp::no_delay option(true);
        socket->set_option(option);

        /* Timeout implementation */
        if (send_timeout > 0) {
          timeout_op send_op(send_timeout, SO_SNDTIMEO);
          socket->set_option(send_op);
        }

        if (recv_timeout > 0) {
          timeout_op recv_op(recv_timeout, SO_RCVTIMEO);
          socket->set_option(recv_op);
        }

        socket_error = false;
      }
    }
示例#8
0
static void do_unlock_close(struct dlm_ls *ls, u64 number,
			    struct file *file, struct file_lock *fl)
{
	struct plock_op *op;

	op = kzalloc(sizeof(*op), GFP_NOFS);
	if (!op)
		return;

	op->info.optype		= DLM_PLOCK_OP_UNLOCK;
	op->info.pid		= fl->fl_pid;
	op->info.fsid		= ls->ls_global_id;
	op->info.number		= number;
	op->info.start		= 0;
	op->info.end		= OFFSET_MAX;
	if (fl->fl_lmops && fl->fl_lmops->lm_grant)
		op->info.owner	= (__u64) fl->fl_pid;
	else
		op->info.owner	= (__u64)(long) fl->fl_owner;

	op->info.flags |= DLM_PLOCK_FL_CLOSE;
	send_op(op);
}
示例#9
0
int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
		   int cmd, struct file_lock *fl)
{
	struct dlm_ls *ls;
	struct plock_op *op;
	struct plock_xop *xop;
	int rv;

	ls = dlm_find_lockspace_local(lockspace);
	if (!ls)
		return -EINVAL;

	xop = kzalloc(sizeof(*xop), GFP_KERNEL);
	if (!xop) {
		rv = -ENOMEM;
		goto out;
	}

	op = &xop->xop;
	op->info.optype		= DLM_PLOCK_OP_LOCK;
	op->info.pid		= fl->fl_pid;
	op->info.ex		= (fl->fl_type == F_WRLCK);
	op->info.wait		= IS_SETLKW(cmd);
	op->info.fsid		= ls->ls_global_id;
	op->info.number		= number;
	op->info.start		= fl->fl_start;
	op->info.end		= fl->fl_end;
	if (fl->fl_lmops && fl->fl_lmops->fl_grant) {
		/* fl_owner is lockd which doesn't distinguish
		   processes on the nfs client */
		op->info.owner	= (__u64) fl->fl_pid;
		xop->callback	= fl->fl_lmops->fl_grant;
		locks_init_lock(&xop->flc);
		locks_copy_lock(&xop->flc, fl);
		xop->fl		= fl;
		xop->file	= file;
	} else {
		op->info.owner	= (__u64)(long) fl->fl_owner;
		xop->callback	= NULL;
	}

	send_op(op);

	if (xop->callback == NULL)
		wait_event(recv_wq, (op->done != 0));
	else {
		rv = FILE_LOCK_DEFERRED;
		goto out;
	}

	spin_lock(&ops_lock);
	if (!list_empty(&op->list)) {
		log_error(ls, "dlm_posix_lock: op on list %llx",
			  (unsigned long long)number);
		list_del(&op->list);
	}
	spin_unlock(&ops_lock);

	rv = op->info.rv;

	if (!rv) {
		if (posix_lock_file_wait(file, fl) < 0)
			log_error(ls, "dlm_posix_lock: vfs lock error %llx",
				  (unsigned long long)number);
	}

	kfree(xop);
out:
	dlm_put_lockspace(ls);
	return rv;
}
示例#10
0
int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
		  struct file_lock *fl)
{
	struct dlm_ls *ls;
	struct plock_op *op;
	int rv;

	ls = dlm_find_lockspace_local(lockspace);
	if (!ls)
		return -EINVAL;

	op = kzalloc(sizeof(*op), GFP_KERNEL);
	if (!op) {
		rv = -ENOMEM;
		goto out;
	}

	op->info.optype		= DLM_PLOCK_OP_GET;
	op->info.pid		= fl->fl_pid;
	op->info.ex		= (fl->fl_type == F_WRLCK);
	op->info.fsid		= ls->ls_global_id;
	op->info.number		= number;
	op->info.start		= fl->fl_start;
	op->info.end		= fl->fl_end;
	if (fl->fl_lmops && fl->fl_lmops->fl_grant)
		op->info.owner	= (__u64) fl->fl_pid;
	else
		op->info.owner	= (__u64)(long) fl->fl_owner;

	send_op(op);
	wait_event(recv_wq, (op->done != 0));

	spin_lock(&ops_lock);
	if (!list_empty(&op->list)) {
		log_error(ls, "dlm_posix_get: op on list %llx",
			  (unsigned long long)number);
		list_del(&op->list);
	}
	spin_unlock(&ops_lock);

	/* info.rv from userspace is 1 for conflict, 0 for no-conflict,
	   -ENOENT if there are no locks on the file */

	rv = op->info.rv;

	fl->fl_type = F_UNLCK;
	if (rv == -ENOENT)
		rv = 0;
	else if (rv > 0) {
		locks_init_lock(fl);
		fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
		fl->fl_flags = FL_POSIX;
		fl->fl_pid = op->info.pid;
		fl->fl_start = op->info.start;
		fl->fl_end = op->info.end;
		rv = 0;
	}

	kfree(op);
out:
	dlm_put_lockspace(ls);
	return rv;
}
示例#11
0
/* Fire an operation and wait for returned operand */
chunk_ptr fire_and_wait_defer(chunk_ptr msg) {
    chunk_ptr rval = NULL;
    if (!send_op(msg)) {
	err(false, "Failed to send message");
	return NULL;
    }
    bool local_done = false;
    while (!(local_done || cmd_done())) {
	/* Select among controller port, and connections to routers.
	   Do not accept console input */
	FD_ZERO(&rset);
	maxrfd = 0;
	add_rfd(controller_fd);
	unsigned ridx;
	for (ridx = 0; ridx < nrouters; ridx++)
	    add_rfd(router_fd_array[ridx]);

	buf_select(maxrfd+1, &rset, NULL, NULL, NULL);
	int fd;
	for (fd = 0; fd <= maxrfd; fd++) {
	    if (!FD_ISSET(fd, &rset))
		continue;
	    bool eof;
	    chunk_ptr msg = chunk_read(fd, &eof);
	    if (eof) {
		/* Unexpected EOF */
		if (fd == controller_fd) {
		    err(true, "Unexpected EOF from controller (fatal)");
		} else {
		    err(false,
			"Unexpected EOF from router with fd %d (shutting down)", fd);
		    finish_cmd();
		    exit(0);
		}
		close(fd);
		continue;
	    }
	    if (msg == NULL) {
		err(false, "Could not read chunk from fd %d (ignored)", fd);
		continue;
	    }
	    word_t h = chunk_get_word(msg, 0);
	    unsigned code = msg_get_header_code(h);
	    if (fd == controller_fd) {
		/* Message from controller */
		switch(code) {
		case MSG_KILL:
		    chunk_free(msg);
#if RPT >= 1
		    report(1, "Received kill message from controller");
#endif
		    quit_agent(0, NULL);
		    break;
		case MSG_DO_FLUSH:
		    chunk_free(msg);
#if RPT >= 2
		    report(2, "Received flush message from controller");
#endif
		    if (flush_helper) {
			flush_helper(0, NULL);
		    }
		    break;
		case MSG_GC_START:
		    /* Got notice that should initiate garbage collection.
		       Defer until current operation done */
#if RPT >= 3
		    report(3, "Deferring GC start");
#endif
		    chunk_free(msg);
		    gc_state = GC_DEFER;
		    break;
		case MSG_GC_FINISH:
#if RPT >= 3
		    report(3,
"Unexpected GC_FINISH message from controller when waiting for result (ignored)");
#endif
		    chunk_free(msg);
		    break;
		default:
		    chunk_free(msg);
		    err(false,
"Unknown message code %u from controller (ignored)", code);
		}
	    } else {
		dword_t dh;
		word_t id = 0;
		/* Must be message from router */
		switch (code) {
		case MSG_OPERATION:
		    chunk_free(msg);
		    err(false, "Received unexpected operation.  Ignored.");
		    local_done = true;
		    break;
		case MSG_OPERAND:
#if RPT >= 5
		    dh = chunk_get_dword(msg, 0);
		    id = msg_get_dheader_op_id(dh);
		    report(5, "Received operand with id 0x%lx", id);
#endif
		    rval = msg;
		    local_done = true;
		    break;
		default:
		    chunk_free(msg);
		    err(false,
"Received message with unknown code %u (ignored)", code);
		    local_done = true;
		}
	    }
	}
    }
    return rval;
}