stanislav-tkach / os_info

Rust library to detect the operating system type
MIT License
175 stars 52 forks source link

Pull in NetBSD SUpport #279

Closed martintc closed 3 years ago

martintc commented 3 years ago

Pull in the boiler plate code that Kraileth started.

stanislav-tkach commented 3 years ago

Thanks for the pull request and sorry for the lack of a timely response!

travispaul commented 3 years ago

Awesome, just forked this repo to add NetBSD, and was happy to see it implemented since I last tried it.

@stanislav-tkach would you be able to cut a new release for this in the near future? Thanks!

stanislav-tkach commented 3 years ago

@travispaul Thanks for the interest to this project! I have just published the 3.0.8 version.

travispaul commented 3 years ago

Thanks @stanislav-tkach !

kraileth commented 2 years ago

@travispaul While os_info is now able to detect NetBSD as the OS as well as the version, it cannot yet detect the bitness. For what I needed this is sufficient. However it would certainly be nice if NetBSD support was actually complete. Since you wrote that you thought about adding NetBSD support - would you by any chance happen to have an idea to implement bitness detection, too?

If yes I can offer to test it on i386 (old machines without long mode support), aarch64 and sparc64.

martintc commented 2 years ago

I think the only thing needed to support for bigness is implementing the proper CLI calls. So to get bit easier of FreeBSD and dragonfly, it just calls for system information from a command line utility with flags to just kickback the architecture option. I tried finding a more platform independent way, but that didn't pan out. So to do it on NetBSD, you just have to implement the call to the command line utility NetBSD uses. If no one can get to this, I can implement this probably next week as my exams will be over.

Edit: I think the only thing needed to support for bitness is implementing the proper CLI calls. So to get the bitness of FreeBSD and dragonfly, it just calls for system information from a command line utility with flags to just kickback the architecture option. I tried finding a more platform independent way, but that didn't pan out. So to do it on NetBSD, you just have to implement the call to the command line utility NetBSD uses. If no one can get to this, I can implement this probably next week as my exams will be over.

I wrote the response during a break at lunch on my phone and did not do to well of a job proof reading. So above is some correction for clarification.

travispaul commented 2 years ago

@kraileth I didn't need bitness so I didn't worry about it.

I'm not aware of a good way to determine bitness by invoking a command (since getconf doesn't have LONG_BIT) everything that comes to mind is either hacky or wouldn't work in all situations. Might be worthwhile to ping the #NetBSD IRC channel to see if anyone has a suggestion.

martintc commented 2 years ago

@kraileth I didn't need bitness so I didn't worry about it.

I'm not aware of a good way to determine bitness by invoking a command (since getconf doesn't have LONG_BIT) everything that comes to mind is either hacky or wouldn't work in all situations. Might be worthwhile to ping the #NetBSD IRC channel to see if anyone has a suggestion.

My plan was to utilize sysctl. Sysctl has a field called "hw.marchine" that will display whether it is i386 or amd64, which will give the bitness.

travispaul commented 2 years ago

Ah ok, I was hoping a lookup/match be avoided but unless there's another option you might want to use hw.machine_arch since arm devices use evbarm for both 32 and 64 bit. For example, in my lab here I have:

Rust Target hw.machine hw.machine_arch Bitness Note
armv7-unknown-netbsd-eabihf evbarm earmv7hf 32 Beaglebone Black
aarch64-unknown-netbsd evbarm aarch64 64 Pineboard A64+

I don't have an i386 machine but based on ./build.sh list-arch that would work there too:

./build.sh list-arch
...
MACHINE=amd64           MACHINE_ARCH=x86_64
...
MACHINE=i386            MACHINE_ARCH=i386
...
MACHINE=evbarm          MACHINE_ARCH=earmv7hf   ALIAS=evbearmv7hf-el    ALIAS=evbarmv7hf-el
...
MACHINE=evbarm          MACHINE_ARCH=aarch64    ALIAS=evbarm64-el       ALIAS=evbarm64 DEFAULT
...
martintc commented 2 years ago

I wrote a little something up during lunch break. Have not tested it, hope to test it tonight. If you want to give it a shot: here is the branch: https://github.com/martintc/os_info/tree/NetBSD-Bitness-Support

Hope I will get to test it tonight, but got lots with school and my test machine is busy crunching away on some large tasks playing around with ravenports.

