bảo toàn các thuộc tính mở rộng với cp / rsync


12

Khi sao chép bằng cp, các thuộc tính mở rộng không được bảo tồn, ngay cả với rõ ràng

cp -a --preserve=all /source /dest

hoặc là

cp -a --preserve=xattr /source /dest

Tương tự là với rsync, tức là

rsync -aq -A -X --delete /source /dest

Tuy nhiên, trên hệ thống tệp đích, tôi có thể tạo thuộc tính mở rộng bằng tay (với chattr). Điều này có nghĩa là hệ thống tập tin đích hỗ trợ xattr.

Tại sao tôi không thể bảo tồn xattrvới cphoặc rsync?

Thông tin thêm:

  • Cả hai hệ thống tập tin nguồn và đích đều là ext4
  • Cả hai hệ thống tập tin nguồn và đích đều là cục bộ (không phải nfs)
  • Tôi đang sử dụng Debian Wheezy

Làm thế nào bạn đang gắn hệ thống tập tin đích này? Có phải qua NFS?
slm

hệ thống tập tin đích là một hệ thống tập tin cục bộ
Martin Vegter

Bạn có thể hiển thị đầu ra mountcho hệ thống tập tin này?
slm

1
Trên biến thể unix và phiên bản nào? Những loại hệ thống tập tin ở cả hai đầu, với các tùy chọn gắn kết?
Gilles 'SO- ngừng trở nên xấu xa'

1
@MartinVegter Bạn có thể cho một thuộc tính mẫu mà tập tin của bạn có không? Tôi vừa tạo hệ thống tập tin ext4 trong hai tập tin và đã thử nghiệm với setfattr -n system.name0 -v "value" test_file. Tôi đã sao chép test_filevào / từ ext4 / jfs / xfs cp --preserve=allvà không gặp vấn đề gì trong việc bảo tồn các thuộc tính mở rộng.
UVV

Câu trả lời:


14

Cập nhật

Sau khi tìm hiểu thêm về điều này và xem xét mã này chattrvà mã khác e2fsprogs, rõ ràng các thuộc tính được đặt bởi chattrvà các thuộc tính được đặt bởi libattr(ví dụ với lệnh setfattr) rất khác nhau. chattrthiết lập các extcờ hệ thống tập tin mà đơn giản là không ánh xạ tới một thuộc tính hoặc không gian tên được đặt tên. Không trong số họ xuất hiện với bất kỳ cuộc gọi đến libattr's listxattr. Có lẽ họ nên ánh xạ tới các thuộc tính được đặt tên trong systemkhông gian tên như được giả định bên dưới, nhưng cho đến nay điều này hoàn toàn không được thực hiện. Ngoài ra, system.posix_acl_accessthuộc tính tôi nhầm với ánh xạ tới một trong các thuộc tính dưới đây, không liên quan gì đến các extcờ hệ thống tập tin và đúng hơn là làm với danh sách kiểm soát truy cập. Liên kếtstracetin nhắn xuất hiện cho bất kỳ tập tin và biến mất khi chỉ cp --preserve=xattrđược sử dụng.

Dường như các thuộc tính được thiết lập chattrlà dành riêng cho các exthệ thống tệp và cách duy nhất để ảnh hưởng đến chúng là thông qua e2fsprogscác công cụ. Trong thực tế, mantrang không thực sự sử dụng thuật ngữ 'thuộc tính mở rộng' cho chúng, mà là 'thuộc tính tệp'. Các thuộc tính mở rộng 'Real' là các cặp tên / giá trị có thể được thay đổi bởi libattrvà được triển khai trên nhiều hệ thống tệp. Đây là những gì cprsynctìm kiếm và chuyển qua các tập tin sao chép khi các tùy chọn phù hợp được đưa ra. Tuy nhiên, dường như systemkhông gian tên tồn tại để ánh xạ các chattrthuộc tính thành tên và cuối cùng là các thuộc tính tương đương trên các hệ thống tệp khác, nhưng hiện tại điều này không hoạt động.

Tôi đã để lại câu trả lời ban đầu nguyên vẹn vì có một số thông tin tốt ở đó, mặc dù nó đi khá xa ở các điểm.

Cập nhật 2

Tôi nên quay lại vấn đề này một lần nữa trước đây, nhưng theo câu trả lời này , nó chattrhoạt động trên nhiều exthệ thống tập tin. Theo Wikipedia , nó tương đương với chflagslệnh trên các hệ thống dựa trên BSD.

Tôi đã viết một tập lệnh để kiểm tra cài đặt và đọc các thuộc tính này trên một vài hệ thống tập tin và nhận được kết quả như sau:

ext4:
suS-iadAcj-t-e-- mnt/test_file
suSDiadAcj-tTe-- mnt/test_dir

reiserfs:
lsattr: Inappropriate ioctl for device While reading flags on mnt/test_file
lsattr: Inappropriate ioctl for device While reading flags on mnt/test_dir

xfs:
--S-iadA-------- mnt/test_file
--S-iadA-------- mnt/test_dir

btrfs:
--S-iadAc------C mnt/test_file
--SDiadAc------C mnt/test_dir

