driver_unix.go 3.9 KB

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