driver_unix.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. //go:build !windows
  2. // +build !windows
  3. /*
  4. Copyright The containerd Authors.
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. */
  15. package driver
  16. import (
  17. "errors"
  18. "fmt"
  19. "os"
  20. "sort"
  21. "github.com/containerd/continuity/devices"
  22. "github.com/containerd/continuity/sysx"
  23. )
  24. func (d *driver) Mknod(path string, mode os.FileMode, major, minor int) error {
  25. err := devices.Mknod(path, mode, major, minor)
  26. if err != nil {
  27. err = &os.PathError{Op: "mknod", Path: path, Err: err}
  28. }
  29. return err
  30. }
  31. func (d *driver) Mkfifo(path string, mode os.FileMode) error {
  32. if mode&os.ModeNamedPipe == 0 {
  33. return errors.New("mode passed to Mkfifo does not have the named pipe bit set")
  34. }
  35. // mknod with a mode that has ModeNamedPipe set creates a fifo, not a
  36. // device.
  37. err := devices.Mknod(path, mode, 0, 0)
  38. if err != nil {
  39. err = &os.PathError{Op: "mkfifo", Path: path, Err: err}
  40. }
  41. return err
  42. }
  43. // Getxattr returns all of the extended attributes for the file at path p.
  44. func (d *driver) Getxattr(p string) (map[string][]byte, error) {
  45. xattrs, err := sysx.Listxattr(p)
  46. if err != nil {
  47. return nil, fmt.Errorf("listing %s xattrs: %v", p, err)
  48. }
  49. sort.Strings(xattrs)
  50. m := make(map[string][]byte, len(xattrs))
  51. for _, attr := range xattrs {
  52. value, err := sysx.Getxattr(p, attr)
  53. if err != nil {
  54. return nil, fmt.Errorf("getting %q xattr on %s: %v", attr, p, err)
  55. }
  56. // NOTE(stevvooe): This append/copy tricky relies on unique
  57. // xattrs. Break this out into an alloc/copy if xattrs are no
  58. // longer unique.
  59. m[attr] = append(m[attr], value...)
  60. }
  61. return m, nil
  62. }
  63. // Setxattr sets all of the extended attributes on file at path, following
  64. // any symbolic links, if necessary. All attributes on the target are
  65. // replaced by the values from attr. If the operation fails to set any
  66. // attribute, those already applied will not be rolled back.
  67. func (d *driver) Setxattr(path string, attrMap map[string][]byte) error {
  68. for attr, value := range attrMap {
  69. if err := sysx.Setxattr(path, attr, value, 0); err != nil {
  70. return fmt.Errorf("error setting xattr %q on %s: %v", attr, path, err)
  71. }
  72. }
  73. return nil
  74. }
  75. // LGetxattr returns all of the extended attributes for the file at path p
  76. // not following symbolic links.
  77. func (d *driver) LGetxattr(p string) (map[string][]byte, error) {
  78. xattrs, err := sysx.LListxattr(p)
  79. if err != nil {
  80. return nil, fmt.Errorf("listing %s xattrs: %v", p, err)
  81. }
  82. sort.Strings(xattrs)
  83. m := make(map[string][]byte, len(xattrs))
  84. for _, attr := range xattrs {
  85. value, err := sysx.LGetxattr(p, attr)
  86. if err != nil {
  87. return nil, fmt.Errorf("getting %q xattr on %s: %v", attr, p, err)
  88. }
  89. // NOTE(stevvooe): This append/copy tricky relies on unique
  90. // xattrs. Break this out into an alloc/copy if xattrs are no
  91. // longer unique.
  92. m[attr] = append(m[attr], value...)
  93. }
  94. return m, nil
  95. }
  96. // LSetxattr sets all of the extended attributes on file at path, not
  97. // following any symbolic links. All attributes on the target are
  98. // replaced by the values from attr. If the operation fails to set any
  99. // attribute, those already applied will not be rolled back.
  100. func (d *driver) LSetxattr(path string, attrMap map[string][]byte) error {
  101. for attr, value := range attrMap {
  102. if err := sysx.LSetxattr(path, attr, value, 0); err != nil {
  103. return fmt.Errorf("error setting xattr %q on %s: %v", attr, path, err)
  104. }
  105. }
  106. return nil
  107. }
  108. func (d *driver) DeviceInfo(fi os.FileInfo) (maj uint64, min uint64, err error) {
  109. return devices.DeviceInfo(fi)
  110. }