Lưu ý rằng tất cả các nỗ lực đọc / đặt reiserfscờ tệp đã đưa ra lỗi trên, mặc dù nó được liệt kê trên Wikipedia là có một số chức năng. Tôi đã không kiểm tra reiser4. Ngoài ra trong khi ccờ có thể được đặt trên ext4nó không được vinh danh. Cũng có thể có các tùy chọn điều chỉnh / gắn kết ảnh hưởng đến các cờ này, nhưng tôi không thể tìm thấy bất kỳ.

Tuy nhiên, dường như hiện tại chattrlà tiện ích duy nhất trên Linux có khả năng sửa đổi các thuộc tính này và vì vậy không có tiện ích sao chép nào có khả năng bảo tồn chúng.

Câu trả lời gốc

Lý do rsyncdường như là thậm chí không thử. Từ -Xphần rsynctài liệu:

For systems that support extended-attribute namespaces, a copy being done by a
super-user copies all namespaces except system.*.  A normal user only  copies
the user.* namespace.

Rất khó để ánh xạ các chữ cái thuộc tính được sử dụng bởi chattrlsattrđến các thuộc tính được đặt tên cơ bản được sử dụng trong hệ thống tệp (đối với một không có danh sách trên internet). Từ các thử nghiệm của tôi, Athuộc tính ánh xạ tới system.posix_acl_accessthuộc tính và vì đây là systemkhông gian tên, rsyncthậm chí sẽ không cố gắng sao chép nó.Hai không gian tên khác không được đề cập trong manđoạn trích là trustedsecurity, các đặc quyền gốc được yêu cầu để đặt chúng (và rsyncsẽ không thử nếu không có).

Rất có thể các thuộc tính bạn đã cố gắng đặt nằm trong systemkhông gian tên mà rsyncbỏ qua (và có lẽ là khôn ngoan). Hoặc là hoặc bạn cần phải root để có được những cái không.

Đối với cp, dường như có lỗi tại chơi.Chạy stracetiếp cp -a, tôi nhận được hai dòng thú vị sau:

fgetxattr(3, "system.posix_acl_access", 0x7fff5181c0e0, 132) = -1 ENODATA (No data available)

fsetxattr(4, "system.posix_acl_access", "\x02\x00\x00\x00\x01\x00\x06\x00\xff\xff\xff\xff\x04\x00\x04\x00\xff\xff\xff\xff \x00\x04\x00\xff\xff\xff\xff", 28, 0) = 0

Đầu tiên, fgetxattrcuộc gọi không trả về bất kỳ dữ liệu nào (có lẽ vì không có bất kỳ dữ liệu nào - sự tồn tại của thuộc tính là đủ), nhưng bằng cách nào đó cptìm thấy 28 byte dữ liệu (rác?) Để đặt làm giá trị thuộc tính trong tệp đích. Điều này có vẻ như là một lỗi trong cp, nhưng đúng hơn là những gì gây ra vấn đề dường như là một lỗi trong libattrkhi fsetattrcuộc gọi trả về 0thành công mà không thực sự thiết lập thuộc tính.

Tôi nhận được hành vi này ext4bất kể tôi gắn kết với user_xattr. Tôi không thể tìm thấy bất kỳ tài liệu nào về điều này ngoài việc nói rằng 'một số hệ thống' cần tùy chọn gắn kết này để các thuộc tính mở rộng hoạt động. Dường như của tôi (Debian Jessie) thì không. Ngay cả có một vấn đề gắn kết tôi đã bỏ lỡ, nó là sai fsetattrvà do đó cpđể âm thầm thất bại.

Trên thực tế user_xattrlà cần thiết trên ext2, ext3, reiserfsvà có thể một số người khác. Nó không cần thiết choext4

Cũng lưu ý rằng các attrcông cụ setfattr, getfattrattr(sau này được ghi chép lại là chỉ dành cho XFSduy nhất, nhưng dường như việc chỉ cũng như những người khác cho ext4) có vấn đề làm việc trong bất cứ điều gì nhưng userkhông gian tên. Tôi nhận được Operation not supportednếu tôi cố gắng sử dụng setfattrđể đặt một thuộc tính trong systemkhông gian tên (hoặc không có không gian tên theo lỗi này ). setfattrdường như thành công trong không gian tên trustedsecuritykhông gian, nhưng sau đó getfattrkhông đọc được gì và cũng không đọc được gì từ systemkhông gian tên được đặt bởi chattr. Lý do chattrthành công là nó sử dụng một ioctlcuộc gọi và không libattr.

Mặc dù vậy, điều làm việc hoàn hảo là đặt các thuộc tính mở rộng trong userkhông gian tên với setfattrvà sử dụng rsynchoặc cpsao chép nguyên vẹn chúng (thậm chí không có vấn đề gì cpnếu bạn không chỉ định giá trị khi tạo thuộc tính). Tôi nghĩ điểm mấu chốt systemlà hiện tại đang sử dụng các giá trị không gian tênlỗi và / hoặckhông được hỗ trợ, ít nhất là trong Debian và có lẽ các bản phân phối khác nữa. Có khả năng các rsyncnhà phát triển biết điều này, đó là lý do tại sao họ bỏ qua chúng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.