| Directory: | cvmfs/ |
|---|---|
| File: | cvmfs/magic_xattr.cc |
| Date: | 2025-11-09 02:35:23 |
| 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 | 560 | MagicXattrManager::MagicXattrManager( | |
| 20 | MountPoint *mountpoint, | ||
| 21 | EVisibility visibility, | ||
| 22 | const std::set<std::string> &protected_xattrs, | ||
| 23 | 560 | const std::set<gid_t> &priviledged_xattr_gids) | |
| 24 | 560 | : mount_point_(mountpoint) | |
| 25 | 560 | , visibility_(visibility) | |
| 26 |
1/2✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
|
560 | , protected_xattrs_(protected_xattrs) |
| 27 |
1/2✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
|
560 | , privileged_xattr_gids_(priviledged_xattr_gids) |
| 28 | 560 | , is_frozen_(false) { | |
| 29 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.catalog_counters", new CatalogCountersMagicXattr()); |
| 30 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.external_host", new ExternalHostMagicXattr()); |
| 31 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.external_timeout", new ExternalTimeoutMagicXattr()); |
| 32 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.fqrn", new FqrnMagicXattr()); |
| 33 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.host", new HostMagicXattr()); |
| 34 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.host_list", new HostListMagicXattr()); |
| 35 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.ncleanup24", new NCleanup24MagicXattr()); |
| 36 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.nclg", new NClgMagicXattr()); |
| 37 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.ndiropen", new NDirOpenMagicXattr()); |
| 38 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.ndownload", new NDownloadMagicXattr()); |
| 39 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.nioerr", new NIOErrMagicXattr()); |
| 40 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.nopen", new NOpenMagicXattr()); |
| 41 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.hitrate", new HitrateMagicXattr()); |
| 42 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.logbuffer", new LogBufferXattr()); |
| 43 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.proxy", new ProxyMagicXattr()); |
| 44 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.proxy_list", new ProxyListMagicXattr()); |
| 45 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.proxy_list_external", new ProxyListExternalMagicXattr()); |
| 46 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.pubkeys", new PubkeysMagicXattr()); |
| 47 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.repo_counters", new RepoCountersMagicXattr()); |
| 48 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.repo_metainfo", new RepoMetainfoMagicXattr()); |
| 49 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.revision", new RevisionMagicXattr()); |
| 50 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.root_hash", new RootHashMagicXattr()); |
| 51 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.rx", new RxMagicXattr()); |
| 52 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.speed", new SpeedMagicXattr()); |
| 53 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.tag", new TagMagicXattr()); |
| 54 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.timeout", new TimeoutMagicXattr()); |
| 55 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.timeout_direct", new TimeoutDirectMagicXattr()); |
| 56 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.timestamp_last_ioerr", new TimestampLastIOErrMagicXattr()); |
| 57 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.usedfd", new UsedFdMagicXattr()); |
| 58 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.useddirp", new UsedDirPMagicXattr()); |
| 59 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.version", new VersionMagicXattr()); |
| 60 | |||
| 61 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.hash", new HashMagicXattr()); |
| 62 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.lhash", new LHashMagicXattr()); |
| 63 | |||
| 64 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.chunk_list", new ChunkListMagicXattr()); |
| 65 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.chunks", new ChunksMagicXattr()); |
| 66 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.compression", new CompressionMagicXattr()); |
| 67 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.direct_io", new DirectIoMagicXattr()); |
| 68 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.external_file", new ExternalFileMagicXattr()); |
| 69 | |||
| 70 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.rawlink", new RawlinkMagicXattr()); |
| 71 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("xfsroot.rawlink", new RawlinkMagicXattr()); |
| 72 | |||
| 73 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.authz", new AuthzMagicXattr()); |
| 74 |
4/8✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
|
560 | Register("user.external_url", new ExternalURLMagicXattr()); |
| 75 | 560 | } | |
| 76 | |||
| 77 | 116 | std::string MagicXattrManager::GetListString(catalog::DirectoryEntry *dirent) { | |
| 78 |
2/2✓ Branch 1 taken 58 times.
✓ Branch 2 taken 58 times.
|
116 | if (visibility() == kVisibilityNever) { |
| 79 |
1/2✓ Branch 2 taken 58 times.
✗ Branch 3 not taken.
|
58 | return ""; |
| 80 | } | ||
| 81 | // Only the root entry has an empty name | ||
| 82 |
7/12✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 58 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 29 times.
✓ Branch 8 taken 29 times.
✓ Branch 9 taken 58 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 29 times.
✓ Branch 13 taken 29 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
58 | if (visibility() == kVisibilityRootOnly && !dirent->name().IsEmpty()) { |
| 83 |
1/2✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
|
29 | return ""; |
| 84 | } | ||
| 85 | |||
| 86 | 29 | std::string result; | |
| 87 | 29 | std::map<std::string, BaseMagicXattr *>::iterator it = xattr_list_.begin(); | |
| 88 |
2/2✓ Branch 3 taken 1218 times.
✓ Branch 4 taken 29 times.
|
1247 | for (; it != xattr_list_.end(); ++it) { |
| 89 |
1/2✓ Branch 2 taken 1218 times.
✗ Branch 3 not taken.
|
1218 | const MagicXattrFlavor flavor = (*it).second->GetXattrFlavor(); |
| 90 | // Skip those which should not be displayed | ||
| 91 |
6/7✓ Branch 0 taken 899 times.
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 145 times.
✓ Branch 3 taken 29 times.
✓ Branch 4 taken 58 times.
✓ Branch 5 taken 29 times.
✗ Branch 6 not taken.
|
1218 | switch (flavor) { |
| 92 | 899 | case kXattrBase: | |
| 93 | 899 | break; | |
| 94 | 58 | case kXattrWithHash: | |
| 95 |
1/2✓ Branch 2 taken 58 times.
✗ Branch 3 not taken.
|
58 | if (dirent->checksum().IsNull()) |
| 96 | 58 | continue; | |
| 97 | ✗ | break; | |
| 98 | 145 | case kXattrRegular: | |
| 99 |
1/2✓ Branch 1 taken 145 times.
✗ Branch 2 not taken.
|
145 | if (!dirent->IsRegular()) |
| 100 | 145 | continue; | |
| 101 | ✗ | break; | |
| 102 | 29 | case kXattrExternal: | |
| 103 |
2/6✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 29 times.
✗ Branch 7 not taken.
|
29 | if (!(dirent->IsRegular() && dirent->IsExternalFile())) |
| 104 | 29 | continue; | |
| 105 | ✗ | break; | |
| 106 | 58 | case kXattrSymlink: | |
| 107 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
58 | if (!dirent->IsLink()) |
| 108 | 58 | continue; | |
| 109 | ✗ | break; | |
| 110 | 29 | case kXattrAuthz: | |
| 111 |
1/2✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
|
29 | if (!mount_point_->has_membership_req()) |
| 112 | 29 | continue; | |
| 113 | ✗ | break; | |
| 114 | ✗ | default: | |
| 115 | ✗ | PANIC("unknown magic xattr flavor"); | |
| 116 | } | ||
| 117 |
1/2✓ Branch 2 taken 899 times.
✗ Branch 3 not taken.
|
899 | result += (*it).first; |
| 118 |
1/2✓ Branch 1 taken 899 times.
✗ Branch 2 not taken.
|
899 | result.push_back('\0'); |
| 119 | } | ||
| 120 | |||
| 121 | 29 | return result; | |
| 122 | 29 | } | |
| 123 | |||
| 124 | 116 | BaseMagicXattr *MagicXattrManager::GetLocked(const std::string &name, | |
| 125 | PathString path, | ||
| 126 | catalog::DirectoryEntry *d) { | ||
| 127 | BaseMagicXattr *result; | ||
| 128 |
1/2✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
|
116 | if (xattr_list_.count(name) > 0) { |
| 129 | 116 | result = xattr_list_[name]; | |
| 130 | } else { | ||
| 131 | ✗ | return NULL; | |
| 132 | } | ||
| 133 | |||
| 134 |
1/2✓ Branch 2 taken 116 times.
✗ Branch 3 not taken.
|
116 | result->Lock(path, d); |
| 135 | |||
| 136 | 116 | return result; | |
| 137 | } | ||
| 138 | |||
| 139 | 23520 | void MagicXattrManager::Register(const std::string &name, | |
| 140 | BaseMagicXattr *magic_xattr) { | ||
| 141 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 23520 times.
|
23520 | assert(!is_frozen_); |
| 142 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 23520 times.
|
23520 | if (xattr_list_.count(name) > 0) { |
| 143 | ✗ | PANIC(kLogSyslogErr, | |
| 144 | "Magic extended attribute with name %s already registered", | ||
| 145 | name.c_str()); | ||
| 146 | } | ||
| 147 | 23520 | magic_xattr->xattr_mgr_ = this; | |
| 148 | 23520 | 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 29 times.
✓ Branch 2 taken 23491 times.
|
23520 | if (protected_xattrs_.count(name) > 0) { |
| 153 | 29 | magic_xattr->MarkProtected(); | |
| 154 | } | ||
| 155 | 23520 | } | |
| 156 | |||
| 157 | 58 | bool MagicXattrManager::IsPrivilegedGid(gid_t gid) { | |
| 158 | 58 | return privileged_xattr_gids_.count(gid) > 0; | |
| 159 | } | ||
| 160 | |||
| 161 | 58 | bool BaseMagicXattr::PrepareValueFencedProtected(gid_t gid) { | |
| 162 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | assert(xattr_mgr_->is_frozen()); |
| 163 |
5/6✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 29 times.
✓ Branch 4 taken 29 times.
✓ Branch 5 taken 29 times.
✓ Branch 6 taken 29 times.
|
58 | if (is_protected_ && !xattr_mgr_->IsPrivilegedGid(gid)) { |
| 164 | 29 | return false; | |
| 165 | } | ||
| 166 | |||
| 167 | 29 | return PrepareValueFenced(); | |
| 168 | } | ||
| 169 | |||
| 170 | 29 | void MagicXattrManager::SanityCheckProtectedXattrs() { | |
| 171 | 29 | std::set<std::string>::const_iterator iter; | |
| 172 | 29 | std::vector<string> tmp; | |
| 173 |
2/2✓ Branch 3 taken 29 times.
✓ Branch 4 taken 29 times.
|
58 | for (iter = protected_xattrs_.begin(); iter != protected_xattrs_.end(); |
| 174 | 29 | iter++) { | |
| 175 |
2/4✓ Branch 3 taken 29 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 29 times.
|
29 | 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 29 times.
|
29 | 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 | 29 | tmp.clear(); | |
| 189 | 29 | std::set<gid_t>::const_iterator iter_gid; | |
| 190 | 29 | for (iter_gid = privileged_xattr_gids_.begin(); | |
| 191 |
2/2✓ Branch 2 taken 29 times.
✓ Branch 3 taken 29 times.
|
58 | iter_gid != privileged_xattr_gids_.end(); |
| 192 | 29 | iter_gid++) { | |
| 193 |
2/4✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 29 times.
✗ Branch 6 not taken.
|
29 | tmp.push_back(StringifyUint(*iter_gid)); |
| 194 | } | ||
| 195 | |||
| 196 |
1/2✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
|
29 | if (tmp.size() > 0) { |
| 197 |
2/4✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 29 times.
✗ Branch 6 not taken.
|
58 | const std::string msg = JoinStrings(tmp, ","); |
| 198 |
1/2✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
|
29 | LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslog, |
| 199 | "Following CVMFS_XATTR_PRIVILEGED_GIDS are set: %s", msg.c_str()); | ||
| 200 | 29 | } | |
| 201 | 29 | } | |
| 202 | |||
| 203 | 116 | std::string BaseMagicXattr::HeaderMultipageHuman(uint32_t requested_page) { | |
| 204 |
3/6✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 116 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 116 times.
✗ Branch 8 not taken.
|
232 | return "# Access page at idx: " + StringifyUint(requested_page) + ". " |
| 205 |
2/4✓ Branch 3 taken 116 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 116 times.
✗ Branch 7 not taken.
|
464 | + "Total num pages: " + StringifyUint(result_pages_.size()) |
| 206 |
1/2✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
|
232 | + " (access other pages: xattr~<page_num>, starting " |
| 207 |
1/2✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
|
232 | + " with 0; number of pages available: xattr~?)\n"; |
| 208 | } | ||
| 209 | |||
| 210 | 580 | 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 580 times.
|
580 | assert(requested_page >= -1); |
| 213 | 580 | result_pages_.clear(); | |
| 214 |
1/2✓ Branch 1 taken 580 times.
✗ Branch 2 not taken.
|
580 | FinalizeValue(); |
| 215 | |||
| 216 |
1/2✓ Branch 2 taken 580 times.
✗ Branch 3 not taken.
|
580 | std::string res = ""; |
| 217 |
2/2✓ Branch 0 taken 406 times.
✓ Branch 1 taken 174 times.
|
580 | if (mode == kXattrMachineMode) { |
| 218 |
2/2✓ Branch 1 taken 58 times.
✓ Branch 2 taken 348 times.
|
406 | if (requested_page >= static_cast<int32_t>(result_pages_.size())) { |
| 219 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
58 | return std::pair<bool, std::string>(false, ""); |
| 220 | } | ||
| 221 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 348 times.
|
348 | 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 174 times.
✗ Branch 1 not taken.
|
174 | } else if (mode == kXattrHumanMode) { |
| 226 |
2/2✓ Branch 1 taken 58 times.
✓ Branch 2 taken 116 times.
|
174 | 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 58 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 58 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 58 times.
✗ Branch 9 not taken.
|
116 | + StringifyUint(result_pages_.size()) + " pages available.\n" |
| 231 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
116 | + "Access them with xattr~<page_num> (machine-readable mode) " |
| 232 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
116 | + "or xattr@<page_num> (human-readable mode).\n" |
| 233 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
58 | + "Use xattr@? or xattr~? to get extra info about the attribute"); |
| 234 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 116 times.
|
116 | } 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 116 times.
✗ Branch 2 not taken.
|
116 | 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 464 times.
✗ Branch 3 not taken.
|
464 | res += result_pages_[requested_page]; |
| 249 | |||
| 250 |
1/2✓ Branch 1 taken 464 times.
✗ Branch 2 not taken.
|
464 | return std::pair<bool, std::string>(true, res); |
| 251 | 580 | } | |
| 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 | 29 | 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 | 58 | void FqrnMagicXattr::FinalizeValue() { | |
| 397 |
1/2✓ Branch 3 taken 58 times.
✗ Branch 4 not taken.
|
58 | result_pages_.push_back(xattr_mgr_->mount_point()->fqrn()); |
| 398 | 58 | } | |
| 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 560 times.
✗ Branch 3 not taken.
|
560 | LogBufferXattr::LogBufferXattr() : BaseMagicXattr(), throttle_(1, 500, 2000) { } |
| 469 | |||
| 470 | 58 | void LogBufferXattr::FinalizeValue() { | |
| 471 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
58 | throttle_.Throttle(); |
| 472 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
58 | std::vector<LogBufferEntry> buffer = GetLogBuffer(); |
| 473 | 58 | std::string result; | |
| 474 | 58 | for (std::vector<LogBufferEntry>::reverse_iterator itr = buffer.rbegin(); | |
| 475 |
3/4✓ Branch 2 taken 638 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 580 times.
✓ Branch 5 taken 58 times.
|
638 | itr != buffer.rend(); |
| 476 | 580 | ++itr) { | |
| 477 |
3/4✓ Branch 1 taken 580 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 29 times.
✓ Branch 5 taken 551 times.
|
580 | if (itr->message.size() > kMaxLogLine) { |
| 478 |
2/4✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
|
29 | itr->message.resize(kMaxLogLine); |
| 479 |
2/4✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
|
29 | itr->message += " <snip>"; |
| 480 | } | ||
| 481 |
6/12✓ Branch 1 taken 580 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 580 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 580 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 580 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 580 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 580 times.
✗ Branch 17 not taken.
|
1160 | result += "[" + StringifyLocalTime(itr->timestamp) + "] " + itr->message |
| 482 |
2/4✓ Branch 1 taken 580 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 580 times.
✗ Branch 5 not taken.
|
580 | + "\n"; |
| 483 | } | ||
| 484 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
58 | result_pages_.push_back(result); |
| 485 | 58 | } | |
| 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 | 464 | void PubkeysMagicXattr::FinalizeValue() { | |
| 604 | 464 | size_t full_size = 0; | |
| 605 | |||
| 606 |
2/2✓ Branch 1 taken 2291 times.
✓ Branch 2 taken 464 times.
|
2755 | for (size_t i = 0; i < pubkeys_.size(); i++) { |
| 607 | 2291 | full_size += pubkeys_[i].size(); | |
| 608 | } | ||
| 609 | |||
| 610 |
2/2✓ Branch 0 taken 58 times.
✓ Branch 1 taken 406 times.
|
464 | if (full_size == 0) { |
| 611 | 58 | return; | |
| 612 | } | ||
| 613 | |||
| 614 | 406 | size_t size_within_page = 0; | |
| 615 |
1/2✓ Branch 2 taken 406 times.
✗ Branch 3 not taken.
|
406 | std::string res = ""; |
| 616 | |||
| 617 |
2/2✓ Branch 1 taken 2291 times.
✓ Branch 2 taken 406 times.
|
2697 | for (size_t i = 0; i < pubkeys_.size(); i++) { |
| 618 |
2/2✓ Branch 2 taken 377 times.
✓ Branch 3 taken 1914 times.
|
2291 | if (size_within_page + pubkeys_[i].size() >= kMaxCharsPerPage) { |
| 619 |
1/2✓ Branch 1 taken 377 times.
✗ Branch 2 not taken.
|
377 | result_pages_.push_back(res); |
| 620 |
1/2✓ Branch 1 taken 377 times.
✗ Branch 2 not taken.
|
377 | res = ""; |
| 621 | 377 | size_within_page = 0; | |
| 622 | } | ||
| 623 | |||
| 624 |
1/2✓ Branch 2 taken 2291 times.
✗ Branch 3 not taken.
|
2291 | res += pubkeys_[i]; |
| 625 | 2291 | size_within_page += pubkeys_[i].size(); | |
| 626 | } | ||
| 627 |
1/2✓ Branch 1 taken 406 times.
✗ Branch 2 not taken.
|
406 | if (res.size() > 0) { |
| 628 |
1/2✓ Branch 1 taken 406 times.
✗ Branch 2 not taken.
|
406 | result_pages_.push_back(res); |
| 629 | } | ||
| 630 | 406 | } | |
| 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 |