Inspect: Preserve permission flags (#13490)

Preserve permission from disk files. Can help identify issues.

Refactor GetRawData function to be cleaner.
This commit is contained in:
Klaus Post 2021-10-21 11:20:13 -07:00 committed by GitHub
parent ac36a377b0
commit 23d6770ff9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 16 deletions

View File

@ -2165,7 +2165,7 @@ func checkConnection(endpointStr string, timeout time.Duration) error {
// getRawDataer provides an interface for getting raw FS files. // getRawDataer provides an interface for getting raw FS files.
type getRawDataer interface { type getRawDataer interface {
GetRawData(ctx context.Context, volume, file string, fn func(r io.Reader, host string, disk string, filename string, size int64, modtime time.Time, isDir bool) error) error GetRawData(ctx context.Context, volume, file string, fn func(r io.Reader, host string, disk string, filename string, info StatInfo) error) error
} }
// InspectDataHandler - GET /minio/admin/v3/inspect-data // InspectDataHandler - GET /minio/admin/v3/inspect-data
@ -2242,19 +2242,23 @@ func (a adminAPIHandlers) InspectDataHandler(w http.ResponseWriter, r *http.Requ
zipWriter := zip.NewWriter(encw) zipWriter := zip.NewWriter(encw)
defer zipWriter.Close() defer zipWriter.Close()
err = o.GetRawData(ctx, volume, file, func(r io.Reader, host, disk, filename string, size int64, modtime time.Time, isDir bool) error { err = o.GetRawData(ctx, volume, file, func(r io.Reader, host, disk, filename string, si StatInfo) error {
// Prefix host+disk // Prefix host+disk
filename = path.Join(host, disk, filename) filename = path.Join(host, disk, filename)
if isDir { if si.Dir {
filename += "/" filename += "/"
size = 0 si.Size = 0
}
if si.Mode == 0 {
// Not, set it to default.
si.Mode = 0600
} }
header, zerr := zip.FileInfoHeader(dummyFileInfo{ header, zerr := zip.FileInfoHeader(dummyFileInfo{
name: filename, name: filename,
size: size, size: si.Size,
mode: 0600, mode: os.FileMode(si.Mode),
modTime: modtime, modTime: si.ModTime,
isDir: isDir, isDir: si.Dir,
sys: nil, sys: nil,
}) })
if zerr != nil { if zerr != nil {

View File

@ -151,7 +151,7 @@ func (z *erasureServerPools) GetDisksID(ids ...string) []StorageAPI {
// GetRawData will return all files with a given raw path to the callback. // GetRawData will return all files with a given raw path to the callback.
// Errors are ignored, only errors from the callback are returned. // Errors are ignored, only errors from the callback are returned.
// For now only direct file paths are supported. // For now only direct file paths are supported.
func (z *erasureServerPools) GetRawData(ctx context.Context, volume, file string, fn func(r io.Reader, host string, disk string, filename string, size int64, modtime time.Time, isDir bool) error) error { func (z *erasureServerPools) GetRawData(ctx context.Context, volume, file string, fn func(r io.Reader, host string, disk string, filename string, info StatInfo) error) error {
found := 0 found := 0
for _, s := range z.serverPools { for _, s := range z.serverPools {
for _, disks := range s.erasureDisks { for _, disks := range s.erasureDisks {
@ -178,7 +178,7 @@ func (z *erasureServerPools) GetRawData(ctx context.Context, volume, file string
} else { } else {
r = io.NopCloser(bytes.NewBuffer([]byte{})) r = io.NopCloser(bytes.NewBuffer([]byte{}))
} }
err = fn(r, disk.Hostname(), did, pathJoin(volume, si.Name), si.Size, si.ModTime, si.Dir) err = fn(r, disk.Hostname(), did, pathJoin(volume, si.Name), si)
r.Close() r.Close()
if err != nil { if err != nil {
return err return err

View File

@ -83,6 +83,7 @@ type StatInfo struct {
ModTime time.Time `json:"modTime"` // ModTime of the object `xl.meta`. ModTime time.Time `json:"modTime"` // ModTime of the object `xl.meta`.
Name string `json:"name"` Name string `json:"name"`
Dir bool `json:"dir"` Dir bool `json:"dir"`
Mode uint32 `json:"mode"`
} }
// ErasureInfo holds erasure coding and bitrot related information. // ErasureInfo holds erasure coding and bitrot related information.

View File

@ -771,6 +771,12 @@ func (z *StatInfo) DecodeMsg(dc *msgp.Reader) (err error) {
err = msgp.WrapError(err, "Dir") err = msgp.WrapError(err, "Dir")
return return
} }
case "Mode":
z.Mode, err = dc.ReadUint32()
if err != nil {
err = msgp.WrapError(err, "Mode")
return
}
default: default:
err = dc.Skip() err = dc.Skip()
if err != nil { if err != nil {
@ -784,9 +790,9 @@ func (z *StatInfo) DecodeMsg(dc *msgp.Reader) (err error) {
// EncodeMsg implements msgp.Encodable // EncodeMsg implements msgp.Encodable
func (z *StatInfo) EncodeMsg(en *msgp.Writer) (err error) { func (z *StatInfo) EncodeMsg(en *msgp.Writer) (err error) {
// map header, size 4 // map header, size 5
// write "Size" // write "Size"
err = en.Append(0x84, 0xa4, 0x53, 0x69, 0x7a, 0x65) err = en.Append(0x85, 0xa4, 0x53, 0x69, 0x7a, 0x65)
if err != nil { if err != nil {
return return
} }
@ -825,15 +831,25 @@ func (z *StatInfo) EncodeMsg(en *msgp.Writer) (err error) {
err = msgp.WrapError(err, "Dir") err = msgp.WrapError(err, "Dir")
return return
} }
// write "Mode"
err = en.Append(0xa4, 0x4d, 0x6f, 0x64, 0x65)
if err != nil {
return
}
err = en.WriteUint32(z.Mode)
if err != nil {
err = msgp.WrapError(err, "Mode")
return
}
return return
} }
// MarshalMsg implements msgp.Marshaler // MarshalMsg implements msgp.Marshaler
func (z *StatInfo) MarshalMsg(b []byte) (o []byte, err error) { func (z *StatInfo) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize()) o = msgp.Require(b, z.Msgsize())
// map header, size 4 // map header, size 5
// string "Size" // string "Size"
o = append(o, 0x84, 0xa4, 0x53, 0x69, 0x7a, 0x65) o = append(o, 0x85, 0xa4, 0x53, 0x69, 0x7a, 0x65)
o = msgp.AppendInt64(o, z.Size) o = msgp.AppendInt64(o, z.Size)
// string "ModTime" // string "ModTime"
o = append(o, 0xa7, 0x4d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65) o = append(o, 0xa7, 0x4d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65)
@ -844,6 +860,9 @@ func (z *StatInfo) MarshalMsg(b []byte) (o []byte, err error) {
// string "Dir" // string "Dir"
o = append(o, 0xa3, 0x44, 0x69, 0x72) o = append(o, 0xa3, 0x44, 0x69, 0x72)
o = msgp.AppendBool(o, z.Dir) o = msgp.AppendBool(o, z.Dir)
// string "Mode"
o = append(o, 0xa4, 0x4d, 0x6f, 0x64, 0x65)
o = msgp.AppendUint32(o, z.Mode)
return return
} }
@ -889,6 +908,12 @@ func (z *StatInfo) UnmarshalMsg(bts []byte) (o []byte, err error) {
err = msgp.WrapError(err, "Dir") err = msgp.WrapError(err, "Dir")
return return
} }
case "Mode":
z.Mode, bts, err = msgp.ReadUint32Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "Mode")
return
}
default: default:
bts, err = msgp.Skip(bts) bts, err = msgp.Skip(bts)
if err != nil { if err != nil {
@ -903,7 +928,7 @@ func (z *StatInfo) UnmarshalMsg(bts []byte) (o []byte, err error) {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *StatInfo) Msgsize() (s int) { func (z *StatInfo) Msgsize() (s int) {
s = 1 + 5 + msgp.Int64Size + 8 + msgp.TimeSize + 5 + msgp.StringPrefixSize + len(z.Name) + 4 + msgp.BoolSize s = 1 + 5 + msgp.Int64Size + 8 + msgp.TimeSize + 5 + msgp.StringPrefixSize + len(z.Name) + 4 + msgp.BoolSize + 5 + msgp.Uint32Size
return return
} }

View File

@ -2270,7 +2270,7 @@ func (s *xlStorage) StatInfoFile(ctx context.Context, volume, path string, glob
if os.PathSeparator != '/' { if os.PathSeparator != '/' {
name = strings.Replace(name, string(os.PathSeparator), "/", -1) name = strings.Replace(name, string(os.PathSeparator), "/", -1)
} }
stat = append(stat, StatInfo{ModTime: st.ModTime(), Size: st.Size(), Name: name, Dir: st.IsDir()}) stat = append(stat, StatInfo{ModTime: st.ModTime(), Size: st.Size(), Name: name, Dir: st.IsDir(), Mode: uint32(st.Mode())})
} }
return stat, nil return stat, nil
} }