From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id ACFD360F7D for ; Fri, 4 Sep 2020 10:52:55 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 9CC991E7C4 for ; Fri, 4 Sep 2020 10:52:25 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 067CF1E7B7 for ; Fri, 4 Sep 2020 10:52:25 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id CA29E44A22 for ; Fri, 4 Sep 2020 10:52:24 +0200 (CEST) Date: Fri, 4 Sep 2020 10:51:41 +0200 (CEST) From: Dietmar Maurer To: Dominik Csapak , Proxmox Backup Server development discussion Message-ID: <357142033.732.1599209502454@webmail.proxmox.com> In-Reply-To: References: <20200903093935.18536-1-d.csapak@proxmox.com> <2037251149.686.1599129383852@webmail.proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Priority: 3 Importance: Normal X-Mailer: Open-Xchange Mailer v7.10.3-Rev21 X-Originating-Client: open-xchange-appsuite X-SPAM-LEVEL: Spam detection results: 0 AWL 0.105 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: Re: [pbs-devel] [PATCH proxmox-backup] server/worker_task: fix 'unknown' status for some big task logs X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Sep 2020 08:52:55 -0000 > no for two reasons: > > if the task log contains only one line (this happens, e.g. 'TASK OK') > or if the last Log line is exactly 8k long (i am not sure that could happen) > > for the first we could check if the file is < 8k long I committed a more optimized version: diff --git a/src/server/worker_task.rs b/src/server/worker_task.rs index a9e4a36..997c249 100644 --- a/src/server/worker_task.rs +++ b/src/server/worker_task.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; use std::fs::File; -use std::io::{BufRead, BufReader}; +use std::io::{Read, BufRead, BufReader}; use std::panic::UnwindSafe; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; @@ -195,8 +195,8 @@ pub fn create_task_log_dirs() -> Result<(), Error> { /// If there is not a single line with at valid datetime, we assume the /// starttime to be the endtime pub fn upid_read_status(upid: &UPID) -> Result { - let mut endtime = upid.starttime; - let mut status = TaskState::Unknown { endtime }; + + let mut status = TaskState::Unknown { endtime: upid.starttime }; let path = upid.log_path(); @@ -207,22 +207,29 @@ pub fn upid_read_status(upid: &UPID) -> Result { use std::io::SeekFrom; let _ = file.seek(SeekFrom::End(-8192)); // ignore errors - let reader = BufReader::new(file); - - for line in reader.lines() { - let line = line?; + let mut data = Vec::with_capacity(8192); + file.read_to_end(&mut data)?; - let mut iter = line.splitn(2, ": "); - if let Some(time_str) = iter.next() { - endtime = chrono::DateTime::parse_from_rfc3339(time_str) - .map_err(|err| format_err!("cannot parse '{}': {}", time_str, err))? - .timestamp(); - } else { - continue; + let last_line = { + let mut start = 0; + for pos in data.len()-1..=0 { + if data[pos] == b'\n' { + start = pos + 1; + break; + } } - match iter.next().and_then(|rest| rest.strip_prefix("TASK ")) { - None => continue, - Some(rest) => { + &data[start..] + }; + + let last_line = std::str::from_utf8(last_line) + .map_err(|err| format_err!("upid_read_status: utf8 parse failed: {}", err))?; + + let mut iter = last_line.splitn(2, ": "); + if let Some(time_str) = iter.next() { + if let Ok(endtime) = chrono::DateTime::parse_from_rfc3339(time_str) { + let endtime = endtime.timestamp(); + + if let Some(rest) = iter.next().and_then(|rest| rest.strip_prefix("TASK ")) { if let Ok(state) = TaskState::from_endtime_and_message(endtime, rest) { status = state; }