bicomsystems / go-libzfs Goto Github PK
View Code? Open in Web Editor NEWgo language link to libzfs C library
License: BSD 3-Clause "New" or "Revised" License
go language link to libzfs C library
License: BSD 3-Clause "New" or "Revised" License
When running pool.Status()
:
allPools, err := zfs.PoolOpenAll()
if err != nil {
println(err)
}
for _, pool := range allPools {
status, err := pool.Status()
if err != nil {
println(err)
}
state, err := pool.State()
if err != nil {
println(err)
}
name, err := pool.Name()
if err != nil {
println(err)
}
fmt.Printf("Pool name: %s\n", name)
fmt.Printf("Status: %s, State: %s\n", status, state)
}
zfs.PoolCloseAll(allPools)
I get this output:
ps@ubuntu-srv-zfs:~/go/src/testzfs$ ./testzfs
Pool name: tank2
Status: REMOVED_DEV, State: ACTIVE
REMOVED_DEV status seems wrong given that I have no issues with my pool:
ps@ubuntu-srv-zfs:~$ sudo zpool status -v
pool: tank2
state: ONLINE
scan: scrub repaired 0B in 9h19m with 0 errors on Sun Dec 15 09:19:05 2019
config:
NAME STATE READ WRITE CKSUM
tank2 ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
wwn-0x5000c500a42a268c ONLINE 0 0 0
wwn-0x5000c500afedf367 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
wwn-0x50014ee25e4b10c8 ONLINE 0 0 0
wwn-0x50014ee2b76f2200 ONLINE 0 0 0
errors: No known data errors
Am I doing something wrong here? I'm expecting to get Status: OK, given my understanding of the source code in zpool.go.
Type | Version/Name |
---|---|
Distribution Name | Ubuntu Server |
Distribution Version | 18.04.3 LTS |
Linux Kernel | GNU/Linux 4.15.0-72-generic |
Architecture | x86_64 |
ZFS Version | 0.7.5-1ubuntu16.6 |
SPL Version | 0.7.5-1ubuntu2 |
go-libzfs tag | v0.2.3 |
Hello! Is it possible to update for zfs-2.1.x?
# go get github.com/bicomsystems/go-libzfs
go: downloading github.com/bicomsystems/go-libzfs v0.3.5
# github.com/bicomsystems/go-libzfs
zfs.c: In function ‘dataset_rename’:
zfs.c:136:43: error: incompatible type for argument 3 of ‘zfs_rename’
return zfs_rename(dataset->zh, new_name, recur, force_unm);
^~~~~
In file included from zfs.c:5:
/usr/include/libzfs/libzfs.h:661:53: note: expected ‘renameflags_t’ {aka ‘struct renameflags’} but argument is of type ‘boolean_t’ {aka ‘enum <anonymous>’}
extern int zfs_rename(zfs_handle_t *, const char *, renameflags_t);
^~~~~~~~~~~~~
zfs.c:136:9: error: too many arguments to function ‘zfs_rename’
return zfs_rename(dataset->zh, new_name, recur, force_unm);
^~~~~~~~~~
In file included from zfs.c:5:
/usr/include/libzfs/libzfs.h:661:12: note: declared here
extern int zfs_rename(zfs_handle_t *, const char *, renameflags_t);
ZFS:
# modinfo zfs
filename: /lib/modules/5.4.17-2136.302.7.2.el8uek.x86_64/extra/zfs.ko.xz
version: 2.1.2-1
Go:
# go version
go version go1.17.6 linux/amd64
I noticed a difference between values provided by zfs.Dataset
properties and zfs.Pool
ones: basically, on ZPool instances, quantity resources like space allocated or space size are expressed as human-readable value, as opposed to what's happening with Dataset where I can get bytes values with ease.
I tried to dig deeper on the C implementation but hadn't luck: do you plan to fill this gap of properties presentation?
JFI ZPool allows to retrieve parsable values:
# zpool list -p
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
mypool 1006632960 419840 1006213120 - - 0 0 1.00 ONLINE -
Hi @fkasumovic, I've had a little bit of trouble symlinking my kernel headers into the correct directory structure and was wondering which kernel & distro have been working for you.
Thanks!
When creating a pool using go-libzfs current latest master commit + zfs 0.8 (ubuntu eoan package), there is a panic in ReloadProperties
:
panic: runtime error: index out of range
goroutine 1 [running]:
github.com/bicomsystems/go-libzfs.(*Pool).ReloadProperties(0xc0000a1538, 0x22011f0, 0x2200380)
/root/go/pkg/mod/github.com/bicomsystems/[email protected]/zpool.go:518 +0x707
github.com/bicomsystems/go-libzfs.PoolOpen(0x4cf5f8, 0x5, 0x22011f0, 0xc0000aa400, 0x20, 0x20, 0x0, 0x0, 0x0)
/root/go/pkg/mod/github.com/bicomsystems/[email protected]/zpool.go:149 +0xa8
github.com/bicomsystems/go-libzfs.PoolCreate(0x4cf5f8, 0x5, 0x4cf4a9, 0x4, 0xc000053dd0, 0x1, 0x1, 0x0, 0x0, 0x0, ...)
/root/go/pkg/mod/github.com/bicomsystems/[email protected]/zpool.go:968 +0xbb5
main.main()
/home/didrocks/work/zsys/main.go:23 +0x2cd
exit status 2
Note that running go test in the project fails similarly.
Here is a small reproducer:
package main
import (
"os"
zfs "github.com/bicomsystems/go-libzfs"
)
func main() {
p := "/tmp/tempPoolFile"
f, _ := os.Create(p)
f.Truncate(100 * 1024 * 1024)
f.Close()
vdev := zfs.VDevTree{
Type: zfs.VDevTypeFile,
Path: p,
Devices: []zfs.VDevTree{{Type: zfs.VDevTypeFile, Path: p}},
}
features := make(map[string]string)
props := make(map[zfs.Prop]string)
fsprops := make(map[zfs.Prop]string)
zfs.PoolCreate("rpool", vdev, features, props, fsprops)
}
Note that this code used to work with zfs 0.7 and v0.2.3 release.
I'm using this package to provide a sort of HTTP APIs to manage ZFS dataset.
So far so good, but we started seeing some random panic
crashes with the following stack:
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x7f76f734a1e5]
runtime stack:
runtime.throw(0xcd90ea, 0x2a)
/usr/local/go/src/runtime/panic.go:774 +0x72
runtime.sigpanic()
/usr/local/go/src/runtime/signal_unix.go:378 +0x47c
goroutine 1524 [syscall]:
runtime.cgocall(0xb12a80, 0xc000165310, 0x300000002)
/usr/local/go/src/runtime/cgocall.go:128 +0x5b fp=0xc0001652e0 sp=0xc0001652a8 pc=0x40992b
github.com/bicomsystems/go-libzfs._Cfunc_dataset_list_close(0x7f76f6fa4fe0)
_cgo_gotypes.go:483 +0x41 fp=0xc000165310 sp=0xc0001652e0 pc=0xa4f901
github.com/bicomsystems/go-libzfs.(*Dataset).Close.func1(0xc000165410)
/go/pkg/mod/github.com/bicomsystems/[email protected]/zfs.go:187 +0x5e fp=0xc000165350 sp=0xc000165310 pc=0xa5e63e
github.com/bicomsystems/go-libzfs.(*Dataset).Close(0xc000165410)
/go/pkg/mod/github.com/bicomsystems/[email protected]/zfs.go:187 +0x5d fp=0xc0001653e8 sp=0xc000165350 pc=0xa5483d
github.com/bicomsystems/go-libzfs.(*Dataset).Close(0xc000165510)
/go/pkg/mod/github.com/bicomsystems/[email protected]/zfs.go:191 +0x10b fp=0xc000165480 sp=0xc0001653e8 pc=0xa548eb
cloud.team/zfs-api/pkg/zfs/dataset.Delete(0xc0001b0736, 0x1d, 0x0, 0xc00012a1a0, 0xc00015b390, 0xcc00d0, 0xa, 0xc00049a0ae, 0xa, 0xc00003a1c0, ...)
/etc/zfs_api/pkg/zfs/dataset/delete.go:29 +0x1f2 fp=0xc000165580 sp=0xc000165480 pc=0xa67c92
cloud.team/zfs-api/pkg/webserver/v1beta1.DeleteDataset(0xc0003fa160)
/etc/zfs_api/pkg/webserver/v1beta1/delete_dataset.go:40 +0x2ef fp=0xc0001656d0 sp=0xc000165580 pc=0xa6f4ef
github.com/gin-gonic/gin.(*Context).Next(0xc0003fa160)
/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:124 +0x3b fp=0xc0001656f0 sp=0xc0001656d0 pc=0xa3a36b
cloud.team/zfs-api/pkg/webserver/utility.DatasetDeleteDefault.func1(0xc0003fa160)
/etc/zfs_api/pkg/webserver/utility/middleware.go:56 +0x118 fp=0xc000165750 sp=0xc0001656f0 pc=0xa644e8
github.com/gin-gonic/gin.(*Context).Next(0xc0003fa160)
/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:124 +0x3b fp=0xc000165770 sp=0xc000165750 pc=0xa3a36b
cloud.team/zfs-api/pkg/webserver/utility.DatasetPathByQueryString.func1(0xc0003fa160)
/etc/zfs_api/pkg/webserver/utility/middleware.go:115 +0x118 fp=0xc0001657d0 sp=0xc000165770 pc=0xa64eb8
github.com/gin-gonic/gin.(*Context).Next(0xc0003fa160)
/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:124 +0x3b fp=0xc0001657f0 sp=0xc0001657d0 pc=0xa3a36b
github.com/gin-gonic/gin.RecoveryWithWriter.func1(0xc0003fa160)
/go/pkg/mod/github.com/gin-gonic/[email protected]/recovery.go:83 +0x64 fp=0xc000165850 sp=0xc0001657f0 pc=0xa4d274
github.com/gin-gonic/gin.(*Context).Next(0xc0003fa160)
/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:124 +0x3b fp=0xc000165870 sp=0xc000165850 pc=0xa3a36b
github.com/Depado/ginprom.(*Prometheus).Instrument.func1(0xc0003fa160)
/go/pkg/mod/github.com/!depado/[email protected]/prom.go:285 +0x115 fp=0xc000165918 sp=0xc000165870 pc=0xadbaa5
github.com/gin-gonic/gin.(*Context).Next(0xc0003fa160)
/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:124 +0x3b fp=0xc000165938 sp=0xc000165918 pc=0xa3a36b
github.com/gin-gonic/gin.LoggerWithConfig.func1(0xc0003fa160)
/go/pkg/mod/github.com/gin-gonic/[email protected]/logger.go:240 +0xe1 fp=0xc000165ad8 sp=0xc000165938 pc=0xa4c321
github.com/gin-gonic/gin.(*Context).Next(0xc0003fa160)
/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:124 +0x3b fp=0xc000165af8 sp=0xc000165ad8 pc=0xa3a36b
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0000e4000, 0xc0003fa160)
/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:389 +0x5b2 fp=0xc000165be0 sp=0xc000165af8 pc=0xa438f2
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0000e4000, 0xdf83e0, 0xc00014c7e0, 0xc000248600)
/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:351 +0x134 fp=0xc000165c18 sp=0xc000165be0 pc=0xa43124
net/http.serverHandler.ServeHTTP(0xc0000160e0, 0xdf83e0, 0xc00014c7e0, 0xc000248600)
/usr/local/go/src/net/http/server.go:2802 +0xa4 fp=0xc000165c48 sp=0xc000165c18 pc=0x76d044
net/http.(*conn).serve(0xc000150fa0, 0xdfb4e0, 0xc000f254c0)
/usr/local/go/src/net/http/server.go:1890 +0x875 fp=0xc000165fc8 sp=0xc000165c48 pc=0x7688e5
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc000165fd0 sp=0xc000165fc8 pc=0x465681
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2928 +0x384
goroutine 1 [IO wait]:
internal/poll.runtime_pollWait(0x7f76f47afdd8, 0x72, 0x0)
/usr/local/go/src/runtime/netpoll.go:184 +0x55
internal/poll.(*pollDesc).wait(0xc00048c298, 0x72, 0x0, 0x0, 0xcbd32b)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Accept(0xc00048c280, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/internal/poll/fd_unix.go:384 +0x1f8
net.(*netFD).accept(0xc00048c280, 0xc0001679d8, 0x76dfd4, 0xc000016180)
/usr/local/go/src/net/fd_unix.go:238 +0x42
net.(*TCPListener).accept(0xc000414e60, 0x5ec77374, 0xc0001679d8, 0x4ca926)
/usr/local/go/src/net/tcpsock_posix.go:139 +0x32
net.(*TCPListener).Accept(0xc000414e60, 0xc000167a28, 0x18, 0xc000000180, 0x76d504)
/usr/local/go/src/net/tcpsock.go:261 +0x47
net/http.(*Server).Serve(0xc0000160e0, 0xdf8120, 0xc000414e60, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:2896 +0x280
net/http.(*Server).ListenAndServe(0xc0000160e0, 0xc0000160e0, 0xc000171c50)
/usr/local/go/src/net/http/server.go:2825 +0xb7
net/http.ListenAndServe(...)
/usr/local/go/src/net/http/server.go:3081
github.com/gin-gonic/gin.(*Engine).Run(0xc0000e4000, 0xc000171cb8, 0x1, 0x1, 0x0, 0x0)
/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:294 +0x16d
cloud.team/zfs-api/pkg/webserver.(*WebServer).Start(0xc0003f0f50)
/etc/zfs_api/pkg/webserver/webserver.go:28 +0xcf
cloud.team/zfs-api/cmd.glob..func2(0x12dc7a0, 0x1c31b48, 0x0, 0x0)
/etc/zfs_api/cmd/root.go:34 +0x166
github.com/spf13/cobra.(*Command).execute(0x12dc7a0, 0xc0000321d0, 0x0, 0x0, 0x12dc7a0, 0xc0000321d0)
/go/pkg/mod/github.com/spf13/[email protected]/command.go:830 +0x2aa
github.com/spf13/cobra.(*Command).ExecuteC(0x12dc7a0, 0x443cfa, 0x12ebaa0, 0xc000000180)
/go/pkg/mod/github.com/spf13/[email protected]/command.go:914 +0x2fb
github.com/spf13/cobra.(*Command).Execute(...)
/go/pkg/mod/github.com/spf13/[email protected]/command.go:864
cloud.team/zfs-api/cmd.Execute()
/etc/zfs_api/cmd/root.go:54 +0x31
main.main()
/etc/zfs_api/main.go:6 +0x20
goroutine 12 [IO wait, 28 minutes]:
internal/poll.runtime_pollWait(0x7f76f47afea8, 0x72, 0x0)
/usr/local/go/src/runtime/netpoll.go:184 +0x55
internal/poll.(*pollDesc).wait(0xc0004a4018, 0x72, 0x0, 0x0, 0xcbd32b)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Accept(0xc0004a4000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/internal/poll/fd_unix.go:384 +0x1f8
net.(*netFD).accept(0xc0004a4000, 0xc000075d80, 0xc000476000, 0x7f76f6dd3b28)
/usr/local/go/src/net/fd_unix.go:238 +0x42
net.(*TCPListener).accept(0xc000304000, 0xc000075db0, 0x4134c8, 0x30)
/usr/local/go/src/net/tcpsock_posix.go:139 +0x32
net.(*TCPListener).Accept(0xc000304000, 0xc46b80, 0xc0003ca180, 0xbc4760, 0x12d1f60)
/usr/local/go/src/net/tcpsock.go:261 +0x47
net/http.(*Server).Serve(0xc000018000, 0xdf8120, 0xc000304000, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:2896 +0x280
net/http.(*Server).ListenAndServe(0xc000018000, 0xc000018000, 0x0)
/usr/local/go/src/net/http/server.go:2825 +0xb7
net/http.ListenAndServe(...)
/usr/local/go/src/net/http/server.go:3081
cloud.team/zfs-api/pkg/webserver.NewWebServer.func1()
/etc/zfs_api/pkg/webserver/webserver.go:40 +0x73
created by cloud.team/zfs-api/pkg/webserver.NewWebServer
/etc/zfs_api/pkg/webserver/webserver.go:39 +0xb7
goroutine 39 [IO wait]:
internal/poll.runtime_pollWait(0x7f76f47afd08, 0x72, 0xffffffffffffffff)
/usr/local/go/src/runtime/netpoll.go:184 +0x55
internal/poll.(*pollDesc).wait(0xc000412018, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc000412000, 0xc000198000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/internal/poll/fd_unix.go:169 +0x1cf
net.(*netFD).Read(0xc000412000, 0xc000198000, 0x1000, 0x1000, 0xc00016e6c0, 0x86, 0x120)
/usr/local/go/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc00012a010, 0xc000198000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/net/net.go:184 +0x68
net/http.(*connReader).Read(0xc000386090, 0xc000198000, 0x1000, 0x1000, 0xc0004a4e80, 0x0, 0x2200000000)
/usr/local/go/src/net/http/server.go:785 +0xf4
bufio.(*Reader).fill(0xc00017a000)
/usr/local/go/src/bufio/bufio.go:100 +0x103
bufio.(*Reader).ReadSlice(0xc00017a000, 0xc0013d4c0a, 0x7f76f4aaebf8, 0xc0010259a8, 0x412c56, 0xc000248200, 0x100)
/usr/local/go/src/bufio/bufio.go:359 +0x3d
bufio.(*Reader).ReadLine(0xc00017a000, 0xc0010259b0, 0x1c14a20, 0x7f76f6dd3b28, 0x0, 0xc7c020, 0xc000291290)
/usr/local/go/src/bufio/bufio.go:388 +0x34
net/textproto.(*Reader).readLineSlice(0xc000291290, 0xc000248200, 0xc000412000, 0x0, 0x0, 0x437dec)
/usr/local/go/src/net/textproto/reader.go:57 +0x6c
net/textproto.(*Reader).ReadLine(...)
/usr/local/go/src/net/textproto/reader.go:38
net/http.readRequest(0xc00017a000, 0x0, 0xc000248200, 0x0, 0x0)
/usr/local/go/src/net/http/request.go:1012 +0x92
net/http.(*conn).readRequest(0xc0000c2b40, 0xdfb4e0, 0xc00013a000, 0x0, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:965 +0x15f
net/http.(*conn).serve(0xc0000c2b40, 0xdfb4e0, 0xc00013a000)
/usr/local/go/src/net/http/server.go:1817 +0x6d4
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2928 +0x384
goroutine 44 [IO wait]:
internal/poll.runtime_pollWait(0x7f76f47afb68, 0x72, 0xffffffffffffffff)
/usr/local/go/src/runtime/netpoll.go:184 +0x55
internal/poll.(*pollDesc).wait(0xc00048c818, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc00048c800, 0xc00021f000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/internal/poll/fd_unix.go:169 +0x1cf
net.(*netFD).Read(0xc00048c800, 0xc00021f000, 0x1000, 0x1000, 0xc000e54370, 0x87, 0xb0)
/usr/local/go/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc00012a068, 0xc00021f000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/net/net.go:184 +0x68
net/http.(*connReader).Read(0xc00031aa50, 0xc00021f000, 0x1000, 0x1000, 0x48227c, 0x12d4f80, 0x22000000b0)
/usr/local/go/src/net/http/server.go:785 +0xf4
bufio.(*Reader).fill(0xc000042d80)
/usr/local/go/src/bufio/bufio.go:100 +0x103
bufio.(*Reader).ReadSlice(0xc000042d80, 0xa, 0x7f76f6ddc6e0, 0xc0001699a8, 0x412c56, 0xc0000c4900, 0x100)
/usr/local/go/src/bufio/bufio.go:359 +0x3d
bufio.(*Reader).ReadLine(0xc000042d80, 0xc0001699b0, 0xc000096700, 0x7f76f6dd2008, 0x0, 0x0, 0xc0001699f0)
/usr/local/go/src/bufio/bufio.go:388 +0x34
net/textproto.(*Reader).readLineSlice(0xc0003a0db0, 0xc0000c4900, 0xc00048c800, 0x0, 0x0, 0x437dec)
/usr/local/go/src/net/textproto/reader.go:57 +0x6c
net/textproto.(*Reader).ReadLine(...)
/usr/local/go/src/net/textproto/reader.go:38
net/http.readRequest(0xc000042d80, 0x0, 0xc0000c4900, 0x0, 0x0)
/usr/local/go/src/net/http/request.go:1012 +0x92
net/http.(*conn).readRequest(0xc000366000, 0xdfb4e0, 0xc00013a240, 0x0, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:965 +0x15f
net/http.(*conn).serve(0xc000366000, 0xdfb4e0, 0xc00013a240)
/usr/local/go/src/net/http/server.go:1817 +0x6d4
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2928 +0x384
goroutine 1024 [IO wait, 2 minutes]:
internal/poll.runtime_pollWait(0x7f76f47af9c8, 0x72, 0xffffffffffffffff)
/usr/local/go/src/runtime/netpoll.go:184 +0x55
internal/poll.(*pollDesc).wait(0xc00034a998, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc00034a980, 0xc000f18000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/internal/poll/fd_unix.go:169 +0x1cf
net.(*netFD).Read(0xc00034a980, 0xc000f18000, 0x1000, 0x1000, 0x0, 0x3030320000000000, 0xed6596a22)
/usr/local/go/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc000010030, 0xc000f18000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/net/net.go:184 +0x68
net/http.(*connReader).Read(0xc00012c450, 0xc000f18000, 0x1000, 0x1000, 0xc00008c640, 0x12e38a8, 0x2)
/usr/local/go/src/net/http/server.go:785 +0xf4
bufio.(*Reader).fill(0xc0013f4480)
/usr/local/go/src/bufio/bufio.go:100 +0x103
bufio.(*Reader).ReadSlice(0xc0013f4480, 0xa, 0xc001029b28, 0xc0010299a8, 0x412c56, 0xc00046c400, 0x100)
/usr/local/go/src/bufio/bufio.go:359 +0x3d
bufio.(*Reader).ReadLine(0xc0013f4480, 0xc0010299b0, 0xc0000e9180, 0x7f76f6dd3b28, 0x0, 0x4, 0xc0010299f0)
/usr/local/go/src/bufio/bufio.go:388 +0x34
net/textproto.(*Reader).readLineSlice(0xc000409c80, 0xc00046c400, 0xc00034a980, 0x0, 0x0, 0x437dec)
/usr/local/go/src/net/textproto/reader.go:57 +0x6c
net/textproto.(*Reader).ReadLine(...)
/usr/local/go/src/net/textproto/reader.go:38
net/http.readRequest(0xc0013f4480, 0x0, 0xc00046c400, 0x0, 0x0)
/usr/local/go/src/net/http/request.go:1012 +0x92
net/http.(*conn).readRequest(0xc0000c3720, 0xdfb4e0, 0xc00013a340, 0x0, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:965 +0x15f
net/http.(*conn).serve(0xc0000c3720, 0xdfb4e0, 0xc00013a340)
/usr/local/go/src/net/http/server.go:1817 +0x6d4
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2928 +0x384
goroutine 1394 [IO wait, 2 minutes]:
internal/poll.runtime_pollWait(0x7f76f47afc38, 0x72, 0xffffffffffffffff)
/usr/local/go/src/runtime/netpoll.go:184 +0x55
internal/poll.(*pollDesc).wait(0xc000413b98, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc000413b80, 0xc000da8000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/internal/poll/fd_unix.go:169 +0x1cf
net.(*netFD).Read(0xc000413b80, 0xc000da8000, 0x1000, 0x1000, 0x0, 0x3030320000000000, 0xed6596a1f)
/usr/local/go/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc000010b20, 0xc000da8000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/net/net.go:184 +0x68
net/http.(*connReader).Read(0xc0001cdbc0, 0xc000da8000, 0x1000, 0x1000, 0xc001358240, 0x12e38a8, 0x2)
/usr/local/go/src/net/http/server.go:785 +0xf4
bufio.(*Reader).fill(0xc00017a4e0)
/usr/local/go/src/bufio/bufio.go:100 +0x103
bufio.(*Reader).ReadSlice(0xc00017a4e0, 0xa, 0xc001023b28, 0xc0010239a8, 0x412c56, 0xc000248800, 0x100)
/usr/local/go/src/bufio/bufio.go:359 +0x3d
bufio.(*Reader).ReadLine(0xc00017a4e0, 0xc0010239b0, 0xc0000e9180, 0x7f76f6dd3460, 0x0, 0x3, 0xc0010239f0)
/usr/local/go/src/bufio/bufio.go:388 +0x34
net/textproto.(*Reader).readLineSlice(0xc00024f920, 0xc000248800, 0xc000413b80, 0x0, 0x0, 0x437dec)
/usr/local/go/src/net/textproto/reader.go:57 +0x6c
net/textproto.(*Reader).ReadLine(...)
/usr/local/go/src/net/textproto/reader.go:38
net/http.readRequest(0xc00017a4e0, 0x0, 0xc000248800, 0x0, 0x0)
/usr/local/go/src/net/http/request.go:1012 +0x92
net/http.(*conn).readRequest(0xc0003668c0, 0xdfb4e0, 0xc000f25900, 0x0, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:965 +0x15f
net/http.(*conn).serve(0xc0003668c0, 0xdfb4e0, 0xc000f25900)
/usr/local/go/src/net/http/server.go:1817 +0x6d4
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2928 +0x384
goroutine 1525 [IO wait]:
internal/poll.runtime_pollWait(0x7f76f47afa98, 0x72, 0xffffffffffffffff)
/usr/local/go/src/runtime/netpoll.go:184 +0x55
internal/poll.(*pollDesc).wait(0xc0004a5498, 0x72, 0x0, 0x1, 0xffffffffffffffff)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/go/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc0004a5480, 0xc0002ddd51, 0x1, 0x1, 0x0, 0x0, 0x0)
/usr/local/go/src/internal/poll/fd_unix.go:169 +0x1cf
net.(*netFD).Read(0xc0004a5480, 0xc0002ddd51, 0x1, 0x1, 0xc000f25458, 0xc00041e768, 0x48007c)
/usr/local/go/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc0001ec138, 0xc0002ddd51, 0x1, 0x1, 0x0, 0x0, 0x0)
/usr/local/go/src/net/net.go:184 +0x68
net/http.(*connReader).backgroundRead(0xc0002ddd40)
/usr/local/go/src/net/http/server.go:677 +0x58
created by net/http.(*connReader).startBackgroundRead
/usr/local/go/src/net/http/server.go:673 +0xd4
Just providing the pkg/zfs/dataset/delete.go
content for getting aligned with the stack trace:
func Delete(pool string, dataset schemas.Dataset, mode schemas.DatasetDestroyMode) errors.Error {
ds, dsErr := zfs.DatasetOpen(NewName(pool, dataset.Path, nil).String())
if dsErr != nil {
return errors.ComposeError(dsErr)
}
defer ds.Close()
// A dataset mounted cannot be deleted unless it's not mounted,
// so we replicate the same behavior of zfs destroy, or unmounting
// and deleting.
if ok, _ := ds.IsMounted(); ok {
if err := mount(&ds, false); err != nil {
return errors.ComposeError(err)
}
}
err := zfsapi.Destroy(ds, mode)
if err != nil {
return errors.ComposeError(err) # <<< delete.go:29
}
return nil
}
func ComposeError(err error) Error {
if strings.Contains(err.Error(), "no such pool") {
return NewPoolNotFound(err)
}
if strings.Contains(err.Error(), "dataset does not exist") {
return NewDatasetNotFound(err)
}
if err.Error() == "dataset already exists" {
return NewDatasetConflict(err)
}
return NewGenericError(err)
}
As you can see, the panic starts at delete.go:29
but I guess it's the deferred function ds.Close()
.
This might be related to cmosetick's issue, or it may not:
$ go get github.com/bicomsystems/go-libzfs
# github.com/bicomsystems/go-libzfs
could not determine kind of name for C.boolean_t
could not determine kind of name for C.clear_last_error
could not determine kind of name for C.libzfs_errno
could not determine kind of name for C.libzfs_error_description
could not determine kind of name for C.libzfs_handle_ptr
could not determine kind of name for C.libzfs_init
and in cloned git repo:
$ go test
# github.com/bicomsystems/go-libzfs
could not determine kind of name for C.boolean_t
could not determine kind of name for C.clear_last_error
could not determine kind of name for C.libzfs_errno
could not determine kind of name for C.libzfs_error_description
could not determine kind of name for C.libzfs_handle_ptr
could not determine kind of name for C.libzfs_init
FAIL github.com/bicomsystems/go-libzfs [build failed]
My system:
Fedora 24, kernel 4.10.11
go-1.6.4 (can't downgrade via package management system to 1.4, so probably not the way to go)
zfs-0.7.0-rc3 and libzfs2 installed and source dir linked to gopath
Am I missing something? Or might something not work with newest versions of some softwares?
Just tried go get
with this on go 1.6:
go get github.com/bicomsystems/go-libzfs
# github.com/bicomsystems/go-libzfs
src/gocode/src/github.com/bicomsystems/go-libzfs/common.go:16:10: fatal error: 'libzfs.h' file not found
#include <libzfs.h>
^
1 error generated.
Platform
OS X 10.11.3
go version go1.6 darwin/amd64
Open ZFS version:
brew cask info openzfs
$ openzfs: 1.4.5
Used to determine whether the pool scrub has stopped
Hello, when I run zpool status
I see
root@pve-1:~# zpool status -v
pool: data
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
data ONLINE 0 0 0
scsi-35002538e402d9b06 ONLINE 0 0 0
scsi-350025388a05aeb61 ONLINE 0 0 0
When I call call pool.Status()
I see "state: ACTIVE".
func check() error {
globalPools, err := zfs.PoolOpenAll()
defer zfs.PoolCloseAll(globalPools)
if err != nil {
return err
}
for _, pool := range globalPools {
state, err := pool.State()
if err != nil {
return err
}
fmt.Println("pool state:", state)
}
return nil
}
pool state: ACTIVE
I would expect to see pool state "ONLINE", not "ACTIVE". Am I doing this incorrectly?
I have a project that depends on go-libzfs. I am currently refreshing it, and was hoping to build against the latest openzfs but I seem to get some errors:
Step 10/14 : RUN GOOS=linux GOARCH=amd64 go test ./...
---> Running in d1570b2a8acc
...
/root/go/pkg/mod/github.com/bicomsystems/[email protected]/zpool.go:1108:39: could not determine kind of name for C.pool_initialize_func_t
/root/go/pkg/mod/github.com/bicomsystems/[email protected]/zpool.go:1108:5: could not determine kind of name for C.zpool_initialize
I can build against an older version, but am wondering if 2.0 is on the roadmap? If contributors are needed, please let me know. I am not at all experienced with C but I do have plenty of Go experience and access to systems running OpenZFS on Linux and FreeBSD. I am happy to deploy test systems.
The zpool status
command returns not only the status code, but also some fairly standard text describing the issue and recovery options.
Would you consider including those texts as const string
in the library, so that a consumer of the library using pool.Status()
can have those strings? I would be happy to open a PR for it.
The strings are all here.
Granted, this is a library and not a CLI, which would need to report those, but the strings are useful for anyone building on this.
[.]# go get github.com/bicomsystems/go-libzfs
# github.com/bicomsystems/go-libzfs
../../../bicomsystems/go-libzfs/zpool.go:245:13: could not determine kind of name for C.zpool_errata_t
I get this error when trying to build on illumos (SmartOS more specifically) using go 1.9
Hello
libzfs had a change recently in the API.
zpool_get_prop now requires an additional boolean_t Could you update to the newest version of libzfs?
libzfs is explicitly not a stable interface; libzfs_core (formerly libzfs2) is intended to provide one when it is complete. The zfs(1M)
and zpool(1M)
userspace tools actually have a stability commitment.
In file included from zpool.c:7:
/usr/include/libzfs/libzutil.h:93:43: note: expected ‘libpc_handle_t *’ {aka ‘struct libpc_handle *’} but argument is of type ‘libzfs_handle_ptr’ {aka ‘struct libzfs_handle *’}
93 | _LIBZUTIL_H nvlist_t *zpool_search_import(libpc_handle_t *, importargs_t *);
| ^~~~~~~~~~~~~~~~
zpool.c:513:17: error: too many arguments to function ‘zpool_search_import’
513 | pools = zpool_search_import(zfsh, &idata, &libzfs_config_ops);
| ^~~~~~~~~~~~~~~~~~~
/usr/include/libzfs/libzutil.h:93:23: note: declared here
93 | _LIBZUTIL_H nvlist_t *zpool_search_import(libpc_handle_t *, importargs_t *);
| ^~~~~~~~~~~~~~~~~~~
make: *** [Makefile:23: bin/kr-fs] Error 1
Hi,
I am thinking about a solution how to set User Dataset Properties through this api (https://pthree.org/2013/01/02/zfs-administration-part-xvi-getting-and-setting-properties/).
Do you have any idea?
I have some changes developed to get go-libzfs compiling against the latest libzfs from OpenZFS 2.2.2 and I'd like to work towards getting these changes upstreamed into here if possible. Currently I have changes which apply to both master and v0.4.0. Can I have some help getting in contact with someone who can give me some recommended next steps on a process or should I just go directly towards submitting PRs?
Appreciate the help, thanks.
Upstream change: openzfs/zfs@e89f1295d#diff-bee8007a3f41acd4ba285b312ea24cc4L432
I'm just trying to run one of the example functions and it hangs on the zfs.DatasetOpenAll() call. Am I missing something?
package main
import (
"fmt"
"github.com/bicomsystems/go-libzfs"
)
func ExampleDatasetOpenAll() {
fmt.Printf("hello\n");
datasets, err := zfs.DatasetOpenAll()
if err != nil {
fmt.Printf("aaaaaaaaaaaaa\n");
panic(err.Error())
}
fmt.Printf("bbbbbbbbbbbbbb\n");
defer zfs.DatasetCloseAll(datasets)
// Print out path and type of root datasets
for _, d := range datasets {
path, err := d.Path()
if err != nil {
panic(err.Error())
}
p, err := d.GetProperty(zfs.DatasetPropType)
if err != nil {
panic(err.Error())
}
fmt.Printf("%30s | %10s\n", path, p.Value)
}
}
func main() {
ExampleDatasetOpenAll();
}
Output:
hello
And program hangs there...
Go version: 1.17.1 linux/amd64
Ubuntu 20.04
$ go get github.com/bicomsystems/go-libzfs
# github.com/bicomsystems/go-libzfs
zfs.c: In function ‘dataset_rename’:
zfs.c:136:2: error: unknown type name ‘renameflags_t’; did you mean ‘recvflags_t’?
136 | renameflags_t flags = {recur,nounmount,force_unm};
| ^~~~~~~~~~~~~
| recvflags_t
zfs.c:136:31: warning: excess elements in scalar initializer
136 | renameflags_t flags = {recur,nounmount,force_unm};
| ^~~~~~~~~
zfs.c:136:31: note: (near initialization for ‘flags’)
zfs.c:136:41: warning: excess elements in scalar initializer
136 | renameflags_t flags = {recur,nounmount,force_unm};
| ^~~~~~~~~
zfs.c:136:41: note: (near initialization for ‘flags’)
zfs.c:137:9: error: too few arguments to function ‘zfs_rename’
137 | return zfs_rename(dataset->zh, new_name, flags);
| ^~~~~~~~~~
In file included from zfs.c:5:
/usr/include/libzfs/libzfs.h:626:12: note: declared here
626 | extern int zfs_rename(zfs_handle_t *, const char *, boolean_t, boolean_t);
|
hoping someone has run into this or knows what's up. Thanks.
Hello, What is the relationship between the go-libzfs version and openZFS version? Thanks!
For a test suite we create a zpool and a set of dataset. Since the test suite runs several tests with similar layouts, a new pool is created for each test in a separate directory and a dataset created on this new pool.
If the name of the dataset is the same across the tests, it uses the wrong pool even if the pool doesn't exist anymore.
A workaround is to name the pool differently for each test.
The test case below demonstrates this behaviour by creating in a loop different zpools and the same dataset name on the zpool.
The output of the run is:
Iteration 1
PoolCreate guid: 7919659312967739317
PoolOpen guid: 7919659312967739317
dataset GUID:5048587912320756274
pool from dataset guid: 7919659312967739317
before datasetclose
before export
before close
Iteration 2
PoolCreate guid: 13613222439384922873
PoolOpen guid: 13613222439384922873
dataset GUID:14116188184690862102
pool from dataset guid: 7919659312967739317
before datasetclose
before export
before close
Iteration 3
PoolCreate guid: 8252255210940518902
PoolOpen guid: 8252255210940518902
dataset GUID:14785461561331967018
pool from dataset guid: 7919659312967739317
before datasetclose
before export
before close
It shows that the GUID of the zpool is different on each iteration but the GUID of the zpool of the newly created dataset is always the value of the first zpool that have been created.
package main
import (
"fmt"
"log"
"os"
"path/filepath"
zfs "github.com/bicomsystems/go-libzfs"
)
const mB = 1024 * 1024
func main() {
for _, i := range []string{"1", "2", "3"} {
func() {
fmt.Printf("Iteration %s\n", i)
p := "/tmp/testzfs" + i + "/disk" + "." + i
if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
log.Fatalf("can't create destination directory for: %q: %v", p, err)
}
f, err := os.Create(p)
if err != nil {
log.Fatal("couldn't create device file on disk", err)
}
if err = f.Truncate(100 * mB); err != nil {
f.Close()
log.Fatal("couldn't initializing device size on disk", err)
}
f.Close()
vdev := zfs.VDevTree{
Type: zfs.VDevTypeFile,
Path: p,
Devices: []zfs.VDevTree{{Type: zfs.VDevTypeFile, Path: p}},
}
features := make(map[string]string)
props := make(map[zfs.Prop]string)
fsprops := make(map[zfs.Prop]string)
pool, err := zfs.PoolCreate("rpool", vdev, features, props, fsprops)
if err != nil {
log.Fatal("couldn't create pool", err)
}
defer pool.Close()
defer fmt.Println("before close")
defer pool.Export(true, "blabla")
defer fmt.Println("before export")
val, _ := pool.GetProperty(zfs.PoolPropGUID)
fmt.Println("PoolCreate guid:", val.Value)
pool1, err := zfs.PoolOpen("rpool")
if err != nil {
log.Fatal("Error:", err)
}
val, _ = pool1.GetProperty(zfs.PoolPropGUID)
fmt.Println("PoolOpen guid:", val.Value)
dprops := make(map[zfs.Prop]zfs.Property)
d, err := zfs.DatasetCreate("rpool/first", zfs.DatasetTypeFilesystem, dprops)
if err != nil {
log.Fatal("couldn't create dataset", err)
}
defer d.Close()
defer fmt.Println("before datasetclose")
val, _ = d.GetProperty(zfs.DatasetPropGUID)
fmt.Println("dataset GUID:" + val.Value)
pool2, err := d.Pool()
if err != nil {
fmt.Println(err)
}
val, _ = pool2.GetProperty(zfs.PoolPropGUID)
fmt.Println("pool from dataset guid:", val.Value)
}()
}
}
This is tested on Ubuntu Eoan (development releases) with zfs-linux 0.7.12-1ubuntu5 also tested with 0.7.13 from debian and 0.8 from upstream. The result is the same.
https://gist.github.com/mikroskeem/ffbb3b15fb074f5c71bec33e24f35857
Using Arch Linux, ZFS 0.8.2, Go 1.13.4 and Linux 5.3.10
Error:
# github.com/bicomsystems/go-libzfs
In file included from root/go/src/github.com/bicomsystems/go-libzfs/common.go:18:0:
./zpool.h:82:1: error: unknown type name '__uint64_t'
__uint64_t set_zpool_vdev_online(zpool_list_t *pool, const char *path, int flags);
^~~~~~~~~~
Reproduce with:
docker run -ti --rm alpine sh
apk --no-cache add go git gcc musl-dev zfs-dev
go get -u github.com/bicomsystems/go-libzfs
It looks like Pool.VDevTree() always returns a VDevTree with every element of Stat.Ops and Stat.Bytes set to zero, though the other members of the structure are set correctly. Running zpool iostat shows that there is in fact activity on my zpools.
Hello! I cannot delete dataset, both ds.Destroy and ds.DestroyRecursive returns "dataset is busy", however I can delete it with "zfs destroy"
zfs-2.1.0
What am I missing?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.