diff --git a/README.md b/README.md index 22b244c..4ab8699 100644 --- a/README.md +++ b/README.md @@ -73,13 +73,8 @@ This software has a custom SNMP library (SNMP agent). * .1.3.6.1.2.1.142.1.6.3.1.1 - logouts * .1.3.6.1.4.1.2021.100.2 - software version (not in Posix version) * .1.3.6.1.4.1.2021.100.3 - build date -* .1.3.6.1.4.1.2021.11.54 - I/O wait in 100ths of a second * .1.3.6.1.4.1.2021.11.9.0 - CPU usage * .1.3.6.1.4.1.2021.13.15.1.1.2 - device name -* .1.3.6.1.4.1.2021.13.15.1.1.3 - number of bytes read -* .1.3.6.1.4.1.2021.13.15.1.1.4 - number of bytes written -* .1.3.6.1.4.1.2021.13.15.1.1.5 - number of reads -* .1.3.6.1.4.1.2021.13.15.1.1.6 - number of writes * .1.3.6.1.4.1.2021.4.11.0 - free RAM (kB heap space, only on microcontrollers) * .1.3.6.1.4.1.2021.9.1.9.1 - disk free estimate (will only work when using TRIM/UNMAP/DISCARD) diff --git a/backend-file.cpp b/backend-file.cpp index 2c30216..71d1c96 100644 --- a/backend-file.cpp +++ b/backend-file.cpp @@ -54,7 +54,6 @@ uint64_t backend_file::get_block_size() const bool backend_file::sync() { - n_syncs++; ts_last_acces = get_micros(); #if defined(__MINGW32__) if (_commit(fd) == 0) @@ -91,7 +90,6 @@ bool backend_file::write(const uint64_t block_nr, const uint32_t n_blocks, const if (rc == -1) DOLOG(logging::ll_error, "backend_file::write", identifier, "ERROR writing: %s", strerror(errno)); ts_last_acces = get_micros(); - bytes_written += n_bytes; return rc == ssize_t(n_bytes); } @@ -117,7 +115,6 @@ bool backend_file::trim(const uint64_t block_nr, const uint32_t n_blocks) #endif if (rc == -1) DOLOG(logging::ll_error, "backend_file::trim", identifier, "unmapping: %s", strerror(errno)); - n_trims += n_blocks; ts_last_acces = get_micros(); return rc == 0; } @@ -145,7 +142,6 @@ bool backend_file::read(const uint64_t block_nr, const uint32_t n_blocks, uint8_ else if (rc != ssize_t(n_bytes)) DOLOG(logging::ll_error, "backend_file::read", identifier, "short read, requested: %zu, received: %zd", n_bytes, rc); ts_last_acces = get_micros(); - bytes_read += n_bytes; return rc == ssize_t(n_bytes); } @@ -183,7 +179,6 @@ backend::cmpwrite_result_t backend_file::cmpwrite(const uint64_t block_nr, const result = cmpwrite_result_t::CWR_READ_ERROR; break; } - bytes_read += block_size; // compare if (memcmp(buffer, &data_compare[i * block_size], block_size) != 0) { @@ -210,8 +205,6 @@ backend::cmpwrite_result_t backend_file::cmpwrite(const uint64_t block_nr, const result = cmpwrite_result_t::CWR_WRITE_ERROR; } else { - bytes_written += block_size; - ts_last_acces = get_micros(); } } diff --git a/backend-nbd.cpp b/backend-nbd.cpp index 76dd01e..06356ee 100644 --- a/backend-nbd.cpp +++ b/backend-nbd.cpp @@ -243,7 +243,6 @@ bool backend_nbd::invoke_nbd(const uint32_t command, const uint64_t offset, cons bool backend_nbd::sync() { - n_syncs++; ts_last_acces = get_micros(); return invoke_nbd(NBD_CMD_FLUSH, 0, 0, nullptr); @@ -262,7 +261,6 @@ bool backend_nbd::write(const uint64_t block_nr, const uint32_t n_blocks, const unlock_range(lock_list); ts_last_acces = get_micros(); - bytes_written += n_bytes; return rc; } @@ -280,7 +278,6 @@ bool backend_nbd::trim(const uint64_t block_nr, const uint32_t n_blocks) unlock_range(lock_list); ts_last_acces = get_micros(); - n_trims += n_blocks; return rc; } @@ -299,7 +296,6 @@ bool backend_nbd::read(const uint64_t block_nr, const uint32_t n_blocks, uint8_t unlock_range(lock_list); ts_last_acces = get_micros(); - bytes_read += n_bytes; return rc; } @@ -324,7 +320,6 @@ backend::cmpwrite_result_t backend_nbd::cmpwrite(const uint64_t block_nr, const result = cmpwrite_result_t::CWR_READ_ERROR; break; } - bytes_read += block_size; // compare if (memcmp(buffer, &data_compare[i * block_size], block_size) != 0) { @@ -344,8 +339,6 @@ backend::cmpwrite_result_t backend_nbd::cmpwrite(const uint64_t block_nr, const result = cmpwrite_result_t::CWR_WRITE_ERROR; } else { - bytes_written += block_size; - ts_last_acces = get_micros(); } } diff --git a/backend.cpp b/backend.cpp index adfbb9f..a4493d9 100644 --- a/backend.cpp +++ b/backend.cpp @@ -15,19 +15,6 @@ backend::~backend() { } -void backend::get_and_reset_stats(uint64_t *const bytes_read, uint64_t *const bytes_written, uint64_t *const n_syncs, uint64_t *const n_trims) -{ - *bytes_read = this->bytes_read; - *bytes_written = this->bytes_written; - *n_syncs = this->n_syncs; - *n_trims = this->n_trims; - - this->bytes_read = 0; - this->bytes_written = 0; - this->n_syncs = 0; - this->n_trims = 0; -} - std::pair backend::get_idle_state() { return { ts_last_acces, 500000 }; diff --git a/backend.h b/backend.h index 9bf2ec8..ef7f3c9 100644 --- a/backend.h +++ b/backend.h @@ -20,11 +20,6 @@ class backend { protected: const std::string identifier; - - uint64_t bytes_read { 0 }; - uint64_t bytes_written { 0 }; - uint64_t n_syncs { 0 }; - uint64_t n_trims { 0 }; uint64_t ts_last_acces { 0 }; #if !(defined(ARDUINO) || defined(TEENSY4_1) || defined(RP2040W)) @@ -51,8 +46,6 @@ class backend virtual bool sync() = 0; - void get_and_reset_stats(uint64_t *const bytes_read, uint64_t *const bytes_written, uint64_t *const n_syncs, uint64_t *const n_trims); - enum cmpwrite_result_t { CWR_OK, CWR_MISMATCH, CWR_READ_ERROR, CWR_WRITE_ERROR }; virtual bool write (const uint64_t block_nr, const uint32_t n_blocks, const uint8_t *const data) = 0; diff --git a/gen.h b/gen.h index cf4666e..1da8a99 100644 --- a/gen.h +++ b/gen.h @@ -12,3 +12,32 @@ struct data_descriptor { uint64_t lba; uint32_t n_sectors; }; + +struct io_stats_t { + uint64_t n_reads { 0 }; + uint64_t bytes_read { 0 }; + uint64_t n_writes { 0 }; + uint64_t bytes_written { 0 }; + uint64_t n_syncs { 0 }; + uint64_t blocks_trimmed { 0 }; + // 1.3.6.1.4.1.2021.11.54: "The number of 'ticks' (typically 1/100s) spent waiting for IO." + // https://www.circitor.fr/Mibs/Html/U/UCD-SNMP-MIB.php#ssCpuRawWait + uint64_t io_wait { 0 }; + + io_stats_t() { + } + + uint64_t get_n_iops() const { + return n_reads + n_writes; + } + + void reset() { + n_reads = 0; + bytes_read = 0; + n_writes = 0; + bytes_written = 0; + n_syncs = 0; + blocks_trimmed = 0; + io_wait = 0; + } +}; diff --git a/iscsi-pdu.cpp b/iscsi-pdu.cpp index 0aa1371..d14ba7e 100644 --- a/iscsi-pdu.cpp +++ b/iscsi-pdu.cpp @@ -439,7 +439,7 @@ std::optional iscsi_pdu_scsi_cmd::get_response(scsi *const s DOLOG(logging::ll_debug, "iscsi_pdu_scsi_cmd::get_response", ses->get_endpoint_name(), "working on ITT %08x for LUN %" PRIu64, get_Itasktag(), lun); uint64_t iscsi_expected = get_ExpDatLen(); - auto scsi_reply = sd->send(lun, get_CDB(), 16, data); + auto scsi_reply = sd->send(ses->get_io_stats(), lun, get_CDB(), 16, data); if (scsi_reply.has_value() == false) { DOLOG(logging::ll_warning, "iscsi_pdu_scsi_cmd::get_response", ses->get_endpoint_name(), "scsi::send returned nothing"); return { }; diff --git a/main.cpp b/main.cpp index 469e6e8..4dc36c7 100644 --- a/main.cpp +++ b/main.cpp @@ -189,8 +189,7 @@ int main(int argc, char *argv[]) init_my_getrandom(); - io_stats_t ios { }; - iscsi_stats_t is { }; + iscsi_stats_t is { }; backend *b = nullptr; @@ -210,7 +209,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Failed to initialize storage backend\n"); return 1; } - scsi sd(b, trim_level, &ios); + scsi sd(b, trim_level); com_sockets c(ip_address, port, &stop); if (c.begin() == false) { @@ -234,7 +233,7 @@ int main(int argc, char *argv[]) snmp *snmp_ { nullptr }; snmp_data *snmp_data_ { nullptr }; if (use_snmp) - init_snmp(&snmp_, &snmp_data_, &ios, &is, get_diskspace, b, &cpu_usage, &ram_free_kb, &stop, snmp_port); + init_snmp(&snmp_, &snmp_data_, &is, get_diskspace, b, &cpu_usage, &ram_free_kb, &stop, snmp_port); server s(&sd, &c, &is, target_name, digest_chk); diff --git a/microcontrollers/RP2040W/backend-sdcard-rp2040w.cpp b/microcontrollers/RP2040W/backend-sdcard-rp2040w.cpp index 89ba056..f964698 100644 --- a/microcontrollers/RP2040W/backend-sdcard-rp2040w.cpp +++ b/microcontrollers/RP2040W/backend-sdcard-rp2040w.cpp @@ -91,12 +91,8 @@ backend_sdcard_rp2040w::~backend_sdcard_rp2040w() bool backend_sdcard_rp2040w::sync() { write_led(led_write, HIGH); - - n_syncs++; - if (file.sync() != FR_OK) DOLOG(logging::ll_error, "backend_sdcard_rp2040w::sync", "-", "Cannot sync data to SD-card"); - write_led(led_write, LOW); ts_last_acces = get_micros(); @@ -129,7 +125,6 @@ bool backend_sdcard_rp2040w::write(const uint64_t block_nr, const uint32_t n_blo } size_t n_bytes_to_write = n_blocks * iscsi_block_size; - bytes_written += n_bytes_to_write; bool rc = false; for(int i=0; i<5; i++) { // 5 is arbitrarily chosen @@ -165,7 +160,6 @@ bool backend_sdcard_rp2040w::trim(const uint64_t block_nr, const uint32_t n_bloc } delete [] data; ts_last_acces = get_micros(); - n_trims++; return rc; } @@ -184,7 +178,6 @@ bool backend_sdcard_rp2040w::read(const uint64_t block_nr, const uint32_t n_bloc } size_t n_bytes_to_read = n_blocks * iscsi_block_size; - bytes_read += n_bytes_to_read; bool rc = false; for(int i=0; i<5; i++) { // 5 is arbitrarily chosen @@ -232,7 +225,6 @@ backend::cmpwrite_result_t backend_sdcard_rp2040w::cmpwrite(const uint64_t block DOLOG(logging::ll_error, "backend_sdcard_rp2040w::cmpwrite", "-", "Cannot read: %d", file.error()); break; } - bytes_read += block_size; // compare if (memcmp(buffer, &data_compare[i * block_size], block_size) != 0) { @@ -255,8 +247,6 @@ backend::cmpwrite_result_t backend_sdcard_rp2040w::cmpwrite(const uint64_t block break; } - bytes_written += block_size; - ts_last_acces = get_micros(); } diff --git a/microcontrollers/RP2040W/main.ino b/microcontrollers/RP2040W/main.ino index d258033..a9f6b01 100644 --- a/microcontrollers/RP2040W/main.ino +++ b/microcontrollers/RP2040W/main.ino @@ -22,7 +22,6 @@ backend_sdcard_rp2040w *bs { nullptr }; scsi *sd { nullptr }; server *s { nullptr }; iscsi_stats_t is; -io_stats_t ios; volatile bool wifi_connected { false }; int led_green { 17 }; int led_yellow { 18 }; @@ -79,7 +78,7 @@ void setup() bs->begin(); Serial.println(F("Create SCSI instance")); - sd = new scsi(bs, 1, &ios); + sd = new scsi(bs, 1); Serial.println(F("Instantiate iSCSI server")); s = new server(sd, c, &is, "test", false); diff --git a/microcontrollers/backend-sdcard-teensy41.cpp b/microcontrollers/backend-sdcard-teensy41.cpp index c701d43..f9c4d7b 100644 --- a/microcontrollers/backend-sdcard-teensy41.cpp +++ b/microcontrollers/backend-sdcard-teensy41.cpp @@ -64,12 +64,8 @@ backend_sdcard_teensy41::~backend_sdcard_teensy41() bool backend_sdcard_teensy41::sync() { write_led(led_write, HIGH); - - n_syncs++; - if (file.sync() == false) DOLOG(logging::ll_error, "backend_sdcard_teensy41::sync", "-", "Cannot sync data to SD-card"); - write_led(led_write, LOW); ts_last_acces = get_micros(); @@ -102,7 +98,6 @@ bool backend_sdcard_teensy41::write(const uint64_t block_nr, const uint32_t n_bl } size_t n_bytes_to_write = n_blocks * iscsi_block_size; - bytes_written += n_bytes_to_write; bool rc = false; for(int i=0; i<5; i++) { // 5 is arbitrarily chosen @@ -139,7 +134,6 @@ bool backend_sdcard_teensy41::trim(const uint64_t block_nr, const uint32_t n_blo } delete [] data; ts_last_acces = get_micros(); - n_trims += n_blocks; return rc; } @@ -158,7 +152,6 @@ bool backend_sdcard_teensy41::read(const uint64_t block_nr, const uint32_t n_blo } size_t n_bytes_to_read = n_blocks * iscsi_block_size; - bytes_read += n_bytes_to_read; bool rc = false; for(int i=0; i<5; i++) { // 5 is arbitrarily chosen @@ -209,7 +202,6 @@ backend::cmpwrite_result_t backend_sdcard_teensy41::cmpwrite(const uint64_t bloc DOLOG(logging::ll_error, "backend_sdcard_teensy41::cmpwrite", "-", "Cannot read: %d", file.getError()); break; } - bytes_read += block_size; // compare if (memcmp(buffer, &data_compare[i * block_size], block_size) != 0) { @@ -233,8 +225,6 @@ backend::cmpwrite_result_t backend_sdcard_teensy41::cmpwrite(const uint64_t bloc break; } - bytes_written += block_size; - ts_last_acces = get_micros(); } diff --git a/microcontrollers/backend-sdcard.cpp b/microcontrollers/backend-sdcard.cpp index 11fe0c6..8974507 100644 --- a/microcontrollers/backend-sdcard.cpp +++ b/microcontrollers/backend-sdcard.cpp @@ -129,8 +129,6 @@ bool backend_sdcard::sync() { write_led(led_write, HIGH); - n_syncs++; - #if defined(RP2040W) mutex_enter_blocking(&serial_access_lock); #else @@ -185,11 +183,9 @@ bool backend_sdcard::write(const uint64_t block_nr, const uint32_t n_blocks, con } size_t n_bytes_to_write = n_blocks * iscsi_block_size; - bytes_written += n_bytes_to_write; - wait_for_card(); - size_t bytes_written = file.write(data, n_bytes_to_write); - bool rc = bytes_written == n_bytes_to_write; + size_t bytes_written = file.write(data, n_bytes_to_write); + bool rc = bytes_written == n_bytes_to_write; if (!rc) Serial.printf("Wrote %zu bytes instead of %zu\r\n", bytes_written, n_bytes_to_write); @@ -217,7 +213,6 @@ bool backend_sdcard::trim(const uint64_t block_nr, const uint32_t n_blocks) } delete [] data; ts_last_acces = get_micros(); - n_trims += n_blocks; return rc; } @@ -245,11 +240,8 @@ bool backend_sdcard::read(const uint64_t block_nr, const uint32_t n_blocks, uint } size_t n_bytes_to_read = n_blocks * iscsi_block_size; - bytes_read += n_bytes_to_read; - - bool rc = false; - size_t bytes_read = file.read(data, n_bytes_to_read); - rc = bytes_read == n_bytes_to_read; + size_t bytes_read = file.read(data, n_bytes_to_read); + bool rc = bytes_read == n_bytes_to_read; if (!rc) Serial.printf("Read %zu bytes instead of %zu\r\n", bytes_read, n_bytes_to_read); @@ -292,7 +284,6 @@ backend::cmpwrite_result_t backend_sdcard::cmpwrite(const uint64_t block_nr, con result = cmpwrite_result_t::CWR_READ_ERROR; break; } - bytes_read += block_size; // compare if (memcmp(buffer, &data_compare[i * block_size], block_size) != 0) { @@ -314,8 +305,6 @@ backend::cmpwrite_result_t backend_sdcard::cmpwrite(const uint64_t block_nr, con break; } - bytes_written += block_size; - ts_last_acces = get_micros(); } diff --git a/microcontrollers/main.ino b/microcontrollers/main.ino index 193be66..44171d2 100644 --- a/microcontrollers/main.ino +++ b/microcontrollers/main.ino @@ -123,7 +123,6 @@ WiFiUDP ntp_udp; NTP ntp(ntp_udp); uint32_t hundredsofasecondcounter = 0; -io_stats_t ios { }; iscsi_stats_t is { }; #if !defined(TEENSY4_1) uint64_t core0_idle = 0; @@ -394,9 +393,6 @@ void loopw(void *) ram_free_kb = get_free_heap_space() / 1024; // in kB - ios.io_wait = ios.io_wait_cur / 10000; // uS to 1/100th - ios.io_wait_cur = 0; - cu_count = 0; } } @@ -647,7 +643,7 @@ void setup() { #endif draw_status(13); - init_snmp(&snmp_, &snmp_data_, &ios, &is, get_diskspace, bs, &cpu_usage, &ram_free_kb, &stop, 161); + init_snmp(&snmp_, &snmp_data_, &is, get_diskspace, bs, &cpu_usage, &ram_free_kb, &stop, 161); draw_status(14); if (bs->begin() == false) { @@ -657,7 +653,7 @@ void setup() { } draw_status(16); - scsi_dev = new scsi(bs, trim_level, &ios); + scsi_dev = new scsi(bs, trim_level); #if !defined(TEENSY4_1) draw_status(20); diff --git a/scsi.cpp b/scsi.cpp index d94be81..c74ad29 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -57,7 +57,7 @@ const std::map scsi_a3_data { constexpr const uint8_t max_compare_and_write_block_count = 1; -scsi::scsi(backend *const b, const int trim_level, io_stats_t *const is) : b(b), trim_level(trim_level), is(is), serial(b->get_serial()) +scsi::scsi(backend *const b, const int trim_level) : b(b), trim_level(trim_level), serial(b->get_serial()) { } @@ -384,7 +384,7 @@ void get_lba_len(const uint8_t *const CDB, const cdb_size_t s, uint64_t *const l } } -scsi_response scsi::write_verify(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data, const uint8_t opcode) +scsi_response scsi::write_verify(io_stats_t *const is, const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data, const uint8_t opcode) { scsi_response response(ir_as_is); @@ -432,7 +432,7 @@ scsi_response scsi::write_verify(const std::string & identifier, const uint64_t uint32_t work_n_blocks = std::min(transfer_length, uint32_t(received_blocks)); if (received_blocks > 0) { - rc = write(lba, work_n_blocks, data.first); + rc = write(is, lba, work_n_blocks, data.first); ok = rc == scsi_rw_result::rw_ok; } @@ -441,10 +441,10 @@ scsi_response scsi::write_verify(const std::string & identifier, const uint64_t uint8_t *temp_buffer = new uint8_t[backend_block_size]; // received_blocks is rounded down above - rc = read(lba + work_n_blocks, 1, temp_buffer); + rc = read(is, lba + work_n_blocks, 1, temp_buffer); if (rc == scsi_rw_result::rw_ok) { memcpy(temp_buffer, &data.first[work_n_blocks * backend_block_size], fragment_size); - rc = write(lba + received_blocks, 1, temp_buffer); + rc = write(is, lba + received_blocks, 1, temp_buffer); } ok = rc == scsi_rw_result::rw_ok; @@ -469,7 +469,7 @@ scsi_response scsi::write_verify(const std::string & identifier, const uint64_t DOLOG(logging::ll_debug, "scsi::write_verify", identifier, "received_size == expected_size"); if (fua) - this->sync(); + this->sync(is); } else { // allow R2T packets to come in response.type = ir_r2t; @@ -546,12 +546,12 @@ scsi_response scsi::read_(const std::string & identifier, const uint64_t lun, co return response; } -scsi_response scsi::sync_cache(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data) +scsi_response scsi::sync_cache(io_stats_t *const is, const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data) { scsi_response response(ir_empty_sense); DOLOG(logging::ll_debug, "scsi::sync_cache", identifier, "SYNC CACHE 10"); - this->sync(); + this->sync(is); return response; } @@ -639,7 +639,7 @@ scsi_response scsi::report_supported_operation_codes(const std::string & identif return response; } -scsi_response scsi::compare_and_write(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data) +scsi_response scsi::compare_and_write(io_stats_t *const is, const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data) { scsi_response response(ir_as_is); @@ -664,7 +664,7 @@ scsi_response scsi::compare_and_write(const std::string & identifier, const uint response.sense_data = error_compare_and_write_count(); } else { - auto result = cmpwrite(lba, block_count, &data.first[block_count * block_size], &data.first[0]); + auto result = cmpwrite(is, lba, block_count, &data.first[block_count * block_size], &data.first[0]); if (result == scsi_rw_result::rw_ok) response.type = ir_empty_sense; @@ -748,7 +748,7 @@ scsi_response scsi::release(const std::string & identifier, const uint64_t lun, return response; } -scsi_response scsi::unmap(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data) +scsi_response scsi::unmap(io_stats_t *const is, const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data) { scsi_response response(ir_as_is); @@ -775,7 +775,7 @@ scsi_response scsi::unmap(const std::string & identifier, const uint64_t lun, co else if (transfer_length > 0) { // 0 is not an error but the backend may not handle it well DOLOG(logging::ll_debug, "scsi::unmap", identifier, "UNMAP trim LBA %" PRIu64 ", %u blocks", lba, transfer_length); - rc = trim(lba, transfer_length); + rc = trim(is, lba, transfer_length); if (rc != rw_ok) { DOLOG(logging::ll_error, "scsi::unmap", identifier, "UNMAP trim failed"); break; @@ -797,7 +797,7 @@ scsi_response scsi::unmap(const std::string & identifier, const uint64_t lun, co return response; } -scsi_response scsi::write_same(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data, const uint8_t opcode) +scsi_response scsi::write_same(io_stats_t *const is, const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data, const uint8_t opcode) { scsi_response response(ir_as_is); @@ -858,16 +858,16 @@ scsi_response scsi::write_same(const std::string & identifier, const uint64_t lu else { for(uint64_t i=lba; iget_size_in_blocks() && rc == rw_ok; i++) { rc = response.r2t.write_same_is_unmap ? - trim(i, 1) : - write(i, 1, data.first); + trim(is, i, 1) : + write(is, i, 1, data.first); } } } else { for(uint32_t i=0; i scsi::send(const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data) +std::optional scsi::send(io_stats_t *const is, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data) { assert(size >= 16); @@ -929,17 +929,17 @@ std::optional scsi::send(const uint64_t lun, const uint8_t *const else if (opcode == o_get_lba_status) response = get_lba_status(lun_identifier, lun, CDB, size, data); else if (opcode == o_write_6 || opcode == o_write_10 || opcode == o_write_verify_10 || opcode == o_write_16) - response = write_verify(lun_identifier, lun, CDB, size, data, opcode); + response = write_verify(is, lun_identifier, lun, CDB, size, data, opcode); else if (opcode == o_read_16 || opcode == o_read_10 || opcode == o_read_6) // 0x88, 0x28, 0x08 response = read_(lun_identifier, lun, CDB, size, data, opcode); else if (opcode == o_sync_cache_10) // 0x35 - response = sync_cache(lun_identifier, lun, CDB, size, data); + response = sync_cache(is, lun_identifier, lun, CDB, size, data); else if (opcode == o_report_luns) // 0xa0 response = report_luns(lun_identifier, lun, CDB, size, data); else if (opcode == o_rep_sup_oper) // 0xa3 response = report_supported_operation_codes(lun_identifier, lun, CDB, size, data); else if (opcode == o_compare_and_write) // 0x89 - response = compare_and_write(lun_identifier, lun, CDB, size, data); + response = compare_and_write(is, lun_identifier, lun, CDB, size, data); else if (opcode == o_prefetch_10 || opcode == o_prefetch_16) // 0x34 & 0x90 response = prefetch(lun_identifier, lun, CDB, size, data, opcode); else if (opcode == o_reserve_6) @@ -947,9 +947,9 @@ std::optional scsi::send(const uint64_t lun, const uint8_t *const else if (opcode == o_release_6) response = release(lun_identifier, lun, CDB, size, data); else if (opcode == o_unmap) - response = unmap(lun_identifier, lun, CDB, size, data); + response = unmap(is, lun_identifier, lun, CDB, size, data); else if (opcode == o_write_same_10 || opcode == o_write_same_16) // 0x41 & 0x93 - response = write_same(lun_identifier, lun, CDB, size, data, opcode); + response = write_same(is, lun_identifier, lun, CDB, size, data, opcode); else { DOLOG(logging::ll_warning, "scsi::send", lun_identifier, "opcode %02xh not implemented", opcode); response.sense_data = error_not_implemented(); @@ -1026,24 +1026,20 @@ uint64_t scsi::get_block_size() const return b->get_block_size(); } -scsi::scsi_rw_result scsi::sync() +scsi::scsi_rw_result scsi::sync(io_stats_t *const is) { if (locking_status() != l_locked_other) { // locked by myself or not locked? - auto start = get_micros(); - bool result = b->sync(); - is->io_wait_cur += get_micros() - start; + auto start = get_micros(); + bool result = b->sync(); + is->n_syncs++; + is->io_wait += get_micros() - start; return result ? rw_ok : rw_fail_general; } return rw_fail_locked; } -void scsi::get_and_reset_stats(uint64_t *const bytes_read, uint64_t *const bytes_written, uint64_t *const n_syncs, uint64_t *const n_trims) -{ - return b->get_and_reset_stats(bytes_read, bytes_written, n_syncs, n_trims); -} - -scsi::scsi_rw_result scsi::write(const uint64_t block_nr, const uint32_t n_blocks, const uint8_t *const data) +scsi::scsi_rw_result scsi::write(io_stats_t *const is, const uint64_t block_nr, const uint32_t n_blocks, const uint8_t *const data) { is->n_writes++; is->bytes_written += n_blocks * b->get_block_size(); @@ -1072,7 +1068,7 @@ scsi::scsi_rw_result scsi::write(const uint64_t block_nr, const uint32_t n_block result = b->write(block_nr, n_blocks, data); } - is->io_wait_cur += get_micros() - start; + is->io_wait += get_micros() - start; return result ? rw_ok : rw_fail_general; } @@ -1080,27 +1076,29 @@ scsi::scsi_rw_result scsi::write(const uint64_t block_nr, const uint32_t n_block return rw_fail_locked; } -scsi::scsi_rw_result scsi::trim(const uint64_t block_nr, const uint32_t n_blocks) +scsi::scsi_rw_result scsi::trim(io_stats_t *const is, const uint64_t block_nr, const uint32_t n_blocks) { if (locking_status() != l_locked_other) { // locked by myself or not locked? + is->blocks_trimmed += n_blocks; + auto start = get_micros(); if (trim_level == 0) { // 0 = do not trim/unmap scsi::scsi_rw_result rc = rw_ok; uint8_t *zero = new uint8_t[get_block_size()](); for(uint32_t i=0; iio_wait_cur += get_micros() - start; + is->io_wait += get_micros() - start; return rc; } else { - bool result = b->trim(block_nr, n_blocks); - is->io_wait_cur += get_micros() - start; + bool result = b->trim(block_nr, n_blocks); + is->io_wait += get_micros() - start; if (result) return rw_ok; } @@ -1111,22 +1109,22 @@ scsi::scsi_rw_result scsi::trim(const uint64_t block_nr, const uint32_t n_blocks return rw_fail_locked; } -scsi::scsi_rw_result scsi::read(const uint64_t block_nr, const uint32_t n_blocks, uint8_t *const data) +scsi::scsi_rw_result scsi::read(io_stats_t *const is, const uint64_t block_nr, const uint32_t n_blocks, uint8_t *const data) { is->n_reads++; is->bytes_read += n_blocks * b->get_block_size(); if (locking_status() != l_locked_other) { // locked by myself or not locked? - auto start = get_micros(); - bool result = b->read(block_nr, n_blocks, data); - is->io_wait_cur += get_micros() - start; + auto start = get_micros(); + bool result = b->read(block_nr, n_blocks, data); + is->io_wait += get_micros() - start; return result ? rw_ok : rw_fail_general; } return rw_fail_locked; } -scsi::scsi_rw_result scsi::cmpwrite(const uint64_t block_nr, const uint32_t n_blocks, const uint8_t *const write_data, const uint8_t *const compare_data) +scsi::scsi_rw_result scsi::cmpwrite(io_stats_t *const is, const uint64_t block_nr, const uint32_t n_blocks, const uint8_t *const write_data, const uint8_t *const compare_data) { is->n_reads++; is->n_writes++; @@ -1134,10 +1132,10 @@ scsi::scsi_rw_result scsi::cmpwrite(const uint64_t block_nr, const uint32_t n_bl is->bytes_written += n_blocks * b->get_block_size(); if (locking_status() != l_locked_other) { - auto start = get_micros(); - auto result = b->cmpwrite(block_nr, n_blocks, write_data, compare_data); + auto start = get_micros(); + auto result = b->cmpwrite(block_nr, n_blocks, write_data, compare_data); - is->io_wait_cur += get_micros() - start; + is->io_wait += get_micros() - start; if (result == backend::cmpwrite_result_t::CWR_OK) return rw_ok; diff --git a/scsi.h b/scsi.h index 7d54432..77ea79a 100644 --- a/scsi.h +++ b/scsi.h @@ -13,17 +13,6 @@ #include "iscsi-pdu.h" -typedef struct { - uint64_t n_reads; - uint64_t bytes_read; - uint64_t n_writes; - uint64_t bytes_written; - // 1.3.6.1.4.1.2021.11.54: "The number of 'ticks' (typically 1/100s) spent waiting for IO." - // https://www.circitor.fr/Mibs/Html/U/UCD-SNMP-MIB.php#ssCpuRawWait - uint32_t io_wait; // will be updated once per second - uint64_t io_wait_cur; // work, in microseconds! -} io_stats_t; - struct scsi_response { iscsi_reacion_t type; @@ -62,7 +51,6 @@ class scsi private: backend *const b { nullptr }; const int trim_level { 1 }; - io_stats_t *const is { nullptr }; std::string serial; #if !defined(ARDUINO) && !defined(NDEBUG) std::atomic_uint64_t cmd_use_count[256] { }; @@ -78,23 +66,23 @@ class scsi scsi_response inquiry(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); scsi_response read_capacity_10(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); scsi_response get_lba_status(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); - scsi_response write_verify(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data, const uint8_t opcode); + scsi_response write_verify(io_stats_t *const is, const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data, const uint8_t opcode); scsi_response read_(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data, const uint8_t opcode); - scsi_response sync_cache(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); + scsi_response sync_cache(io_stats_t *const is, const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); scsi_response report_luns(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); scsi_response report_supported_operation_codes(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); - scsi_response compare_and_write(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); + scsi_response compare_and_write(io_stats_t *const is, const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); scsi_response prefetch(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data, const uint8_t opcode); scsi_response reserve(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); scsi_response release(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); - scsi_response unmap(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); - scsi_response write_same(const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data, const uint8_t opcode); + scsi_response unmap(io_stats_t *const is, const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); + scsi_response write_same(io_stats_t *const is, const std::string & identifier, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data, const uint8_t opcode); std::optional > validate_request(const uint64_t lba, const uint32_t n_blocks, const uint8_t *const CDB) const; std::optional > validate_request(const uint64_t lba) const; public: - scsi(backend *const b, const int trim_level, io_stats_t *const is); + scsi(backend *const b, const int trim_level); virtual ~scsi(); enum scsi_opcode { @@ -142,19 +130,17 @@ class scsi uint64_t get_size_in_blocks() const; uint64_t get_block_size() const; - void get_and_reset_stats(uint64_t *const bytes_read, uint64_t *const bytes_written, uint64_t *const n_syncs, uint64_t *const n_trims); - scsi_lock_status reserve_device(); bool unlock_device(); scsi_lock_status locking_status(); - scsi_rw_result sync(); - scsi_rw_result write (const uint64_t block_nr, const uint32_t n_blocks, const uint8_t *const data); - scsi_rw_result trim (const uint64_t block_nr, const uint32_t n_blocks); - scsi_rw_result read (const uint64_t block_nr, const uint32_t n_blocks, uint8_t *const data); - scsi_rw_result cmpwrite(const uint64_t block_nr, const uint32_t n_blocks, const uint8_t *const write_data, const uint8_t *const compare_data); + scsi_rw_result sync (io_stats_t *const is); + scsi_rw_result write (io_stats_t *const is, const uint64_t block_nr, const uint32_t n_blocks, const uint8_t *const data); + scsi_rw_result trim (io_stats_t *const is, const uint64_t block_nr, const uint32_t n_blocks); + scsi_rw_result read (io_stats_t *const is, const uint64_t block_nr, const uint32_t n_blocks, uint8_t *const data); + scsi_rw_result cmpwrite(io_stats_t *const is, const uint64_t block_nr, const uint32_t n_blocks, const uint8_t *const write_data, const uint8_t *const compare_data); - std::optional send(const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); + std::optional send(io_stats_t *const is, const uint64_t lun, const uint8_t *const CDB, const size_t size, std::pair data); std::vector error_reservation_conflict_1() const; std::vector error_reservation_conflict_2() const; diff --git a/server.cpp b/server.cpp index 353c3b6..a1a6049 100644 --- a/server.cpp +++ b/server.cpp @@ -307,18 +307,18 @@ iscsi_fail_reason server::push_response(com_client *const cc, session *const ses uint32_t n_blocks = session->bytes_left / block_size; if (session->write_same_is_unmap) { - rc = s->trim(session->buffer_lba, n_blocks); + rc = s->trim(ses->get_io_stats(), session->buffer_lba, n_blocks); } else { for(uint32_t i=0; iwrite(lba + i, 1, data.value().first); + rc = s->write(ses->get_io_stats(), lba + i, 1, data.value().first); if (rc != scsi::rw_ok) break; } } } else { - rc = s->write(lba, data.value().second / block_size, data.value().first); + rc = s->write(ses->get_io_stats(), lba, data.value().second / block_size, data.value().first); } if (rc != scsi::rw_ok) { @@ -327,7 +327,7 @@ iscsi_fail_reason server::push_response(com_client *const cc, session *const ses } if (session->fua) { - if (s->sync() == false) { + if (s->sync(ses->get_io_stats()) == false) { DOLOG(logging::ll_error, "server::push_response", cc->get_endpoint_name(), "DATA-OUT problem syncing data"); return IFR_IO_ERROR; } @@ -487,13 +487,13 @@ iscsi_fail_reason server::push_response(com_client *const cc, session *const ses if (current_n < s->get_block_size()) { uint8_t *temp_buffer = new uint8_t[s->get_block_size()]; - rc = s->read(current_lba, 1, temp_buffer); + rc = s->read(ses->get_io_stats(), current_lba, 1, temp_buffer); if (rc == scsi::rw_ok) memcpy(data_pointer, temp_buffer, current_n); delete [] temp_buffer; } else { - rc = s->read(current_lba, is_n_blocks, data_pointer); + rc = s->read(ses->get_io_stats(), current_lba, is_n_blocks, data_pointer); } if (rc != scsi::rw_ok) { @@ -565,13 +565,13 @@ void server::handler() #else DOLOG(logging::ll_info, "server::handler", "-", "new session with %s", endpoint.c_str()); #endif - auto prev_output = get_millis(); - unsigned long busy = 0; - const long interval = 5000; - session *ses = nullptr; - bool ok = true; - int fail_counter = 0; - auto block_size = s->get_block_size(); + auto prev_output = get_millis(); + unsigned long busy = 0; + constexpr long interval = 5000; + session *ses = nullptr; + bool ok = true; + int fail_counter = 0; + auto block_size = s->get_block_size(); do { #if defined(LED_BUILTIN) && defined(ARDUINO) @@ -652,6 +652,8 @@ void server::handler() if (ifr == IFR_OK) fail_counter = 0; else { + ses->inc_error_count(); + fail_counter++; if (fail_counter >= 16) { ok = false; @@ -672,22 +674,27 @@ void server::handler() auto took = now - prev_output; if (took >= interval) { prev_output = now; - double dtook = took / 1000.; - double dkB = dtook * 1024; - uint64_t bytes_read = 0; - uint64_t bytes_written = 0; - uint64_t n_syncs = 0; - uint64_t n_trims = 0; - s->get_and_reset_stats(&bytes_read, &bytes_written, &n_syncs, &n_trims); -#if defined(ARDUINO) - Serial.printf("%.3f] PDU/s: %.2f, send: %.2f kB/s, recv: %.2f kB/s, written: %.2f kB/s, read: %.2f kB/s, syncs: %.2f/s, unmaps: %.2f MB/s, load: %.2f%%, mem: %" PRIu32 "\r\n", now / 1000., ses->get_pdu_count() / dtook, ses->get_bytes_tx() / dkB, ses->get_bytes_rx() / dkB, bytes_written / dkB, bytes_read / dkB, n_syncs / dtook, n_trims * block_size / 1024 / 1024 / dtook, busy * 0.1 / took, get_free_heap_space()); -#else - DOLOG(logging::ll_info, "server::handler", endpoint, "PDU/s: %.2f, send: %.2f kB/s, recv: %.2f kB/s, written: %.2f kB/s, read: %.2f kB/s, syncs: %.2f/s, unmaps: %.2f kB/s, load: %.2f%%", ses->get_pdu_count() / dtook, ses->get_bytes_tx() / dkB, ses->get_bytes_rx() / dkB, bytes_written / dkB, bytes_read / dkB, n_syncs / dtook, n_trims * block_size / 1024 / 1024 / dtook, busy * 0.1 / took); -#endif + double dtook = took / 1000.; + double dkB = dtook * 1024; + const io_stats_t *const is = ses->get_io_stats(); + + DOLOG(logging::ll_info, "server::handler", endpoint, + "PDU/s: %.2f, IOPS: %.2f " + "send: %.2f kB/s, recv: %.2f kB/s, " + "written: %.2f kB/s, read: %.2f kB/s, " + "syncs: %.2f/s, unmapped: %.2f kB/s, " + "load: %.2f%%, errors: %u, mem: %u", + ses->get_pdu_count() / dtook, is->get_n_iops() / dtook, + ses->get_bytes_tx() / dkB, ses->get_bytes_rx() / dkB, + is->bytes_written / dkB, is->bytes_read / dkB, + is->n_syncs / dtook, is->blocks_trimmed * block_size / 1024 / 1024 / dtook, + busy * 0.1 / took, ses->get_error_count(), get_free_heap_space()); + ses->reset_pdu_count(); ses->reset_bytes_rx(); ses->reset_bytes_tx(); - busy = 0; + ses->reset_io_stats(); + busy = 0; } #if defined(LED_BUILTIN) && defined(ARDUINO) @@ -701,7 +708,7 @@ void server::handler() DOLOG(logging::ll_debug, "server::handler", endpoint, "session finished"); #endif - s->sync(); + s->sync(ses->get_io_stats()); if (s->locking_status() == scsi::l_locked) { DOLOG(logging::ll_debug, "server::handler", endpoint, "unlocking device"); s->unlock_device(); diff --git a/session.h b/session.h index 8cffcb1..1120401 100644 --- a/session.h +++ b/session.h @@ -4,6 +4,7 @@ #include #include "com.h" +#include "gen.h" #include "iscsi.h" @@ -19,9 +20,11 @@ class session uint32_t block_size { 0 }; struct { - uint64_t bytes_rx { 0 }; - uint64_t bytes_tx { 0 }; - uint32_t pdu_count { 0 }; + uint64_t bytes_rx { 0 }; + uint64_t bytes_tx { 0 }; + uint32_t pdu_count { 0 }; + unsigned error_count { 0 }; + io_stats_t is; } statistics; uint32_t max_seg_len { MAX_DATA_SEGMENT_SIZE }; @@ -50,15 +53,19 @@ class session void set_max_seg_len(const uint32_t v) { max_seg_len = v; } uint32_t get_max_seg_len() const { return max_seg_len; } - void add_bytes_rx(const uint64_t n) { statistics.bytes_rx += n; } - uint64_t get_bytes_rx() const { return statistics.bytes_rx; } - void reset_bytes_rx() { statistics.bytes_rx = 0; } - void add_bytes_tx(const uint64_t n) { statistics.bytes_tx += n; } - uint64_t get_bytes_tx() const { return statistics.bytes_tx; } - void reset_bytes_tx() { statistics.bytes_tx = 0; } - void inc_pdu_count() { statistics.pdu_count++; } - uint32_t get_pdu_count() const { return statistics.pdu_count; } - void reset_pdu_count() { statistics.pdu_count = 0; } + void add_bytes_rx(const uint64_t n) { statistics.bytes_rx += n; } + uint64_t get_bytes_rx() const { return statistics.bytes_rx; } + void reset_bytes_rx() { statistics.bytes_rx = 0; } + void add_bytes_tx(const uint64_t n) { statistics.bytes_tx += n; } + uint64_t get_bytes_tx() const { return statistics.bytes_tx; } + void reset_bytes_tx() { statistics.bytes_tx = 0; } + void inc_pdu_count() { statistics.pdu_count++; } + uint32_t get_pdu_count() const { return statistics.pdu_count; } + void reset_pdu_count() { statistics.pdu_count = 0; } + io_stats_t *get_io_stats() { return &statistics.is; } + void reset_io_stats() { statistics.is.reset(); } + void inc_error_count() { statistics.error_count++; } + unsigned get_error_count() const { return statistics.error_count; } uint32_t get_inc_datasn(const uint32_t itt); diff --git a/snmp.cpp b/snmp.cpp index 37574ca..fee25c0 100644 --- a/snmp.cpp +++ b/snmp.cpp @@ -7,7 +7,7 @@ #include "snmp/snmp.h" -void init_snmp(snmp **const snmp_, snmp_data **const snmp_data_, io_stats_t *const ios, iscsi_stats_t *const is, std::function get_percentage_diskspace, void *const gpd_context, int *const cpu_usage, int *const ram_free_kb, std::atomic_bool *const stop, const int port) +void init_snmp(snmp **const snmp_, snmp_data **const snmp_data_, iscsi_stats_t *const is, std::function get_percentage_diskspace, void *const gpd_context, int *const cpu_usage, int *const ram_free_kb, std::atomic_bool *const stop, const int port) { *snmp_data_ = new snmp_data(); (*snmp_data_)->register_oid("1.3.6.1.2.1.1.1.0", "iESP" ); @@ -26,7 +26,6 @@ void init_snmp(snmp **const snmp_, snmp_data **const snmp_data_, io_stats_t *con (*snmp_data_)->register_oid("1.3.6.1.2.1.142.1.10.2.1.1", new snmp_data_type_stats(snmp_integer::snmp_integer_type::si_counter32, &is->iscsiSsnCmdPDUs)); (*snmp_data_)->register_oid("1.3.6.1.2.1.142.1.10.2.1.3", new snmp_data_type_stats(snmp_integer::snmp_integer_type::si_counter64, &is->iscsiSsnTxDataOctets)); (*snmp_data_)->register_oid("1.3.6.1.2.1.142.1.10.2.1.4", new snmp_data_type_stats(snmp_integer::snmp_integer_type::si_counter64, &is->iscsiSsnRxDataOctets)); - (*snmp_data_)->register_oid("1.3.6.1.4.1.2021.11.54", new snmp_data_type_stats_uint32_t(&ios->io_wait)); (*snmp_data_)->register_oid("1.3.6.1.4.1.2021.13.15.1.1.2", "iESP" ); (*snmp_data_)->register_oid("1.3.6.1.4.1.2021.100.1", snmp_integer::snmp_integer_type::si_integer, 1); #if defined(ARDUINO) @@ -34,10 +33,6 @@ void init_snmp(snmp **const snmp_, snmp_data **const snmp_data_, io_stats_t *con #endif (*snmp_data_)->register_oid("1.3.6.1.4.1.2021.100.3", __DATE__); - (*snmp_data_)->register_oid("1.3.6.1.4.1.2021.13.15.1.1.3", new snmp_data_type_stats(snmp_integer::snmp_integer_type::si_counter64, &ios->bytes_read )); - (*snmp_data_)->register_oid("1.3.6.1.4.1.2021.13.15.1.1.4", new snmp_data_type_stats(snmp_integer::snmp_integer_type::si_counter64, &ios->bytes_written)); - (*snmp_data_)->register_oid("1.3.6.1.4.1.2021.13.15.1.1.5", new snmp_data_type_stats(snmp_integer::snmp_integer_type::si_counter64, &ios->n_reads )); - (*snmp_data_)->register_oid("1.3.6.1.4.1.2021.13.15.1.1.6", new snmp_data_type_stats(snmp_integer::snmp_integer_type::si_counter64, &ios->n_writes )); (*snmp_data_)->register_oid("1.3.6.1.4.1.2021.4.11.0", new snmp_data_type_stats_int(ram_free_kb)); (*snmp_data_)->register_oid("1.3.6.1.4.1.2021.9.1.9.1", new snmp_data_type_stats_int_callback(get_percentage_diskspace, gpd_context)); (*snmp_data_)->register_oid("1.3.6.1.4.1.2021.11.9.0", new snmp_data_type_stats_int(cpu_usage)); diff --git a/snmp.h b/snmp.h index e566358..3e26531 100644 --- a/snmp.h +++ b/snmp.h @@ -2,4 +2,4 @@ #include "snmp/snmp.h" -void init_snmp(snmp **const snmp_, snmp_data **const snmp_data_, io_stats_t *const ios, iscsi_stats_t *const is, std::function percentage_diskspace, void *const gpd_context, int *const cpu_usage, int *const ram_free_kb, std::atomic_bool *const stop, const int port); +void init_snmp(snmp **const snmp_, snmp_data **const snmp_data_, iscsi_stats_t *const is, std::function percentage_diskspace, void *const gpd_context, int *const cpu_usage, int *const ram_free_kb, std::atomic_bool *const stop, const int port); diff --git a/todo b/todo index 62d8319..6aa73a3 100644 --- a/todo +++ b/todo @@ -7,6 +7,8 @@ - teensy4.1: get rid of retry-loop in sd-card code +- io-wait: 100ths of a second, once a second + - in libiscsi test-set: [SKIPPED] Not an iSCSI device. Skipping test [SKIPPED] Not an iSCSI device. Skipping test