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