Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CP-47754: Do not report errors attempting to read PCI vendor:product #5451

Merged
merged 1 commit into from
Mar 4, 2024

Conversation

freddy77
Copy link
Collaborator

Different network card (like virtual ones or USB ones) do not have a vendor:product causing networkd daemon to report a lot of errors like

Error in read one line of file: /sys/class/net/eth0/device/device, exception Unix.Unix_error(Unix.ENOENT, "open", "/sys/class/net/eth0/device/device")
Raised by primitive operation at Xapi_stdext_unix__Unixext.with_file in file "lib/xapi-stdext-unix/unixext.ml", line 68, characters 11-40
Called from Xapi_stdext_unix__Unixext.buffer_of_file in file "lib/xapi-stdext-unix/unixext.ml" (inlined), line 155, characters 31-83
Called from Xapi_stdext_unix__Unixext.string_of_file in file "lib/xapi-stdext-unix/unixext.ml", line 157, characters 47-73
Called from Network_utils.Sysfs.read_one_line in file "ocaml/networkd/lib/network_utils.ml", line 156, characters 6-33

Do not report these missing file as errors.

Copy link

codecov bot commented Feb 12, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (e17089c) 49.07% compared to head (221e86e) 49.07%.
Report is 11 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #5451   +/-   ##
=======================================
  Coverage   49.07%   49.07%           
=======================================
  Files          18       18           
  Lines        2319     2319           
=======================================
  Hits         1138     1138           
  Misses       1181     1181           
Flag Coverage Δ
python2.7 53.38% <ø> (ø)
python3.11 55.85% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@@ -226,7 +226,9 @@ module Sysfs = struct
let get_pci_ids name =
let read_id_from path =
try
let l = read_one_line path in
let l =
Unixext.string_of_file path |> Astring.String.take ~sat:(( <> ) '\n')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This copies what read_one_line does, without logging on error. Another option is to add an optional argument ?(log = true) to read_one_line to control whether to log or not, so we don't need to duplicate the function.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed I'm a bit puzzled about that. I understand the change proposed. On the other side this read_one_line function is doing something "unexpected" with EINVAL error. I understand it's useful for some virtual files (like reading speed or carrier which can be read only when card is up). Potentially also that log option (OT: maybe ignore_errors should be a better name?) could be reused somewhere else but it makes the read_one_line more complicated. In different paths in the same file something different like Unixext.string_of_file path |> String.trim is used.

I was also wondering if we should only ignore some type of errors, not all. For instance EPERM or ENFILE although unlikely should be reported.

One other comment on this function is that it should return either ("<VENDOR>", "<PRODUCT>") or ("", ""), not something like ("<VENDOR>", "").

My knowledge about Ocaml tends to zero.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To ensure that last property you can move where 'try/with' is, if you move it one level up to the 'get_pci_ids' function and on error have it return "", "", it should ensure the consistency property you're looking for.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I think the (existing) code is too complicated. Reading a few words from /sys could be simpler:

@freddy77 freddy77 force-pushed the no_pci branch 2 times, most recently from 378429e to dd4076c Compare February 12, 2024 14:15
(* trim 0x *)
String.sub l 2 (String.length l - 2)
with _ -> ""
let l = Unixext.string_of_file path |> String.trim in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think let l = path |> Unixext.string_of_file |> String.trim is a bit easier to read.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have expectations towards what to find in /sys, we should not use explicit string operations to split and trim strings but I advocate using scanf.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lindig I have no idea how to implement your proposal and it looks like an additional change not having to do a lot with the problem this change is trying to fix. That code is assuming hexadecimal format like 0xHHHH but then it takes the HHHH verbatim so with scanf I suppose we would like to get the decimal number and then we'll need to format in hexadecimal again.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compare the apparatus currently employed against this:

let finally f always = Fun.protect ~finally:always f

let scanning path f =
  let io = Scanf.Scanning.open_in path in
  finally (fun () -> f io) (fun () -> Scanf.Scanning.close_in io)

scanning "/sys/class/net/wlp0s20f3/device/vendor" @@ fun io ->  Scanf.bscanf io {|%i|} (fun d -> Printf.sprintf "%x" d)

- : string = "8086"

lindig@dell:xs$ cat /sys/class/net/wlp0s20f3/device/vendor 
0x8086

This is what I mean when I say the current code is too complicated. My code reads the hex value as an integer and emits it again as hex but without a prefix. I understand that this is not the problem you are solving but we should try to make things simpler.

Copy link
Collaborator Author

@freddy77 freddy77 Feb 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lindig your proposed change is out of my reach, I understand roughly what is doing but giving my Ocaml knowledge is more complicated. Also your snippet does not address the intention of this pull request (handling missing files) but changes the file parsing using scanf+printf. However I thing you are also introducing a regressions; you are stripping leading hexadecimal digits while we want to retain them.

Can you propose a full solution addressing the device issue and the suggested scanf changes ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's merge this. I will take a look at the code independently.

Different network card (like virtual ones or USB ones) do not
have a vendor:product causing networkd daemon to report a lot
of errors like

  Error in read one line of file: /sys/class/net/eth0/device/device, exception Unix.Unix_error(Unix.ENOENT, "open", "/sys/class/net/eth0/device/device")
  Raised by primitive operation at Xapi_stdext_unix__Unixext.with_file in file "lib/xapi-stdext-unix/unixext.ml", line 68, characters 11-40
  Called from Xapi_stdext_unix__Unixext.buffer_of_file in file "lib/xapi-stdext-unix/unixext.ml" (inlined), line 155, characters 31-83
  Called from Xapi_stdext_unix__Unixext.string_of_file in file "lib/xapi-stdext-unix/unixext.ml", line 157, characters 47-73
  Called from Network_utils.Sysfs.read_one_line in file "ocaml/networkd/lib/network_utils.ml", line 156, characters 6-33

Do not report these missing file as errors.

Signed-off-by: Frediano Ziglio <frediano.ziglio@cloud.com>
@lindig
Copy link
Contributor

lindig commented Feb 13, 2024

This is related to the interface renaming problem we have seen with iptables(8) stumbling over bridge names that exceed 15 characters.

Copy link
Member

@robhoes robhoes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine, but we'll not merge it immediately.

@psafont psafont merged commit 59dd2f3 into xapi-project:master Mar 4, 2024
8 checks passed
@freddy77 freddy77 deleted the no_pci branch March 4, 2024 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants