djberg96 / sys-proctable

A cross-platform Ruby interface for gathering process information on your operating system
Apache License 2.0
150 stars 33 forks source link

Solaris 11.4: Errno::EBADF (Bad file number) #105

Closed rwaffen closed 1 year ago

rwaffen commented 2 years ago

i run in the following error and dont know what to do. did i do something wrong?

irb(main):004:0> ProcTable.ps { |process| pp process.comm }
Traceback (most recent call last):
        8: from /opt/puppetlabs/puppet/bin/irb:11:in `<main>'
        7: from (irb):4
        6: from /opt/puppetlabs/puppet/lib/ruby/gems/2.5.0/gems/sys-proctable-1.2.6/lib/sunos/sys/proctable.rb:248:in `ps'
        5: from /opt/puppetlabs/puppet/lib/ruby/gems/2.5.0/gems/sys-proctable-1.2.6/lib/sunos/sys/proctable.rb:248:in `foreach'
        4: from /opt/puppetlabs/puppet/lib/ruby/gems/2.5.0/gems/sys-proctable-1.2.6/lib/sunos/sys/proctable.rb:316:in `block in ps'
        3: from /opt/puppetlabs/puppet/lib/ruby/gems/2.5.0/gems/sys-proctable-1.2.6/lib/sunos/sys/proctable.rb:316:in `open'
        2: from /opt/puppetlabs/puppet/lib/ruby/gems/2.5.0/gems/sys-proctable-1.2.6/lib/sunos/sys/proctable.rb:334:in `block (2 levels) in ps'
        1: from /opt/puppetlabs/puppet/lib/ruby/gems/2.5.0/gems/sys-proctable-1.2.6/lib/sunos/sys/proctable.rb:334:in `sysread'
Errno::EBADF (Bad file number)

some code runs on a linux vm without problems.

Environment

root@solaris11:~# /opt/puppetlabs/puppet/bin/ruby -v
ruby 2.5.9p229 (2021-04-05 revision 67939) [i386-solaris2.11]

root@solaris11:~# facter os
{
  architecture => "i86pc",
  family => "Solaris",
  hardware => "i86pc",
  name => "Solaris",
  release => {
    full => "11.4",
    major => "11",
    minor => "4"
  }
}

How to reproduce:

vagrant solaris 11.4 with puppet for ruby 2.5.x

Vagrant.configure("2") do |config|
  config.vm.define "solaris" do |solaris|
    solaris.vm.box = "rbrunckhorst/solaris11.4"
    solaris.vm.box_version = "1.1"
    solaris.vm.synced_folder ".", "/vagrant"

    $solaris_script = <<-SCRIPT
      wget -nv "https://pm.puppetlabs.com/puppet-agent/2019.8.12/6.28.0/repos/solaris/11/puppet6/puppet-agent@6.28.0,5.11-1.i386.p5p"
      pkg install -g file:///export/home/vagrant/puppet-agent\@6.28.0\,5.11-1.i386.p5p pkg:/puppet-agent

      echo "alias ll='ls -la --color=auto'" >> /root/.profile
      echo 'export PATH="$PATH:/opt/puppetlabs/bin:/opt/puppetlabs/puppet/bin"' >> /root/.profile
    SCRIPT

    solaris.vm.provision :shell, inline: $solaris_script
  end
end
vagrant ssh solaris
sudo -i
/opt/puppetlabs/puppet/bin/gem install sys-proctable
/opt/puppetlabs/puppet/bin/irb
# irb > require 'sys/proctable'
# irb > include Sys
# irb > ProcTable.ps { |process| pp process.comm }
djberg96 commented 2 years ago

Looking at that line, it seems I already rescue Errno::EACCES, Errno::EOVERFLOW, EOFError, and RangeError but not Errno::EBADF. That error could mean that the file isn't available for reading by the time the loop actually gets to it.

You can modify the line at 346 to include Errno::EBADF. Temporarily add a debug print in the rescue block if you want to see which file it is.

djberg96 commented 2 years ago

Oops, didn't mean to close it, hit the wrong button.

rwaffen commented 2 years ago

when i add something like this

        rescue Errno::EACCES, Errno::EOVERFLOW, EOFError, RangeError
          # Skip this if we don't have proper permissions, if there's
          # no associated environment, or if there's a largefile issue.
        rescue Errno::EBADF
          puts "file not readable #{file}"
        rescue Errno::ENOENT
          next # The process has terminated. Bail out!
        end
irb(main):003:0> ProcTable.ps { |process| pp process.comm }
file not readable 0
"sched"
file not readable 5
"zpool-rpool"
file not readable 6
"kmem_task"
"init"
file not readable 2
"pageout"
file not readable 3
"fsflush"
file not readable 7
"intrd"
file not readable 8
"vmtasks"
file not readable 9
"postwaittq"
"ibmgmtd"
"svc.startd"
"svc.configd"

this are all 0 byte /proc/**/as files. so maybe check first if file is 0 byte and skip, before try reading it?

djberg96 commented 2 years ago

You can try wrapping that block with a if File.size(file) > 0 check, but the check itself might cause an Errno::EBADF, you'll have to experiment.

rwaffen commented 2 years ago

okay, i will try this out and then come back with a PR

djberg96 commented 1 year ago

@rwaffen Looking back at your Vagrant file, what version of Ruby was it using?

rwaffen commented 1 year ago

the ruby from puppet 6.28.0

root@solaris11:~# /opt/puppetlabs/puppet/bin/ruby -v
ruby 2.5.9p229 (2021-04-05 revision 67939) [i386-solaris2.11]