Go on z/OS - Group home

IBM Go1.22 syscall package update

  

Introduction:

A list of new system callable services was added to IBM go1.22 syscall package. This aim is to provide more capability to port Golang applications into z/OS system as well as provide a more Unix-like interface for the Go syscall package.

 

Preparation:

To illustrate the benefits of Go1.22, let’s look at an example to compare the difference between Go1.21 and Go1.22 for porting a utility called paxrat

Download paxrat from github (https://github.com/subgraph/paxrat.git). 

[~/demo]git clone https://github.com/subgraph/paxrat.git
Cloning into 'paxrat'...
remote: Enumerating objects: 222, done.
remote: Total 222 (delta 0), reused 0 (delta 0), pack-reused 222
Receiving objects: 100% (222/222), 73.76 KiB | 14.75 MiB/s, done.
Resolving deltas: 100% (110/110), done.

The paxrat package relies on another package called subgraph/inotify. However, Go cannot find it because it's not installed on the system. To address this, we'll use Go modules to manage the dependency.

[~/demo]cd paxrat/
[~/demo/paxrat]go build -o paxrat.exe paxrat.go
paxrat.go:24:2: no required module provides package github.com/subgraph/inotify: go.mod file not found in current directory or any parent directory; see 'go help modules'
[~/demo/paxrat]
[~/demo/paxrat]
[~/demo/paxrat]go mod init github.com/paxrat
go: creating new go.mod: module github.com/paxrat
go: to add module requirements and sums:
        go mod tidy
[~/demo/paxrat]go mod tidy
go: finding module for package github.com/subgraph/inotify
go: downloading github.com/subgraph/inotify v0.0.1
go: found github.com/subgraph/inotify in github.com/subgraph/inotify v0.0.1
[~/demo/paxrat]
[~/demo/paxrat]
[~/demo/paxrat]go build -o paxrat.exe paxrat.go
package command-line-arguments
        imports github.com/subgraph/inotify: build constraints exclude all Go files in /home/me/go/pkg/mod/github.com/subgraph/inotify@v0.0.1

I encounter an error message "build constraints exclude all Go files" during the build process often indicates an incompatibility with the target operating system. In this case, building the subgraph/inotify package fails on z/OS due to a lack of official support.

Fortunately, there's a valuable tool within z/OS Open Tools known as Wharf. Wharf is designed specifically to facilitate the seamless porting of third-party Go projects to z/OS. Wharf utilizes Go's workspace technology, which requires creating a workspace in the package's parent directory.

[~/demo]go work init ./paxrat
[~/demo]
[~/demo]wharf ./paxrat
Build errors occurred in: github.com/paxrat
github.com/subgraph/inotify v0.0.1 (IMPORTED)
# github.com/subgraph/inotify
Applying tags to match platform(s): linux
inotify_linux.go: added zos tag
Backed up workspace to /home/zhilong/demo/go.work.backup
Patches applied successfully!

Note: to port paxrat using Wharf, Go version 1.22 or higher is required.

[~/demo]wharf ./paxrat/
Build errors occurred in: github.com/paxrat
Package require manual porting: github.com/subgraph/inotify
        no applicable options available to port package github.com/subgraph/inotify
github.com/subgraph/inotify v0.0.1 (LOCKED)
Backed up workspace to /home/me/demo/go.work.backup
Patches applied successfully!

Using an older version of Go will result in a compilation error, as Wharf cannot find a valid build.

Building:

Now using Go1.21 to build the package causes a compilation error

[~/demo]go version
go version go1.21.7 zos/s390x
[~/demo]go build -o paxrat.exe ./paxrat
# github.com/subgraph/inotify
inotify/inotify_zos.go:252:34: undefined: syscall.IN_DONT_FOLLOW
inotify/inotify_zos.go:253:34: undefined: syscall.IN_ONESHOT
inotify/inotify_zos.go:254:34: undefined: syscall.IN_ONLYDIR
inotify/inotify_zos.go:261:36: undefined: syscall.IN_ACCESS
inotify/inotify_zos.go:262:36: undefined: syscall.IN_ALL_EVENTS
inotify/inotify_zos.go:263:36: undefined: syscall.IN_ATTRIB
inotify/inotify_zos.go:264:36: undefined: syscall.IN_CLOSE
inotify/inotify_zos.go:265:36: undefined: syscall.IN_CLOSE_NOWRITE
inotify/inotify_zos.go:266:36: undefined: syscall.IN_CLOSE_WRITE
inotify/inotify_zos.go:267:36: undefined: syscall.IN_CREATE
inotify/inotify_zos.go:267:36: too many errors

Using Go1.22 to build the package 

[~/demo]go version
go version go1.22.0 zos/s390x
[~/demo]go build -o paxrat.exe ./paxrat
[~/demo]
[~/demo]
[~/demo]ls
go.mod      go.work     inotify     paxrat      paxrat.exe

syscall.Syscall

Go 1.22 enables the capability to handle the syscall.Syscall interface like Linux. 

An example to showcase the benefit of the Go 1.22 update is https://github.com/HouzuoGuo/tiedot

Preparation:

Let's download tiedot and try to build it. Before we proceed, we need to ensure it's properly set up as a Go module.

[~/demo]git clone https://github.com/HouzuoGuo/tiedot.git
Cloning into 'tiedot'...
remote: Enumerating objects: 5494, done.
remote: Counting objects: 100% (30/30), done.
remote: Compressing objects: 100% (26/26), done.
remote: Total 5494 (delta 7), reused 15 (delta 4), pack-reused 5464
Receiving objects: 100% (5494/5494), 7.36 MiB | 22.24 MiB/s, done.
Resolving deltas: 100% (3254/3254), done.
[~/demo]cd tiedot/
[~/demo/tiedot]go mod init github.com/HouzuoGuo/tiedot
go: creating new go.mod: module github.com/HouzuoGuo/tiedot
go: to add module requirements and sums:
        go mod tidy
[~/demo/tiedot]go mod tidy
go: finding module for package github.com/dgrijalva/jwt-go/request
go: finding module for package github.com/dgrijalva/jwt-go
go: downloading github.com/dgrijalva/jwt-go v3.2.0+incompatible
go: found github.com/dgrijalva/jwt-go in github.com/dgrijalva/jwt-go v3.2.0+incompatible
go: found github.com/dgrijalva/jwt-go/request in github.com/dgrijalva/jwt-go v3.2.0+incompatible
[~/demo/tiedot]
[~/demo/tiedot]go build -o tiedot .
# github.com/HouzuoGuo/tiedot/gommap
gommap/mmap.go:40:9: undefined: mmap
gommap/mmap.go:55:9: undefined: unmap

The compiler gives us a compilation error because it cannot find the mmap and unmap functions. We can try using Wharf.

[~/demo]go work init tiedot/
[~/demo]
[~/demo]wharf ./tiedot/
Build errors occurred in: github.com/HouzuoGuo/tiedot/gommap
# github.com/HouzuoGuo/tiedot/gommap
Applying tags to match platform(s): linux, openbsd, freebsd, netbsd, darwin
mmap_unix.go: added zos tag
Backed up workspace to /home/me/demo/go.work.backup
Patches applied successfully!

Now, we have finished porting tiedot.

Note: to port tiedot using Wharf, Go version 1.22 or higher is required.

Building:

Using Go1.21

Go1.21 lacks of Syscall interface in the syscall package, so it unable to build the package

[~/demo]go version
go version go1.21.7 zos/s390x
[~/demo]go build -o tiedot.exe ./tiedot
# github.com/HouzuoGuo/tiedot/gommap
tiedot/gommap/mmap_unix.go:18:25: undefined: syscall.Syscall

Using Go1.22

The support for the syscall.Syscall interface enables tiedot to be compiled and run on z/OS systems.

[~/demo]go version
go version go1.22.0 zos/s390x
[~/demo]go build -o tiedot.exe ./tiedot/
[~/demo]ls
go.work     tiedot      tiedot.exe

Conclusion:

Go1.22 enhances the capability for porting packages. It provides Linux-like syscall.Syscall interfaces. This interface provides access to system callable services, which are essential for interacting with the operating system's functionalities.

Note: 

The functions within the paxrat and tiedot packages haven't been thoroughly tested on z/OS systems. This may lead to unexpected behavior or issues when running the packages on z/OS. Please proceed with caution and consider conducting further testing specific to your environment.