]> git.proxmox.com Git - proxmox-backup.git/blob - pbs-client/src/pxar/flags.rs
eca5ee97ad0e8fe877bff5087aed04a6e4671d4c
[proxmox-backup.git] / pbs-client / src / pxar / flags.rs
1 //! Feature flags for *pxar* allow to control what is stored/restored in/from the
2 //! archive.
3 //! Flags for known supported features for a given filesystem can be derived
4 //! from the superblocks magic number.
5
6 use libc::c_long;
7
8 use bitflags::bitflags;
9
10 bitflags! {
11 pub struct Flags: u64 {
12 /// FAT-style 2s time granularity
13 const WITH_2SEC_TIME = 0x40;
14 /// Preserve read only flag of files
15 const WITH_READ_ONLY = 0x80;
16 /// Preserve unix permissions
17 const WITH_PERMISSIONS = 0x100;
18 /// Include symbolik links
19 const WITH_SYMLINKS = 0x200;
20 /// Include device nodes
21 const WITH_DEVICE_NODES = 0x400;
22 /// Include FIFOs
23 const WITH_FIFOS = 0x800;
24 /// Include Sockets
25 const WITH_SOCKETS = 0x1000;
26
27 /// Preserve DOS file flag `HIDDEN`
28 const WITH_FLAG_HIDDEN = 0x2000;
29 /// Preserve DOS file flag `SYSTEM`
30 const WITH_FLAG_SYSTEM = 0x4000;
31 /// Preserve DOS file flag `ARCHIVE`
32 const WITH_FLAG_ARCHIVE = 0x8000;
33
34 // chattr() flags
35 /// Linux file attribute `APPEND`
36 const WITH_FLAG_APPEND = 0x10000;
37 /// Linux file attribute `NOATIME`
38 const WITH_FLAG_NOATIME = 0x20000;
39 /// Linux file attribute `COMPR`
40 const WITH_FLAG_COMPR = 0x40000;
41 /// Linux file attribute `NOCOW`
42 const WITH_FLAG_NOCOW = 0x80000;
43 /// Linux file attribute `NODUMP`
44 const WITH_FLAG_NODUMP = 0x0010_0000;
45 /// Linux file attribute `DIRSYNC`
46 const WITH_FLAG_DIRSYNC = 0x0020_0000;
47 /// Linux file attribute `IMMUTABLE`
48 const WITH_FLAG_IMMUTABLE = 0x0040_0000;
49 /// Linux file attribute `SYNC`
50 const WITH_FLAG_SYNC = 0x0080_0000;
51 /// Linux file attribute `NOCOMP`
52 const WITH_FLAG_NOCOMP = 0x0100_0000;
53 /// Linux file attribute `PROJINHERIT`
54 const WITH_FLAG_PROJINHERIT = 0x0200_0000;
55
56
57 /// Preserve BTRFS subvolume flag
58 const WITH_SUBVOLUME = 0x0400_0000;
59 /// Preserve BTRFS read-only subvolume flag
60 const WITH_SUBVOLUME_RO = 0x0800_0000;
61
62 /// Preserve Extended Attribute metadata
63 const WITH_XATTRS = 0x1000_0000;
64 /// Preserve Access Control List metadata
65 const WITH_ACL = 0x2000_0000;
66 /// Preserve SELinux security context
67 const WITH_SELINUX = 0x4000_0000;
68 /// Preserve "security.capability" xattr
69 const WITH_FCAPS = 0x8000_0000;
70
71 /// Preserve XFS/ext4/ZFS project quota ID
72 const WITH_QUOTA_PROJID = 0x0001_0000_0000;
73
74 /// Support ".pxarexclude" files
75 const EXCLUDE_FILE = 0x1000_0000_0000_0000;
76 /// Exclude submounts
77 const EXCLUDE_SUBMOUNTS = 0x4000_0000_0000_0000;
78 /// Exclude entries with chattr flag NODUMP
79 const EXCLUDE_NODUMP = 0x8000_0000_0000_0000;
80
81 // Definitions of typical feature flags for the *pxar* encoder/decoder.
82 // By this expensive syscalls for unsupported features are avoided.
83
84 /// All chattr file attributes
85 const WITH_CHATTR =
86 Flags::WITH_FLAG_APPEND.bits() |
87 Flags::WITH_FLAG_NOATIME.bits() |
88 Flags::WITH_FLAG_COMPR.bits() |
89 Flags::WITH_FLAG_NOCOW.bits() |
90 Flags::WITH_FLAG_NODUMP.bits() |
91 Flags::WITH_FLAG_DIRSYNC.bits() |
92 Flags::WITH_FLAG_IMMUTABLE.bits() |
93 Flags::WITH_FLAG_SYNC.bits() |
94 Flags::WITH_FLAG_NOCOMP.bits() |
95 Flags::WITH_FLAG_PROJINHERIT.bits();
96
97 /// All FAT file attributes
98 const WITH_FAT_ATTRS =
99 Flags::WITH_FLAG_HIDDEN.bits() |
100 Flags::WITH_FLAG_SYSTEM.bits() |
101 Flags::WITH_FLAG_ARCHIVE.bits();
102
103 /// All bits that may also be exposed via fuse
104 const WITH_FUSE =
105 Flags::WITH_2SEC_TIME.bits() |
106 Flags::WITH_READ_ONLY.bits() |
107 Flags::WITH_PERMISSIONS.bits() |
108 Flags::WITH_SYMLINKS.bits() |
109 Flags::WITH_DEVICE_NODES.bits() |
110 Flags::WITH_FIFOS.bits() |
111 Flags::WITH_SOCKETS.bits() |
112 Flags::WITH_FAT_ATTRS.bits() |
113 Flags::WITH_CHATTR.bits() |
114 Flags::WITH_XATTRS.bits();
115
116
117 /// Default feature flags for encoder/decoder
118 const DEFAULT =
119 Flags::WITH_SYMLINKS.bits() |
120 Flags::WITH_DEVICE_NODES.bits() |
121 Flags::WITH_FIFOS.bits() |
122 Flags::WITH_SOCKETS.bits() |
123 Flags::WITH_FLAG_HIDDEN.bits() |
124 Flags::WITH_FLAG_SYSTEM.bits() |
125 Flags::WITH_FLAG_ARCHIVE.bits() |
126 Flags::WITH_FLAG_APPEND.bits() |
127 Flags::WITH_FLAG_NOATIME.bits() |
128 Flags::WITH_FLAG_COMPR.bits() |
129 Flags::WITH_FLAG_NOCOW.bits() |
130 //WITH_FLAG_NODUMP.bits() |
131 Flags::WITH_FLAG_DIRSYNC.bits() |
132 Flags::WITH_FLAG_IMMUTABLE.bits() |
133 Flags::WITH_FLAG_SYNC.bits() |
134 Flags::WITH_FLAG_NOCOMP.bits() |
135 Flags::WITH_FLAG_PROJINHERIT.bits() |
136 Flags::WITH_SUBVOLUME.bits() |
137 Flags::WITH_SUBVOLUME_RO.bits() |
138 Flags::WITH_XATTRS.bits() |
139 Flags::WITH_ACL.bits() |
140 Flags::WITH_SELINUX.bits() |
141 Flags::WITH_FCAPS.bits() |
142 Flags::WITH_QUOTA_PROJID.bits() |
143 Flags::EXCLUDE_NODUMP.bits() |
144 Flags::EXCLUDE_FILE.bits();
145 }
146 }
147
148 impl Default for Flags {
149 fn default() -> Flags {
150 Flags::DEFAULT
151 }
152 }
153
154 // form /usr/include/linux/fs.h
155 const FS_APPEND_FL: c_long = 0x0000_0020;
156 const FS_NOATIME_FL: c_long = 0x0000_0080;
157 const FS_COMPR_FL: c_long = 0x0000_0004;
158 const FS_NOCOW_FL: c_long = 0x0080_0000;
159 const FS_NODUMP_FL: c_long = 0x0000_0040;
160 const FS_DIRSYNC_FL: c_long = 0x0001_0000;
161 const FS_IMMUTABLE_FL: c_long = 0x0000_0010;
162 const FS_SYNC_FL: c_long = 0x0000_0008;
163 const FS_NOCOMP_FL: c_long = 0x0000_0400;
164 const FS_PROJINHERIT_FL: c_long = 0x2000_0000;
165
166 pub(crate) const INITIAL_FS_FLAGS: c_long =
167 FS_NOATIME_FL
168 | FS_COMPR_FL
169 | FS_NOCOW_FL
170 | FS_NOCOMP_FL
171 | FS_PROJINHERIT_FL;
172
173 #[rustfmt::skip]
174 const CHATTR_MAP: [(Flags, c_long); 10] = [
175 ( Flags::WITH_FLAG_APPEND, FS_APPEND_FL ),
176 ( Flags::WITH_FLAG_NOATIME, FS_NOATIME_FL ),
177 ( Flags::WITH_FLAG_COMPR, FS_COMPR_FL ),
178 ( Flags::WITH_FLAG_NOCOW, FS_NOCOW_FL ),
179 ( Flags::WITH_FLAG_NODUMP, FS_NODUMP_FL ),
180 ( Flags::WITH_FLAG_DIRSYNC, FS_DIRSYNC_FL ),
181 ( Flags::WITH_FLAG_IMMUTABLE, FS_IMMUTABLE_FL ),
182 ( Flags::WITH_FLAG_SYNC, FS_SYNC_FL ),
183 ( Flags::WITH_FLAG_NOCOMP, FS_NOCOMP_FL ),
184 ( Flags::WITH_FLAG_PROJINHERIT, FS_PROJINHERIT_FL ),
185 ];
186
187 // from /usr/include/linux/msdos_fs.h
188 const ATTR_HIDDEN: u32 = 2;
189 const ATTR_SYS: u32 = 4;
190 const ATTR_ARCH: u32 = 32;
191
192 #[rustfmt::skip]
193 const FAT_ATTR_MAP: [(Flags, u32); 3] = [
194 ( Flags::WITH_FLAG_HIDDEN, ATTR_HIDDEN ),
195 ( Flags::WITH_FLAG_SYSTEM, ATTR_SYS ),
196 ( Flags::WITH_FLAG_ARCHIVE, ATTR_ARCH ),
197 ];
198
199 impl Flags {
200 /// Get a set of feature flags from file attributes.
201 pub fn from_chattr(attr: c_long) -> Flags {
202 let mut flags = Flags::empty();
203
204 for (fe_flag, fs_flag) in &CHATTR_MAP {
205 if (attr & fs_flag) != 0 {
206 flags |= *fe_flag;
207 }
208 }
209
210 flags
211 }
212
213 /// Get the chattr bit representation of these feature flags.
214 pub fn to_chattr(self) -> c_long {
215 let mut flags: c_long = 0;
216
217 for (fe_flag, fs_flag) in &CHATTR_MAP {
218 if self.contains(*fe_flag) {
219 flags |= *fs_flag;
220 }
221 }
222
223 flags
224 }
225
226 pub fn to_initial_chattr(self) -> c_long {
227 self.to_chattr() & INITIAL_FS_FLAGS
228 }
229
230 /// Get a set of feature flags from FAT attributes.
231 pub fn from_fat_attr(attr: u32) -> Flags {
232 let mut flags = Flags::empty();
233
234 for (fe_flag, fs_flag) in &FAT_ATTR_MAP {
235 if (attr & fs_flag) != 0 {
236 flags |= *fe_flag;
237 }
238 }
239
240 flags
241 }
242
243 /// Get the fat attribute bit representation of these feature flags.
244 pub fn to_fat_attr(self) -> u32 {
245 let mut flags = 0u32;
246
247 for (fe_flag, fs_flag) in &FAT_ATTR_MAP {
248 if self.contains(*fe_flag) {
249 flags |= *fs_flag;
250 }
251 }
252
253 flags
254 }
255
256 /// Return the supported *pxar* feature flags based on the magic number of the filesystem.
257 pub fn from_magic(magic: i64) -> Flags {
258 use proxmox::sys::linux::magic::*;
259 match magic {
260 MSDOS_SUPER_MAGIC => {
261 Flags::WITH_2SEC_TIME |
262 Flags::WITH_READ_ONLY |
263 Flags::WITH_FAT_ATTRS
264 },
265 EXT4_SUPER_MAGIC => {
266 Flags::WITH_2SEC_TIME |
267 Flags::WITH_READ_ONLY |
268 Flags::WITH_PERMISSIONS |
269 Flags::WITH_SYMLINKS |
270 Flags::WITH_DEVICE_NODES |
271 Flags::WITH_FIFOS |
272 Flags::WITH_SOCKETS |
273 Flags::WITH_FLAG_APPEND |
274 Flags::WITH_FLAG_NOATIME |
275 Flags::WITH_FLAG_NODUMP |
276 Flags::WITH_FLAG_DIRSYNC |
277 Flags::WITH_FLAG_IMMUTABLE |
278 Flags::WITH_FLAG_SYNC |
279 Flags::WITH_XATTRS |
280 Flags::WITH_ACL |
281 Flags::WITH_SELINUX |
282 Flags::WITH_FCAPS |
283 Flags::WITH_QUOTA_PROJID
284 },
285 XFS_SUPER_MAGIC => {
286 Flags::WITH_2SEC_TIME |
287 Flags::WITH_READ_ONLY |
288 Flags::WITH_PERMISSIONS |
289 Flags::WITH_SYMLINKS |
290 Flags::WITH_DEVICE_NODES |
291 Flags::WITH_FIFOS |
292 Flags::WITH_SOCKETS |
293 Flags::WITH_FLAG_APPEND |
294 Flags::WITH_FLAG_NOATIME |
295 Flags::WITH_FLAG_NODUMP |
296 Flags::WITH_FLAG_IMMUTABLE |
297 Flags::WITH_FLAG_SYNC |
298 Flags::WITH_XATTRS |
299 Flags::WITH_ACL |
300 Flags::WITH_SELINUX |
301 Flags::WITH_FCAPS |
302 Flags::WITH_QUOTA_PROJID
303 },
304 ZFS_SUPER_MAGIC => {
305 Flags::WITH_2SEC_TIME |
306 Flags::WITH_READ_ONLY |
307 Flags::WITH_PERMISSIONS |
308 Flags::WITH_SYMLINKS |
309 Flags::WITH_DEVICE_NODES |
310 Flags::WITH_FIFOS |
311 Flags::WITH_SOCKETS |
312 Flags::WITH_FLAG_APPEND |
313 Flags::WITH_FLAG_NOATIME |
314 Flags::WITH_FLAG_NODUMP |
315 Flags::WITH_FLAG_DIRSYNC |
316 Flags::WITH_FLAG_IMMUTABLE |
317 Flags::WITH_FLAG_SYNC |
318 Flags::WITH_XATTRS |
319 Flags::WITH_ACL |
320 Flags::WITH_SELINUX |
321 Flags::WITH_FCAPS |
322 Flags::WITH_QUOTA_PROJID
323 },
324 BTRFS_SUPER_MAGIC => {
325 Flags::WITH_2SEC_TIME |
326 Flags::WITH_READ_ONLY |
327 Flags::WITH_PERMISSIONS |
328 Flags::WITH_SYMLINKS |
329 Flags::WITH_DEVICE_NODES |
330 Flags::WITH_FIFOS |
331 Flags::WITH_SOCKETS |
332 Flags::WITH_FLAG_APPEND |
333 Flags::WITH_FLAG_NOATIME |
334 Flags::WITH_FLAG_COMPR |
335 Flags::WITH_FLAG_NOCOW |
336 Flags::WITH_FLAG_NODUMP |
337 Flags::WITH_FLAG_DIRSYNC |
338 Flags::WITH_FLAG_IMMUTABLE |
339 Flags::WITH_FLAG_SYNC |
340 Flags::WITH_FLAG_NOCOMP |
341 Flags::WITH_XATTRS |
342 Flags::WITH_ACL |
343 Flags::WITH_SELINUX |
344 Flags::WITH_SUBVOLUME |
345 Flags::WITH_SUBVOLUME_RO |
346 Flags::WITH_FCAPS
347 },
348 TMPFS_MAGIC => {
349 Flags::WITH_2SEC_TIME |
350 Flags::WITH_READ_ONLY |
351 Flags::WITH_PERMISSIONS |
352 Flags::WITH_SYMLINKS |
353 Flags::WITH_DEVICE_NODES |
354 Flags::WITH_FIFOS |
355 Flags::WITH_SOCKETS |
356 Flags::WITH_ACL |
357 Flags::WITH_SELINUX
358 },
359 // FUSE mounts are special as the supported feature set
360 // is not clear a priori.
361 FUSE_SUPER_MAGIC => {
362 Flags::WITH_FUSE
363 },
364 _ => {
365 Flags::WITH_2SEC_TIME |
366 Flags::WITH_READ_ONLY |
367 Flags::WITH_PERMISSIONS |
368 Flags::WITH_SYMLINKS |
369 Flags::WITH_DEVICE_NODES |
370 Flags::WITH_FIFOS |
371 Flags::WITH_SOCKETS |
372 Flags::WITH_XATTRS |
373 Flags::WITH_ACL |
374 Flags::WITH_FCAPS
375 },
376 }
377 }
378 }