freebsd-ports/sysutils/minikube/files/patch-third__party_go9p_ufs__freebsd.go
Danilo Egea Gondolfo 79cb9ead32 - New port: sysutils/minikube
Minikube is a tool that makes it easy to run Kubernetes locally.
Minikube runs a single-node Kubernetes cluster inside a VM on your laptop
for users looking to try out Kubernetes or develop with it day-to-day.
2018-08-11 19:25:41 +00:00

238 lines
5.5 KiB
Go

--- third_party/go9p/ufs_freebsd.go.orig 2018-08-08 17:01:39 UTC
+++ third_party/go9p/ufs_freebsd.go
@@ -0,0 +1,235 @@
+package go9p
+
+import (
+ "fmt"
+ "os"
+ "os/user"
+ "path"
+ "strconv"
+ "strings"
+ "syscall"
+ "time"
+)
+
+func atime(stat *syscall.Stat_t) time.Time {
+ return time.Unix(stat.Atimespec.Unix())
+}
+
+// IsBlock reports if the file is a block device
+func isBlock(d os.FileInfo) bool {
+ stat := d.Sys().(*syscall.Stat_t)
+ return (stat.Mode & syscall.S_IFMT) == syscall.S_IFBLK
+ return true
+}
+
+// IsChar reports if the file is a character device
+func isChar(d os.FileInfo) bool {
+ stat := d.Sys().(*syscall.Stat_t)
+ return (stat.Mode & syscall.S_IFMT) == syscall.S_IFCHR
+ return true
+}
+
+func dir2Qid(d os.FileInfo) *Qid {
+ var qid Qid
+
+ qid.Path = uint64(d.Sys().(*syscall.Stat_t).Ino)
+ qid.Version = uint32(d.ModTime().UnixNano() / 1000000)
+ qid.Type = dir2QidType(d)
+
+ return &qid
+}
+
+func dir2Dir(path string, d os.FileInfo, dotu bool, upool Users) (*Dir, error) {
+ if r := recover(); r != nil {
+ fmt.Print("stat failed: ", r)
+ return nil, &os.PathError{"dir2Dir", path, nil}
+ }
+ sysif := d.Sys()
+ if sysif == nil {
+ return nil, &os.PathError{"dir2Dir: sysif is nil", path, nil}
+ }
+ sysMode := sysif.(*syscall.Stat_t)
+
+ dir := new(ufsDir)
+ dir.Qid = *dir2Qid(d)
+ dir.Mode = dir2Npmode(d, dotu)
+ dir.Atime = uint32(0 /*atime(sysMode).Unix()*/)
+ dir.Mtime = uint32(d.ModTime().Unix())
+ dir.Length = uint64(d.Size())
+ dir.Name = path[strings.LastIndex(path, "/")+1:]
+
+ if dotu {
+ dir.dotu(path, d, upool, sysMode)
+ return &dir.Dir, nil
+ }
+
+ unixUid := int(sysMode.Uid)
+ unixGid := int(sysMode.Gid)
+ dir.Uid = strconv.Itoa(unixUid)
+ dir.Gid = strconv.Itoa(unixGid)
+
+ // BUG(akumar): LookupId will never find names for
+ // groups, as it only operates on user ids.
+ u, err := user.LookupId(dir.Uid)
+ if err == nil {
+ dir.Uid = u.Username
+ }
+ g, err := user.LookupId(dir.Gid)
+ if err == nil {
+ dir.Gid = g.Username
+ }
+
+ /* For Akaros, we use the Muid as the link value. */
+ if *Akaros && (d.Mode()&os.ModeSymlink != 0) {
+ dir.Muid, err = os.Readlink(path)
+ if err == nil {
+ dir.Mode |= DMSYMLINK
+ }
+ }
+ return &dir.Dir, nil
+}
+
+func (dir *ufsDir) dotu(path string, d os.FileInfo, upool Users, sysMode *syscall.Stat_t) {
+ u := upool.Uid2User(int(sysMode.Uid))
+ g := upool.Gid2Group(int(sysMode.Gid))
+ dir.Uid = u.Name()
+ if dir.Uid == "" {
+ dir.Uid = "none"
+ }
+
+ dir.Gid = g.Name()
+ if dir.Gid == "" {
+ dir.Gid = "none"
+ }
+ dir.Muid = "none"
+ dir.Ext = ""
+ dir.Uidnum = uint32(u.Id())
+ dir.Gidnum = uint32(g.Id())
+ dir.Muidnum = NOUID
+ if d.Mode()&os.ModeSymlink != 0 {
+ var err error
+ dir.Ext, err = os.Readlink(path)
+ if err != nil {
+ dir.Ext = ""
+ }
+ } else if isBlock(d) {
+ dir.Ext = fmt.Sprintf("b %d %d", sysMode.Rdev>>24, sysMode.Rdev&0xFFFFFF)
+ } else if isChar(d) {
+ dir.Ext = fmt.Sprintf("c %d %d", sysMode.Rdev>>24, sysMode.Rdev&0xFFFFFF)
+ }
+}
+
+func (u *Ufs) Wstat(req *SrvReq) {
+ fid := req.Fid.Aux.(*ufsFid)
+ err := fid.stat()
+ if err != nil {
+ req.RespondError(err)
+ return
+ }
+
+ dir := &req.Tc.Dir
+ if dir.Mode != 0xFFFFFFFF {
+ mode := dir.Mode & 0777
+ if req.Conn.Dotu {
+ if dir.Mode&DMSETUID > 0 {
+ mode |= syscall.S_ISUID
+ }
+ if dir.Mode&DMSETGID > 0 {
+ mode |= syscall.S_ISGID
+ }
+ }
+ e := os.Chmod(fid.path, os.FileMode(mode))
+ if e != nil {
+ req.RespondError(toError(e))
+ return
+ }
+ }
+
+ uid, gid := NOUID, NOUID
+ if req.Conn.Dotu {
+ uid = dir.Uidnum
+ gid = dir.Gidnum
+ }
+
+ // Try to find local uid, gid by name.
+ if (dir.Uid != "" || dir.Gid != "") && !req.Conn.Dotu {
+ uid, err = lookup(dir.Uid, false)
+ if err != nil {
+ req.RespondError(err)
+ return
+ }
+
+ // BUG(akumar): Lookup will never find gids
+ // corresponding to group names, because
+ // it only operates on user names.
+ gid, err = lookup(dir.Gid, true)
+ if err != nil {
+ req.RespondError(err)
+ return
+ }
+ }
+
+ if uid != NOUID || gid != NOUID {
+ e := os.Chown(fid.path, int(uid), int(gid))
+ if e != nil {
+ req.RespondError(toError(e))
+ return
+ }
+ }
+
+ if dir.Name != "" {
+ fmt.Printf("Rename %s to %s\n", fid.path, dir.Name)
+ // if first char is / it is relative to root, else relative to
+ // cwd.
+ var destpath string
+ if dir.Name[0] == '/' {
+ destpath = path.Join(u.Root, dir.Name)
+ fmt.Printf("/ results in %s\n", destpath)
+ } else {
+ fiddir, _ := path.Split(fid.path)
+ destpath = path.Join(fiddir, dir.Name)
+ fmt.Printf("rel results in %s\n", destpath)
+ }
+ err := syscall.Rename(fid.path, destpath)
+ fmt.Printf("rename %s to %s gets %v\n", fid.path, destpath, err)
+ if err != nil {
+ req.RespondError(toError(err))
+ return
+ }
+ fid.path = destpath
+ }
+
+ if dir.Length != 0xFFFFFFFFFFFFFFFF {
+ e := os.Truncate(fid.path, int64(dir.Length))
+ if e != nil {
+ req.RespondError(toError(e))
+ return
+ }
+ }
+
+ // If either mtime or atime need to be changed, then
+ // we must change both.
+ if dir.Mtime != ^uint32(0) || dir.Atime != ^uint32(0) {
+ mt, at := time.Unix(int64(dir.Mtime), 0), time.Unix(int64(dir.Atime), 0)
+ if cmt, cat := (dir.Mtime == ^uint32(0)), (dir.Atime == ^uint32(0)); cmt || cat {
+ st, e := os.Stat(fid.path)
+ if e != nil {
+ req.RespondError(toError(e))
+ return
+ }
+ switch cmt {
+ case true:
+ mt = st.ModTime()
+ default:
+ //at = time.Time(0)//atime(st.Sys().(*syscall.Stat_t))
+ }
+ }
+ e := os.Chtimes(fid.path, at, mt)
+ if e != nil {
+ req.RespondError(toError(e))
+ return
+ }
+ }
+
+ req.RespondRwstat()
+}