It currently only supports amd64, i386 and aarch64, if it works on those, adding in new architectures would be easy.

martintc commented 2 years ago

Ah ok, I was hoping a lookup/match be avoided but unless there's another option you might want to use hw.machine_arch since arm devices use evbarm for both 32 and 64 bit. For example, in my lab here I have: Rust Target hw.machine hw.machine_arch Bitness Note armv7-unknown-netbsd-eabihf evbarm earmv7hf 32 Beaglebone Black aarch64-unknown-netbsd evbarm aarch64 64 Pineboard A64+

I don't have an i386 machine but based on ./build.sh list-arch that would work there too:

./build.sh list-arch
...
MACHINE=amd64           MACHINE_ARCH=x86_64
...
MACHINE=i386            MACHINE_ARCH=i386
...
MACHINE=evbarm          MACHINE_ARCH=earmv7hf   ALIAS=evbearmv7hf-el    ALIAS=evbarmv7hf-el
...
MACHINE=evbarm          MACHINE_ARCH=aarch64    ALIAS=evbarm64-el       ALIAS=evbarm64 DEFAULT
...

Yea, I was hoping to avoid look up matching and tried to see if I could find a tricky way to get bitness at runtime. I have a closed PR where you can see I tried to do it. Ended up looking at the assembly and seeing that looking it up from the system was the only way to get the true bitness. The ways I tried worked so long as you compiled it as 32-bit and only ran it on 32-bit. But if you compiled on 32-bit, but ran it on 64-bit, it still would show as 32-bit. All of those values get hard coded into the assembly, so there was not a real good run time way other than using system utilities to look it up.

martintc commented 2 years ago

Alright, so got it testing and working. Then created a new branch and did a squash merge to clean up commits since I was using git to transfer from one machine to the next. PR is at this link: https://github.com/stanislav-tkach/os_info/pull/283

Works on my 64 bit core 2 duo machine. Only does limited architectures, but can easily add on.

travispaul commented 2 years ago

@martintc looks good to me, I tested on amd64, pine64, and beaglebone. The supported machine architectures in your PR appear to work as intended to me (I don't have an i386 machine readily available to test though.)

If you'd like your PR to include beaglebone support you could also add:

diff --git a/os_info/src/bitness.rs b/os_info/src/bitness.rs
index 4156b29..295ca85 100644
--- a/os_info/src/bitness.rs
+++ b/os_info/src/bitness.rs
@@ -51,6 +51,7 @@ pub fn get() -> Bitness {
             Ok(Output { stdout, .. }) if stdout == b"x86_64\n" => Bitness::X64,
             Ok(Output { stdout, .. }) if stdout == b"i386\n" => Bitness::X32,
             Ok(Output { stdout, .. }) if stdout == b"aarch64\n" => Bitness::X64,
+            Ok(Output { stdout, .. }) if stdout == b"earmv7hf\n" => Bitness::X32,
             _ => Bitness::Unknown,
         };
         return bitness;

Tested on the beaglebone I have here.

kraileth commented 2 years ago

Tested on pure i386. It works, too.

martintc commented 2 years ago

@martintc looks good to me, I tested on amd64, pine64, and beaglebone. The supported machine architectures in your PR appear to work as intended to me (I don't have an i386 machine readily available to test though.)

If you'd like your PR to include beaglebone support you could also add:

diff --git a/os_info/src/bitness.rs b/os_info/src/bitness.rs
index 4156b29..295ca85 100644
--- a/os_info/src/bitness.rs
+++ b/os_info/src/bitness.rs
@@ -51,6 +51,7 @@ pub fn get() -> Bitness {
             Ok(Output { stdout, .. }) if stdout == b"x86_64\n" => Bitness::X64,
             Ok(Output { stdout, .. }) if stdout == b"i386\n" => Bitness::X32,
             Ok(Output { stdout, .. }) if stdout == b"aarch64\n" => Bitness::X64,
+            Ok(Output { stdout, .. }) if stdout == b"earmv7hf\n" => Bitness::X32,
             _ => Bitness::Unknown,
         };
         return bitness;

Tested on the beaglebone I have here.

Tested on pure i386. It works, too.

Awesome!

Added in support for earmv7hf in the open PR. Down the line, I'd like to maybe try to refactor some to perhaps use a map and call that from outside bitness.rs for future readability, but we will get this landed first in main before doing that.