@wenathlan/saddle 1.8.17 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +1339 -0
- package/README.md +68 -22
- package/alternatives.ts +1218 -0
- package/biome.json +153 -0
- package/boards.json +1517 -0
- package/compute.ts +3144 -0
- package/cores.json +1801 -0
- package/dist/acquisition.d.ts +359 -0
- package/dist/acquisition.d.ts.map +1 -0
- package/dist/acquisition.js +629 -0
- package/dist/acquisition.js.map +1 -0
- package/dist/alternatives.d.ts +509 -0
- package/dist/alternatives.d.ts.map +1 -0
- package/dist/alternatives.js +951 -0
- package/dist/alternatives.js.map +1 -0
- package/dist/automation.d.ts +426 -0
- package/dist/automation.d.ts.map +1 -0
- package/dist/automation.js +561 -0
- package/dist/automation.js.map +1 -0
- package/dist/browser.d.ts +562 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +1057 -0
- package/dist/browser.js.map +1 -0
- package/dist/capacitor.config.d.ts +13 -0
- package/dist/capacitor.config.d.ts.map +1 -0
- package/dist/capacitor.config.js +26 -0
- package/dist/capacitor.config.js.map +1 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +111 -0
- package/dist/cli.js.map +1 -0
- package/dist/communication.d.ts +192 -0
- package/dist/communication.d.ts.map +1 -0
- package/dist/communication.js +418 -0
- package/dist/communication.js.map +1 -0
- package/dist/compute.d.ts +1161 -0
- package/dist/compute.d.ts.map +1 -0
- package/dist/compute.js +2273 -0
- package/dist/compute.js.map +1 -0
- package/dist/distribution.d.ts +529 -0
- package/dist/distribution.d.ts.map +1 -0
- package/dist/distribution.js +811 -0
- package/dist/distribution.js.map +1 -0
- package/dist/execution.d.ts +530 -0
- package/dist/execution.d.ts.map +1 -0
- package/dist/execution.js +761 -0
- package/dist/execution.js.map +1 -0
- package/dist/format.d.ts +19 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +60 -0
- package/dist/format.js.map +1 -0
- package/dist/foundation.d.ts +176 -0
- package/dist/foundation.d.ts.map +1 -0
- package/dist/foundation.js +309 -0
- package/dist/foundation.js.map +1 -0
- package/dist/index.d.ts +733 -122
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1018 -122
- package/dist/index.js.map +1 -1
- package/dist/integration.d.ts +236 -0
- package/dist/integration.d.ts.map +1 -0
- package/dist/integration.js +236 -0
- package/dist/integration.js.map +1 -0
- package/dist/intelligence.d.ts +94 -0
- package/dist/intelligence.d.ts.map +1 -0
- package/dist/intelligence.js +145 -0
- package/dist/intelligence.js.map +1 -0
- package/dist/isolation.d.ts +129 -0
- package/dist/isolation.d.ts.map +1 -0
- package/dist/isolation.js +96 -0
- package/dist/isolation.js.map +1 -0
- package/dist/media.d.ts +344 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +986 -0
- package/dist/media.js.map +1 -0
- package/dist/modes.d.ts +359 -0
- package/dist/modes.d.ts.map +1 -0
- package/dist/modes.js +134 -0
- package/dist/modes.js.map +1 -0
- package/dist/{library/public.d.ts → operations.d.ts} +15 -1
- package/dist/operations.d.ts.map +1 -0
- package/dist/{library/public.js → operations.js} +18 -7
- package/dist/operations.js.map +1 -0
- package/dist/orchestrator.d.ts +1339 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +4308 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/performance.d.ts +416 -0
- package/dist/performance.d.ts.map +1 -0
- package/dist/performance.js +827 -0
- package/dist/performance.js.map +1 -0
- package/dist/quantum.d.ts +810 -0
- package/dist/quantum.d.ts.map +1 -0
- package/dist/quantum.js +2073 -0
- package/dist/quantum.js.map +1 -0
- package/dist/render.d.ts +381 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +1073 -0
- package/dist/render.js.map +1 -0
- package/dist/scheduler.d.ts +596 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +1259 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/security.d.ts +501 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +1170 -0
- package/dist/security.js.map +1 -0
- package/dist/server.d.ts +21 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/{server/node.js → server.js} +16 -2
- package/dist/server.js.map +1 -0
- package/dist/tiers.d.ts +1002 -0
- package/dist/tiers.d.ts.map +1 -0
- package/dist/tiers.js +2165 -0
- package/dist/tiers.js.map +1 -0
- package/dist/virtual.d.ts +641 -0
- package/dist/virtual.d.ts.map +1 -0
- package/dist/virtual.js +1285 -0
- package/dist/virtual.js.map +1 -0
- package/dist/virtualcpu.d.ts +316 -0
- package/dist/virtualcpu.d.ts.map +1 -0
- package/dist/virtualcpu.js +1180 -0
- package/dist/virtualcpu.js.map +1 -0
- package/dist/virtualgpu.d.ts +345 -0
- package/dist/virtualgpu.d.ts.map +1 -0
- package/dist/virtualgpu.js +1000 -0
- package/dist/virtualgpu.js.map +1 -0
- package/dist/virtualization.d.ts +607 -0
- package/dist/virtualization.d.ts.map +1 -0
- package/dist/virtualization.js +1187 -0
- package/dist/virtualization.js.map +1 -0
- package/dist/virtualmemory.d.ts +818 -0
- package/dist/virtualmemory.d.ts.map +1 -0
- package/dist/virtualmemory.js +1796 -0
- package/dist/virtualmemory.js.map +1 -0
- package/dist/webscrape.d.ts +720 -0
- package/dist/webscrape.d.ts.map +1 -0
- package/dist/webscrape.js +2697 -0
- package/dist/webscrape.js.map +1 -0
- package/docker.config +769 -0
- package/docs/CONVERSA.txt +1523 -0
- package/docs/alternatives.md +499 -0
- package/docs/architecture-1.8.19.md +76 -0
- package/docs/architecture-1.8.19.mmd +33 -0
- package/docs/architecture-1.8.19.png +0 -0
- package/docs/architecture.md +355 -0
- package/docs/artifactavailability.md +6 -0
- package/docs/brancharchive-2026-08-18.md +18 -0
- package/docs/browser.md +7 -0
- package/docs/consolidation.md +70 -0
- package/docs/e2ugh-engine.md +528 -0
- package/{dist/examples/localjob.js → docs/example-localjob.ts} +3 -3
- package/{dist/examples/publicapi.js → docs/example-publicapi.ts} +2 -2
- package/docs/hardware.md +342 -0
- package/docs/optimization.md +126 -0
- package/docs/performance.md +499 -0
- package/docs/planning.1.8.18.md +94 -0
- package/docs/planning.1.8.19.md +49 -0
- package/docs/releasenotes-1.8.17.md +6 -0
- package/docs/releasenotes-1.8.18.md +32 -0
- package/docs/releasenotes-1.8.19.md +35 -0
- package/docs/research-1.8.18-isolation.md +43 -0
- package/docs/research-1.8.19-virtual-browser.md +27 -0
- package/docs/saddle.archive.1.8.17.tar.gz.gpg +0 -0
- package/docs/security.md +454 -0
- package/docs/todo-1.8.16.md +56 -1
- package/docs/todo-1.8.18.md +164 -0
- package/docs/todo-1.8.19.md +241 -0
- package/docs/viability.md +777 -0
- package/docs/virtualization.md +335 -0
- package/docs/web-duplicatecleanup.md +9 -0
- package/docs/web-ideas.md +106 -0
- package/docs/workflowimprovements-2026-08-19.md +70 -0
- package/gpumonitor.cpp +1543 -0
- package/gpus.json +2408 -0
- package/index.ts +1478 -0
- package/media.ts +1337 -0
- package/mttg.config +1549 -0
- package/orchestrator.ts +5462 -0
- package/package.json +304 -55
- package/passage.config +1331 -0
- package/performance.ts +1049 -0
- package/processors.json +2217 -0
- package/qemu.config +1062 -0
- package/qemubridge.py +1340 -0
- package/quantum.ts +2393 -0
- package/render.ts +1325 -0
- package/scheduler.ts +1600 -0
- package/security.ts +1449 -0
- package/tiers.ts +2871 -0
- package/tsconfig.json +29 -0
- package/virtualcpu.ts +1273 -0
- package/virtualgpu.ts +1181 -0
- package/virtualhardware.c +1011 -0
- package/virtualhardware.json +739 -0
- package/virtualization.ts +1628 -0
- package/virtualizationcore.cpp +4635 -0
- package/virtualmemory.ts +2303 -0
- package/vm.config.json +1910 -0
- package/{extension → web/extension}/manifest.json +1 -1
- package/web/readme.md +382 -0
- package/web/tsconfig.json +25 -0
- package/dist/adapters/forge.d.ts +0 -17
- package/dist/adapters/forge.d.ts.map +0 -1
- package/dist/adapters/forge.js +0 -19
- package/dist/adapters/forge.js.map +0 -1
- package/dist/adapters/forgejo.d.ts +0 -49
- package/dist/adapters/forgejo.d.ts.map +0 -1
- package/dist/adapters/forgejo.js +0 -8
- package/dist/adapters/forgejo.js.map +0 -1
- package/dist/adapters/github.d.ts +0 -12
- package/dist/adapters/github.d.ts.map +0 -1
- package/dist/adapters/github.js +0 -20
- package/dist/adapters/github.js.map +0 -1
- package/dist/adapters/gitlab.d.ts +0 -17
- package/dist/adapters/gitlab.d.ts.map +0 -1
- package/dist/adapters/gitlab.js +0 -10
- package/dist/adapters/gitlab.js.map +0 -1
- package/dist/adapters/huggingface.d.ts +0 -17
- package/dist/adapters/huggingface.d.ts.map +0 -1
- package/dist/adapters/huggingface.js +0 -6
- package/dist/adapters/huggingface.js.map +0 -1
- package/dist/adapters/socket.d.ts +0 -11
- package/dist/adapters/socket.d.ts.map +0 -1
- package/dist/adapters/socket.js +0 -17
- package/dist/adapters/socket.js.map +0 -1
- package/dist/adapters/transport.d.ts +0 -7
- package/dist/adapters/transport.d.ts.map +0 -1
- package/dist/adapters/transport.js +0 -36
- package/dist/adapters/transport.js.map +0 -1
- package/dist/ai/chunk.d.ts +0 -2
- package/dist/ai/chunk.d.ts.map +0 -1
- package/dist/ai/chunk.js +0 -36
- package/dist/ai/chunk.js.map +0 -1
- package/dist/ai/llmstxt.d.ts +0 -6
- package/dist/ai/llmstxt.d.ts.map +0 -1
- package/dist/ai/llmstxt.js +0 -12
- package/dist/ai/llmstxt.js.map +0 -1
- package/dist/ai/provenance.d.ts +0 -22
- package/dist/ai/provenance.d.ts.map +0 -1
- package/dist/ai/provenance.js +0 -25
- package/dist/ai/provenance.js.map +0 -1
- package/dist/ai/rag.d.ts +0 -26
- package/dist/ai/rag.d.ts.map +0 -1
- package/dist/ai/rag.js +0 -22
- package/dist/ai/rag.js.map +0 -1
- package/dist/ai/tokens.d.ts +0 -15
- package/dist/ai/tokens.d.ts.map +0 -1
- package/dist/ai/tokens.js +0 -9
- package/dist/ai/tokens.js.map +0 -1
- package/dist/api/auth.d.ts +0 -16
- package/dist/api/auth.d.ts.map +0 -1
- package/dist/api/auth.js +0 -19
- package/dist/api/auth.js.map +0 -1
- package/dist/api/contracts.d.ts +0 -28
- package/dist/api/contracts.d.ts.map +0 -1
- package/dist/api/contracts.js +0 -14
- package/dist/api/contracts.js.map +0 -1
- package/dist/api/control.d.ts +0 -10
- package/dist/api/control.d.ts.map +0 -1
- package/dist/api/control.js +0 -35
- package/dist/api/control.js.map +0 -1
- package/dist/api/http.d.ts +0 -7
- package/dist/api/http.d.ts.map +0 -1
- package/dist/api/http.js +0 -12
- package/dist/api/http.js.map +0 -1
- package/dist/api/rate.d.ts +0 -28
- package/dist/api/rate.d.ts.map +0 -1
- package/dist/api/rate.js +0 -36
- package/dist/api/rate.js.map +0 -1
- package/dist/api/security.d.ts +0 -12
- package/dist/api/security.d.ts.map +0 -1
- package/dist/api/security.js +0 -56
- package/dist/api/security.js.map +0 -1
- package/dist/api/service.d.ts +0 -5
- package/dist/api/service.d.ts.map +0 -1
- package/dist/api/service.js +0 -70
- package/dist/api/service.js.map +0 -1
- package/dist/apps/registry.d.ts +0 -33
- package/dist/apps/registry.d.ts.map +0 -1
- package/dist/apps/registry.js +0 -24
- package/dist/apps/registry.js.map +0 -1
- package/dist/binary/archive.d.ts +0 -27
- package/dist/binary/archive.d.ts.map +0 -1
- package/dist/binary/archive.js +0 -46
- package/dist/binary/archive.js.map +0 -1
- package/dist/binary/build.d.ts +0 -29
- package/dist/binary/build.d.ts.map +0 -1
- package/dist/binary/build.js +0 -17
- package/dist/binary/build.js.map +0 -1
- package/dist/binary/transform.d.ts +0 -70
- package/dist/binary/transform.d.ts.map +0 -1
- package/dist/binary/transform.js +0 -105
- package/dist/binary/transform.js.map +0 -1
- package/dist/bot/adapter.d.ts +0 -5
- package/dist/bot/adapter.d.ts.map +0 -1
- package/dist/bot/adapter.js +0 -11
- package/dist/bot/adapter.js.map +0 -1
- package/dist/bot/bot.d.ts +0 -28
- package/dist/bot/bot.d.ts.map +0 -1
- package/dist/bot/bot.js +0 -52
- package/dist/bot/bot.js.map +0 -1
- package/dist/bot/commands.d.ts +0 -8
- package/dist/bot/commands.d.ts.map +0 -1
- package/dist/bot/commands.js +0 -19
- package/dist/bot/commands.js.map +0 -1
- package/dist/bot/permissions.d.ts +0 -13
- package/dist/bot/permissions.d.ts.map +0 -1
- package/dist/bot/permissions.js +0 -16
- package/dist/bot/permissions.js.map +0 -1
- package/dist/browser/actions.d.ts +0 -33
- package/dist/browser/actions.d.ts.map +0 -1
- package/dist/browser/actions.js +0 -44
- package/dist/browser/actions.js.map +0 -1
- package/dist/browser/agent.d.ts +0 -21
- package/dist/browser/agent.d.ts.map +0 -1
- package/dist/browser/agent.js +0 -13
- package/dist/browser/agent.js.map +0 -1
- package/dist/browser/context.d.ts +0 -43
- package/dist/browser/context.d.ts.map +0 -1
- package/dist/browser/context.js +0 -54
- package/dist/browser/context.js.map +0 -1
- package/dist/browser/fingerprint.d.ts +0 -4
- package/dist/browser/fingerprint.d.ts.map +0 -1
- package/dist/browser/fingerprint.js +0 -12
- package/dist/browser/fingerprint.js.map +0 -1
- package/dist/browser/index.d.ts +0 -11
- package/dist/browser/index.d.ts.map +0 -1
- package/dist/browser/index.js +0 -11
- package/dist/browser/index.js.map +0 -1
- package/dist/browser/playwright.d.ts +0 -11
- package/dist/browser/playwright.d.ts.map +0 -1
- package/dist/browser/playwright.js +0 -24
- package/dist/browser/playwright.js.map +0 -1
- package/dist/browser/recorder.d.ts +0 -21
- package/dist/browser/recorder.d.ts.map +0 -1
- package/dist/browser/recorder.js +0 -58
- package/dist/browser/recorder.js.map +0 -1
- package/dist/browser/session.d.ts +0 -14
- package/dist/browser/session.d.ts.map +0 -1
- package/dist/browser/session.js +0 -21
- package/dist/browser/session.js.map +0 -1
- package/dist/browser/snapshot.d.ts +0 -69
- package/dist/browser/snapshot.d.ts.map +0 -1
- package/dist/browser/snapshot.js +0 -133
- package/dist/browser/snapshot.js.map +0 -1
- package/dist/captcha/contract.d.ts +0 -35
- package/dist/captcha/contract.d.ts.map +0 -1
- package/dist/captcha/contract.js +0 -17
- package/dist/captcha/contract.js.map +0 -1
- package/dist/captcha/evidence.d.ts +0 -10
- package/dist/captcha/evidence.d.ts.map +0 -1
- package/dist/captcha/evidence.js +0 -9
- package/dist/captcha/evidence.js.map +0 -1
- package/dist/captcha/guard.d.ts +0 -23
- package/dist/captcha/guard.d.ts.map +0 -1
- package/dist/captcha/guard.js +0 -12
- package/dist/captcha/guard.js.map +0 -1
- package/dist/cli/main.d.ts +0 -4
- package/dist/cli/main.d.ts.map +0 -1
- package/dist/cli/main.js +0 -46
- package/dist/cli/main.js.map +0 -1
- package/dist/core/errors.d.ts +0 -84
- package/dist/core/errors.d.ts.map +0 -1
- package/dist/core/errors.js +0 -54
- package/dist/core/errors.js.map +0 -1
- package/dist/core/events.d.ts +0 -9
- package/dist/core/events.d.ts.map +0 -1
- package/dist/core/events.js +0 -21
- package/dist/core/events.js.map +0 -1
- package/dist/core/hash.d.ts +0 -10
- package/dist/core/hash.d.ts.map +0 -1
- package/dist/core/hash.js +0 -82
- package/dist/core/hash.js.map +0 -1
- package/dist/core/ids.d.ts +0 -10
- package/dist/core/ids.d.ts.map +0 -1
- package/dist/core/ids.js +0 -15
- package/dist/core/ids.js.map +0 -1
- package/dist/delivery/manifest.d.ts +0 -35
- package/dist/delivery/manifest.d.ts.map +0 -1
- package/dist/delivery/manifest.js +0 -68
- package/dist/delivery/manifest.js.map +0 -1
- package/dist/deploy/index.d.ts +0 -6
- package/dist/deploy/index.d.ts.map +0 -1
- package/dist/deploy/index.js +0 -6
- package/dist/deploy/index.js.map +0 -1
- package/dist/dispatch/resumable.d.ts +0 -102
- package/dist/dispatch/resumable.d.ts.map +0 -1
- package/dist/dispatch/resumable.js +0 -64
- package/dist/dispatch/resumable.js.map +0 -1
- package/dist/dispatch/workflow.d.ts +0 -6
- package/dist/dispatch/workflow.d.ts.map +0 -1
- package/dist/dispatch/workflow.js +0 -37
- package/dist/dispatch/workflow.js.map +0 -1
- package/dist/domain/artifacts.d.ts +0 -12
- package/dist/domain/artifacts.d.ts.map +0 -1
- package/dist/domain/artifacts.js +0 -14
- package/dist/domain/artifacts.js.map +0 -1
- package/dist/domain/jobs.d.ts +0 -12
- package/dist/domain/jobs.d.ts.map +0 -1
- package/dist/domain/jobs.js +0 -20
- package/dist/domain/jobs.js.map +0 -1
- package/dist/domain/providers.d.ts +0 -10
- package/dist/domain/providers.d.ts.map +0 -1
- package/dist/domain/providers.js +0 -8
- package/dist/domain/providers.js.map +0 -1
- package/dist/domain/runtime.d.ts +0 -14
- package/dist/domain/runtime.d.ts.map +0 -1
- package/dist/domain/runtime.js +0 -10
- package/dist/domain/runtime.js.map +0 -1
- package/dist/domain/sessions.d.ts +0 -12
- package/dist/domain/sessions.d.ts.map +0 -1
- package/dist/domain/sessions.js +0 -57
- package/dist/domain/sessions.js.map +0 -1
- package/dist/examples/localjob.d.ts +0 -2
- package/dist/examples/localjob.d.ts.map +0 -1
- package/dist/examples/localjob.js.map +0 -1
- package/dist/examples/publicapi.d.ts +0 -2
- package/dist/examples/publicapi.d.ts.map +0 -1
- package/dist/examples/publicapi.js.map +0 -1
- package/dist/extension/build.d.ts +0 -9
- package/dist/extension/build.d.ts.map +0 -1
- package/dist/extension/build.js +0 -85
- package/dist/extension/build.js.map +0 -1
- package/dist/extension/content.d.ts +0 -6
- package/dist/extension/content.d.ts.map +0 -1
- package/dist/extension/content.js +0 -135
- package/dist/extension/content.js.map +0 -1
- package/dist/extension/index.d.ts +0 -7
- package/dist/extension/index.d.ts.map +0 -1
- package/dist/extension/index.js +0 -7
- package/dist/extension/index.js.map +0 -1
- package/dist/extension/pagebridge.d.ts +0 -6
- package/dist/extension/pagebridge.d.ts.map +0 -1
- package/dist/extension/pagebridge.js +0 -42
- package/dist/extension/pagebridge.js.map +0 -1
- package/dist/extension/permissions.d.ts +0 -26
- package/dist/extension/permissions.d.ts.map +0 -1
- package/dist/extension/permissions.js +0 -28
- package/dist/extension/permissions.js.map +0 -1
- package/dist/extension/popup.d.ts +0 -5
- package/dist/extension/popup.d.ts.map +0 -1
- package/dist/extension/popup.js +0 -26
- package/dist/extension/popup.js.map +0 -1
- package/dist/extension/protocol.d.ts +0 -58
- package/dist/extension/protocol.d.ts.map +0 -1
- package/dist/extension/protocol.js +0 -101
- package/dist/extension/protocol.js.map +0 -1
- package/dist/extension/serviceworker.d.ts +0 -25
- package/dist/extension/serviceworker.d.ts.map +0 -1
- package/dist/extension/serviceworker.js +0 -102
- package/dist/extension/serviceworker.js.map +0 -1
- package/dist/extension/worker.d.ts +0 -28
- package/dist/extension/worker.d.ts.map +0 -1
- package/dist/extension/worker.js +0 -22
- package/dist/extension/worker.js.map +0 -1
- package/dist/format/check.d.ts +0 -8
- package/dist/format/check.d.ts.map +0 -1
- package/dist/format/check.js +0 -38
- package/dist/format/check.js.map +0 -1
- package/dist/library/public.d.ts.map +0 -1
- package/dist/library/public.js.map +0 -1
- package/dist/mcp/browser.d.ts +0 -9
- package/dist/mcp/browser.d.ts.map +0 -1
- package/dist/mcp/browser.js +0 -13
- package/dist/mcp/browser.js.map +0 -1
- package/dist/mcp/server.d.ts +0 -35
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/mcp/server.js +0 -40
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/transport.d.ts +0 -7
- package/dist/mcp/transport.d.ts.map +0 -1
- package/dist/mcp/transport.js +0 -17
- package/dist/mcp/transport.js.map +0 -1
- package/dist/memory/bridge.d.ts +0 -14
- package/dist/memory/bridge.d.ts.map +0 -1
- package/dist/memory/bridge.js +0 -16
- package/dist/memory/bridge.js.map +0 -1
- package/dist/memory/engine.d.ts +0 -38
- package/dist/memory/engine.d.ts.map +0 -1
- package/dist/memory/engine.js +0 -109
- package/dist/memory/engine.js.map +0 -1
- package/dist/memory/modes.d.ts +0 -43
- package/dist/memory/modes.d.ts.map +0 -1
- package/dist/memory/modes.js +0 -66
- package/dist/memory/modes.js.map +0 -1
- package/dist/memory/objects.d.ts +0 -21
- package/dist/memory/objects.d.ts.map +0 -1
- package/dist/memory/objects.js +0 -20
- package/dist/memory/objects.js.map +0 -1
- package/dist/memory/planner.d.ts +0 -66
- package/dist/memory/planner.d.ts.map +0 -1
- package/dist/memory/planner.js +0 -108
- package/dist/memory/planner.js.map +0 -1
- package/dist/memory/targets.d.ts +0 -78
- package/dist/memory/targets.d.ts.map +0 -1
- package/dist/memory/targets.js +0 -29
- package/dist/memory/targets.js.map +0 -1
- package/dist/memory/transforms.d.ts +0 -19
- package/dist/memory/transforms.d.ts.map +0 -1
- package/dist/memory/transforms.js +0 -14
- package/dist/memory/transforms.js.map +0 -1
- package/dist/modes/matrix.d.ts +0 -23
- package/dist/modes/matrix.d.ts.map +0 -1
- package/dist/modes/matrix.js +0 -18
- package/dist/modes/matrix.js.map +0 -1
- package/dist/modes/modes.d.ts +0 -33
- package/dist/modes/modes.d.ts.map +0 -1
- package/dist/modes/modes.js +0 -15
- package/dist/modes/modes.js.map +0 -1
- package/dist/modes/resolve.d.ts +0 -96
- package/dist/modes/resolve.d.ts.map +0 -1
- package/dist/modes/resolve.js +0 -48
- package/dist/modes/resolve.js.map +0 -1
- package/dist/observability/metrics.d.ts +0 -14
- package/dist/observability/metrics.d.ts.map +0 -1
- package/dist/observability/metrics.js +0 -18
- package/dist/observability/metrics.js.map +0 -1
- package/dist/packager/manifest.d.ts +0 -66
- package/dist/packager/manifest.d.ts.map +0 -1
- package/dist/packager/manifest.js +0 -94
- package/dist/packager/manifest.js.map +0 -1
- package/dist/packager/publish.d.ts +0 -51
- package/dist/packager/publish.d.ts.map +0 -1
- package/dist/packager/publish.js +0 -18
- package/dist/packager/publish.js.map +0 -1
- package/dist/packager/targetcli.d.ts +0 -7
- package/dist/packager/targetcli.d.ts.map +0 -1
- package/dist/packager/targetcli.js +0 -22
- package/dist/packager/targetcli.js.map +0 -1
- package/dist/persistence/adapter.d.ts +0 -5
- package/dist/persistence/adapter.d.ts.map +0 -1
- package/dist/persistence/adapter.js +0 -11
- package/dist/persistence/adapter.js.map +0 -1
- package/dist/persistence/drizzle.d.ts +0 -2
- package/dist/persistence/drizzle.d.ts.map +0 -1
- package/dist/persistence/drizzle.js +0 -12
- package/dist/persistence/drizzle.js.map +0 -1
- package/dist/persistence/memory.d.ts +0 -2
- package/dist/persistence/memory.d.ts.map +0 -1
- package/dist/persistence/memory.js +0 -27
- package/dist/persistence/memory.js.map +0 -1
- package/dist/persistence/migrations.d.ts +0 -19
- package/dist/persistence/migrations.d.ts.map +0 -1
- package/dist/persistence/migrations.js +0 -13
- package/dist/persistence/migrations.js.map +0 -1
- package/dist/persistence/prisma.d.ts +0 -2
- package/dist/persistence/prisma.d.ts.map +0 -1
- package/dist/persistence/prisma.js +0 -25
- package/dist/persistence/prisma.js.map +0 -1
- package/dist/persistence/schema.d.ts +0 -63
- package/dist/persistence/schema.d.ts.map +0 -1
- package/dist/persistence/schema.js +0 -28
- package/dist/persistence/schema.js.map +0 -1
- package/dist/persistence/sql.d.ts +0 -3
- package/dist/persistence/sql.d.ts.map +0 -1
- package/dist/persistence/sql.js +0 -37
- package/dist/persistence/sql.js.map +0 -1
- package/dist/protocol/blocks.d.ts +0 -10
- package/dist/protocol/blocks.d.ts.map +0 -1
- package/dist/protocol/blocks.js +0 -26
- package/dist/protocol/blocks.js.map +0 -1
- package/dist/protocol/json.d.ts +0 -6
- package/dist/protocol/json.d.ts.map +0 -1
- package/dist/protocol/json.js +0 -6
- package/dist/protocol/json.js.map +0 -1
- package/dist/protocol/ndjson.d.ts +0 -3
- package/dist/protocol/ndjson.d.ts.map +0 -1
- package/dist/protocol/ndjson.js +0 -20
- package/dist/protocol/ndjson.js.map +0 -1
- package/dist/protocol/sse.d.ts +0 -7
- package/dist/protocol/sse.d.ts.map +0 -1
- package/dist/protocol/sse.js +0 -25
- package/dist/protocol/sse.js.map +0 -1
- package/dist/proxy/pool.d.ts +0 -9
- package/dist/proxy/pool.d.ts.map +0 -1
- package/dist/proxy/pool.js +0 -27
- package/dist/proxy/pool.js.map +0 -1
- package/dist/queue/idempotency.d.ts +0 -10
- package/dist/queue/idempotency.d.ts.map +0 -1
- package/dist/queue/idempotency.js +0 -13
- package/dist/queue/idempotency.js.map +0 -1
- package/dist/queue/persistent.d.ts +0 -14
- package/dist/queue/persistent.d.ts.map +0 -1
- package/dist/queue/persistent.js +0 -66
- package/dist/queue/persistent.js.map +0 -1
- package/dist/queue/queue.d.ts +0 -7
- package/dist/queue/queue.d.ts.map +0 -1
- package/dist/queue/queue.js +0 -55
- package/dist/queue/queue.js.map +0 -1
- package/dist/queue/saga.d.ts +0 -5
- package/dist/queue/saga.d.ts.map +0 -1
- package/dist/queue/saga.js +0 -20
- package/dist/queue/saga.js.map +0 -1
- package/dist/release/assets.d.ts +0 -144
- package/dist/release/assets.d.ts.map +0 -1
- package/dist/release/assets.js +0 -157
- package/dist/release/assets.js.map +0 -1
- package/dist/release/evidence.d.ts +0 -92
- package/dist/release/evidence.d.ts.map +0 -1
- package/dist/release/evidence.js +0 -148
- package/dist/release/evidence.js.map +0 -1
- package/dist/release/verify.d.ts +0 -12
- package/dist/release/verify.d.ts.map +0 -1
- package/dist/release/verify.js +0 -112
- package/dist/release/verify.js.map +0 -1
- package/dist/runners/chain.d.ts +0 -125
- package/dist/runners/chain.d.ts.map +0 -1
- package/dist/runners/chain.js +0 -95
- package/dist/runners/chain.js.map +0 -1
- package/dist/runners/health.d.ts +0 -36
- package/dist/runners/health.d.ts.map +0 -1
- package/dist/runners/health.js +0 -26
- package/dist/runners/health.js.map +0 -1
- package/dist/runners/heartbeat.d.ts +0 -23
- package/dist/runners/heartbeat.d.ts.map +0 -1
- package/dist/runners/heartbeat.js +0 -29
- package/dist/runners/heartbeat.js.map +0 -1
- package/dist/runners/inprocess.d.ts +0 -17
- package/dist/runners/inprocess.d.ts.map +0 -1
- package/dist/runners/inprocess.js +0 -20
- package/dist/runners/inprocess.js.map +0 -1
- package/dist/runners/scheduler.d.ts +0 -5
- package/dist/runners/scheduler.d.ts.map +0 -1
- package/dist/runners/scheduler.js +0 -19
- package/dist/runners/scheduler.js.map +0 -1
- package/dist/runtime/abort.d.ts +0 -8
- package/dist/runtime/abort.d.ts.map +0 -1
- package/dist/runtime/abort.js +0 -13
- package/dist/runtime/abort.js.map +0 -1
- package/dist/runtime/compatibility.d.ts +0 -37
- package/dist/runtime/compatibility.d.ts.map +0 -1
- package/dist/runtime/compatibility.js +0 -10
- package/dist/runtime/compatibility.js.map +0 -1
- package/dist/runtime/detect.d.ts +0 -13
- package/dist/runtime/detect.d.ts.map +0 -1
- package/dist/runtime/detect.js +0 -18
- package/dist/runtime/detect.js.map +0 -1
- package/dist/runtime/engine.d.ts +0 -20
- package/dist/runtime/engine.d.ts.map +0 -1
- package/dist/runtime/engine.js +0 -61
- package/dist/runtime/engine.js.map +0 -1
- package/dist/runtime/retry.d.ts +0 -19
- package/dist/runtime/retry.d.ts.map +0 -1
- package/dist/runtime/retry.js +0 -54
- package/dist/runtime/retry.js.map +0 -1
- package/dist/runtime/worker.d.ts +0 -10
- package/dist/runtime/worker.d.ts.map +0 -1
- package/dist/runtime/worker.js +0 -25
- package/dist/runtime/worker.js.map +0 -1
- package/dist/scrape/cache.d.ts +0 -45
- package/dist/scrape/cache.d.ts.map +0 -1
- package/dist/scrape/cache.js +0 -45
- package/dist/scrape/cache.js.map +0 -1
- package/dist/scrape/crawl.d.ts +0 -47
- package/dist/scrape/crawl.d.ts.map +0 -1
- package/dist/scrape/crawl.js +0 -114
- package/dist/scrape/crawl.js.map +0 -1
- package/dist/scrape/extract.d.ts +0 -63
- package/dist/scrape/extract.d.ts.map +0 -1
- package/dist/scrape/extract.js +0 -47
- package/dist/scrape/extract.js.map +0 -1
- package/dist/scrape/normalize.d.ts +0 -52
- package/dist/scrape/normalize.d.ts.map +0 -1
- package/dist/scrape/normalize.js +0 -102
- package/dist/scrape/normalize.js.map +0 -1
- package/dist/scrape/robots.d.ts +0 -37
- package/dist/scrape/robots.d.ts.map +0 -1
- package/dist/scrape/robots.js +0 -71
- package/dist/scrape/robots.js.map +0 -1
- package/dist/scrape/schema.d.ts +0 -23
- package/dist/scrape/schema.d.ts.map +0 -1
- package/dist/scrape/schema.js +0 -92
- package/dist/scrape/schema.js.map +0 -1
- package/dist/scrape/scraper.d.ts +0 -6
- package/dist/scrape/scraper.d.ts.map +0 -1
- package/dist/scrape/scraper.js +0 -46
- package/dist/scrape/scraper.js.map +0 -1
- package/dist/scrape/semantic.d.ts +0 -25
- package/dist/scrape/semantic.d.ts.map +0 -1
- package/dist/scrape/semantic.js +0 -27
- package/dist/scrape/semantic.js.map +0 -1
- package/dist/server/node.d.ts +0 -7
- package/dist/server/node.d.ts.map +0 -1
- package/dist/server/node.js.map +0 -1
- package/dist/sessions/file.d.ts +0 -25
- package/dist/sessions/file.d.ts.map +0 -1
- package/dist/sessions/file.js +0 -13
- package/dist/sessions/file.js.map +0 -1
- package/dist/sessions/replay.d.ts +0 -9
- package/dist/sessions/replay.d.ts.map +0 -1
- package/dist/sessions/replay.js +0 -70
- package/dist/sessions/replay.js.map +0 -1
- package/dist/sessions/store.d.ts +0 -25
- package/dist/sessions/store.d.ts.map +0 -1
- package/dist/sessions/store.js +0 -13
- package/dist/sessions/store.js.map +0 -1
- package/dist/storage/adapter.d.ts +0 -5
- package/dist/storage/adapter.d.ts.map +0 -1
- package/dist/storage/adapter.js +0 -11
- package/dist/storage/adapter.js.map +0 -1
- package/dist/storage/cache.d.ts +0 -23
- package/dist/storage/cache.d.ts.map +0 -1
- package/dist/storage/cache.js +0 -79
- package/dist/storage/cache.js.map +0 -1
- package/dist/storage/checksum.d.ts +0 -3
- package/dist/storage/checksum.d.ts.map +0 -1
- package/dist/storage/checksum.js +0 -19
- package/dist/storage/checksum.js.map +0 -1
- package/dist/storage/chunked.d.ts +0 -21
- package/dist/storage/chunked.d.ts.map +0 -1
- package/dist/storage/chunked.js +0 -67
- package/dist/storage/chunked.js.map +0 -1
- package/dist/storage/content.d.ts +0 -24
- package/dist/storage/content.d.ts.map +0 -1
- package/dist/storage/content.js +0 -44
- package/dist/storage/content.js.map +0 -1
- package/dist/storage/filehosting.d.ts +0 -2
- package/dist/storage/filehosting.d.ts.map +0 -1
- package/dist/storage/filehosting.js +0 -24
- package/dist/storage/filehosting.js.map +0 -1
- package/dist/storage/githubcontents.d.ts +0 -2
- package/dist/storage/githubcontents.d.ts.map +0 -1
- package/dist/storage/githubcontents.js +0 -29
- package/dist/storage/githubcontents.js.map +0 -1
- package/dist/storage/index.d.ts +0 -12
- package/dist/storage/index.d.ts.map +0 -1
- package/dist/storage/index.js +0 -12
- package/dist/storage/index.js.map +0 -1
- package/dist/storage/local.d.ts +0 -2
- package/dist/storage/local.d.ts.map +0 -1
- package/dist/storage/local.js +0 -72
- package/dist/storage/local.js.map +0 -1
- package/dist/storage/memory.d.ts +0 -6
- package/dist/storage/memory.d.ts.map +0 -1
- package/dist/storage/memory.js +0 -36
- package/dist/storage/memory.js.map +0 -1
- package/dist/storage/pool.d.ts +0 -95
- package/dist/storage/pool.d.ts.map +0 -1
- package/dist/storage/pool.js +0 -202
- package/dist/storage/pool.js.map +0 -1
- package/dist/storage/s3compatible.d.ts +0 -3
- package/dist/storage/s3compatible.d.ts.map +0 -1
- package/dist/storage/s3compatible.js +0 -70
- package/dist/storage/s3compatible.js.map +0 -1
- package/dist/storage/sync.d.ts +0 -47
- package/dist/storage/sync.d.ts.map +0 -1
- package/dist/storage/sync.js +0 -75
- package/dist/storage/sync.js.map +0 -1
- package/dist/surfaces/adapters.d.ts +0 -97
- package/dist/surfaces/adapters.d.ts.map +0 -1
- package/dist/surfaces/adapters.js +0 -50
- package/dist/surfaces/adapters.js.map +0 -1
- package/dist/surfaces/controls.d.ts +0 -18
- package/dist/surfaces/controls.d.ts.map +0 -1
- package/dist/surfaces/controls.js +0 -45
- package/dist/surfaces/controls.js.map +0 -1
- package/dist/surfaces/manifest.d.ts +0 -68
- package/dist/surfaces/manifest.d.ts.map +0 -1
- package/dist/surfaces/manifest.js +0 -42
- package/dist/surfaces/manifest.js.map +0 -1
- package/dist/surfaces/n8n.d.ts +0 -25
- package/dist/surfaces/n8n.d.ts.map +0 -1
- package/dist/surfaces/n8n.js +0 -31
- package/dist/surfaces/n8n.js.map +0 -1
- package/dist/surfaces/operations.d.ts +0 -32
- package/dist/surfaces/operations.d.ts.map +0 -1
- package/dist/surfaces/operations.js +0 -53
- package/dist/surfaces/operations.js.map +0 -1
- package/dist/surfaces/requirements.d.ts +0 -29
- package/dist/surfaces/requirements.d.ts.map +0 -1
- package/dist/surfaces/requirements.js +0 -50
- package/dist/surfaces/requirements.js.map +0 -1
- package/dist/surfaces/targets.d.ts +0 -196
- package/dist/surfaces/targets.d.ts.map +0 -1
- package/dist/surfaces/targets.js +0 -27
- package/dist/surfaces/targets.js.map +0 -1
- package/dist/webhook/delivery.d.ts +0 -18
- package/dist/webhook/delivery.d.ts.map +0 -1
- package/dist/webhook/delivery.js +0 -36
- package/dist/webhook/delivery.js.map +0 -1
- package/dist/webhook/receiver.d.ts +0 -26
- package/dist/webhook/receiver.d.ts.map +0 -1
- package/dist/webhook/receiver.js +0 -24
- package/dist/webhook/receiver.js.map +0 -1
- package/dist/webhook/signature.d.ts +0 -3
- package/dist/webhook/signature.d.ts.map +0 -1
- package/dist/webhook/signature.js +0 -7
- package/dist/webhook/signature.js.map +0 -1
- package/dist/workflow/manifest.d.ts +0 -22
- package/dist/workflow/manifest.d.ts.map +0 -1
- package/dist/workflow/manifest.js +0 -21
- package/dist/workflow/manifest.js.map +0 -1
- package/dist/workflow/registry.d.ts +0 -7
- package/dist/workflow/registry.d.ts.map +0 -1
- package/dist/workflow/registry.js +0 -18
- package/dist/workflow/registry.js.map +0 -1
- package/dist/workflow/templates.d.ts +0 -6
- package/dist/workflow/templates.d.ts.map +0 -1
- package/dist/workflow/templates.js +0 -18
- package/dist/workflow/templates.js.map +0 -1
- package/dist/workflow/triggers.d.ts +0 -64
- package/dist/workflow/triggers.d.ts.map +0 -1
- package/dist/workflow/triggers.js +0 -99
- package/dist/workflow/triggers.js.map +0 -1
- package/docs/logs/.gitkeep +0 -0
- package/docs/plans/00.index.md +0 -50
- package/docs/plans/01.architecture.md +0 -86
- package/docs/plans/02.research.computer.use.md +0 -58
- package/docs/plans/03.research.captcha.bypass.md +0 -68
- package/docs/plans/04.research.sandbox.ai.md +0 -52
- package/docs/plans/05.capture.platform.md +0 -57
- package/docs/plans/06.dependencies.md +0 -97
- package/docs/plans/07.captcha.test.page.md +0 -41
- package/docs/plans/08.production.infra.md +0 -70
- package/docs/plans/09.database.schema.md +0 -121
- package/docs/plans/10.cloudinary.storage.md +0 -57
- package/docs/plans/11.movement.logs.json.md +0 -72
- package/docs/plans/12.research.atlas.agent.browser.md +0 -79
- package/docs/plans/13.research.anti.detection.md +0 -898
- package/docs/plans/14.research.proxy.md +0 -1495
- package/docs/plans/15.research.retry.rate.limit.md +0 -1958
- package/docs/plans/16.research.crawling.md +0 -1417
- package/docs/plans/17.research.caching.md +0 -1610
- package/docs/plans/18.research.content.extraction.md +0 -1952
- package/docs/plans/19.research.errors.events.md +0 -1523
- package/docs/plans/20.research.zod.validation.md +0 -1350
- package/docs/plans/21.research.batch.concurrency.md +0 -1888
- package/docs/plans/22.research.universal.runtime.md +0 -944
- package/docs/plans/23.research.ai.integration.md +0 -1465
- package/docs/plans/24.research.memory.persistence.md +0 -1979
- package/docs/plans/25.research.server.api.md +0 -342
- package/docs/plans/26.research.compilation.md +0 -249
- package/docs/plans/27.research.html.parsing.md +0 -251
- package/docs/plans/28.action.plan.md +0 -50
- package/docs/plans/29.api.reference.md +0 -174
- package/docs/plans/30.architecture.plan.md +0 -94
- package/docs/plans/31.auditoria.dados.md +0 -163
- package/docs/plans/32.bots.automacao.computacional.md +0 -214
- package/docs/plans/33.bots.codigo.revisao.md +0 -220
- package/docs/plans/34.bots.seguranca.cicd.md +0 -366
- package/docs/plans/35.comparativo.concorrencia.md +0 -464
- package/docs/plans/36.computational.memory.md +0 -340
- package/docs/plans/37.deploystrategy.md +0 -394
- package/docs/plans/38.flow.md +0 -155
- package/docs/plans/39.multi.platform.bot.md +0 -252
- package/docs/plans/40.npm.publish.md +0 -250
- package/docs/plans/41.o.que.falta.md +0 -407
- package/docs/plans/42.pesquisa.concorrencia.md +0 -721
- package/docs/plans/43.plan.universal.architecture.md +0 -496
- package/docs/plans/44.reference.md +0 -100
- package/docs/plans/45.robotarchitecture.md +0 -237
- package/docs/plans/46.scdnintegration.md +0 -284
- package/docs/plans/47.multiforge.readme.md +0 -129
- package/docs/plans/48.theory.v4.repo.os.md +0 -152
- package/docs/plans/49.third.party.infra.md +0 -12
- package/docs/plans/50.file.as.compute.md +0 -39
- package/docs/plans/51.architecture.virtual.processor.md +0 -80
- package/docs/plans/52.manifesto.v8.md +0 -11
- package/docs/plans/58.cdn.list.md +0 -23
- package/docs/plans/59.sql.frameworks.md +0 -33
- package/docs/plans/60.sql.thirdparty.md +0 -26
- package/docs/plans/61.objective.multiforge.md +0 -63
- package/docs/plans/62.huggingface.upload.md +0 -26
- package/docs/plans/63.kaggle.upload.md +0 -24
- package/docs/plans/64.npm.storage.md +0 -30
- package/docs/plans/65.rclone.terabox.md +0 -32
- package/docs/plans/66.buckets.and.models.todo.md +0 -14
- package/docs/plans/67.database.todo.md +0 -13
- package/docs/plans/68.deploy.packages.todo.md +0 -12
- package/docs/plans/69.report.human.operator.md +0 -133
- package/docs/plans/70.report.brain2qwerty.ems.md +0 -135
- package/docs/plans/71.report.hd.infinito.vram.md +0 -155
- package/docs/plans/72.plan.hd.infinito.node.md +0 -146
- package/docs/plans/73.plan.scifi.repos.md +0 -125
- package/docs/plans/74.000.manifesto.v8.flat.2..md +0 -11
- package/docs/plans/README.md +0 -489
- package/docs/plans/aggregate_platforms.mjs +0 -146
- package/docs/plans/examplesession.json +0 -36
- package/docs/plans/missing-facts.md +0 -192
- package/docs/plans/models.md +0 -64
- package/docs/plans/organize.cjs +0 -270
- package/docs/plans/platforms.md +0 -2887
- package/docs/plans/sites.md +0 -31322
- package/docs/sources/farm.py +0 -117
- package/docs/sources/html/saddle1.html +0 -132
- package/docs/sources/html/saddle2.html +0 -157
- package/docs/sources/html/saddle3.html +0 -119
- package/docs/sources/html/saddle4.html +0 -144
- package/docs/sources/html/saddle5.html +0 -72
- package/docs/sources/html/saddle6.html +0 -171
- package/docs/sources/html/saddle7.html +0 -236
- package/docs/sources/saddle.ts +0 -74
- package/docs/sources/schema.prisma +0 -88
- package/docs/sources/script.sh +0 -64
- package/docs/sources/workflows.yml +0 -458
- package/docs/talks1/_body.txt +0 -14
- package/docs/talks1/_index.md +0 -15
- package/docs/talks1/_screenshot.png +0 -0
- package/docs/talks1/assistant-01.md +0 -5
- package/docs/talks1/assistant-02.md +0 -5
- package/docs/talks1/assistant-03.md +0 -531
- package/docs/talks1/assistant-04.md +0 -26
- package/docs/talks1/assistant-05.md +0 -774
- package/docs/talks1/assistant-06.md +0 -1718
- package/docs/talks1/scrape-share.cjs +0 -185
- package/docs/talks1/scrape-share.ts +0 -183
- package/docs/talks1/user-01.md +0 -3
- package/docs/talks1/user-02.md +0 -3
- package/docs/talks1/user-03.md +0 -88
- package/docs/talks1/user-04.md +0 -3
- package/docs/talks1/user-05.md +0 -3
- package/docs/talks1/user-06.md +0 -88
- package/docs/talks1/user-07.md +0 -88
- package/docs/talks2/_body.txt +0 -14
- package/docs/talks2/_index.md +0 -16
- package/docs/talks2/_screenshot.png +0 -0
- package/docs/talks2/assistant-01.md +0 -5
- package/docs/talks2/assistant-02.md +0 -5
- package/docs/talks2/assistant-03.md +0 -424
- package/docs/talks2/assistant-04.md +0 -598
- package/docs/talks2/assistant-05.md +0 -1280
- package/docs/talks2/assistant-06.md +0 -1227
- package/docs/talks2/assistant-07.md +0 -1252
- package/docs/talks2/user-01.md +0 -3
- package/docs/talks2/user-02.md +0 -3
- package/docs/talks2/user-03.md +0 -88
- package/docs/talks2/user-04.md +0 -88
- package/docs/talks2/user-05.md +0 -88
- package/docs/talks2/user-06.md +0 -88
- package/docs/talks2/user-07.md +0 -3
- package/docs/talks3/_body.txt +0 -467
- package/docs/talks3/_index.md +0 -10
- package/docs/talks3/_screenshot.png +0 -0
- package/docs/talks3/assistant-01.md +0 -417
- package/docs/talks3/assistant-02.md +0 -417
- package/docs/talks3/assistant-03.md +0 -29
- package/docs/talks3/assistant-04.md +0 -727
- package/docs/talks3/user-01.md +0 -88
- package/docs/talks3/user-02.md +0 -88
- package/docs/talks3/user-03.md +0 -3
- package/docs/talks3/user-04.md +0 -3
- package/docs/talks4/_body.txt +0 -14
- package/docs/talks4/_index.md +0 -12
- package/docs/talks4/_screenshot.png +0 -0
- package/docs/talks4/assistant-01.md +0 -5
- package/docs/talks4/assistant-02.md +0 -5
- package/docs/talks4/assistant-03.md +0 -35
- package/docs/talks4/assistant-04.md +0 -512
- package/docs/talks4/assistant-05.md +0 -599
- package/docs/talks4/user-01.md +0 -3
- package/docs/talks4/user-02.md +0 -3
- package/docs/talks4/user-03.md +0 -88
- package/docs/talks4/user-04.md +0 -88
- package/docs/talks4/user-05.md +0 -7
- package/docs/talks5/_body.txt +0 -14
- package/docs/talks5/_index.md +0 -13
- package/docs/talks5/_screenshot.png +0 -0
- package/docs/talks5/assistant-01.md +0 -5
- package/docs/talks5/assistant-02.md +0 -5
- package/docs/talks5/assistant-03.md +0 -690
- package/docs/talks5/assistant-04.md +0 -758
- package/docs/talks5/assistant-05.md +0 -974
- package/docs/talks5/user-01.md +0 -3
- package/docs/talks5/user-02.md +0 -3
- package/docs/talks5/user-03.md +0 -105
- package/docs/talks5/user-04.md +0 -105
- package/docs/talks5/user-05.md +0 -63
- package/docs/talks5/user-06.md +0 -105
- package/docs/talks6/_body.txt +0 -14
- package/docs/talks6/_index.md +0 -9
- package/docs/talks6/_screenshot.png +0 -0
- package/docs/talks6/assistant-01.md +0 -5
- package/docs/talks6/assistant-02.md +0 -5
- package/docs/talks6/assistant-03.md +0 -1499
- package/docs/talks6/user-01.md +0 -3
- package/docs/talks6/user-02.md +0 -3
- package/docs/talks6/user-03.md +0 -88
- package/docs/talks6/user-04.md +0 -88
- package/docs/talks7/_body.txt +0 -14
- package/docs/talks7/_index.md +0 -10
- package/docs/talks7/_screenshot.png +0 -0
- package/docs/talks7/assistant-01.md +0 -5
- package/docs/talks7/assistant-02.md +0 -5
- package/docs/talks7/assistant-03.md +0 -523
- package/docs/talks7/assistant-04.md +0 -617
- package/docs/talks7/user-01.md +0 -3
- package/docs/talks7/user-02.md +0 -3
- package/docs/talks7/user-03.md +0 -105
- package/docs/talks7/user-04.md +0 -67
- package/docs/talks8/conversa1.txt +0 -1322
- package/docs/talks8/conversa2.txt +0 -237
- package/docs/talks9/Beyond the Obvious_ 50 Plataformas Auto-Hospedadas de Forja de C/303/263digo para Al/303/251m de Gitea e GitLab.md" +0 -174
- package/docs/talks9/De NPM a Multi-Linguagem_ Uma Arquitetura T/303/251cnica para a Execu/303/247/303/243o Integrada de C/303/263digo no Ecossistema Node.js.md" +0 -59
- package/docs/talks9/De NPM a VMs Virtuais_ Uma An/303/241lise Arquitet/303/264nica para a Realiza/303/247/303/243o do Ciclo de Vida do Projeto SADDLE.md" +0 -91
- package/docs/talks9/Mapeamento da Engrenagem Computacional_ Uma Arquitetura para Execu/303/247/303/243o Isolada e Persist/303/252ncia em Ambientes Distribu/303/255dos.md" +0 -116
- package/docs/talks9/O Cen/303/241rio Pr/303/241tico do SADDLE_ Uma An/303/241lise de Viabilidade e Modelo de Ciclo de Vida Integrado.md" +0 -128
- package/docs/talks9/README (2).md +0 -489
- package/docs/talks9/README.md +0 -198
- package/docs/talks9/Viabilidade do Saddle_ Uma An/303/241lise T/303/251cnica da Transforma/303/247/303/243o de Armazenamento Remoto em Mem/303/263ria Computacional.md" +0 -80
- package/docs/talks9/conversa.txt +0 -544
- package/docs/talks9/other (2).md +0 -39
- package/docs/talks9/other.md +0 -57
- package/docs/talks9/outro.txt +0 -24
- /package/{extension/README.md → docs/extension.md} +0 -0
|
@@ -0,0 +1,1011 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* virtualhardware.c — ld_preload hardware spoofing core for the virtual hardware
|
|
3
|
+
* engine v5 (vhe).
|
|
4
|
+
*
|
|
5
|
+
* the library intercepts the complete libc file-access family and rewrites
|
|
6
|
+
* reads of procfs hardware sources so that unmodified dynamic binaries observe
|
|
7
|
+
* the virtual machine profile instead of the physical host:
|
|
8
|
+
*
|
|
9
|
+
* /proc/cpuinfo -> /etc/virtual/cpuinfo (EPYC 9965, 192c/384t, zen 5)
|
|
10
|
+
* /proc/meminfo -> /etc/virtual/meminfo (128 GB default, dynamic mode)
|
|
11
|
+
* /proc/uptime -> /etc/virtual/uptime (configurable base + real delta)
|
|
12
|
+
* /proc/loadavg -> /etc/virtual/loadavg (scaled to VHE_CPUS)
|
|
13
|
+
* /proc/version -> /etc/virtual/version (custom kernel release)
|
|
14
|
+
*
|
|
15
|
+
* technique provenance (all verified 22/08/2026, see worklog task 1-e):
|
|
16
|
+
* - open/open64/openat/openat64/fopen/fopen64/freopen/freopen64 interception
|
|
17
|
+
* and the inotify regeneration thread follow the memoverlay design
|
|
18
|
+
* (github.com/stantheawesomeman/memoverlay).
|
|
19
|
+
* - the sysinfo() hook with mem_unit normalization and the uname() hook
|
|
20
|
+
* follow the dolos design (github.com/cdt4/dolos, dolos/hooks.c).
|
|
21
|
+
* - real symbol resolution always uses dlsym(RTLD_NEXT, ...) per man3 dlsym:
|
|
22
|
+
* "find the next occurrence of the symbol after the current object".
|
|
23
|
+
*
|
|
24
|
+
* global installation (per dolos): echo /usr/local/lib/libvirtualhardware.so
|
|
25
|
+
* >> /etc/ld.so.preload — the docker image installs it exactly this way.
|
|
26
|
+
* per-process installation: LD_PRELOAD=/usr/local/lib/libvirtualhardware.so prog.
|
|
27
|
+
* setuid binaries ignore ld_preload and /etc/ld.so.preload by design of the
|
|
28
|
+
* dynamic loader, so privileged tools always see the real host.
|
|
29
|
+
*
|
|
30
|
+
* known limitations, documented for operators:
|
|
31
|
+
* - statically linked binaries and go binaries that issue raw syscalls
|
|
32
|
+
* bypass the PLT and cannot be interposed (news.ycombinator.com/item?id=19190275,
|
|
33
|
+
* reddit.com/r/golang/comments/dlhfm7); the seccomp user_notif technique
|
|
34
|
+
* from rios0rios0/termux-etc-redirect covers those cases and stays a
|
|
35
|
+
* future extension.
|
|
36
|
+
* - cpuid instructions and the real core count cannot be virtualized without a
|
|
37
|
+
* VM; the engine pairs this library with QEMU -cpu EPYC-v5 for that layer.
|
|
38
|
+
*
|
|
39
|
+
* environment variables (all optional, evaluated once at load time):
|
|
40
|
+
* VHE_ENABLED 0 disables every hook after resolution (default 1)
|
|
41
|
+
* VHE_CPUINFO path overriding /etc/virtual/cpuinfo
|
|
42
|
+
* VHE_MEMINFO path overriding /etc/virtual/meminfo (implies static
|
|
43
|
+
* mode, memoverlay-compatible behavior)
|
|
44
|
+
* VHE_MEMINFO_MODE dynamic (default) regenerates the scaled meminfo in a
|
|
45
|
+
* private /tmp directory; static reads the file as-is
|
|
46
|
+
* VHE_TOTALRAM_GB virtual total ram in GiB (default 128, EPYC-class node)
|
|
47
|
+
* VHE_CPUS virtual logical cpu count (default 192, EPYC 9965)
|
|
48
|
+
* VHE_UPTIME virtual uptime base in seconds added to the real uptime
|
|
49
|
+
* VHE_KERNEL_RELEASE virtual uname release (default "6.18.0-vhe")
|
|
50
|
+
* VHE_KERNEL_VERSION virtual uname version string
|
|
51
|
+
* VHE_SYSNAME virtual uname sysname (default "Linux")
|
|
52
|
+
* VHE_MACHINE virtual uname machine (default "x86_64")
|
|
53
|
+
* VHE_MEMINFO_REFRESH dynamic meminfo refresh interval in seconds (default 5)
|
|
54
|
+
* VHE_DEBUG 1 prints interception decisions to stderr (fd 2 via
|
|
55
|
+
* dprintf, never stdio, so no recursion into fopen)
|
|
56
|
+
*
|
|
57
|
+
* build: clang -std=c11 -O3 -march=native -flto -shared -fPIC -pthread -ldl \
|
|
58
|
+
* virtualhardware.c -o libvirtualhardware.so
|
|
59
|
+
* the dockerfile pins exactly these flags; -march=native matches the per-
|
|
60
|
+
* platform native build of the multi-arch image (amd64 and arm64).
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
#define _GNU_SOURCE /* O_PATH, RTLD_NEXT, syscall, strdupa, memunit helpers */
|
|
64
|
+
|
|
65
|
+
#include <dlfcn.h>
|
|
66
|
+
#include <errno.h>
|
|
67
|
+
#include <fcntl.h>
|
|
68
|
+
#include <limits.h>
|
|
69
|
+
#include <pthread.h>
|
|
70
|
+
#include <stdarg.h>
|
|
71
|
+
#include <stdint.h>
|
|
72
|
+
#include <stdio.h>
|
|
73
|
+
#include <stdlib.h>
|
|
74
|
+
#include <string.h>
|
|
75
|
+
#include <sys/inotify.h>
|
|
76
|
+
#include <sys/stat.h>
|
|
77
|
+
#include <sys/syscall.h>
|
|
78
|
+
#include <sys/sysinfo.h>
|
|
79
|
+
#include <sys/types.h>
|
|
80
|
+
#include <sys/utsname.h>
|
|
81
|
+
#include <poll.h>
|
|
82
|
+
#include <unistd.h>
|
|
83
|
+
|
|
84
|
+
/* ------------------------------------------------------------------------ */
|
|
85
|
+
/* compile-time profile defaults, kept in sync with /etc/virtual generation */
|
|
86
|
+
/* ------------------------------------------------------------------------ */
|
|
87
|
+
|
|
88
|
+
#define VHEETCBASE "/etc/virtual"
|
|
89
|
+
#define VHETMPPREFIX "/tmp/.vhe"
|
|
90
|
+
#define VHEDEFAULTRAMGB 128UL /* 128 GiB node, matches dockerfile */
|
|
91
|
+
#define VHEDEFAULTCPUS 192U /* EPYC 9965 logical processors */
|
|
92
|
+
#define VHEDEFAULTRELEASE "6.18.0-vhe"
|
|
93
|
+
#define VHEDEFAULTVERSION "#1 SMP VHE PREEMPT_DYNAMIC 2026-08-22"
|
|
94
|
+
#define VHEREFRESHSECS 5U
|
|
95
|
+
#define VHEGIB (1UL << 30) /* 1 GiB in bytes */
|
|
96
|
+
#define VHEKIB 1024UL
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* runtime configuration, resolved exactly once (pthread_once) from the
|
|
100
|
+
* environment and the filesystem. every field keeps a fallback so the
|
|
101
|
+
* library stays inert when the operator provides no /etc/virtual tree.
|
|
102
|
+
*/
|
|
103
|
+
typedef struct vheconfig {
|
|
104
|
+
const char *cpuinfopath; /* resolved cpuinfo override or NULL */
|
|
105
|
+
const char *meminfopath; /* resolved meminfo override or NULL */
|
|
106
|
+
const char *uptimepath; /* resolved uptime override or NULL */
|
|
107
|
+
const char *loadavgpath; /* resolved loadavg override or NULL */
|
|
108
|
+
const char *versionpath; /* resolved version override or NULL */
|
|
109
|
+
char scratchdir[128]; /* private dynamic-mode directory */
|
|
110
|
+
unsigned long totalrambytes;/* VHE_TOTALRAM_GB << 30 */
|
|
111
|
+
unsigned long cpus; /* VHE_CPUS */
|
|
112
|
+
unsigned long uptimebase; /* VHE_UPTIME */
|
|
113
|
+
unsigned refreshsecs; /* VHE_MEMINFO_REFRESH */
|
|
114
|
+
const char *release; /* uname release */
|
|
115
|
+
const char *version; /* uname version */
|
|
116
|
+
const char *sysname; /* uname sysname */
|
|
117
|
+
const char *machine; /* uname machine */
|
|
118
|
+
int dynamicmem; /* 1 = regenerate meminfo via inotify */
|
|
119
|
+
int debug; /* VHE_DEBUG */
|
|
120
|
+
int enabled; /* VHE_ENABLED */
|
|
121
|
+
} vheconfig;
|
|
122
|
+
|
|
123
|
+
static vheconfig vhecfg;
|
|
124
|
+
static pthread_once_t vheonce = PTHREAD_ONCE_INIT;
|
|
125
|
+
static volatile int vhestop; /* watched by the reaper thread */
|
|
126
|
+
static pthread_t vhewatcherthread;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* thread-local reentrancy guard. the library itself opens files (regenerating
|
|
130
|
+
* the scaled meminfo, logging); those internal calls must reach the real libc
|
|
131
|
+
* symbols or the hooks would recurse forever. memoverlay uses the same pattern.
|
|
132
|
+
*/
|
|
133
|
+
static __thread int vhebusy;
|
|
134
|
+
|
|
135
|
+
/* resolved real libc symbols; never called directly by the engine */
|
|
136
|
+
typedef FILE *(*vhefopenfn)(const char *, const char *);
|
|
137
|
+
typedef FILE *(*vhefreopenfn)(const char *, const char *, FILE *);
|
|
138
|
+
typedef int (*vheopenfn)(const char *, int, ...);
|
|
139
|
+
typedef int (*vheopenatfn)(int, const char *, int, ...);
|
|
140
|
+
typedef int (*vhestatfn)(const char *, struct stat *);
|
|
141
|
+
typedef int (*vheaccessfn)(const char *, int);
|
|
142
|
+
typedef int (*vhesysinfofn)(struct sysinfo *);
|
|
143
|
+
typedef int (*vheunamefn)(struct utsname *);
|
|
144
|
+
typedef int (*vhemkdirfn)(const char *, mode_t);
|
|
145
|
+
|
|
146
|
+
static struct {
|
|
147
|
+
vhefopenfn fopen;
|
|
148
|
+
vhefopenfn fopen64;
|
|
149
|
+
vhefreopenfn freopen;
|
|
150
|
+
vhefreopenfn freopen64;
|
|
151
|
+
vheopenfn open;
|
|
152
|
+
vheopenfn open64;
|
|
153
|
+
vheopenatfn openat;
|
|
154
|
+
vheopenatfn openat64;
|
|
155
|
+
vhestatfn stat;
|
|
156
|
+
vhestatfn lstat;
|
|
157
|
+
vheaccessfn access;
|
|
158
|
+
vhesysinfofn sysinfo;
|
|
159
|
+
vheunamefn uname;
|
|
160
|
+
vhemkdirfn mkdir;
|
|
161
|
+
} vhereal;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* logs a debug line to fd 2 when VHE_DEBUG=1. dprintf never allocates a FILE
|
|
165
|
+
* stream and never calls open, so the logger cannot reenter the hooks.
|
|
166
|
+
* @param fmt printf-style format string
|
|
167
|
+
* @return nothing; errors on fd 2 are intentionally ignored
|
|
168
|
+
*/
|
|
169
|
+
static void vhelog(const char *fmt, ...)
|
|
170
|
+
{
|
|
171
|
+
char msg[256];
|
|
172
|
+
va_list ap;
|
|
173
|
+
int n;
|
|
174
|
+
|
|
175
|
+
if (!vhecfg.debug)
|
|
176
|
+
return;
|
|
177
|
+
va_start(ap, fmt);
|
|
178
|
+
n = vsnprintf(msg, sizeof(msg), fmt, ap);
|
|
179
|
+
va_end(ap);
|
|
180
|
+
if (n < 0)
|
|
181
|
+
return;
|
|
182
|
+
(void)dprintf(2, "[vhe] %s\n", msg);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* resolves one real libc symbol through dlsym(RTLD_NEXT, name). RTLD_NEXT is
|
|
187
|
+
* required (never RTLD_DEFAULT) because the library itself defines the symbol
|
|
188
|
+
* and a default lookup would find the hook again, looping forever.
|
|
189
|
+
* @param name symbol name such as "openat" or "sysinfo"
|
|
190
|
+
* @return function pointer, or NULL when no later object exports it
|
|
191
|
+
*/
|
|
192
|
+
static void *vheresolve(const char *name)
|
|
193
|
+
{
|
|
194
|
+
void *sym = dlsym(RTLD_NEXT, name);
|
|
195
|
+
if (sym == NULL)
|
|
196
|
+
vhelog("cannot resolve %s: %s", name, dlerror() ? dlerror() : "?");
|
|
197
|
+
return sym;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* checks readability without recursing into the interposed access() hook.
|
|
202
|
+
* the raw syscall is used because the guard thread and constructor may run
|
|
203
|
+
* before the caller expects any interception at all.
|
|
204
|
+
* @param path absolute path to probe
|
|
205
|
+
* @return 1 when readable, 0 otherwise
|
|
206
|
+
*/
|
|
207
|
+
static int vhepathreadable(const char *path)
|
|
208
|
+
{
|
|
209
|
+
if (path == NULL)
|
|
210
|
+
return 0;
|
|
211
|
+
return syscall(SYS_faccessat, AT_FDCWD, path, R_OK, 0) == 0;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* reads a positive unsigned long from an environment variable.
|
|
216
|
+
* @param name variable name
|
|
217
|
+
* @param fallback value used when unset, empty or malformed
|
|
218
|
+
* @return parsed value or fallback (strtoul with full validation)
|
|
219
|
+
*/
|
|
220
|
+
static unsigned long vheenvulong(const char *name, unsigned long fallback)
|
|
221
|
+
{
|
|
222
|
+
const char *raw = getenv(name);
|
|
223
|
+
char *end = NULL;
|
|
224
|
+
unsigned long val;
|
|
225
|
+
|
|
226
|
+
if (raw == NULL || *raw == '\0')
|
|
227
|
+
return fallback;
|
|
228
|
+
errno = 0;
|
|
229
|
+
val = strtoul(raw, &end, 10);
|
|
230
|
+
if (errno != 0 || end == raw || *end != '\0')
|
|
231
|
+
return fallback;
|
|
232
|
+
return val;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* reads an optional string variable, returning NULL for unset or empty so
|
|
237
|
+
* callers can keep their defaults without extra branches.
|
|
238
|
+
* @param name variable name
|
|
239
|
+
* @return pointer into the environment, or NULL
|
|
240
|
+
*/
|
|
241
|
+
static const char *vheenvstr(const char *name)
|
|
242
|
+
{
|
|
243
|
+
const char *raw = getenv(name);
|
|
244
|
+
return (raw != NULL && *raw != '\0') ? raw : NULL;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* builds the private dynamic-mode directory (/tmp/.vhe-<uid>) used for the
|
|
249
|
+
* regenerated meminfo, uptime and loadavg files, following the memoverlay
|
|
250
|
+
* pattern of writing scaled copies outside procfs (procfs is read-only and
|
|
251
|
+
* does not support inotify watches, so the scaled copy must live on tmpfs).
|
|
252
|
+
* @return nothing; failure downgrades the library to static mode
|
|
253
|
+
*/
|
|
254
|
+
static void vhepreparescratch(void)
|
|
255
|
+
{
|
|
256
|
+
int rc = snprintf(vhecfg.scratchdir, sizeof(vhecfg.scratchdir),
|
|
257
|
+
"%s-%ld", VHETMPPREFIX, (long)getuid());
|
|
258
|
+
if (rc < 0 || (size_t)rc >= sizeof(vhecfg.scratchdir)) {
|
|
259
|
+
vhecfg.scratchdir[0] = '\0';
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
if (vhereal.mkdir == NULL)
|
|
263
|
+
vhereal.mkdir = (vhemkdirfn)vheresolve("mkdir");
|
|
264
|
+
if (vhereal.mkdir == NULL ||
|
|
265
|
+
(vhereal.mkdir(vhecfg.scratchdir, 0700) != 0 && errno != EEXIST)) {
|
|
266
|
+
vhelog("scratch dir %s unusable, dynamic meminfo disabled",
|
|
267
|
+
vhecfg.scratchdir);
|
|
268
|
+
vhecfg.scratchdir[0] = '\0';
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* joins the scratch directory and a leaf name into a fixed buffer.
|
|
274
|
+
* @param out output buffer
|
|
275
|
+
* @param outsz buffer size
|
|
276
|
+
* @param leaf file name such as "meminfo"
|
|
277
|
+
* @return 0 on success, -1 on truncation (caller falls back safely)
|
|
278
|
+
*/
|
|
279
|
+
static int vhescratchpath(char *out, size_t outsz, const char *leaf)
|
|
280
|
+
{
|
|
281
|
+
int rc;
|
|
282
|
+
if (vhecfg.scratchdir[0] == '\0')
|
|
283
|
+
return -1;
|
|
284
|
+
rc = snprintf(out, outsz, "%s/%s", vhecfg.scratchdir, leaf);
|
|
285
|
+
return (rc < 0 || (size_t)rc >= outsz) ? -1 : 0;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* deterministic pseudo-random 32-bit walk (xorshift32) used to derive stable
|
|
290
|
+
* per-refresh values for meminfo, so successive reads look alive without a
|
|
291
|
+
* real prng dependency.
|
|
292
|
+
* @param seed previous state, any nonzero value
|
|
293
|
+
* @return next state
|
|
294
|
+
*/
|
|
295
|
+
static uint32_t vhenextrand(uint32_t *seed)
|
|
296
|
+
{
|
|
297
|
+
uint32_t x = *seed ? *seed : 0x9e3779b9u;
|
|
298
|
+
x ^= x << 13;
|
|
299
|
+
x ^= x >> 17;
|
|
300
|
+
x ^= x << 5;
|
|
301
|
+
*seed = x;
|
|
302
|
+
return x;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* reads the real uptime seconds from /proc/uptime through the raw openat
|
|
307
|
+
* syscall, bypassing the hooks on purpose: the dynamic layer anchors every
|
|
308
|
+
* virtual value added to the real monotonic uptime of the container.
|
|
309
|
+
* @return uptime in seconds, or 0 when unreadable (defensive)
|
|
310
|
+
*/
|
|
311
|
+
static unsigned long vherealuptime(void)
|
|
312
|
+
{
|
|
313
|
+
char buf[128];
|
|
314
|
+
ssize_t n;
|
|
315
|
+
int fd = (int)syscall(SYS_openat, AT_FDCWD, "/proc/uptime", O_RDONLY, 0);
|
|
316
|
+
if (fd < 0)
|
|
317
|
+
return 0;
|
|
318
|
+
n = read(fd, buf, sizeof(buf) - 1);
|
|
319
|
+
close(fd);
|
|
320
|
+
if (n <= 0)
|
|
321
|
+
return 0;
|
|
322
|
+
buf[n] = '\0';
|
|
323
|
+
return (unsigned long)strtoul(buf, NULL, 10);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* regenerates the dynamic virtual files: meminfo, uptime and loadavg. the layout
|
|
328
|
+
* mirrors a real 6.x kernel meminfo (40+ fields in kB) scaled from
|
|
329
|
+
* VHE_TOTALRAM_GB; MemFree keeps the dolos ratio total/4 for consistency with
|
|
330
|
+
* the sysinfo() hook, Buffers total/16, Cached a drifting fraction so tools
|
|
331
|
+
* polling twice observe movement (the memoverlay inotify thread behavior).
|
|
332
|
+
* @return nothing; failures only disable individual leaves
|
|
333
|
+
*/
|
|
334
|
+
static void vheregenerate(void)
|
|
335
|
+
{
|
|
336
|
+
char path[192];
|
|
337
|
+
unsigned long totalkb = vhecfg.totalrambytes / VHEKIB;
|
|
338
|
+
unsigned long uptime = vherealuptime() + vhecfg.uptimebase;
|
|
339
|
+
unsigned long freekb = totalkb / 4;
|
|
340
|
+
unsigned long bufferskb = totalkb / 16;
|
|
341
|
+
unsigned long cachedkb, availkb, usedkb, loads[3];
|
|
342
|
+
uint32_t seed = (uint32_t)uptime | 1u;
|
|
343
|
+
int fd, i;
|
|
344
|
+
|
|
345
|
+
vhebusy = 1; /* internal writes must not be re-intercepted */
|
|
346
|
+
|
|
347
|
+
/* meminfo: MemFree keeps the fixed dolos ratio total/4 so the sysinfo()
|
|
348
|
+
* hook and the file view always agree; the drifting fields are the
|
|
349
|
+
* caches, giving polling tools visible movement across refreshes. */
|
|
350
|
+
usedkb = totalkb / 5 + (vhenextrand(&seed) % (totalkb / 20));
|
|
351
|
+
cachedkb = totalkb / 4 + (vhenextrand(&seed) % (totalkb / 16));
|
|
352
|
+
bufferskb += vhenextrand(&seed) % (totalkb / 64);
|
|
353
|
+
availkb = freekb + cachedkb + bufferskb;
|
|
354
|
+
|
|
355
|
+
if (vhescratchpath(path, sizeof(path), "meminfo") == 0) {
|
|
356
|
+
fd = (int)syscall(SYS_openat, AT_FDCWD, path,
|
|
357
|
+
O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
358
|
+
if (fd >= 0) {
|
|
359
|
+
dprintf(fd, "MemTotal: %10lu kB\n", totalkb);
|
|
360
|
+
dprintf(fd, "MemFree: %10lu kB\n", freekb);
|
|
361
|
+
dprintf(fd, "MemAvailable: %10lu kB\n", availkb);
|
|
362
|
+
dprintf(fd, "Buffers: %10lu kB\n", bufferskb);
|
|
363
|
+
dprintf(fd, "Cached: %10lu kB\n", cachedkb);
|
|
364
|
+
dprintf(fd, "SwapCached: %10lu kB\n", 0UL);
|
|
365
|
+
dprintf(fd, "Active: %10lu kB\n", usedkb + cachedkb / 2);
|
|
366
|
+
dprintf(fd, "Inactive: %10lu kB\n", cachedkb / 2);
|
|
367
|
+
dprintf(fd, "Active(anon): %10lu kB\n", usedkb);
|
|
368
|
+
dprintf(fd, "Inactive(anon): %10lu kB\n", usedkb / 8);
|
|
369
|
+
dprintf(fd, "Active(file): %10lu kB\n", cachedkb / 2);
|
|
370
|
+
dprintf(fd, "Inactive(file): %10lu kB\n", cachedkb / 2);
|
|
371
|
+
dprintf(fd, "Unevictable: %10lu kB\n", 0UL);
|
|
372
|
+
dprintf(fd, "Mlocked: %10lu kB\n", 0UL);
|
|
373
|
+
dprintf(fd, "SwapTotal: %10lu kB\n", totalkb / 2);
|
|
374
|
+
dprintf(fd, "SwapFree: %10lu kB\n", totalkb / 2);
|
|
375
|
+
dprintf(fd, "Zswap: %10lu kB\n", 0UL);
|
|
376
|
+
dprintf(fd, "Zswapped: %10lu kB\n", 0UL);
|
|
377
|
+
dprintf(fd, "Dirty: %10lu kB\n", totalkb / 512);
|
|
378
|
+
dprintf(fd, "Writeback: %10lu kB\n", 0UL);
|
|
379
|
+
dprintf(fd, "AnonPages: %10lu kB\n", usedkb);
|
|
380
|
+
dprintf(fd, "Mapped: %10lu kB\n", usedkb / 4);
|
|
381
|
+
dprintf(fd, "Shmem: %10lu kB\n", totalkb / 128);
|
|
382
|
+
dprintf(fd, "KReclaimable: %10lu kB\n", totalkb / 64);
|
|
383
|
+
dprintf(fd, "Slab: %10lu kB\n", totalkb / 32);
|
|
384
|
+
dprintf(fd, "SReclaimable: %10lu kB\n", totalkb / 64);
|
|
385
|
+
dprintf(fd, "SUnreclaim: %10lu kB\n", totalkb / 64);
|
|
386
|
+
dprintf(fd, "KernelStack: %10lu kB\n", totalkb / 2048);
|
|
387
|
+
dprintf(fd, "PageTables: %10lu kB\n", totalkb / 1024);
|
|
388
|
+
dprintf(fd, "NFS_Unstable: %10lu kB\n", 0UL);
|
|
389
|
+
dprintf(fd, "Bounce: %10lu kB\n", 0UL);
|
|
390
|
+
dprintf(fd, "WritebackTmp: %10lu kB\n", 0UL);
|
|
391
|
+
dprintf(fd, "CommitLimit: %10lu kB\n", totalkb);
|
|
392
|
+
dprintf(fd, "Committed_AS: %10lu kB\n", usedkb * 2);
|
|
393
|
+
dprintf(fd, "VmallocTotal: %10lu kB\n", 34359738367UL);
|
|
394
|
+
dprintf(fd, "VmallocUsed: %10lu kB\n", totalkb / 128);
|
|
395
|
+
dprintf(fd, "VmallocChunk: %10lu kB\n", 0UL);
|
|
396
|
+
dprintf(fd, "Percpu: %10lu kB\n", totalkb / 2048);
|
|
397
|
+
dprintf(fd, "HardwareCorrupted: %7lu kB\n", 0UL);
|
|
398
|
+
dprintf(fd, "AnonHugePages: %10lu kB\n", 0UL);
|
|
399
|
+
dprintf(fd, "ShmemHugePages: %10lu kB\n", 0UL);
|
|
400
|
+
dprintf(fd, "FileHugePages: %10lu kB\n", 0UL);
|
|
401
|
+
dprintf(fd, "HugePages_Total: %7lu\n", 0UL);
|
|
402
|
+
dprintf(fd, "HugePages_Free: %7lu\n", 0UL);
|
|
403
|
+
dprintf(fd, "HugePages_Rsvd: %7lu\n", 0UL);
|
|
404
|
+
dprintf(fd, "HugePages_Surp: %7lu\n", 0UL);
|
|
405
|
+
dprintf(fd, "Hugepagesize: %7lu kB\n", 2048UL);
|
|
406
|
+
dprintf(fd, "Hugetlb: %10lu kB\n", 0UL);
|
|
407
|
+
dprintf(fd, "DirectMap4k: %10lu kB\n", totalkb / 64);
|
|
408
|
+
dprintf(fd, "DirectMap2M: %10lu kB\n", totalkb / 2);
|
|
409
|
+
dprintf(fd, "DirectMap1G: %10lu kB\n", totalkb / 2);
|
|
410
|
+
close(fd);
|
|
411
|
+
} else {
|
|
412
|
+
vhelog("regenerate meminfo failed on %s: errno=%d", path, errno);
|
|
413
|
+
}
|
|
414
|
+
} else {
|
|
415
|
+
vhelog("scratch meminfo unavailable, skipping regeneration");
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (vhescratchpath(path, sizeof(path), "uptime") == 0 &&
|
|
419
|
+
(fd = (int)syscall(SYS_openat, AT_FDCWD, path,
|
|
420
|
+
O_WRONLY | O_CREAT | O_TRUNC, 0644)) >= 0) {
|
|
421
|
+
dprintf(fd, "%lu.%02lu %lu.%02lu\n",
|
|
422
|
+
uptime, vhenextrand(&seed) % 100UL,
|
|
423
|
+
uptime * 3 / 4, vhenextrand(&seed) % 100UL);
|
|
424
|
+
close(fd);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (vhescratchpath(path, sizeof(path), "loadavg") == 0 &&
|
|
428
|
+
(fd = (int)syscall(SYS_openat, AT_FDCWD, path,
|
|
429
|
+
O_WRONLY | O_CREAT | O_TRUNC, 0644)) >= 0) {
|
|
430
|
+
for (i = 0; i < 3; i++)
|
|
431
|
+
loads[i] = vhenextrand(&seed) % (vhecfg.cpus * 80 / 100);
|
|
432
|
+
dprintf(fd, "%lu.%02lu %lu.%02lu %lu.%02lu %lu/%lu\n",
|
|
433
|
+
loads[0] / 100, loads[0] % 100,
|
|
434
|
+
loads[1] / 100, loads[1] % 100,
|
|
435
|
+
loads[2] / 100, loads[2] % 100,
|
|
436
|
+
64UL + vhenextrand(&seed) % 512UL, vhecfg.cpus * 4);
|
|
437
|
+
close(fd);
|
|
438
|
+
}
|
|
439
|
+
vhebusy = 0;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* watcher thread body, the memoverlay inotify pattern. the thread watches the
|
|
444
|
+
* /etc/virtual configuration directory (IN_CLOSE_WRITE | IN_MOVED_TO) so an
|
|
445
|
+
* operator editing meminfo triggers an immediate regeneration, and poll()
|
|
446
|
+
* doubles as the periodic timer (VHE_MEMINFO_REFRESH) that keeps the dynamic
|
|
447
|
+
* values moving even without manual edits. when inotify or the config
|
|
448
|
+
* directory are unavailable the loop degrades to a pure nanosleep timer.
|
|
449
|
+
* @param arg unused
|
|
450
|
+
* @return NULL always
|
|
451
|
+
*/
|
|
452
|
+
static void *vhewatcher(void *arg)
|
|
453
|
+
{
|
|
454
|
+
char buf[sizeof(struct inotify_event) + NAME_MAX + 1];
|
|
455
|
+
struct inotify_event *ev;
|
|
456
|
+
int ifd = inotify_init1(IN_CLOEXEC);
|
|
457
|
+
int wd = -1;
|
|
458
|
+
ssize_t n;
|
|
459
|
+
char *p;
|
|
460
|
+
|
|
461
|
+
(void)arg;
|
|
462
|
+
if (ifd >= 0)
|
|
463
|
+
wd = inotify_add_watch(ifd, VHEETCBASE,
|
|
464
|
+
IN_CLOSE_WRITE | IN_MOVED_TO);
|
|
465
|
+
vhelog("watcher started (ifd=%d wd=%d refresh=%us dynamic=%d)",
|
|
466
|
+
ifd, wd, vhecfg.refreshsecs, vhecfg.dynamicmem);
|
|
467
|
+
|
|
468
|
+
while (!vhestop) {
|
|
469
|
+
if (ifd >= 0 && wd >= 0) {
|
|
470
|
+
struct pollfd pfd = { ifd, POLLIN, 0 };
|
|
471
|
+
int prc = poll(&pfd, 1, (int)vhecfg.refreshsecs * 1000);
|
|
472
|
+
if (prc > 0 && (pfd.revents & POLLIN)) {
|
|
473
|
+
n = read(ifd, buf, sizeof(buf));
|
|
474
|
+
if (n > 0) {
|
|
475
|
+
for (p = buf; p < buf + n;
|
|
476
|
+
p += sizeof(*ev) + (size_t)ev->len) {
|
|
477
|
+
ev = (struct inotify_event *)p;
|
|
478
|
+
vhelog("config event 0x%x on %.*s", ev->mask,
|
|
479
|
+
(int)ev->len, ev->name);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
} else if (prc < 0 && errno != EINTR) {
|
|
483
|
+
vhelog("poll failed: errno=%d", errno);
|
|
484
|
+
break;
|
|
485
|
+
}
|
|
486
|
+
} else {
|
|
487
|
+
struct timespec ts;
|
|
488
|
+
ts.tv_sec = (time_t)vhecfg.refreshsecs;
|
|
489
|
+
ts.tv_nsec = 0;
|
|
490
|
+
nanosleep(&ts, NULL);
|
|
491
|
+
}
|
|
492
|
+
if (vhecfg.dynamicmem)
|
|
493
|
+
vheregenerate();
|
|
494
|
+
}
|
|
495
|
+
if (ifd >= 0) {
|
|
496
|
+
if (wd >= 0)
|
|
497
|
+
inotify_rm_watch(ifd, wd);
|
|
498
|
+
close(ifd);
|
|
499
|
+
}
|
|
500
|
+
return NULL;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* one-shot initializer, executed under pthread_once from the constructor or
|
|
505
|
+
* from the first hook invocation, whichever happens first. resolves every
|
|
506
|
+
* real symbol, evaluates the environment, probes /etc/virtual and decides
|
|
507
|
+
* the redirect table. any failure leaves the corresponding hook disabled,
|
|
508
|
+
* which makes the library fail open (binaries keep running against the real
|
|
509
|
+
* procfs) instead of breaking the process.
|
|
510
|
+
*/
|
|
511
|
+
static void vheinitonce(void)
|
|
512
|
+
{
|
|
513
|
+
const char *env;
|
|
514
|
+
char etc[192];
|
|
515
|
+
|
|
516
|
+
memset(&vhecfg, 0, sizeof(vhecfg));
|
|
517
|
+
vhecfg.totalrambytes = VHEDEFAULTRAMGB * VHEGIB;
|
|
518
|
+
vhecfg.cpus = VHEDEFAULTCPUS;
|
|
519
|
+
vhecfg.refreshsecs = VHEREFRESHSECS;
|
|
520
|
+
vhecfg.release = VHEDEFAULTRELEASE;
|
|
521
|
+
vhecfg.version = VHEDEFAULTVERSION;
|
|
522
|
+
vhecfg.sysname = "Linux";
|
|
523
|
+
vhecfg.machine = "x86_64";
|
|
524
|
+
vhecfg.enabled = 1;
|
|
525
|
+
|
|
526
|
+
vhereal.fopen = (vhefopenfn)vheresolve("fopen");
|
|
527
|
+
vhereal.fopen64 = (vhefopenfn)vheresolve("fopen64");
|
|
528
|
+
vhereal.freopen = (vhefreopenfn)vheresolve("freopen");
|
|
529
|
+
vhereal.freopen64 = (vhefreopenfn)vheresolve("freopen64");
|
|
530
|
+
vhereal.open = (vheopenfn)vheresolve("open");
|
|
531
|
+
vhereal.open64 = (vheopenfn)vheresolve("open64");
|
|
532
|
+
vhereal.openat = (vheopenatfn)vheresolve("openat");
|
|
533
|
+
vhereal.openat64 = (vheopenatfn)vheresolve("openat64");
|
|
534
|
+
vhereal.stat = (vhestatfn)vheresolve("stat");
|
|
535
|
+
vhereal.lstat = (vhestatfn)vheresolve("lstat");
|
|
536
|
+
vhereal.access = (vheaccessfn)vheresolve("access");
|
|
537
|
+
vhereal.sysinfo = (vhesysinfofn)vheresolve("sysinfo");
|
|
538
|
+
vhereal.uname = (vheunamefn)vheresolve("uname");
|
|
539
|
+
|
|
540
|
+
vhecfg.totalrambytes = vheenvulong("VHE_TOTALRAM_GB",
|
|
541
|
+
VHEDEFAULTRAMGB) * VHEGIB;
|
|
542
|
+
vhecfg.cpus = vheenvulong("VHE_CPUS", VHEDEFAULTCPUS);
|
|
543
|
+
vhecfg.uptimebase = vheenvulong("VHE_UPTIME", 0);
|
|
544
|
+
vhecfg.refreshsecs = (unsigned)vheenvulong("VHE_MEMINFO_REFRESH",
|
|
545
|
+
VHEREFRESHSECS);
|
|
546
|
+
if ((env = vheenvstr("VHE_KERNEL_RELEASE")) != NULL)
|
|
547
|
+
vhecfg.release = env;
|
|
548
|
+
if ((env = vheenvstr("VHE_KERNEL_VERSION")) != NULL)
|
|
549
|
+
vhecfg.version = env;
|
|
550
|
+
if ((env = vheenvstr("VHE_SYSNAME")) != NULL)
|
|
551
|
+
vhecfg.sysname = env;
|
|
552
|
+
if ((env = vheenvstr("VHE_MACHINE")) != NULL)
|
|
553
|
+
vhecfg.machine = env;
|
|
554
|
+
vhecfg.debug = vheenvulong("VHE_DEBUG", 0) != 0;
|
|
555
|
+
vhecfg.enabled = vheenvulong("VHE_ENABLED", 1) != 0;
|
|
556
|
+
|
|
557
|
+
/* redirect resolution order per source, all defensive:
|
|
558
|
+
* 1. explicit env override (VHE_CPUINFO, VHE_MEMINFO, ...)
|
|
559
|
+
* 2. /etc/virtual/<leaf> baked into the docker image
|
|
560
|
+
* 3. dynamic scratch copy for meminfo/uptime/loadavg
|
|
561
|
+
* 4. NULL = passthrough to the real procfs entry
|
|
562
|
+
*/
|
|
563
|
+
if ((env = vheenvstr("VHE_CPUINFO")) != NULL &&
|
|
564
|
+
vhepathreadable(env))
|
|
565
|
+
vhecfg.cpuinfopath = env;
|
|
566
|
+
else if (snprintf(etc, sizeof(etc), "%s/cpuinfo", VHEETCBASE) > 0 &&
|
|
567
|
+
vhepathreadable(etc))
|
|
568
|
+
vhecfg.cpuinfopath = VHEETCBASE "/cpuinfo";
|
|
569
|
+
|
|
570
|
+
/* memoverlay default: the watcher regenerates a scaled meminfo copy; the
|
|
571
|
+
* operator opts out with VHE_MEMINFO_MODE=static or an explicit file. */
|
|
572
|
+
if ((env = vheenvstr("VHE_MEMINFO_MODE")) != NULL)
|
|
573
|
+
vhecfg.dynamicmem = strcmp(env, "static") != 0;
|
|
574
|
+
else
|
|
575
|
+
vhecfg.dynamicmem = 1;
|
|
576
|
+
if (vheenvstr("VHE_MEMINFO") != NULL)
|
|
577
|
+
vhecfg.dynamicmem = 0; /* explicit file implies static mode */
|
|
578
|
+
|
|
579
|
+
if ((env = vheenvstr("VHE_MEMINFO")) != NULL && vhepathreadable(env))
|
|
580
|
+
vhecfg.meminfopath = env;
|
|
581
|
+
else if (!vhecfg.dynamicmem &&
|
|
582
|
+
snprintf(etc, sizeof(etc), "%s/meminfo", VHEETCBASE) > 0 &&
|
|
583
|
+
vhepathreadable(etc))
|
|
584
|
+
vhecfg.meminfopath = VHEETCBASE "/meminfo";
|
|
585
|
+
|
|
586
|
+
if ((env = vheenvstr("VHE_UPTIME_PATH")) != NULL && vhepathreadable(env))
|
|
587
|
+
vhecfg.uptimepath = env;
|
|
588
|
+
else if (snprintf(etc, sizeof(etc), "%s/uptime", VHEETCBASE) > 0 &&
|
|
589
|
+
vhepathreadable(etc))
|
|
590
|
+
vhecfg.uptimepath = VHEETCBASE "/uptime";
|
|
591
|
+
|
|
592
|
+
if ((env = vheenvstr("VHE_LOADAVG_PATH")) != NULL && vhepathreadable(env))
|
|
593
|
+
vhecfg.loadavgpath = env;
|
|
594
|
+
else if (snprintf(etc, sizeof(etc), "%s/loadavg", VHEETCBASE) > 0 &&
|
|
595
|
+
vhepathreadable(etc))
|
|
596
|
+
vhecfg.loadavgpath = VHEETCBASE "/loadavg";
|
|
597
|
+
|
|
598
|
+
if ((env = vheenvstr("VHE_VERSION_PATH")) != NULL && vhepathreadable(env))
|
|
599
|
+
vhecfg.versionpath = env;
|
|
600
|
+
else if (snprintf(etc, sizeof(etc), "%s/version", VHEETCBASE) > 0 &&
|
|
601
|
+
vhepathreadable(etc))
|
|
602
|
+
vhecfg.versionpath = VHEETCBASE "/version";
|
|
603
|
+
|
|
604
|
+
if (vhecfg.dynamicmem) {
|
|
605
|
+
vhepreparescratch();
|
|
606
|
+
if (vhecfg.scratchdir[0] == '\0') {
|
|
607
|
+
/* no writable scratch: degrade to static mode defensively */
|
|
608
|
+
vhecfg.dynamicmem = 0;
|
|
609
|
+
if (snprintf(etc, sizeof(etc), "%s/meminfo", VHEETCBASE) > 0 &&
|
|
610
|
+
vhepathreadable(etc))
|
|
611
|
+
vhecfg.meminfopath = VHEETCBASE "/meminfo";
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/* first generation before any consumer can observe the scratch tree */
|
|
616
|
+
if (vhecfg.dynamicmem)
|
|
617
|
+
vheregenerate();
|
|
618
|
+
|
|
619
|
+
if (vhecfg.dynamicmem) {
|
|
620
|
+
if (vhescratchpath(etc, sizeof(etc), "meminfo") == 0)
|
|
621
|
+
vhecfg.meminfopath = strdup(etc);
|
|
622
|
+
if (vhecfg.uptimepath == NULL &&
|
|
623
|
+
vhescratchpath(etc, sizeof(etc), "uptime") == 0)
|
|
624
|
+
vhecfg.uptimepath = strdup(etc);
|
|
625
|
+
if (vhecfg.loadavgpath == NULL &&
|
|
626
|
+
vhescratchpath(etc, sizeof(etc), "loadavg") == 0)
|
|
627
|
+
vhecfg.loadavgpath = strdup(etc);
|
|
628
|
+
}
|
|
629
|
+
if (vhecfg.versionpath == NULL && vhecfg.dynamicmem &&
|
|
630
|
+
vhescratchpath(etc, sizeof(etc), "version") == 0) {
|
|
631
|
+
int fd = (int)syscall(SYS_openat, AT_FDCWD, etc,
|
|
632
|
+
O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
633
|
+
if (fd >= 0) {
|
|
634
|
+
dprintf(fd, "Linux version %s (vhe-builder@vhe) "
|
|
635
|
+
"(clang version 19.1.0) %s\n",
|
|
636
|
+
vhecfg.release, vhecfg.version);
|
|
637
|
+
close(fd);
|
|
638
|
+
vhecfg.versionpath = strdup(etc);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
if (vhecfg.dynamicmem) {
|
|
643
|
+
vhestop = 0;
|
|
644
|
+
if (pthread_create(&vhewatcherthread, NULL, vhewatcher, NULL) != 0)
|
|
645
|
+
vhelog("watcher thread creation failed: errno=%d", errno);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
vhelog("initialized ram=%luGiB cpus=%lu cpuinfo=%s meminfo=%s "
|
|
649
|
+
"dynamic=%d release=%s",
|
|
650
|
+
vhecfg.totalrambytes >> 30, vhecfg.cpus,
|
|
651
|
+
vhecfg.cpuinfopath ? vhecfg.cpuinfopath : "(real)",
|
|
652
|
+
vhecfg.meminfopath ? vhecfg.meminfopath : "(real)",
|
|
653
|
+
vhecfg.dynamicmem, vhecfg.release);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* lazy-init shim invoked at the top of every hook: cheap once pthread_once
|
|
658
|
+
* has completed, and it covers processes that load the library through an
|
|
659
|
+
* explicit dlopen() after startup (no constructor run for them).
|
|
660
|
+
*/
|
|
661
|
+
static void vheensure(void)
|
|
662
|
+
{
|
|
663
|
+
pthread_once(&vheonce, vheinitonce);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* translates an intercepted procfs path to its virtual replacement.
|
|
668
|
+
* @param path path as passed by the caller (may be NULL or relative)
|
|
669
|
+
* @return replacement path, or NULL when the request must pass through
|
|
670
|
+
*/
|
|
671
|
+
static const char *vhetranslate(const char *path)
|
|
672
|
+
{
|
|
673
|
+
if (path == NULL || path[0] != '/' || vhebusy || !vhecfg.enabled)
|
|
674
|
+
return NULL;
|
|
675
|
+
if (strcmp(path, "/proc/cpuinfo") == 0)
|
|
676
|
+
return vhecfg.cpuinfopath;
|
|
677
|
+
if (strcmp(path, "/proc/meminfo") == 0)
|
|
678
|
+
return vhecfg.meminfopath;
|
|
679
|
+
if (strcmp(path, "/proc/uptime") == 0)
|
|
680
|
+
return vhecfg.uptimepath;
|
|
681
|
+
if (strcmp(path, "/proc/loadavg") == 0)
|
|
682
|
+
return vhecfg.loadavgpath;
|
|
683
|
+
if (strcmp(path, "/proc/version") == 0)
|
|
684
|
+
return vhecfg.versionpath;
|
|
685
|
+
return NULL;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* shared implementation for open() and open64(): pulls the optional mode
|
|
690
|
+
* argument exactly like glibc does for O_CREAT and O_TMPFILE, translates the
|
|
691
|
+
* path and forwards to the resolved real function. relative paths are never
|
|
692
|
+
* rewritten because their meaning depends on dirfd (and procfs targets are
|
|
693
|
+
* always absolute).
|
|
694
|
+
* @param real resolved real open/open64
|
|
695
|
+
* @param path caller path
|
|
696
|
+
* @param flags open flags
|
|
697
|
+
* @param ap va_list positioned at the optional mode
|
|
698
|
+
* @return file descriptor or -1 with errno set by the real function
|
|
699
|
+
*/
|
|
700
|
+
static int vheopencommon(vheopenfn real, const char *path, int flags,
|
|
701
|
+
va_list ap)
|
|
702
|
+
{
|
|
703
|
+
const char *mapped = vhetranslate(path);
|
|
704
|
+
mode_t mode = 0;
|
|
705
|
+
|
|
706
|
+
if (flags & (O_CREAT | O_TMPFILE))
|
|
707
|
+
mode = (mode_t)va_arg(ap, int); /* mode_t promotes through varargs */
|
|
708
|
+
if (mapped != NULL) {
|
|
709
|
+
vhelog("open %s -> %s", path, mapped);
|
|
710
|
+
return real(mapped, flags, mode);
|
|
711
|
+
}
|
|
712
|
+
return real(path, flags, mode);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* hook for open(3). the full family is required: coreutils and many daemons
|
|
717
|
+
* issue openat instead of open (stackoverflow.com/questions/77489799 shows
|
|
718
|
+
* netstat reaching procfs only through openat), so hooking open alone leaks
|
|
719
|
+
* the real hardware to a large class of tools.
|
|
720
|
+
*/
|
|
721
|
+
int open(const char *path, int flags, ...)
|
|
722
|
+
{
|
|
723
|
+
va_list ap;
|
|
724
|
+
int rc;
|
|
725
|
+
|
|
726
|
+
vheensure();
|
|
727
|
+
va_start(ap, flags);
|
|
728
|
+
rc = vheopencommon(vhereal.open, path, flags, ap);
|
|
729
|
+
va_end(ap);
|
|
730
|
+
return rc;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/** hook for open64(3), the legacy large-file entry point still present in
|
|
734
|
+
* every glibc build; older java and fortran runtimes reach procfs here. */
|
|
735
|
+
int open64(const char *path, int flags, ...)
|
|
736
|
+
{
|
|
737
|
+
va_list ap;
|
|
738
|
+
int rc;
|
|
739
|
+
|
|
740
|
+
vheensure();
|
|
741
|
+
va_start(ap, flags);
|
|
742
|
+
rc = vheopencommon(vhereal.open64, path, flags, ap);
|
|
743
|
+
va_end(ap);
|
|
744
|
+
return rc;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* shared implementation for openat()/openat64(). only absolute paths are
|
|
749
|
+
* translated; a relative "cpuinfo" resolved through dirfd must keep its
|
|
750
|
+
* caller-provided meaning.
|
|
751
|
+
* @param real resolved real openat/openat64
|
|
752
|
+
* @param dirfd directory file descriptor
|
|
753
|
+
* @param path caller path
|
|
754
|
+
* @param flags open flags
|
|
755
|
+
* @param ap va_list positioned at the optional mode
|
|
756
|
+
* @return file descriptor or -1 with errno set by the real function
|
|
757
|
+
*/
|
|
758
|
+
static int vheopenatcommon(vheopenatfn real, int dirfd, const char *path,
|
|
759
|
+
int flags, va_list ap)
|
|
760
|
+
{
|
|
761
|
+
const char *mapped = vhetranslate(path);
|
|
762
|
+
mode_t mode = 0;
|
|
763
|
+
|
|
764
|
+
if (flags & (O_CREAT | O_TMPFILE))
|
|
765
|
+
mode = (mode_t)va_arg(ap, int);
|
|
766
|
+
if (mapped != NULL) {
|
|
767
|
+
vhelog("openat %s -> %s", path, mapped);
|
|
768
|
+
return real(AT_FDCWD, mapped, flags, mode);
|
|
769
|
+
}
|
|
770
|
+
return real(dirfd, path, flags, mode);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/** hook for openat(2), the modern glibc entry point used by coreutils. */
|
|
774
|
+
int openat(int dirfd, const char *path, int flags, ...)
|
|
775
|
+
{
|
|
776
|
+
va_list ap;
|
|
777
|
+
int rc;
|
|
778
|
+
|
|
779
|
+
vheensure();
|
|
780
|
+
va_start(ap, flags);
|
|
781
|
+
rc = vheopenatcommon(vhereal.openat, dirfd, path, flags, ap);
|
|
782
|
+
va_end(ap);
|
|
783
|
+
return rc;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/** hook for openat64(2), large-file variant of openat. */
|
|
787
|
+
int openat64(int dirfd, const char *path, int flags, ...)
|
|
788
|
+
{
|
|
789
|
+
va_list ap;
|
|
790
|
+
int rc;
|
|
791
|
+
|
|
792
|
+
vheensure();
|
|
793
|
+
va_start(ap, flags);
|
|
794
|
+
rc = vheopenatcommon(vhereal.openat64, dirfd, path, flags, ap);
|
|
795
|
+
va_end(ap);
|
|
796
|
+
return rc;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
* hook for fopen(3), the entry point used by python (open()), perl, php and
|
|
801
|
+
* most interpreted runtimes when they read /proc files.
|
|
802
|
+
* @return stream over the virtual file, or the real result on passthrough
|
|
803
|
+
*/
|
|
804
|
+
FILE *fopen(const char *path, const char *mode)
|
|
805
|
+
{
|
|
806
|
+
const char *mapped;
|
|
807
|
+
|
|
808
|
+
vheensure();
|
|
809
|
+
mapped = vhetranslate(path);
|
|
810
|
+
if (mapped != NULL) {
|
|
811
|
+
vhelog("fopen %s -> %s", path, mapped);
|
|
812
|
+
return vhereal.fopen(mapped, mode);
|
|
813
|
+
}
|
|
814
|
+
return vhereal.fopen(path, mode);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
/** hook for fopen64(3), large-file fopen reached by some 32-bit builds. */
|
|
818
|
+
FILE *fopen64(const char *path, const char *mode)
|
|
819
|
+
{
|
|
820
|
+
const char *mapped;
|
|
821
|
+
|
|
822
|
+
vheensure();
|
|
823
|
+
mapped = vhetranslate(path);
|
|
824
|
+
if (mapped != NULL)
|
|
825
|
+
return vhereal.fopen64(mapped, mode);
|
|
826
|
+
return vhereal.fopen64(path, mode);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* hook for freopen(3). a NULL path means "reopen the current stream" and is
|
|
831
|
+
* forwarded untouched; only real paths participate in translation.
|
|
832
|
+
* @return the reused stream from the real freopen
|
|
833
|
+
*/
|
|
834
|
+
FILE *freopen(const char *path, const char *mode, FILE *stream)
|
|
835
|
+
{
|
|
836
|
+
const char *mapped;
|
|
837
|
+
|
|
838
|
+
vheensure();
|
|
839
|
+
if (path == NULL)
|
|
840
|
+
return vhereal.freopen(NULL, mode, stream);
|
|
841
|
+
mapped = vhetranslate(path);
|
|
842
|
+
if (mapped != NULL) {
|
|
843
|
+
vhelog("freopen %s -> %s", path, mapped);
|
|
844
|
+
return vhereal.freopen(mapped, mode, stream);
|
|
845
|
+
}
|
|
846
|
+
return vhereal.freopen(path, mode, stream);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/** hook for freopen64(3), large-file variant of freopen. */
|
|
850
|
+
FILE *freopen64(const char *path, const char *mode, FILE *stream)
|
|
851
|
+
{
|
|
852
|
+
const char *mapped;
|
|
853
|
+
|
|
854
|
+
vheensure();
|
|
855
|
+
if (path == NULL)
|
|
856
|
+
return vhereal.freopen64(NULL, mode, stream);
|
|
857
|
+
mapped = vhetranslate(path);
|
|
858
|
+
if (mapped != NULL)
|
|
859
|
+
return vhereal.freopen64(mapped, mode, stream);
|
|
860
|
+
return vhereal.freopen64(path, mode, stream);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* shared implementation for stat() and lstat(): procfs entries are never
|
|
865
|
+
* symlinks, so both hooks share one body and only translate the path before
|
|
866
|
+
* the real call fills the caller-provided struct stat.
|
|
867
|
+
* @param real resolved real stat or lstat
|
|
868
|
+
* @param path caller path
|
|
869
|
+
* @param buf caller stat buffer
|
|
870
|
+
* @return 0 on success, -1 with errno on failure
|
|
871
|
+
*/
|
|
872
|
+
static int vhestatcommon(vhestatfn real, const char *path,
|
|
873
|
+
struct stat *buf)
|
|
874
|
+
{
|
|
875
|
+
const char *mapped = vhetranslate(path);
|
|
876
|
+
|
|
877
|
+
if (mapped != NULL) {
|
|
878
|
+
vhelog("stat %s -> %s", path, mapped);
|
|
879
|
+
return real(mapped, buf);
|
|
880
|
+
}
|
|
881
|
+
return real(path, buf);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/** hook for stat(2); lscpu and monitoring agents stat procfs before reading. */
|
|
885
|
+
int stat(const char *path, struct stat *buf)
|
|
886
|
+
{
|
|
887
|
+
vheensure();
|
|
888
|
+
return vhestatcommon(vhereal.stat, path, buf);
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
/** hook for lstat(2); kept symmetric so symlink-aware tools stay consistent. */
|
|
892
|
+
int lstat(const char *path, struct stat *buf)
|
|
893
|
+
{
|
|
894
|
+
vheensure();
|
|
895
|
+
return vhestatcommon(vhereal.lstat, path, buf);
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
/**
|
|
899
|
+
* hook for access(2). tools probing with access("/proc/cpuinfo", R_OK)
|
|
900
|
+
* before reading must observe the virtual view too, otherwise they would
|
|
901
|
+
* bypass the redirection and report the physical host.
|
|
902
|
+
* @return 0 when the virtual path is accessible, real result otherwise
|
|
903
|
+
*/
|
|
904
|
+
int access(const char *path, int mode)
|
|
905
|
+
{
|
|
906
|
+
const char *mapped;
|
|
907
|
+
|
|
908
|
+
vheensure();
|
|
909
|
+
mapped = vhetranslate(path);
|
|
910
|
+
if (mapped != NULL) {
|
|
911
|
+
vhelog("access %s -> %s", path, mapped);
|
|
912
|
+
return vhereal.access(mapped, mode);
|
|
913
|
+
}
|
|
914
|
+
return vhereal.access(path, mode);
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* hook for sysinfo(2), the syscall behind glibc's sysinfo() as used by busybox
|
|
919
|
+
* free, some build systems and language runtimes. the dolos normalization is
|
|
920
|
+
* mandatory: totalram is expressed in mem_unit units, so the fake byte count
|
|
921
|
+
* must be divided by info->mem_unit or the value explodes by that factor
|
|
922
|
+
* (dolos/hooks.c got this right; naive hooks report exabytes by accident).
|
|
923
|
+
* ratios follow dolos: freeram = total/4, sharedram = total/32,
|
|
924
|
+
* bufferram = total/16; swap mirrors total/2 fully free.
|
|
925
|
+
* @param info caller-provided sysinfo struct
|
|
926
|
+
* @return 0 on success, -1 on real failure (passthrough, defensive)
|
|
927
|
+
*/
|
|
928
|
+
int sysinfo(struct sysinfo *info)
|
|
929
|
+
{
|
|
930
|
+
int rc;
|
|
931
|
+
|
|
932
|
+
vheensure();
|
|
933
|
+
rc = vhereal.sysinfo(info);
|
|
934
|
+
if (rc != 0 || info == NULL || !vhecfg.enabled)
|
|
935
|
+
return rc;
|
|
936
|
+
if (info->mem_unit == 0)
|
|
937
|
+
info->mem_unit = 1; /* never divide by zero, glibc always sets it */
|
|
938
|
+
info->totalram = vhecfg.totalrambytes / info->mem_unit;
|
|
939
|
+
info->freeram = info->totalram / 4;
|
|
940
|
+
info->sharedram = info->totalram / 32;
|
|
941
|
+
info->bufferram = info->totalram / 16;
|
|
942
|
+
info->totalswap = info->totalram / 2;
|
|
943
|
+
info->freeswap = info->totalswap;
|
|
944
|
+
if (vhecfg.uptimebase != 0)
|
|
945
|
+
info->uptime += vhecfg.uptimebase;
|
|
946
|
+
vhelog("sysinfo totalram=%lu units (mem_unit=%u)",
|
|
947
|
+
info->totalram, info->mem_unit);
|
|
948
|
+
return 0;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* copies one utsname field with hard bounds (__NEW_UTS_LEN + 1 per sys/utsname
|
|
953
|
+
* semantics), never truncating the nul terminator.
|
|
954
|
+
* @param dst destination field inside struct utsname
|
|
955
|
+
* @param dstsz field size (65 on linux)
|
|
956
|
+
* @param src replacement string, may be NULL for "keep real value"
|
|
957
|
+
*/
|
|
958
|
+
static void vhecopyuts(char *dst, size_t dstsz, const char *src)
|
|
959
|
+
{
|
|
960
|
+
if (src == NULL || dst == NULL || dstsz == 0)
|
|
961
|
+
return;
|
|
962
|
+
snprintf(dst, dstsz, "%s", src);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* hook for uname(2). the real uname runs first so nodename and every field
|
|
967
|
+
* the operator did not override stay authentic, then the configured fields
|
|
968
|
+
* are rewritten (dolos also hooks gethostname; those symbols live in libc
|
|
969
|
+
* proper and stay passthrough here to keep the preload surface minimal).
|
|
970
|
+
* @param buf caller-provided utsname
|
|
971
|
+
* @return 0 on success, -1 on real failure (defensive passthrough)
|
|
972
|
+
*/
|
|
973
|
+
int uname(struct utsname *buf)
|
|
974
|
+
{
|
|
975
|
+
int rc;
|
|
976
|
+
|
|
977
|
+
vheensure();
|
|
978
|
+
rc = vhereal.uname(buf);
|
|
979
|
+
if (rc != 0 || buf == NULL || !vhecfg.enabled)
|
|
980
|
+
return rc;
|
|
981
|
+
vhecopyuts(buf->sysname, sizeof(buf->sysname), vhecfg.sysname);
|
|
982
|
+
vhecopyuts(buf->release, sizeof(buf->release), vhecfg.release);
|
|
983
|
+
vhecopyuts(buf->version, sizeof(buf->version), vhecfg.version);
|
|
984
|
+
vhecopyuts(buf->machine, sizeof(buf->machine), vhecfg.machine);
|
|
985
|
+
vhelog("uname release=%s machine=%s", buf->release, buf->machine);
|
|
986
|
+
return 0;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* library constructor. priority 101 keeps it ahead of generic constructors
|
|
991
|
+
* (0..100) so the redirect table is ready before any application constructor
|
|
992
|
+
* reads /proc. runs under pthread_once so a dlopen-based load cannot double
|
|
993
|
+
* initialize either.
|
|
994
|
+
*/
|
|
995
|
+
__attribute__((constructor(101)))
|
|
996
|
+
static void vhector(void)
|
|
997
|
+
{
|
|
998
|
+
vheensure();
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
/**
|
|
1002
|
+
* library destructor: signals the watcher thread to stop. the thread is
|
|
1003
|
+
* detached-free (joined implicitly at process exit by the loader) and every
|
|
1004
|
+
* syscall it may touch is async-signal-safe enough for teardown.
|
|
1005
|
+
*/
|
|
1006
|
+
__attribute__((destructor(101)))
|
|
1007
|
+
static void vhedtor(void)
|
|
1008
|
+
{
|
|
1009
|
+
vhestop = 1;
|
|
1010
|
+
vhelog("shutdown requested");
|
|
1011
|
+
}
|