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; }
/* 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); }
/* 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; }
/* 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; }
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; }
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; }
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; } }
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); }
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; }
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; }
/* 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; }