Directory: | cvmfs/ |
---|---|
File: | cvmfs/magic_xattr.cc |
Date: | 2025-07-13 02:35:07 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 181 | 486 | 37.2% |
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 | 532 | MagicXattrManager::MagicXattrManager( | |
20 | MountPoint *mountpoint, | ||
21 | EVisibility visibility, | ||
22 | const std::set<std::string> &protected_xattrs, | ||
23 | 532 | const std::set<gid_t> &priviledged_xattr_gids) | |
24 | 532 | : mount_point_(mountpoint) | |
25 | 532 | , visibility_(visibility) | |
26 |
1/2✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
|
532 | , protected_xattrs_(protected_xattrs) |
27 |
1/2✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
|
532 | , privileged_xattr_gids_(priviledged_xattr_gids) |
28 | 532 | , is_frozen_(false) { | |
29 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.catalog_counters", new CatalogCountersMagicXattr()); |
30 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.external_host", new ExternalHostMagicXattr()); |
31 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.external_timeout", new ExternalTimeoutMagicXattr()); |
32 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.fqrn", new FqrnMagicXattr()); |
33 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.host", new HostMagicXattr()); |
34 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.host_list", new HostListMagicXattr()); |
35 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.ncleanup24", new NCleanup24MagicXattr()); |
36 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.nclg", new NClgMagicXattr()); |
37 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.ndiropen", new NDirOpenMagicXattr()); |
38 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.ndownload", new NDownloadMagicXattr()); |
39 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.nioerr", new NIOErrMagicXattr()); |
40 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.nopen", new NOpenMagicXattr()); |
41 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.hitrate", new HitrateMagicXattr()); |
42 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.logbuffer", new LogBufferXattr()); |
43 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.proxy", new ProxyMagicXattr()); |
44 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.proxy_list", new ProxyListMagicXattr()); |
45 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.proxy_list_external", new ProxyListExternalMagicXattr()); |
46 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.pubkeys", new PubkeysMagicXattr()); |
47 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.repo_counters", new RepoCountersMagicXattr()); |
48 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.repo_metainfo", new RepoMetainfoMagicXattr()); |
49 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.revision", new RevisionMagicXattr()); |
50 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.root_hash", new RootHashMagicXattr()); |
51 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.rx", new RxMagicXattr()); |
52 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.speed", new SpeedMagicXattr()); |
53 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.tag", new TagMagicXattr()); |
54 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.timeout", new TimeoutMagicXattr()); |
55 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.timeout_direct", new TimeoutDirectMagicXattr()); |
56 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.timestamp_last_ioerr", new TimestampLastIOErrMagicXattr()); |
57 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.usedfd", new UsedFdMagicXattr()); |
58 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.useddirp", new UsedDirPMagicXattr()); |
59 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.version", new VersionMagicXattr()); |
60 | |||
61 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.hash", new HashMagicXattr()); |
62 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.lhash", new LHashMagicXattr()); |
63 | |||
64 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.chunk_list", new ChunkListMagicXattr()); |
65 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.chunks", new ChunksMagicXattr()); |
66 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.compression", new CompressionMagicXattr()); |
67 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.direct_io", new DirectIoMagicXattr()); |
68 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.external_file", new ExternalFileMagicXattr()); |
69 | |||
70 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.rawlink", new RawlinkMagicXattr()); |
71 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("xfsroot.rawlink", new RawlinkMagicXattr()); |
72 | |||
73 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.authz", new AuthzMagicXattr()); |
74 |
4/8✓ Branch 1 taken 532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 532 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
|
532 | Register("user.external_url", new ExternalURLMagicXattr()); |
75 | 532 | } | |
76 | |||
77 | 192 | std::string MagicXattrManager::GetListString(catalog::DirectoryEntry *dirent) { | |
78 |
2/2✓ Branch 1 taken 96 times.
✓ Branch 2 taken 96 times.
|
192 | if (visibility() == kVisibilityNever) { |
79 |
1/2✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
|
96 | return ""; |
80 | } | ||
81 | // Only the root entry has an empty name | ||
82 |
7/12✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 48 times.
✓ Branch 8 taken 48 times.
✓ Branch 9 taken 96 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 48 times.
✓ Branch 13 taken 48 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
96 | if (visibility() == kVisibilityRootOnly && !dirent->name().IsEmpty()) { |
83 |
1/2✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
|
48 | return ""; |
84 | } | ||
85 | |||
86 | 48 | std::string result; | |
87 | 48 | std::map<std::string, BaseMagicXattr *>::iterator it = xattr_list_.begin(); | |
88 |
2/2✓ Branch 3 taken 2016 times.
✓ Branch 4 taken 48 times.
|
2064 | for (; it != xattr_list_.end(); ++it) { |
89 |
1/2✓ Branch 2 taken 2016 times.
✗ Branch 3 not taken.
|
2016 | const MagicXattrFlavor flavor = (*it).second->GetXattrFlavor(); |
90 | // Skip those which should not be displayed | ||
91 |
6/7✓ Branch 0 taken 1488 times.
✓ Branch 1 taken 96 times.
✓ Branch 2 taken 240 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 96 times.
✓ Branch 5 taken 48 times.
✗ Branch 6 not taken.
|
2016 | switch (flavor) { |
92 | 1488 | case kXattrBase: | |
93 | 1488 | break; | |
94 | 96 | case kXattrWithHash: | |
95 |
1/2✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
|
96 | if (dirent->checksum().IsNull()) |
96 | 96 | continue; | |
97 | ✗ | break; | |
98 | 240 | case kXattrRegular: | |
99 |
1/2✓ Branch 1 taken 240 times.
✗ Branch 2 not taken.
|
240 | if (!dirent->IsRegular()) |
100 | 240 | continue; | |
101 | ✗ | break; | |
102 | 48 | case kXattrExternal: | |
103 |
2/6✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 48 times.
✗ Branch 7 not taken.
|
48 | if (!(dirent->IsRegular() && dirent->IsExternalFile())) |
104 | 48 | continue; | |
105 | ✗ | break; | |
106 | 96 | case kXattrSymlink: | |
107 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | if (!dirent->IsLink()) |
108 | 96 | continue; | |
109 | ✗ | break; | |
110 | 48 | case kXattrAuthz: | |
111 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | if (!mount_point_->has_membership_req()) |
112 | 48 | continue; | |
113 | ✗ | break; | |
114 | ✗ | default: | |
115 | ✗ | PANIC("unknown magic xattr flavor"); | |
116 | } | ||
117 |
1/2✓ Branch 2 taken 1488 times.
✗ Branch 3 not taken.
|
1488 | result += (*it).first; |
118 |
1/2✓ Branch 1 taken 1488 times.
✗ Branch 2 not taken.
|
1488 | result.push_back('\0'); |
119 | } | ||
120 | |||
121 | 48 | return result; | |
122 | 48 | } | |
123 | |||
124 | 192 | BaseMagicXattr *MagicXattrManager::GetLocked(const std::string &name, | |
125 | PathString path, | ||
126 | catalog::DirectoryEntry *d) { | ||
127 | BaseMagicXattr *result; | ||
128 |
1/2✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
|
192 | if (xattr_list_.count(name) > 0) { |
129 | 192 | result = xattr_list_[name]; | |
130 | } else { | ||
131 | ✗ | return NULL; | |
132 | } | ||
133 | |||
134 |
1/2✓ Branch 2 taken 192 times.
✗ Branch 3 not taken.
|
192 | result->Lock(path, d); |
135 | |||
136 | 192 | return result; | |
137 | } | ||
138 | |||
139 | 22344 | void MagicXattrManager::Register(const std::string &name, | |
140 | BaseMagicXattr *magic_xattr) { | ||
141 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 22344 times.
|
22344 | assert(!is_frozen_); |
142 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 22344 times.
|
22344 | if (xattr_list_.count(name) > 0) { |
143 | ✗ | PANIC(kLogSyslogErr, | |
144 | "Magic extended attribute with name %s already registered", | ||
145 | name.c_str()); | ||
146 | } | ||
147 | 22344 | magic_xattr->xattr_mgr_ = this; | |
148 | 22344 | 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 48 times.
✓ Branch 2 taken 22296 times.
|
22344 | if (protected_xattrs_.count(name) > 0) { |
153 | 48 | magic_xattr->MarkProtected(); | |
154 | } | ||
155 | 22344 | } | |
156 | |||
157 | 96 | bool MagicXattrManager::IsPrivilegedGid(gid_t gid) { | |
158 | 96 | return privileged_xattr_gids_.count(gid) > 0; | |
159 | } | ||
160 | |||
161 | 96 | bool BaseMagicXattr::PrepareValueFencedProtected(gid_t gid) { | |
162 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
|
96 | assert(xattr_mgr_->is_frozen()); |
163 |
5/6✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 48 times.
|
96 | if (is_protected_ && !xattr_mgr_->IsPrivilegedGid(gid)) { |
164 | 48 | return false; | |
165 | } | ||
166 | |||
167 | 48 | return PrepareValueFenced(); | |
168 | } | ||
169 | |||
170 | 48 | void MagicXattrManager::SanityCheckProtectedXattrs() { | |
171 | 48 | std::set<std::string>::const_iterator iter; | |
172 | 48 | std::vector<string> tmp; | |
173 |
2/2✓ Branch 3 taken 48 times.
✓ Branch 4 taken 48 times.
|
96 | for (iter = protected_xattrs_.begin(); iter != protected_xattrs_.end(); |
174 | 48 | iter++) { | |
175 |
2/4✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 48 times.
|
48 | 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 48 times.
|
48 | 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 | 48 | tmp.clear(); | |
189 | 48 | std::set<gid_t>::const_iterator iter_gid; | |
190 | 48 | for (iter_gid = privileged_xattr_gids_.begin(); | |
191 |
2/2✓ Branch 2 taken 48 times.
✓ Branch 3 taken 48 times.
|
96 | iter_gid != privileged_xattr_gids_.end(); |
192 | 48 | iter_gid++) { | |
193 |
2/4✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 48 times.
✗ Branch 6 not taken.
|
48 | tmp.push_back(StringifyUint(*iter_gid)); |
194 | } | ||
195 | |||
196 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | if (tmp.size() > 0) { |
197 |
2/4✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 48 times.
✗ Branch 6 not taken.
|
96 | const std::string msg = JoinStrings(tmp, ","); |
198 |
1/2✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
|
48 | LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslog, |
199 | "Following CVMFS_XATTR_PRIVILEGED_GIDS are set: %s", msg.c_str()); | ||
200 | 48 | } | |
201 | 48 | } | |
202 | |||
203 | 192 | std::string BaseMagicXattr::HeaderMultipageHuman(uint32_t requested_page) { | |
204 |
3/6✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 192 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 192 times.
✗ Branch 8 not taken.
|
384 | return "# Access page at idx: " + StringifyUint(requested_page) + ". " |
205 |
2/4✓ Branch 3 taken 192 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 192 times.
✗ Branch 7 not taken.
|
768 | + "Total num pages: " + StringifyUint(result_pages_.size()) |
206 |
1/2✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
|
384 | + " (access other pages: xattr~<page_num>, starting " |
207 |
1/2✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
|
384 | + " with 0; number of pages available: xattr~?)\n"; |
208 | } | ||
209 | |||
210 | 960 | 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 960 times.
|
960 | assert(requested_page >= -1); |
213 | 960 | result_pages_.clear(); | |
214 |
1/2✓ Branch 1 taken 960 times.
✗ Branch 2 not taken.
|
960 | FinalizeValue(); |
215 | |||
216 |
1/2✓ Branch 2 taken 960 times.
✗ Branch 3 not taken.
|
960 | std::string res = ""; |
217 |
2/2✓ Branch 0 taken 672 times.
✓ Branch 1 taken 288 times.
|
960 | if (mode == kXattrMachineMode) { |
218 |
2/2✓ Branch 1 taken 96 times.
✓ Branch 2 taken 576 times.
|
672 | if (requested_page >= static_cast<int32_t>(result_pages_.size())) { |
219 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | return std::pair<bool, std::string>(false, ""); |
220 | } | ||
221 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 576 times.
|
576 | 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 288 times.
✗ Branch 1 not taken.
|
288 | } else if (mode == kXattrHumanMode) { |
226 |
2/2✓ Branch 1 taken 96 times.
✓ Branch 2 taken 192 times.
|
288 | 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 96 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 96 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 96 times.
✗ Branch 9 not taken.
|
192 | + StringifyUint(result_pages_.size()) + " pages available.\n" |
231 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
192 | + "Access them with xattr~<page_num> (machine-readable mode) " |
232 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
192 | + "or xattr@<page_num> (human-readable mode).\n" |
233 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | + "Use xattr@? or xattr~? to get extra info about the attribute"); |
234 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 192 times.
|
192 | } 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 192 times.
✗ Branch 2 not taken.
|
192 | 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 768 times.
✗ Branch 3 not taken.
|
768 | res += result_pages_[requested_page]; |
249 | |||
250 |
1/2✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
|
768 | return std::pair<bool, std::string>(true, res); |
251 | 960 | } | |
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 | 48 | 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 | 96 | void FqrnMagicXattr::FinalizeValue() { | |
397 |
1/2✓ Branch 3 taken 96 times.
✗ Branch 4 not taken.
|
96 | result_pages_.push_back(xattr_mgr_->mount_point()->fqrn()); |
398 | 96 | } | |
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 = xattr_mgr_->mount_point() | |
456 | ->file_system() | ||
457 | ->cache_mgr() | ||
458 | ✗ | ->ChecksumFd(fd, &hash); | |
459 | ✗ | if (retval_i != 0) | |
460 | ✗ | result = "I/O error (" + StringifyInt(retval_i) + ")"; | |
461 | else | ||
462 | ✗ | result = hash.ToString(); | |
463 | ✗ | xattr_mgr_->mount_point()->file_system()->cache_mgr()->Close(fd); | |
464 | } | ||
465 | ✗ | result_pages_.push_back(result); | |
466 | } | ||
467 | |||
468 |
1/2✓ Branch 2 taken 532 times.
✗ Branch 3 not taken.
|
532 | LogBufferXattr::LogBufferXattr() : BaseMagicXattr(), throttle_(1, 500, 2000) { } |
469 | |||
470 | 96 | void LogBufferXattr::FinalizeValue() { | |
471 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | throttle_.Throttle(); |
472 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | std::vector<LogBufferEntry> buffer = GetLogBuffer(); |
473 | 96 | std::string result; | |
474 | 96 | for (std::vector<LogBufferEntry>::reverse_iterator itr = buffer.rbegin(); | |
475 |
3/4✓ Branch 2 taken 1056 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 960 times.
✓ Branch 5 taken 96 times.
|
1056 | itr != buffer.rend(); |
476 | 960 | ++itr) { | |
477 |
3/4✓ Branch 1 taken 960 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 912 times.
|
960 | if (itr->message.size() > kMaxLogLine) { |
478 |
2/4✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
|
48 | itr->message.resize(kMaxLogLine); |
479 |
2/4✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
|
48 | itr->message += " <snip>"; |
480 | } | ||
481 |
6/12✓ Branch 1 taken 960 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 960 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 960 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 960 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 960 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 960 times.
✗ Branch 17 not taken.
|
1920 | result += "[" + StringifyLocalTime(itr->timestamp) + "] " + itr->message |
482 |
2/4✓ Branch 1 taken 960 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 960 times.
✗ Branch 5 not taken.
|
960 | + "\n"; |
483 | } | ||
484 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | result_pages_.push_back(result); |
485 | 96 | } | |
486 | |||
487 | ✗ | void NCleanup24MagicXattr::FinalizeValue() { | |
488 | ✗ | QuotaManager *quota_mgr = xattr_mgr_->mount_point() | |
489 | ->file_system() | ||
490 | ->cache_mgr() | ||
491 | ✗ | ->quota_mgr(); | |
492 | ✗ | if (!quota_mgr->HasCapability(QuotaManager::kCapIntrospectCleanupRate)) { | |
493 | ✗ | result_pages_.push_back(StringifyInt(-1)); | |
494 | } else { | ||
495 | ✗ | const uint64_t period_s = 24 * 60 * 60; | |
496 | ✗ | const uint64_t rate = quota_mgr->GetCleanupRate(period_s); | |
497 | ✗ | result_pages_.push_back(StringifyUint(rate)); | |
498 | } | ||
499 | } | ||
500 | |||
501 | ✗ | bool NClgMagicXattr::PrepareValueFenced() { | |
502 | ✗ | n_catalogs_ = xattr_mgr_->mount_point()->catalog_mgr()->GetNumCatalogs(); | |
503 | ✗ | return true; | |
504 | } | ||
505 | |||
506 | ✗ | void NClgMagicXattr::FinalizeValue() { | |
507 | ✗ | result_pages_.push_back(StringifyInt(n_catalogs_)); | |
508 | } | ||
509 | |||
510 | ✗ | void NDirOpenMagicXattr::FinalizeValue() { | |
511 | ✗ | result_pages_.push_back( | |
512 | ✗ | xattr_mgr_->mount_point()->file_system()->n_fs_dir_open()->ToString()); | |
513 | } | ||
514 | |||
515 | ✗ | void NDownloadMagicXattr::FinalizeValue() { | |
516 | ✗ | result_pages_.push_back(xattr_mgr_->mount_point() | |
517 | ->statistics() | ||
518 | ->Lookup("fetch.n_downloads") | ||
519 | ✗ | ->Print()); | |
520 | } | ||
521 | |||
522 | ✗ | void NIOErrMagicXattr::FinalizeValue() { | |
523 | ✗ | result_pages_.push_back(StringifyInt( | |
524 | ✗ | xattr_mgr_->mount_point()->file_system()->io_error_info()->count())); | |
525 | } | ||
526 | |||
527 | ✗ | void NOpenMagicXattr::FinalizeValue() { | |
528 | ✗ | result_pages_.push_back( | |
529 | ✗ | xattr_mgr_->mount_point()->file_system()->n_fs_open()->ToString()); | |
530 | } | ||
531 | |||
532 | ✗ | void HitrateMagicXattr::FinalizeValue() { | |
533 | ✗ | const int64_t n_invocations = xattr_mgr_->mount_point() | |
534 | ->statistics() | ||
535 | ->Lookup("fetch.n_invocations") | ||
536 | ✗ | ->Get(); | |
537 | ✗ | if (n_invocations == 0) { | |
538 | ✗ | result_pages_.push_back("n/a"); | |
539 | ✗ | return; | |
540 | } | ||
541 | |||
542 | ✗ | const int64_t n_downloads = xattr_mgr_->mount_point() | |
543 | ->statistics() | ||
544 | ->Lookup("fetch.n_downloads") | ||
545 | ✗ | ->Get(); | |
546 | ✗ | const float hitrate = 100. | |
547 | ✗ | * (1. | |
548 | ✗ | - (static_cast<float>(n_downloads) | |
549 | ✗ | / static_cast<float>(n_invocations))); | |
550 | ✗ | result_pages_.push_back(StringifyDouble(hitrate)); | |
551 | } | ||
552 | |||
553 | ✗ | void ProxyMagicXattr::FinalizeValue() { | |
554 | ✗ | vector<vector<download::DownloadManager::ProxyInfo> > proxy_chain; | |
555 | unsigned current_group; | ||
556 | ✗ | xattr_mgr_->mount_point()->download_mgr()->GetProxyInfo(&proxy_chain, | |
557 | ¤t_group, NULL); | ||
558 | ✗ | if (proxy_chain.size()) { | |
559 | ✗ | result_pages_.push_back(proxy_chain[current_group][0].url); | |
560 | } else { | ||
561 | ✗ | result_pages_.push_back("DIRECT"); | |
562 | } | ||
563 | } | ||
564 | |||
565 | ✗ | static void ListProxy(download::DownloadManager *dm, | |
566 | std::vector<std::string> *result_pages) { | ||
567 | ✗ | vector<vector<download::DownloadManager::ProxyInfo> > proxy_chain; | |
568 | unsigned current_group; | ||
569 | ✗ | dm->GetProxyInfo(&proxy_chain, ¤t_group, NULL); | |
570 | ✗ | std::string buf = ""; | |
571 | ✗ | for (unsigned int i = 0; i < proxy_chain.size(); i++) { | |
572 | ✗ | for (unsigned int j = 0; j < proxy_chain[i].size(); j++) { | |
573 | ✗ | buf += proxy_chain[i][j].url; | |
574 | ✗ | buf += "\n"; | |
575 | } | ||
576 | |||
577 | ✗ | if (buf.size() > BaseMagicXattr::kMaxCharsPerPage) { | |
578 | ✗ | result_pages->push_back(buf); | |
579 | ✗ | buf = ""; | |
580 | } | ||
581 | } | ||
582 | |||
583 | ✗ | if (buf.size() > 0 || result_pages->size() == 0) { | |
584 | ✗ | result_pages->push_back(buf); | |
585 | } | ||
586 | } | ||
587 | |||
588 | ✗ | void ProxyListMagicXattr::FinalizeValue() { | |
589 | ✗ | ListProxy(xattr_mgr_->mount_point()->download_mgr(), &result_pages_); | |
590 | } | ||
591 | |||
592 | ✗ | void ProxyListExternalMagicXattr::FinalizeValue() { | |
593 | ✗ | ListProxy(xattr_mgr_->mount_point()->external_download_mgr(), &result_pages_); | |
594 | } | ||
595 | |||
596 | ✗ | bool PubkeysMagicXattr::PrepareValueFenced() { | |
597 | ✗ | pubkeys_ = xattr_mgr_->mount_point() | |
598 | ->signature_mgr() | ||
599 | ✗ | ->GetActivePubkeysAsVector(); | |
600 | ✗ | return true; | |
601 | } | ||
602 | |||
603 | 768 | void PubkeysMagicXattr::FinalizeValue() { | |
604 | 768 | size_t full_size = 0; | |
605 | |||
606 |
2/2✓ Branch 1 taken 3792 times.
✓ Branch 2 taken 768 times.
|
4560 | for (size_t i = 0; i < pubkeys_.size(); i++) { |
607 | 3792 | full_size += pubkeys_[i].size(); | |
608 | } | ||
609 | |||
610 |
2/2✓ Branch 0 taken 96 times.
✓ Branch 1 taken 672 times.
|
768 | if (full_size == 0) { |
611 | 96 | return; | |
612 | } | ||
613 | |||
614 | 672 | size_t size_within_page = 0; | |
615 |
1/2✓ Branch 2 taken 672 times.
✗ Branch 3 not taken.
|
672 | std::string res = ""; |
616 | |||
617 |
2/2✓ Branch 1 taken 3792 times.
✓ Branch 2 taken 672 times.
|
4464 | for (size_t i = 0; i < pubkeys_.size(); i++) { |
618 |
2/2✓ Branch 2 taken 624 times.
✓ Branch 3 taken 3168 times.
|
3792 | if (size_within_page + pubkeys_[i].size() >= kMaxCharsPerPage) { |
619 |
1/2✓ Branch 1 taken 624 times.
✗ Branch 2 not taken.
|
624 | result_pages_.push_back(res); |
620 |
1/2✓ Branch 1 taken 624 times.
✗ Branch 2 not taken.
|
624 | res = ""; |
621 | 624 | size_within_page = 0; | |
622 | } | ||
623 | |||
624 |
1/2✓ Branch 2 taken 3792 times.
✗ Branch 3 not taken.
|
3792 | res += pubkeys_[i]; |
625 | 3792 | size_within_page += pubkeys_[i].size(); | |
626 | } | ||
627 |
1/2✓ Branch 1 taken 672 times.
✗ Branch 2 not taken.
|
672 | if (res.size() > 0) { |
628 |
1/2✓ Branch 1 taken 672 times.
✗ Branch 2 not taken.
|
672 | result_pages_.push_back(res); |
629 | } | ||
630 | 672 | } | |
631 | |||
632 | ✗ | bool RawlinkMagicXattr::PrepareValueFenced() { return dirent_->IsLink(); } | |
633 | |||
634 | ✗ | void RawlinkMagicXattr::FinalizeValue() { | |
635 | ✗ | result_pages_.push_back(dirent_->symlink().ToString()); | |
636 | } | ||
637 | |||
638 | ✗ | bool RepoCountersMagicXattr::PrepareValueFenced() { | |
639 | ✗ | counters_ = xattr_mgr_->mount_point() | |
640 | ✗ | ->catalog_mgr() | |
641 | ->GetRootCatalog() | ||
642 | ✗ | ->GetCounters(); | |
643 | ✗ | return true; | |
644 | } | ||
645 | |||
646 | ✗ | void RepoCountersMagicXattr::FinalizeValue() { | |
647 | ✗ | result_pages_.push_back(counters_.GetCsvMap()); | |
648 | } | ||
649 | |||
650 | uint64_t RepoMetainfoMagicXattr::kMaxMetainfoLength = 65536; | ||
651 | |||
652 | ✗ | bool RepoMetainfoMagicXattr::PrepareValueFenced() { | |
653 | ✗ | if (!xattr_mgr_->mount_point()->catalog_mgr()->manifest()) { | |
654 | ✗ | error_reason_ = "manifest not available"; | |
655 | ✗ | return true; | |
656 | } | ||
657 | |||
658 | ✗ | metainfo_hash_ = xattr_mgr_->mount_point() | |
659 | ->catalog_mgr() | ||
660 | ->manifest() | ||
661 | ✗ | ->meta_info(); | |
662 | ✗ | if (metainfo_hash_.IsNull()) { | |
663 | ✗ | error_reason_ = "metainfo not available"; | |
664 | ✗ | return true; | |
665 | } | ||
666 | ✗ | return true; | |
667 | } | ||
668 | |||
669 | ✗ | void RepoMetainfoMagicXattr::FinalizeValue() { | |
670 | ✗ | if (metainfo_hash_.IsNull()) { | |
671 | ✗ | result_pages_.push_back(error_reason_); | |
672 | ✗ | return; | |
673 | } | ||
674 | |||
675 | ✗ | CacheManager::Label label; | |
676 | ✗ | label.path = xattr_mgr_->mount_point()->fqrn() + "(" | |
677 | ✗ | + metainfo_hash_.ToString() + ")"; | |
678 | ✗ | label.flags = CacheManager::kLabelMetainfo; | |
679 | ✗ | const int fd = xattr_mgr_->mount_point()->fetcher()->Fetch( | |
680 | ✗ | CacheManager::LabeledObject(metainfo_hash_, label)); | |
681 | ✗ | if (fd < 0) { | |
682 | ✗ | result_pages_.push_back("Failed to open metadata file"); | |
683 | ✗ | return; | |
684 | } | ||
685 | ✗ | const uint64_t actual_size = xattr_mgr_->mount_point() | |
686 | ->file_system() | ||
687 | ✗ | ->cache_mgr() | |
688 | ✗ | ->GetSize(fd); | |
689 | ✗ | if (actual_size > kMaxMetainfoLength) { | |
690 | ✗ | xattr_mgr_->mount_point()->file_system()->cache_mgr()->Close(fd); | |
691 | ✗ | result_pages_.push_back("Failed to open: metadata file is too big"); | |
692 | ✗ | return; | |
693 | } | ||
694 | ✗ | char buffer[kMaxMetainfoLength]; | |
695 | const int64_t | ||
696 | ✗ | bytes_read = xattr_mgr_->mount_point()->file_system()->cache_mgr()->Pread( | |
697 | fd, buffer, actual_size, 0); | ||
698 | ✗ | xattr_mgr_->mount_point()->file_system()->cache_mgr()->Close(fd); | |
699 | ✗ | if (bytes_read < 0) { | |
700 | ✗ | result_pages_.push_back("Failed to read metadata file"); | |
701 | ✗ | return; | |
702 | } | ||
703 | ✗ | result_pages_.push_back(string(buffer, buffer + bytes_read)); | |
704 | } | ||
705 | |||
706 | ✗ | bool RevisionMagicXattr::PrepareValueFenced() { | |
707 | ✗ | revision_ = xattr_mgr_->mount_point()->catalog_mgr()->GetRevision(); | |
708 | ✗ | return true; | |
709 | } | ||
710 | |||
711 | ✗ | void RevisionMagicXattr::FinalizeValue() { | |
712 | ✗ | result_pages_.push_back(StringifyUint(revision_)); | |
713 | } | ||
714 | |||
715 | ✗ | bool RootHashMagicXattr::PrepareValueFenced() { | |
716 | ✗ | root_hash_ = xattr_mgr_->mount_point()->catalog_mgr()->GetRootHash(); | |
717 | ✗ | return true; | |
718 | } | ||
719 | |||
720 | ✗ | void RootHashMagicXattr::FinalizeValue() { | |
721 | ✗ | result_pages_.push_back(root_hash_.ToString()); | |
722 | } | ||
723 | |||
724 | ✗ | void RxMagicXattr::FinalizeValue() { | |
725 | ✗ | perf::Statistics *statistics = xattr_mgr_->mount_point()->statistics(); | |
726 | ✗ | const int64_t rx = statistics->Lookup("download.sz_transferred_bytes")->Get(); | |
727 | ✗ | result_pages_.push_back(StringifyInt(rx / 1024)); | |
728 | } | ||
729 | |||
730 | ✗ | void SpeedMagicXattr::FinalizeValue() { | |
731 | ✗ | perf::Statistics *statistics = xattr_mgr_->mount_point()->statistics(); | |
732 | ✗ | const int64_t rx = statistics->Lookup("download.sz_transferred_bytes")->Get(); | |
733 | ✗ | const int64_t time = statistics->Lookup("download.sz_transfer_time")->Get(); | |
734 | ✗ | if (time == 0) { | |
735 | ✗ | result_pages_.push_back("n/a"); | |
736 | } else { | ||
737 | ✗ | result_pages_.push_back(StringifyInt((1000 * (rx / 1024)) / time)); | |
738 | } | ||
739 | } | ||
740 | |||
741 | ✗ | bool TagMagicXattr::PrepareValueFenced() { | |
742 | ✗ | tag_ = xattr_mgr_->mount_point()->repository_tag(); | |
743 | ✗ | return true; | |
744 | } | ||
745 | |||
746 | ✗ | void TagMagicXattr::FinalizeValue() { result_pages_.push_back(tag_); } | |
747 | |||
748 | ✗ | void TimeoutMagicXattr::FinalizeValue() { | |
749 | unsigned seconds, seconds_direct; | ||
750 | ✗ | xattr_mgr_->mount_point()->download_mgr()->GetTimeout(&seconds, | |
751 | &seconds_direct); | ||
752 | ✗ | result_pages_.push_back(StringifyUint(seconds)); | |
753 | } | ||
754 | |||
755 | ✗ | void TimeoutDirectMagicXattr::FinalizeValue() { | |
756 | unsigned seconds, seconds_direct; | ||
757 | ✗ | xattr_mgr_->mount_point()->download_mgr()->GetTimeout(&seconds, | |
758 | &seconds_direct); | ||
759 | ✗ | result_pages_.push_back(StringifyUint(seconds_direct)); | |
760 | } | ||
761 | |||
762 | ✗ | void TimestampLastIOErrMagicXattr::FinalizeValue() { | |
763 | ✗ | result_pages_.push_back(StringifyInt(xattr_mgr_->mount_point() | |
764 | ->file_system() | ||
765 | ->io_error_info() | ||
766 | ->timestamp_last())); | ||
767 | } | ||
768 | |||
769 | ✗ | void UsedFdMagicXattr::FinalizeValue() { | |
770 | ✗ | result_pages_.push_back( | |
771 | ✗ | xattr_mgr_->mount_point()->file_system()->no_open_files()->ToString()); | |
772 | } | ||
773 | |||
774 | ✗ | void UsedDirPMagicXattr::FinalizeValue() { | |
775 | ✗ | result_pages_.push_back( | |
776 | ✗ | xattr_mgr_->mount_point()->file_system()->no_open_dirs()->ToString()); | |
777 | } | ||
778 | |||
779 | ✗ | void VersionMagicXattr::FinalizeValue() { | |
780 | ✗ | result_pages_.push_back(std::string(CVMFS_VERSION) + "." | |
781 | ✗ | + std::string(CVMFS_PATCH_LEVEL)); | |
782 | } | ||
783 | |||
784 | ✗ | void ExternalURLMagicXattr::FinalizeValue() { | |
785 | ✗ | std::vector<std::string> host_chain; | |
786 | ✗ | std::vector<int> rtt; | |
787 | unsigned current_host; | ||
788 | ✗ | if (xattr_mgr_->mount_point()->external_download_mgr() != NULL) { | |
789 | ✗ | xattr_mgr_->mount_point()->external_download_mgr()->GetHostInfo( | |
790 | &host_chain, &rtt, ¤t_host); | ||
791 | ✗ | if (host_chain.size()) { | |
792 | ✗ | result_pages_.push_back(std::string(host_chain[current_host]) | |
793 | ✗ | + std::string(path_.c_str())); | |
794 | ✗ | return; | |
795 | } | ||
796 | } | ||
797 | ✗ | result_pages_.push_back(""); | |
798 | } | ||
799 | |||
800 | ✗ | bool ExternalURLMagicXattr::PrepareValueFenced() { | |
801 | ✗ | return dirent_->IsRegular() && dirent_->IsExternalFile(); | |
802 | } | ||
803 |