Directory: | cvmfs/ |
---|---|
File: | cvmfs/magic_xattr.cc |
Date: | 2025-06-22 02:36:02 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 181 | 481 | 37.6% |
Branches: | 289 | 983 | 29.4% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * This file is part of the CernVM File System. | ||
3 | */ | ||
4 | |||
5 | #include "magic_xattr.h" | ||
6 | |||
7 | #include <cassert> | ||
8 | #include <string> | ||
9 | #include <vector> | ||
10 | |||
11 | #include "catalog_mgr_client.h" | ||
12 | #include "crypto/signature.h" | ||
13 | #include "fetch.h" | ||
14 | #include "mountpoint.h" | ||
15 | #include "quota.h" | ||
16 | #include "util/logging.h" | ||
17 | #include "util/string.h" | ||
18 | |||
19 | 1116 | MagicXattrManager::MagicXattrManager( | |
20 | MountPoint *mountpoint, | ||
21 | EVisibility visibility, | ||
22 | const std::set<std::string> &protected_xattrs, | ||
23 | 1116 | const std::set<gid_t> &priviledged_xattr_gids) | |
24 | 1116 | : mount_point_(mountpoint) | |
25 | 1116 | , visibility_(visibility) | |
26 |
1/2✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
|
1116 | , protected_xattrs_(protected_xattrs) |
27 |
1/2✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
|
1116 | , privileged_xattr_gids_(priviledged_xattr_gids) |
28 | 1116 | , is_frozen_(false) { | |
29 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.catalog_counters", new CatalogCountersMagicXattr()); |
30 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.external_host", new ExternalHostMagicXattr()); |
31 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.external_timeout", new ExternalTimeoutMagicXattr()); |
32 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.fqrn", new FqrnMagicXattr()); |
33 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.host", new HostMagicXattr()); |
34 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.host_list", new HostListMagicXattr()); |
35 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.ncleanup24", new NCleanup24MagicXattr()); |
36 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.nclg", new NClgMagicXattr()); |
37 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.ndiropen", new NDirOpenMagicXattr()); |
38 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.ndownload", new NDownloadMagicXattr()); |
39 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.nioerr", new NIOErrMagicXattr()); |
40 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.nopen", new NOpenMagicXattr()); |
41 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.hitrate", new HitrateMagicXattr()); |
42 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.logbuffer", new LogBufferXattr()); |
43 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.proxy", new ProxyMagicXattr()); |
44 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.proxy_list", new ProxyListMagicXattr()); |
45 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.proxy_list_external", new ProxyListExternalMagicXattr()); |
46 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.pubkeys", new PubkeysMagicXattr()); |
47 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.repo_counters", new RepoCountersMagicXattr()); |
48 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.repo_metainfo", new RepoMetainfoMagicXattr()); |
49 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.revision", new RevisionMagicXattr()); |
50 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.root_hash", new RootHashMagicXattr()); |
51 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.rx", new RxMagicXattr()); |
52 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.speed", new SpeedMagicXattr()); |
53 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.tag", new TagMagicXattr()); |
54 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.timeout", new TimeoutMagicXattr()); |
55 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.timeout_direct", new TimeoutDirectMagicXattr()); |
56 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.timestamp_last_ioerr", new TimestampLastIOErrMagicXattr()); |
57 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.usedfd", new UsedFdMagicXattr()); |
58 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.useddirp", new UsedDirPMagicXattr()); |
59 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.version", new VersionMagicXattr()); |
60 | |||
61 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.hash", new HashMagicXattr()); |
62 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.lhash", new LHashMagicXattr()); |
63 | |||
64 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.chunk_list", new ChunkListMagicXattr()); |
65 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.chunks", new ChunksMagicXattr()); |
66 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.compression", new CompressionMagicXattr()); |
67 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.direct_io", new DirectIoMagicXattr()); |
68 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.external_file", new ExternalFileMagicXattr()); |
69 | |||
70 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.rawlink", new RawlinkMagicXattr()); |
71 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("xfsroot.rawlink", new RawlinkMagicXattr()); |
72 | |||
73 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.authz", new AuthzMagicXattr()); |
74 |
4/8✓ Branch 1 taken 1116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1116 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1116 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1116 times.
✗ Branch 12 not taken.
|
1116 | Register("user.external_url", new ExternalURLMagicXattr()); |
75 | 1116 | } | |
76 | |||
77 | 36 | std::string MagicXattrManager::GetListString(catalog::DirectoryEntry *dirent) { | |
78 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 2 taken 18 times.
|
36 | if (visibility() == kVisibilityNever) { |
79 |
1/2✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
|
18 | return ""; |
80 | } | ||
81 | // Only the root entry has an empty name | ||
82 |
7/12✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 9 times.
✓ Branch 9 taken 18 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 9 times.
✓ Branch 13 taken 9 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
18 | if (visibility() == kVisibilityRootOnly && !dirent->name().IsEmpty()) { |
83 |
1/2✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
9 | return ""; |
84 | } | ||
85 | |||
86 | 9 | std::string result; | |
87 | 9 | std::map<std::string, BaseMagicXattr *>::iterator it = xattr_list_.begin(); | |
88 |
2/2✓ Branch 3 taken 378 times.
✓ Branch 4 taken 9 times.
|
387 | for (; it != xattr_list_.end(); ++it) { |
89 |
1/2✓ Branch 2 taken 378 times.
✗ Branch 3 not taken.
|
378 | const MagicXattrFlavor flavor = (*it).second->GetXattrFlavor(); |
90 | // Skip those which should not be displayed | ||
91 |
6/7✓ Branch 0 taken 279 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
|
378 | switch (flavor) { |
92 | 279 | case kXattrBase: | |
93 | 279 | break; | |
94 | 18 | case kXattrWithHash: | |
95 |
1/2✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
|
18 | if (dirent->checksum().IsNull()) |
96 | 18 | continue; | |
97 | ✗ | break; | |
98 | 45 | case kXattrRegular: | |
99 |
1/2✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
|
45 | if (!dirent->IsRegular()) |
100 | 45 | continue; | |
101 | ✗ | break; | |
102 | 9 | case kXattrExternal: | |
103 |
2/6✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
|
9 | if (!(dirent->IsRegular() && dirent->IsExternalFile())) |
104 | 9 | continue; | |
105 | ✗ | break; | |
106 | 18 | case kXattrSymlink: | |
107 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | if (!dirent->IsLink()) |
108 | 18 | continue; | |
109 | ✗ | break; | |
110 | 9 | case kXattrAuthz: | |
111 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | if (!mount_point_->has_membership_req()) |
112 | 9 | continue; | |
113 | ✗ | break; | |
114 | ✗ | default: | |
115 | ✗ | PANIC("unknown magic xattr flavor"); | |
116 | } | ||
117 |
1/2✓ Branch 2 taken 279 times.
✗ Branch 3 not taken.
|
279 | result += (*it).first; |
118 |
1/2✓ Branch 1 taken 279 times.
✗ Branch 2 not taken.
|
279 | result.push_back('\0'); |
119 | } | ||
120 | |||
121 | 9 | return result; | |
122 | 9 | } | |
123 | |||
124 | 36 | BaseMagicXattr *MagicXattrManager::GetLocked(const std::string &name, | |
125 | PathString path, | ||
126 | catalog::DirectoryEntry *d) { | ||
127 | BaseMagicXattr *result; | ||
128 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
36 | if (xattr_list_.count(name) > 0) { |
129 | 36 | result = xattr_list_[name]; | |
130 | } else { | ||
131 | ✗ | return NULL; | |
132 | } | ||
133 | |||
134 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | result->Lock(path, d); |
135 | |||
136 | 36 | return result; | |
137 | } | ||
138 | |||
139 | 46872 | void MagicXattrManager::Register(const std::string &name, | |
140 | BaseMagicXattr *magic_xattr) { | ||
141 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 46872 times.
|
46872 | assert(!is_frozen_); |
142 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 46872 times.
|
46872 | if (xattr_list_.count(name) > 0) { |
143 | ✗ | PANIC(kLogSyslogErr, | |
144 | "Magic extended attribute with name %s already registered", | ||
145 | name.c_str()); | ||
146 | } | ||
147 | 46872 | magic_xattr->xattr_mgr_ = this; | |
148 | 46872 | xattr_list_[name] = magic_xattr; | |
149 | |||
150 | // Mark Xattr protected so that only certain fuse_gids' can access it. | ||
151 | // If Xattr with registered "name" is part of *protected_xattrs | ||
152 |
2/2✓ Branch 1 taken 9 times.
✓ Branch 2 taken 46863 times.
|
46872 | if (protected_xattrs_.count(name) > 0) { |
153 | 9 | magic_xattr->MarkProtected(); | |
154 | } | ||
155 | 46872 | } | |
156 | |||
157 | 18 | bool MagicXattrManager::IsPrivilegedGid(gid_t gid) { | |
158 | 18 | return privileged_xattr_gids_.count(gid) > 0; | |
159 | } | ||
160 | |||
161 | 18 | bool BaseMagicXattr::PrepareValueFencedProtected(gid_t gid) { | |
162 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
|
18 | assert(xattr_mgr_->is_frozen()); |
163 |
5/6✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 9 times.
|
18 | if (is_protected_ && !xattr_mgr_->IsPrivilegedGid(gid)) { |
164 | 9 | return false; | |
165 | } | ||
166 | |||
167 | 9 | return PrepareValueFenced(); | |
168 | } | ||
169 | |||
170 | 9 | void MagicXattrManager::SanityCheckProtectedXattrs() { | |
171 | 9 | std::set<std::string>::const_iterator iter; | |
172 | 9 | std::vector<string> tmp; | |
173 |
2/2✓ Branch 3 taken 9 times.
✓ Branch 4 taken 9 times.
|
18 | for (iter = protected_xattrs_.begin(); iter != protected_xattrs_.end(); |
174 | 9 | iter++) { | |
175 |
2/4✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 9 times.
|
9 | if (xattr_list_.find(*iter) == xattr_list_.end()) { |
176 | ✗ | tmp.push_back(*iter); | |
177 | } | ||
178 | } | ||
179 | |||
180 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
|
9 | if (tmp.size() > 0) { |
181 | ✗ | const std::string msg = JoinStrings(tmp, ","); | |
182 | ✗ | LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogWarn, | |
183 | "Following CVMFS_XATTR_PROTECTED_XATTRS are " | ||
184 | "set but not recognized: %s", | ||
185 | msg.c_str()); | ||
186 | } | ||
187 | |||
188 | 9 | tmp.clear(); | |
189 | 9 | std::set<gid_t>::const_iterator iter_gid; | |
190 | 9 | for (iter_gid = privileged_xattr_gids_.begin(); | |
191 |
2/2✓ Branch 2 taken 9 times.
✓ Branch 3 taken 9 times.
|
18 | iter_gid != privileged_xattr_gids_.end(); |
192 | 9 | iter_gid++) { | |
193 |
2/4✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
|
9 | tmp.push_back(StringifyUint(*iter_gid)); |
194 | } | ||
195 | |||
196 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | if (tmp.size() > 0) { |
197 |
2/4✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
|
18 | const std::string msg = JoinStrings(tmp, ","); |
198 |
1/2✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
9 | LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslog, |
199 | "Following CVMFS_XATTR_PRIVILEGED_GIDS are set: %s", msg.c_str()); | ||
200 | 9 | } | |
201 | 9 | } | |
202 | |||
203 | 36 | std::string BaseMagicXattr::HeaderMultipageHuman(uint32_t requested_page) { | |
204 |
3/6✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 36 times.
✗ Branch 8 not taken.
|
72 | return "# Access page at idx: " + StringifyUint(requested_page) + ". " |
205 |
2/4✓ Branch 3 taken 36 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 36 times.
✗ Branch 7 not taken.
|
144 | + "Total num pages: " + StringifyUint(result_pages_.size()) |
206 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
72 | + " (access other pages: xattr~<page_num>, starting " |
207 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
72 | + " with 0; number of pages available: xattr~?)\n"; |
208 | } | ||
209 | |||
210 | 180 | std::pair<bool, std::string> BaseMagicXattr::GetValue( | |
211 | int32_t requested_page, const MagicXattrMode mode) { | ||
212 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 180 times.
|
180 | assert(requested_page >= -1); |
213 | 180 | result_pages_.clear(); | |
214 |
1/2✓ Branch 1 taken 180 times.
✗ Branch 2 not taken.
|
180 | FinalizeValue(); |
215 | |||
216 |
1/2✓ Branch 2 taken 180 times.
✗ Branch 3 not taken.
|
180 | std::string res = ""; |
217 |
2/2✓ Branch 0 taken 126 times.
✓ Branch 1 taken 54 times.
|
180 | if (mode == kXattrMachineMode) { |
218 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 2 taken 108 times.
|
126 | if (requested_page >= static_cast<int32_t>(result_pages_.size())) { |
219 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | return std::pair<bool, std::string>(false, ""); |
220 | } | ||
221 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
|
108 | if (requested_page == -1) { |
222 | return std::pair<bool, std::string>( | ||
223 | ✗ | true, "num_pages, " + StringifyUint(result_pages_.size())); | |
224 | } | ||
225 |
1/2✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
|
54 | } else if (mode == kXattrHumanMode) { |
226 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 2 taken 36 times.
|
54 | if (requested_page >= static_cast<int32_t>(result_pages_.size())) { |
227 | return std::pair<bool, std::string>( | ||
228 | true, | ||
229 | "Page requested does not exists. There are " | ||
230 |
3/6✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 18 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 18 times.
✗ Branch 9 not taken.
|
36 | + StringifyUint(result_pages_.size()) + " pages available.\n" |
231 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
36 | + "Access them with xattr~<page_num> (machine-readable mode) " |
232 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
36 | + "or xattr@<page_num> (human-readable mode).\n" |
233 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | + "Use xattr@? or xattr~? to get extra info about the attribute"); |
234 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
|
36 | } else if (requested_page == -1) { |
235 | return std::pair<bool, std::string>( | ||
236 | true, | ||
237 | "Access xattr with xattr~<page_num> (machine-readable mode) or " | ||
238 | ✗ | + std::string(" xattr@<page_num> (human-readable mode).\n") | |
239 | ✗ | + "Pages available: " + StringifyUint(result_pages_.size())); | |
240 | } else { | ||
241 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
36 | res = HeaderMultipageHuman(requested_page); |
242 | } | ||
243 | } else { | ||
244 | ✗ | PANIC(kLogStderr | kLogSyslogErr, | |
245 | "Unknown mode of magic xattr requested: %d", mode); | ||
246 | } | ||
247 | |||
248 |
1/2✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
|
144 | res += result_pages_[requested_page]; |
249 | |||
250 |
1/2✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
|
144 | return std::pair<bool, std::string>(true, res); |
251 | 180 | } | |
252 | |||
253 | ✗ | bool AuthzMagicXattr::PrepareValueFenced() { | |
254 | ✗ | return xattr_mgr_->mount_point()->has_membership_req(); | |
255 | } | ||
256 | |||
257 | ✗ | void AuthzMagicXattr::FinalizeValue() { | |
258 | ✗ | result_pages_.push_back(xattr_mgr_->mount_point()->membership_req()); | |
259 | } | ||
260 | |||
261 | 9 | MagicXattrFlavor AuthzMagicXattr::GetXattrFlavor() { return kXattrAuthz; } | |
262 | |||
263 | ✗ | bool CatalogCountersMagicXattr::PrepareValueFenced() { | |
264 | ✗ | counters_ = xattr_mgr_->mount_point()->catalog_mgr()->LookupCounters( | |
265 | ✗ | path_, &subcatalog_path_, &hash_); | |
266 | ✗ | return true; | |
267 | } | ||
268 | |||
269 | ✗ | void CatalogCountersMagicXattr::FinalizeValue() { | |
270 | ✗ | std::string res; | |
271 | ✗ | res = "catalog_hash: " + hash_.ToString() + "\n"; | |
272 | ✗ | res += "catalog_mountpoint: " + subcatalog_path_ + "\n"; | |
273 | ✗ | res += counters_.GetCsvMap(); | |
274 | |||
275 | ✗ | result_pages_.push_back(res); | |
276 | } | ||
277 | |||
278 | ✗ | bool ChunkListMagicXattr::PrepareValueFenced() { | |
279 | ✗ | chunk_list_.clear(); | |
280 | |||
281 | ✗ | const std::string header = "hash,offset,size\n"; | |
282 | ✗ | std::string chunk_list_page_(header); | |
283 | ✗ | if (!dirent_->IsRegular()) { | |
284 | ✗ | chunk_list_.push_back(chunk_list_page_); | |
285 | ✗ | return false; | |
286 | } | ||
287 | ✗ | if (dirent_->IsChunkedFile()) { | |
288 | ✗ | FileChunkList chunks; | |
289 | ✗ | if (!xattr_mgr_->mount_point()->catalog_mgr()->ListFileChunks( | |
290 | ✗ | path_, dirent_->hash_algorithm(), &chunks) | |
291 | ✗ | || chunks.IsEmpty()) { | |
292 | ✗ | LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogErr, | |
293 | "file %s is marked as " | ||
294 | "'chunked', but no chunks found.", | ||
295 | path_.c_str()); | ||
296 | ✗ | return false; | |
297 | } else { | ||
298 | ✗ | for (size_t i = 0; i < chunks.size(); ++i) { | |
299 | ✗ | chunk_list_page_ += chunks.At(i).content_hash().ToString() + ","; | |
300 | ✗ | chunk_list_page_ += StringifyInt(chunks.At(i).offset()) + ","; | |
301 | ✗ | chunk_list_page_ += StringifyUint(chunks.At(i).size()) + "\n"; | |
302 | |||
303 | ✗ | if (chunk_list_page_.size() > kMaxCharsPerPage) { | |
304 | ✗ | chunk_list_.push_back(chunk_list_page_); | |
305 | ✗ | chunk_list_page_ = header; | |
306 | } | ||
307 | } | ||
308 | } | ||
309 | ✗ | } else { | |
310 | ✗ | chunk_list_page_ += dirent_->checksum().ToString() + ","; | |
311 | ✗ | chunk_list_page_ += "0,"; | |
312 | ✗ | chunk_list_page_ += StringifyUint(dirent_->size()) + "\n"; | |
313 | } | ||
314 | |||
315 | // add the last page | ||
316 | ✗ | if (chunk_list_page_.size() > header.size()) { | |
317 | ✗ | chunk_list_.push_back(chunk_list_page_); | |
318 | } | ||
319 | |||
320 | ✗ | return true; | |
321 | } | ||
322 | |||
323 | ✗ | void ChunkListMagicXattr::FinalizeValue() { result_pages_ = chunk_list_; } | |
324 | |||
325 | ✗ | bool ChunksMagicXattr::PrepareValueFenced() { | |
326 | ✗ | if (!dirent_->IsRegular()) { | |
327 | ✗ | return false; | |
328 | } | ||
329 | ✗ | if (dirent_->IsChunkedFile()) { | |
330 | ✗ | FileChunkList chunks; | |
331 | ✗ | if (!xattr_mgr_->mount_point()->catalog_mgr()->ListFileChunks( | |
332 | ✗ | path_, dirent_->hash_algorithm(), &chunks) | |
333 | ✗ | || chunks.IsEmpty()) { | |
334 | ✗ | LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogErr, | |
335 | "file %s is marked as " | ||
336 | "'chunked', but no chunks found.", | ||
337 | path_.c_str()); | ||
338 | ✗ | return false; | |
339 | } else { | ||
340 | ✗ | n_chunks_ = chunks.size(); | |
341 | } | ||
342 | ✗ | } else { | |
343 | ✗ | n_chunks_ = 1; | |
344 | } | ||
345 | |||
346 | ✗ | return true; | |
347 | } | ||
348 | |||
349 | ✗ | void ChunksMagicXattr::FinalizeValue() { | |
350 | ✗ | result_pages_.push_back(StringifyUint(n_chunks_)); | |
351 | } | ||
352 | |||
353 | ✗ | bool CompressionMagicXattr::PrepareValueFenced() { | |
354 | ✗ | return dirent_->IsRegular(); | |
355 | } | ||
356 | |||
357 | ✗ | void CompressionMagicXattr::FinalizeValue() { | |
358 | ✗ | result_pages_.push_back( | |
359 | ✗ | zlib::AlgorithmName(dirent_->compression_algorithm())); | |
360 | } | ||
361 | |||
362 | ✗ | bool DirectIoMagicXattr::PrepareValueFenced() { return dirent_->IsRegular(); } | |
363 | |||
364 | ✗ | void DirectIoMagicXattr::FinalizeValue() { | |
365 | ✗ | result_pages_.push_back(dirent_->IsDirectIo() ? "1" : "0"); | |
366 | } | ||
367 | |||
368 | ✗ | bool ExternalFileMagicXattr::PrepareValueFenced() { | |
369 | ✗ | return dirent_->IsRegular(); | |
370 | } | ||
371 | |||
372 | ✗ | void ExternalFileMagicXattr::FinalizeValue() { | |
373 | ✗ | result_pages_.push_back(dirent_->IsExternalFile() ? "1" : "0"); | |
374 | } | ||
375 | |||
376 | ✗ | void ExternalHostMagicXattr::FinalizeValue() { | |
377 | ✗ | std::vector<string> host_chain; | |
378 | ✗ | std::vector<int> rtt; | |
379 | unsigned current_host; | ||
380 | ✗ | xattr_mgr_->mount_point()->external_download_mgr()->GetHostInfo( | |
381 | &host_chain, &rtt, ¤t_host); | ||
382 | ✗ | if (host_chain.size()) { | |
383 | ✗ | result_pages_.push_back(std::string(host_chain[current_host])); | |
384 | } else { | ||
385 | ✗ | result_pages_.push_back("internal error: no hosts defined"); | |
386 | } | ||
387 | } | ||
388 | |||
389 | ✗ | void ExternalTimeoutMagicXattr::FinalizeValue() { | |
390 | unsigned seconds, seconds_direct; | ||
391 | ✗ | xattr_mgr_->mount_point()->external_download_mgr()->GetTimeout( | |
392 | &seconds, &seconds_direct); | ||
393 | ✗ | result_pages_.push_back(StringifyUint(seconds_direct)); | |
394 | } | ||
395 | |||
396 | 18 | void FqrnMagicXattr::FinalizeValue() { | |
397 |
1/2✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
|
18 | result_pages_.push_back(xattr_mgr_->mount_point()->fqrn()); |
398 | 18 | } | |
399 | |||
400 | ✗ | bool HashMagicXattr::PrepareValueFenced() { | |
401 | ✗ | return !dirent_->checksum().IsNull(); | |
402 | } | ||
403 | |||
404 | ✗ | void HashMagicXattr::FinalizeValue() { | |
405 | ✗ | result_pages_.push_back(dirent_->checksum().ToString()); | |
406 | } | ||
407 | |||
408 | ✗ | void HostMagicXattr::FinalizeValue() { | |
409 | ✗ | std::vector<std::string> host_chain; | |
410 | ✗ | std::vector<int> rtt; | |
411 | unsigned current_host; | ||
412 | ✗ | xattr_mgr_->mount_point()->download_mgr()->GetHostInfo(&host_chain, &rtt, | |
413 | ¤t_host); | ||
414 | ✗ | if (host_chain.size()) { | |
415 | ✗ | result_pages_.push_back(std::string(host_chain[current_host])); | |
416 | } else { | ||
417 | ✗ | result_pages_.push_back("internal error: no hosts defined"); | |
418 | } | ||
419 | } | ||
420 | |||
421 | ✗ | void HostListMagicXattr::FinalizeValue() { | |
422 | ✗ | std::string result; | |
423 | ✗ | std::vector<std::string> host_chain; | |
424 | ✗ | std::vector<int> rtt; | |
425 | unsigned current_host; | ||
426 | ✗ | xattr_mgr_->mount_point()->download_mgr()->GetHostInfo(&host_chain, &rtt, | |
427 | ¤t_host); | ||
428 | ✗ | if (host_chain.size()) { | |
429 | ✗ | result = host_chain[current_host]; | |
430 | ✗ | for (unsigned i = 1; i < host_chain.size(); ++i) { | |
431 | ✗ | result += ";" + host_chain[(i + current_host) % host_chain.size()]; | |
432 | } | ||
433 | } else { | ||
434 | ✗ | result = "internal error: no hosts defined"; | |
435 | } | ||
436 | ✗ | result_pages_.push_back(result); | |
437 | } | ||
438 | |||
439 | ✗ | bool LHashMagicXattr::PrepareValueFenced() { | |
440 | ✗ | return !dirent_->checksum().IsNull(); | |
441 | } | ||
442 | |||
443 | ✗ | void LHashMagicXattr::FinalizeValue() { | |
444 | ✗ | string result; | |
445 | ✗ | CacheManager::Label label; | |
446 | ✗ | label.path = path_.ToString(); | |
447 | ✗ | if (xattr_mgr_->mount_point()->catalog_mgr()->volatile_flag()) | |
448 | ✗ | label.flags = CacheManager::kLabelVolatile; | |
449 | ✗ | const int fd = xattr_mgr_->mount_point()->file_system()->cache_mgr()->Open( | |
450 | ✗ | CacheManager::LabeledObject(dirent_->checksum(), label)); | |
451 | ✗ | if (fd < 0) { | |
452 | ✗ | result = "Not in cache"; | |
453 | } else { | ||
454 | ✗ | shash::Any hash(dirent_->checksum().algorithm); | |
455 | const int retval_i = | ||
456 | ✗ | xattr_mgr_->mount_point()->file_system()->cache_mgr()->ChecksumFd( | |
457 | fd, &hash); | ||
458 | ✗ | if (retval_i != 0) | |
459 | ✗ | result = "I/O error (" + StringifyInt(retval_i) + ")"; | |
460 | else | ||
461 | ✗ | result = hash.ToString(); | |
462 | ✗ | xattr_mgr_->mount_point()->file_system()->cache_mgr()->Close(fd); | |
463 | } | ||
464 | ✗ | result_pages_.push_back(result); | |
465 | } | ||
466 | |||
467 |
1/2✓ Branch 2 taken 1116 times.
✗ Branch 3 not taken.
|
1116 | LogBufferXattr::LogBufferXattr() : BaseMagicXattr(), throttle_(1, 500, 2000) { } |
468 | |||
469 | 18 | void LogBufferXattr::FinalizeValue() { | |
470 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | throttle_.Throttle(); |
471 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | std::vector<LogBufferEntry> buffer = GetLogBuffer(); |
472 | 18 | std::string result; | |
473 | 18 | for (std::vector<LogBufferEntry>::reverse_iterator itr = buffer.rbegin(); | |
474 |
3/4✓ Branch 2 taken 198 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 180 times.
✓ Branch 5 taken 18 times.
|
198 | itr != buffer.rend(); |
475 | 180 | ++itr) { | |
476 |
3/4✓ Branch 1 taken 180 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 171 times.
|
180 | if (itr->message.size() > kMaxLogLine) { |
477 |
2/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
9 | itr->message.resize(kMaxLogLine); |
478 |
2/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
9 | itr->message += " <snip>"; |
479 | } | ||
480 |
6/12✓ Branch 1 taken 180 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 180 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 180 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 180 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 180 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 180 times.
✗ Branch 17 not taken.
|
360 | result += "[" + StringifyLocalTime(itr->timestamp) + "] " + itr->message |
481 |
2/4✓ Branch 1 taken 180 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 180 times.
✗ Branch 5 not taken.
|
180 | + "\n"; |
482 | } | ||
483 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | result_pages_.push_back(result); |
484 | 18 | } | |
485 | |||
486 | ✗ | void NCleanup24MagicXattr::FinalizeValue() { | |
487 | ✗ | QuotaManager *quota_mgr = xattr_mgr_->mount_point() | |
488 | ->file_system() | ||
489 | ->cache_mgr() | ||
490 | ✗ | ->quota_mgr(); | |
491 | ✗ | if (!quota_mgr->HasCapability(QuotaManager::kCapIntrospectCleanupRate)) { | |
492 | ✗ | result_pages_.push_back(StringifyInt(-1)); | |
493 | } else { | ||
494 | ✗ | const uint64_t period_s = 24 * 60 * 60; | |
495 | ✗ | const uint64_t rate = quota_mgr->GetCleanupRate(period_s); | |
496 | ✗ | result_pages_.push_back(StringifyUint(rate)); | |
497 | } | ||
498 | } | ||
499 | |||
500 | ✗ | bool NClgMagicXattr::PrepareValueFenced() { | |
501 | ✗ | n_catalogs_ = xattr_mgr_->mount_point()->catalog_mgr()->GetNumCatalogs(); | |
502 | ✗ | return true; | |
503 | } | ||
504 | |||
505 | ✗ | void NClgMagicXattr::FinalizeValue() { | |
506 | ✗ | result_pages_.push_back(StringifyInt(n_catalogs_)); | |
507 | } | ||
508 | |||
509 | ✗ | void NDirOpenMagicXattr::FinalizeValue() { | |
510 | ✗ | result_pages_.push_back( | |
511 | ✗ | xattr_mgr_->mount_point()->file_system()->n_fs_dir_open()->ToString()); | |
512 | } | ||
513 | |||
514 | ✗ | void NDownloadMagicXattr::FinalizeValue() { | |
515 | ✗ | result_pages_.push_back(xattr_mgr_->mount_point() | |
516 | ->statistics() | ||
517 | ->Lookup("fetch.n_downloads") | ||
518 | ✗ | ->Print()); | |
519 | } | ||
520 | |||
521 | ✗ | void NIOErrMagicXattr::FinalizeValue() { | |
522 | ✗ | result_pages_.push_back(StringifyInt( | |
523 | ✗ | xattr_mgr_->mount_point()->file_system()->io_error_info()->count())); | |
524 | } | ||
525 | |||
526 | ✗ | void NOpenMagicXattr::FinalizeValue() { | |
527 | ✗ | result_pages_.push_back( | |
528 | ✗ | xattr_mgr_->mount_point()->file_system()->n_fs_open()->ToString()); | |
529 | } | ||
530 | |||
531 | ✗ | void HitrateMagicXattr::FinalizeValue() { | |
532 | ✗ | const int64_t n_invocations = xattr_mgr_->mount_point() | |
533 | ->statistics() | ||
534 | ->Lookup("fetch.n_invocations") | ||
535 | ✗ | ->Get(); | |
536 | ✗ | if (n_invocations == 0) { | |
537 | ✗ | result_pages_.push_back("n/a"); | |
538 | ✗ | return; | |
539 | } | ||
540 | |||
541 | ✗ | const int64_t n_downloads = xattr_mgr_->mount_point() | |
542 | ->statistics() | ||
543 | ->Lookup("fetch.n_downloads") | ||
544 | ✗ | ->Get(); | |
545 | ✗ | const float hitrate = 100. * (1. - (static_cast<float>(n_downloads) / | |
546 | ✗ | static_cast<float>(n_invocations))); | |
547 | ✗ | result_pages_.push_back(StringifyDouble(hitrate)); | |
548 | } | ||
549 | |||
550 | ✗ | void ProxyMagicXattr::FinalizeValue() { | |
551 | ✗ | vector<vector<download::DownloadManager::ProxyInfo> > proxy_chain; | |
552 | unsigned current_group; | ||
553 | ✗ | xattr_mgr_->mount_point()->download_mgr()->GetProxyInfo(&proxy_chain, | |
554 | ¤t_group, NULL); | ||
555 | ✗ | if (proxy_chain.size()) { | |
556 | ✗ | result_pages_.push_back(proxy_chain[current_group][0].url); | |
557 | } else { | ||
558 | ✗ | result_pages_.push_back("DIRECT"); | |
559 | } | ||
560 | } | ||
561 | |||
562 | ✗ | static void ListProxy(download::DownloadManager *dm, | |
563 | std::vector<std::string> *result_pages) { | ||
564 | ✗ | vector<vector<download::DownloadManager::ProxyInfo> > proxy_chain; | |
565 | unsigned current_group; | ||
566 | ✗ | dm->GetProxyInfo(&proxy_chain, ¤t_group, NULL); | |
567 | ✗ | std::string buf = ""; | |
568 | ✗ | for (unsigned int i = 0; i < proxy_chain.size(); i++) { | |
569 | ✗ | for (unsigned int j = 0; j < proxy_chain[i].size(); j++) { | |
570 | ✗ | buf += proxy_chain[i][j].url; | |
571 | ✗ | buf += "\n"; | |
572 | } | ||
573 | |||
574 | ✗ | if (buf.size() > BaseMagicXattr::kMaxCharsPerPage) { | |
575 | ✗ | result_pages->push_back(buf); | |
576 | ✗ | buf = ""; | |
577 | } | ||
578 | } | ||
579 | |||
580 | ✗ | if (buf.size() > 0 || result_pages->size() == 0) { | |
581 | ✗ | result_pages->push_back(buf); | |
582 | } | ||
583 | } | ||
584 | |||
585 | ✗ | void ProxyListMagicXattr::FinalizeValue() { | |
586 | ✗ | ListProxy(xattr_mgr_->mount_point()->download_mgr(), &result_pages_); | |
587 | } | ||
588 | |||
589 | ✗ | void ProxyListExternalMagicXattr::FinalizeValue() { | |
590 | ✗ | ListProxy(xattr_mgr_->mount_point()->external_download_mgr(), &result_pages_); | |
591 | } | ||
592 | |||
593 | ✗ | bool PubkeysMagicXattr::PrepareValueFenced() { | |
594 | ✗ | pubkeys_ = xattr_mgr_->mount_point() | |
595 | ->signature_mgr() | ||
596 | ✗ | ->GetActivePubkeysAsVector(); | |
597 | ✗ | return true; | |
598 | } | ||
599 | |||
600 | 144 | void PubkeysMagicXattr::FinalizeValue() { | |
601 | 144 | size_t full_size = 0; | |
602 | |||
603 |
2/2✓ Branch 1 taken 711 times.
✓ Branch 2 taken 144 times.
|
855 | for (size_t i = 0; i < pubkeys_.size(); i++) { |
604 | 711 | full_size += pubkeys_[i].size(); | |
605 | } | ||
606 | |||
607 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 126 times.
|
144 | if (full_size == 0) { |
608 | 18 | return; | |
609 | } | ||
610 | |||
611 | 126 | size_t size_within_page = 0; | |
612 |
1/2✓ Branch 2 taken 126 times.
✗ Branch 3 not taken.
|
126 | std::string res = ""; |
613 | |||
614 |
2/2✓ Branch 1 taken 711 times.
✓ Branch 2 taken 126 times.
|
837 | for (size_t i = 0; i < pubkeys_.size(); i++) { |
615 |
2/2✓ Branch 2 taken 117 times.
✓ Branch 3 taken 594 times.
|
711 | if (size_within_page + pubkeys_[i].size() >= kMaxCharsPerPage) { |
616 |
1/2✓ Branch 1 taken 117 times.
✗ Branch 2 not taken.
|
117 | result_pages_.push_back(res); |
617 |
1/2✓ Branch 1 taken 117 times.
✗ Branch 2 not taken.
|
117 | res = ""; |
618 | 117 | size_within_page = 0; | |
619 | } | ||
620 | |||
621 |
1/2✓ Branch 2 taken 711 times.
✗ Branch 3 not taken.
|
711 | res += pubkeys_[i]; |
622 | 711 | size_within_page += pubkeys_[i].size(); | |
623 | } | ||
624 |
1/2✓ Branch 1 taken 126 times.
✗ Branch 2 not taken.
|
126 | if (res.size() > 0) { |
625 |
1/2✓ Branch 1 taken 126 times.
✗ Branch 2 not taken.
|
126 | result_pages_.push_back(res); |
626 | } | ||
627 | 126 | } | |
628 | |||
629 | ✗ | bool RawlinkMagicXattr::PrepareValueFenced() { return dirent_->IsLink(); } | |
630 | |||
631 | ✗ | void RawlinkMagicXattr::FinalizeValue() { | |
632 | ✗ | result_pages_.push_back(dirent_->symlink().ToString()); | |
633 | } | ||
634 | |||
635 | ✗ | bool RepoCountersMagicXattr::PrepareValueFenced() { | |
636 | ✗ | counters_ = xattr_mgr_->mount_point() | |
637 | ✗ | ->catalog_mgr() | |
638 | ->GetRootCatalog() | ||
639 | ✗ | ->GetCounters(); | |
640 | ✗ | return true; | |
641 | } | ||
642 | |||
643 | ✗ | void RepoCountersMagicXattr::FinalizeValue() { | |
644 | ✗ | result_pages_.push_back(counters_.GetCsvMap()); | |
645 | } | ||
646 | |||
647 | uint64_t RepoMetainfoMagicXattr::kMaxMetainfoLength = 65536; | ||
648 | |||
649 | ✗ | bool RepoMetainfoMagicXattr::PrepareValueFenced() { | |
650 | ✗ | if (!xattr_mgr_->mount_point()->catalog_mgr()->manifest()) { | |
651 | ✗ | error_reason_ = "manifest not available"; | |
652 | ✗ | return true; | |
653 | } | ||
654 | |||
655 | ✗ | metainfo_hash_ = xattr_mgr_->mount_point() | |
656 | ->catalog_mgr() | ||
657 | ->manifest() | ||
658 | ✗ | ->meta_info(); | |
659 | ✗ | if (metainfo_hash_.IsNull()) { | |
660 | ✗ | error_reason_ = "metainfo not available"; | |
661 | ✗ | return true; | |
662 | } | ||
663 | ✗ | return true; | |
664 | } | ||
665 | |||
666 | ✗ | void RepoMetainfoMagicXattr::FinalizeValue() { | |
667 | ✗ | if (metainfo_hash_.IsNull()) { | |
668 | ✗ | result_pages_.push_back(error_reason_); | |
669 | ✗ | return; | |
670 | } | ||
671 | |||
672 | ✗ | CacheManager::Label label; | |
673 | ✗ | label.path = xattr_mgr_->mount_point()->fqrn() + "(" | |
674 | ✗ | + metainfo_hash_.ToString() + ")"; | |
675 | ✗ | label.flags = CacheManager::kLabelMetainfo; | |
676 | ✗ | const int fd = xattr_mgr_->mount_point()->fetcher()->Fetch( | |
677 | ✗ | CacheManager::LabeledObject(metainfo_hash_, label)); | |
678 | ✗ | if (fd < 0) { | |
679 | ✗ | result_pages_.push_back("Failed to open metadata file"); | |
680 | ✗ | return; | |
681 | } | ||
682 | const uint64_t actual_size = | ||
683 | ✗ | xattr_mgr_->mount_point()->file_system()->cache_mgr()->GetSize(fd); | |
684 | ✗ | if (actual_size > kMaxMetainfoLength) { | |
685 | ✗ | xattr_mgr_->mount_point()->file_system()->cache_mgr()->Close(fd); | |
686 | ✗ | result_pages_.push_back("Failed to open: metadata file is too big"); | |
687 | ✗ | return; | |
688 | } | ||
689 | ✗ | char buffer[kMaxMetainfoLength]; | |
690 | const int64_t bytes_read = | ||
691 | ✗ | xattr_mgr_->mount_point()->file_system()->cache_mgr()->Pread( | |
692 | fd, buffer, actual_size, 0); | ||
693 | ✗ | xattr_mgr_->mount_point()->file_system()->cache_mgr()->Close(fd); | |
694 | ✗ | if (bytes_read < 0) { | |
695 | ✗ | result_pages_.push_back("Failed to read metadata file"); | |
696 | ✗ | return; | |
697 | } | ||
698 | ✗ | result_pages_.push_back(string(buffer, buffer + bytes_read)); | |
699 | } | ||
700 | |||
701 | ✗ | bool RevisionMagicXattr::PrepareValueFenced() { | |
702 | ✗ | revision_ = xattr_mgr_->mount_point()->catalog_mgr()->GetRevision(); | |
703 | ✗ | return true; | |
704 | } | ||
705 | |||
706 | ✗ | void RevisionMagicXattr::FinalizeValue() { | |
707 | ✗ | result_pages_.push_back(StringifyUint(revision_)); | |
708 | } | ||
709 | |||
710 | ✗ | bool RootHashMagicXattr::PrepareValueFenced() { | |
711 | ✗ | root_hash_ = xattr_mgr_->mount_point()->catalog_mgr()->GetRootHash(); | |
712 | ✗ | return true; | |
713 | } | ||
714 | |||
715 | ✗ | void RootHashMagicXattr::FinalizeValue() { | |
716 | ✗ | result_pages_.push_back(root_hash_.ToString()); | |
717 | } | ||
718 | |||
719 | ✗ | void RxMagicXattr::FinalizeValue() { | |
720 | ✗ | perf::Statistics *statistics = xattr_mgr_->mount_point()->statistics(); | |
721 | ✗ | const int64_t rx = statistics->Lookup("download.sz_transferred_bytes")->Get(); | |
722 | ✗ | result_pages_.push_back(StringifyInt(rx / 1024)); | |
723 | } | ||
724 | |||
725 | ✗ | void SpeedMagicXattr::FinalizeValue() { | |
726 | ✗ | perf::Statistics *statistics = xattr_mgr_->mount_point()->statistics(); | |
727 | ✗ | const int64_t rx = statistics->Lookup("download.sz_transferred_bytes")->Get(); | |
728 | ✗ | const int64_t time = statistics->Lookup("download.sz_transfer_time")->Get(); | |
729 | ✗ | if (time == 0) { | |
730 | ✗ | result_pages_.push_back("n/a"); | |
731 | } else { | ||
732 | ✗ | result_pages_.push_back(StringifyInt((1000 * (rx / 1024)) / time)); | |
733 | } | ||
734 | } | ||
735 | |||
736 | ✗ | bool TagMagicXattr::PrepareValueFenced() { | |
737 | ✗ | tag_ = xattr_mgr_->mount_point()->repository_tag(); | |
738 | ✗ | return true; | |
739 | } | ||
740 | |||
741 | ✗ | void TagMagicXattr::FinalizeValue() { result_pages_.push_back(tag_); } | |
742 | |||
743 | ✗ | void TimeoutMagicXattr::FinalizeValue() { | |
744 | unsigned seconds, seconds_direct; | ||
745 | ✗ | xattr_mgr_->mount_point()->download_mgr()->GetTimeout(&seconds, | |
746 | &seconds_direct); | ||
747 | ✗ | result_pages_.push_back(StringifyUint(seconds)); | |
748 | } | ||
749 | |||
750 | ✗ | void TimeoutDirectMagicXattr::FinalizeValue() { | |
751 | unsigned seconds, seconds_direct; | ||
752 | ✗ | xattr_mgr_->mount_point()->download_mgr()->GetTimeout(&seconds, | |
753 | &seconds_direct); | ||
754 | ✗ | result_pages_.push_back(StringifyUint(seconds_direct)); | |
755 | } | ||
756 | |||
757 | ✗ | void TimestampLastIOErrMagicXattr::FinalizeValue() { | |
758 | ✗ | result_pages_.push_back(StringifyInt(xattr_mgr_->mount_point() | |
759 | ->file_system() | ||
760 | ->io_error_info() | ||
761 | ->timestamp_last())); | ||
762 | } | ||
763 | |||
764 | ✗ | void UsedFdMagicXattr::FinalizeValue() { | |
765 | ✗ | result_pages_.push_back( | |
766 | ✗ | xattr_mgr_->mount_point()->file_system()->no_open_files()->ToString()); | |
767 | } | ||
768 | |||
769 | ✗ | void UsedDirPMagicXattr::FinalizeValue() { | |
770 | ✗ | result_pages_.push_back( | |
771 | ✗ | xattr_mgr_->mount_point()->file_system()->no_open_dirs()->ToString()); | |
772 | } | ||
773 | |||
774 | ✗ | void VersionMagicXattr::FinalizeValue() { | |
775 | ✗ | result_pages_.push_back(std::string(CVMFS_VERSION) + "." | |
776 | ✗ | + std::string(CVMFS_PATCH_LEVEL)); | |
777 | } | ||
778 | |||
779 | ✗ | void ExternalURLMagicXattr::FinalizeValue() { | |
780 | ✗ | std::vector<std::string> host_chain; | |
781 | ✗ | std::vector<int> rtt; | |
782 | unsigned current_host; | ||
783 | ✗ | if (xattr_mgr_->mount_point()->external_download_mgr() != NULL) { | |
784 | ✗ | xattr_mgr_->mount_point()->external_download_mgr()->GetHostInfo( | |
785 | &host_chain, &rtt, ¤t_host); | ||
786 | ✗ | if (host_chain.size()) { | |
787 | ✗ | result_pages_.push_back(std::string(host_chain[current_host]) | |
788 | ✗ | + std::string(path_.c_str())); | |
789 | ✗ | return; | |
790 | } | ||
791 | } | ||
792 | ✗ | result_pages_.push_back(""); | |
793 | } | ||
794 | |||
795 | ✗ | bool ExternalURLMagicXattr::PrepareValueFenced() { | |
796 | ✗ | return dirent_->IsRegular() && dirent_->IsExternalFile(); | |
797 | } | ||
798 |