void LevelDB::open(StepFunction stepF, MessageFunction messageF) throw(DbException) { bool forceRepair = Util::fileExists(getRepairFlag()); if (forceRepair) { repair(stepF, messageF); File::deleteFile(getRepairFlag()); } auto ret = leveldb::DB::Open(defaultOptions, Text::fromUtf8(dbPath), &db); if (!ret.ok()) { if (ret.IsIOError()) { // most likely there's another instance running or the permissions are wrong messageF(STRING_F(DB_OPEN_FAILED_IO, getNameLower() % Text::toUtf8(ret.ToString()) % APPNAME % dbPath % APPNAME), false, true); throw DbException(); } else if (!forceRepair) { // the database is corrupted? messageF(STRING_F(DB_OPEN_FAILED_REPAIR, getNameLower() % Text::toUtf8(ret.ToString()) % APPNAME), false, false); repair(stepF, messageF); // try it again ret = leveldb::DB::Open(defaultOptions, Text::fromUtf8(dbPath), &db); } } if (!ret.ok()) { messageF(STRING_F(DB_OPEN_FAILED, getNameLower() % Text::toUtf8(ret.ToString()) % APPNAME), false, true); throw DbException(); } }
/* send_queued_write() * * inputs - fd to have queue sent, client we're sending to * outputs - contents of queue * side effects - write is rescheduled if queue isnt emptied */ void send_queued(struct Client *to) { int retlen; #ifdef USE_IODEBUG_HOOKS hook_data_int hd; #endif rb_fde_t *F = to->localClient->F; if (!F) return; /* cant write anything to a dead socket. */ if(IsIOError(to)) return; /* Something wants us to not send anything currently */ /* if(IsCork(to)) return; */ /* try to flush later when the write event resets this */ if(IsFlush(to)) return; #ifdef USE_IODEBUG_HOOKS hd.client = to; if(to->localClient->buf_sendq.list.head) hd.arg1 = ((buf_line_t *) to->localClient->buf_sendq.list.head->data)->buf + to->localClient->buf_sendq.writeofs; #endif if(rb_linebuf_len(&to->localClient->buf_sendq)) { while ((retlen = rb_linebuf_flush(F, &to->localClient->buf_sendq)) > 0) { /* We have some data written .. update counters */ #ifdef USE_IODEBUG_HOOKS hd.arg2 = retlen; call_hook(h_iosend_id, &hd); if(to->localClient->buf_sendq.list.head) hd.arg1 = ((buf_line_t *) to->localClient->buf_sendq.list.head-> data)->buf + to->localClient->buf_sendq.writeofs; #endif ClearFlush(to); to->localClient->sendB += retlen; me.localClient->sendB += retlen; if(to->localClient->sendB > 1023) { to->localClient->sendK += (to->localClient->sendB >> 10); to->localClient->sendB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */ } else if(me.localClient->sendB > 1023) { me.localClient->sendK += (me.localClient->sendB >> 10); me.localClient->sendB &= 0x03ff; }
/* send_linebuf() * * inputs - client to send to, linebuf to attach * outputs - * side effects - linebuf is attached to client */ static int _send_linebuf(struct Client *to, buf_head_t *linebuf) { if(IsMe(to)) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send message to myself!"); return 0; } if(!MyConnect(to) || IsIOError(to)) return 0; if(linebuf_len(&to->localClient->buf_sendq) > get_sendq(to)) { if(IsServer(to)) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "Max SendQ limit exceeded for %s: %u > %lu", get_server_name(to, HIDE_IP), linebuf_len(&to->localClient->buf_sendq), get_sendq(to)); ilog(L_SERVER, "Max SendQ limit exceeded for %s: %u > %lu", log_client_name(to, SHOW_IP), linebuf_len(&to->localClient->buf_sendq), get_sendq(to)); } if(IsClient(to)) to->flags |= FLAGS_SENDQEX; dead_link(to); return -1; } else { /* just attach the linebuf to the sendq instead of * generating a new one */ linebuf_attach(&to->localClient->buf_sendq, linebuf); } /* ** Update statistics. The following is slightly incorrect ** because it counts messages even if queued, but bytes ** only really sent. Queued bytes get updated in SendQueued. */ to->localClient->sendM += 1; me.localClient->sendM += 1; if(linebuf_len(&to->localClient->buf_sendq) > 0) send_queued_write(to->localClient->fd, to); return 0; }
/* send_queued_write() * * inputs - fd to have queue sent, client we're sending to * outputs - contents of queue * side effects - write is rescheduled if queue isnt emptied */ void send_queued_write(int fd, void *data) { struct Client *to = data; int retlen; int flags; #ifdef USE_IODEBUG_HOOKS hook_data_int hd; #endif /* cant write anything to a dead socket. */ if(IsIOError(to)) return; #ifdef USE_IODEBUG_HOOKS hd.client = to; if(to->localClient->buf_sendq.list.head) hd.arg1 = ((buf_line_t *) to->localClient->buf_sendq.list.head->data)->buf + to->localClient->buf_sendq.writeofs; #endif if(linebuf_len(&to->localClient->buf_sendq)) { while ((retlen = linebuf_flush(to->localClient->fd, &to->localClient->buf_sendq)) > 0) { /* We have some data written .. update counters */ #ifdef USE_IODEBUG_HOOKS hd.arg2 = retlen; call_hook(h_iosend_id, &hd); if(to->localClient->buf_sendq.list.head) hd.arg1 = ((buf_line_t *) to->localClient->buf_sendq.list.head-> data)->buf + to->localClient->buf_sendq.writeofs; #endif to->localClient->sendB += retlen; me.localClient->sendB += retlen; if(to->localClient->sendB > 1023) { to->localClient->sendK += (to->localClient->sendB >> 10); to->localClient->sendB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */ } else if(me.localClient->sendB > 1023) { me.localClient->sendK += (me.localClient->sendB >> 10); me.localClient->sendB &= 0x03ff; }
Status DBHandle::Put(const std::string& domain, const std::string& key, const std::string& value) const { if (read_only_) { return Status(0, "Database in readonly mode"); } auto cfh = getHandleForColumnFamily(domain); if (cfh == nullptr) { return Status(1, "Could not get column family for " + domain); } auto s = getDB()->Put(rocksdb::WriteOptions(), cfh, key, value); if (s.code() != 0 && s.IsIOError()) { // An error occurred, check if it is an IO error and remove the offending // specific filename or log name. std::string error_string = s.ToString(); size_t error_pos = error_string.find_last_of(":"); if (error_pos != std::string::npos) { return Status(s.code(), "IOError: " + error_string.substr(error_pos + 2)); } } return Status(s.code(), s.ToString()); }
/* send_queued_write() * * inputs - fd to have queue sent, client we're sending to * outputs - contents of queue * side effects - write is rescheduled if queue isnt emptied */ void send_queued(struct Client *to) { int retlen; rb_fde_t *F = to->localClient->F; if (!F) return; /* cant write anything to a dead socket. */ if(IsIOError(to)) return; /* try to flush later when the write event resets this */ if(IsFlush(to)) return; if(rb_linebuf_len(&to->localClient->buf_sendq)) { while ((retlen = rb_linebuf_flush(F, &to->localClient->buf_sendq)) > 0) { /* We have some data written .. update counters */ ClearFlush(to); to->localClient->sendB += retlen; me.localClient->sendB += retlen; if(to->localClient->sendB > 1023) { to->localClient->sendK += (to->localClient->sendB >> 10); to->localClient->sendB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */ } else if(me.localClient->sendB > 1023) { me.localClient->sendK += (me.localClient->sendB >> 10); me.localClient->sendB &= 0x03ff; }