diff --git a/docs/cloudlinuxos/cloudlinux_os_components/README.md b/docs/cloudlinuxos/cloudlinux_os_components/README.md index 5e7062043..36093c69f 100644 --- a/docs/cloudlinuxos/cloudlinux_os_components/README.md +++ b/docs/cloudlinuxos/cloudlinux_os_components/README.md @@ -246,6 +246,13 @@ The main configuration file `/etc/sysconfig/lvestats2` * `timeout` - timeout for custom plugins (seconds). If plugin execution does not finish within this period, plugin is terminated. Default value is 5 seconds. * `interval` - duration of one cycle of lvestats-server (seconds). This should be less than total duration of execution of all plugins. Default value is 5 seconds. Increasing this parameter makes precision of statistics worse. * `keep_history_days` - period of time (in days) to keep history in th database. Old data is removed from the database automatically. Default value is 30 days. +* `keep_history_days_domain` - period of time (in days) to keep **per-domain** history, collected for accounts with [CloudLinux Isolates](/cloudlinuxos/isolates/#lve-per-domain) enabled. Default value is 7 days. This window is deliberately not inherited from `keep_history_days`: the per-domain tables hold one series per isolated domain, so reusing the account window would multiply the database footprint several-fold. + + :::warning keep_history_days caps keep_history_days_domain + The effective per-domain window is the smaller of the two. Setting `keep_history_days_domain = 14` on a server where `keep_history_days` is `7` yields `7` days, not `14`. The cap is required for correctness, not tidiness: per-domain averages are divided by the number of heartbeat rows in the per-account history table over the requested range, so a per-domain window reaching further back than the per-account one would divide by a count that no longer exists. + + `lvestats-server` reports the effective value, and whether it came from the configuration file or the default, in its startup summary. + ::: * `mode` – sets compatibility output mode (compatibility with older lveinfo version * Value `v1` enables compatibility with old version of lveinfo. * Value `v2` enables `extended` output mode, but can break LVE plugins for control panels (statistics in LVE Manager, Resource Usage, etc). Support of `v2` mode will be added to LVE plugins in the recent future. When mode parameter is absent, later version of lveinfo is implied. @@ -835,6 +842,26 @@ The list of variables that can be used in the template: | `lPMem` `lEP` `PMemF` `lVMem` `anyF` `IOf` `VMemF` `lCPU` `aIOPS` `aEP` `aPMem` `IOPSf` `lIO` `lIOPS` `aIO` `EPf` `aCPU` `aVMem` `NprocF` `aNproc` `lNproc` `CPUf` | | See description in `lveinfo --help` output. Available only for users| |`STATS_HTML` | | html table with the list of users that exceeded limits. Available for administrator and reseller.| |`STATS` | | ASCII - table with the list of users that exceeded limits. Available only for admins and resellers.| +|`domain_faults` | | List of the user's individual websites that exceeded a limit during the period, when [CloudLinux Isolates](/cloudlinuxos/isolates/#lve-per-domain) is in use. Available only for users, and **defined only when at least one of that user's domains faulted**.| + +**The `domain_faults` variable** + +When an account has [CloudLinux Isolates](/cloudlinuxos/isolates/#lve-per-domain) enabled, a limit can be hit by one website rather than by the account as a whole. The notification then identifies which one. The variable is a list; each entry describes a single domain: + +| | | +|-|-| +|Field | Description| +|`domain` | The domain name, or its document root when the control panel cannot resolve a name. Never the numeric domain LVE id, which names nothing the recipient would recognize.| +|`cpuf` `vmemf` `pmemf` `epf` `nprocf` `iof` `iopsf` | Fault counters, in the same sense as the account-level `CPUf`, `VMemF` and so on. **A counter is absent rather than zero when that limit did not fault**, so a template can print only the limits that actually fired.| +|`lcpu` `lvmem` `lpmem` `lep` `lnproc` `lio` `liops` | The domain's limits, in the units the account section of the same email already uses: CPU in percent, memory in KB, I/O in KB/s.| + +:::tip Note +The same thresholds and period govern the domain section and the account section, so a domain appears here only under the notification settings that would have surfaced an account-level fault. + +Fault counts in the **user** notification are split, not repeated. The kernel records a fault only against the container whose limit refused the request, and lve-stats then rolls a website's faults into its account's total — so on every other surface (`lveinfo`, `cloudlinux-statistics`, `cloudlinux-top`, and the administrator and reseller notification tables) an account's fault counters already include its websites'. + +The user notification is the one exception: because it also renders the per-domain section above, the account figures in it have the websites' fault counts **subtracted**, so the same refusal is never stated twice. An account whose faults were *all* its websites' therefore renders no account fault section at all, and the domain section carries the email on its own. Usage averages and limits are not adjusted this way — "your account used this much" is true of the account and its websites together, which is what the reader is being told. +::: Sender’s email address by default is administrator email address from control panel settings `(root@{hostn_name}` if there is no email in the control panel). diff --git a/docs/cloudlinuxos/command-line_tools/README.md b/docs/cloudlinuxos/command-line_tools/README.md index a987a2676..318713fdd 100644 --- a/docs/cloudlinuxos/command-line_tools/README.md +++ b/docs/cloudlinuxos/command-line_tools/README.md @@ -263,6 +263,8 @@ lveinfo [-h] [-v] [--dbgov DBGOV] [-f YYYY-MM-DD[HH:MM]] [--time-unit TIME_UNIT] [-m {v1,v2}] [--blank-value [BLANK_VALUE]] + + [--with-domains] [--domain DOMAIN] ``` @@ -371,10 +373,19 @@ lveinfo [-h] [-v] [--dbgov DBGOV] [-f YYYY-MM-DD[HH:MM]] |`uIOPS` |The percentage of user-allocated resource I/O Operations (LVE version >= 8)| |`lIOPS` |I/O Operations Limit (LVE version >= 8)| |`IOPSf` |Out Of I/O Operations Faults (LVE version >= 8)| + |`domain_id` |Domain LVE id. Per-domain only — see `--with-domains`| + |`domain` |Domain name, or its document root when the control panel cannot resolve a name. Per-domain only| + |`parent_uid` |UID of the account that owns the domain. Per-domain only| + +:::tip Note +The three per-domain identity columns are never part of a default column set. They appear when `--with-domains` or `--domain` is used, or when named explicitly in `--show-columns`. On a per-account row they render as an empty cell, which means "not applicable" rather than zero. +::: * `--time-unit TIME_UNIT` – time step for grouping statistic in minutes; 1 min., by default; can use `m\|h\|d` suffixes; for example: `1h or 1h30m or 1d12h` * `-m {v1,v2}`, `--compat {v1,v2}` – `v1` - return old output mode; `v2` - new mode; default `v1`; you can change default in config * `--blank-value [BLANK_VALUE]` – Use to fill unsupported limits; default `-` +* `--with-domains` – report per-domain usage instead of per-account for accounts that have [CloudLinux Isolates](/cloudlinuxos/isolates/#lve-per-domain) enabled, adding the `domain_id`, `domain` and `parent_uid` columns. Without the flag nothing about the output changes; accounts with no isolated domains are unaffected by it +* `--domain DOMAIN` – report a single domain, selected by domain name, document root, or numeric domain LVE id. Implies `--with-domains` * `-f YYYY-MM-DD[ HH:MM]`, `--from YYYY-MM-DD[ HH:MM]` – run report from date and time in `[YY]YY-MM-DD[ HH:MM]` format; if not present last 10 minutes are assumed * `-t YYYY-MM-DD[ HH:MM]`, `--to YYYY-MM-DD[ HH:MM]` – run report up to date and time in `[YY]YY-MM-DD[ HH:MM]` format; if not present, reports results up to now * `--period PERIOD` – time period; specify minutes with `m`, `h` - hours, days with `d`, and values: `today`, `yesterday`; `5m` - last 5 minutes, `4h` - last four hours, `2d` - last 2 days, as well as `today` @@ -399,6 +410,10 @@ Prefixes `Kb`, `Mb` and ALIAS options are not case sensitive. ::: +:::warning Per-domain history is kept for fewer days than per-account history +Per-domain rows are retained for `keep_history_days_domain` days (default `7`), while per-account rows are retained for `keep_history_days` days (default `30`). A wide range such as `--with-domains --period 30d` therefore returns three weeks less per-domain data than the same range returns per account, and nothing in the result set itself says so — `lveinfo` notes it in the log rather than on `stdout`/`stderr`, both of which belong to the caller. See [LVE-Stats 2 configuration](/cloudlinuxos/cloudlinux_os_components/#configuration) (`/etc/sysconfig/lvestats2`). +::: +
#### lvechart @@ -432,6 +447,11 @@ All ALIAS options are not case sensitive. | `--show-all` |Show all graphs (by default shows graphs for which limits are set)| | `--style=` |`admin`, `user` set chart style, CPU limits are normalized to 100% in user’s style| | `--format=` |`svg`, `png` set chart output format| +| `--domain=` |Chart one isolated domain instead of the account. Takes the same selector as `lveinfo --domain` and `cloudlinux-statistics --domain`: a domain name, a document root, or a numeric domain LVE id. Requires [CloudLinux Isolates](/cloudlinuxos/isolates/#lve-per-domain)| + +:::tip Note +`--domain` identifies the account by itself, so it does not need to be combined with `--id` or `--user`. A non-root caller can only chart a domain owned by an account within their own scope; a domain outside it reports as not found. +:::
@@ -544,7 +564,7 @@ Utility provides information about current MySQL and LVE usage of a running syst ``` cloudlinux-top [-h] [-v] [-j] [--hide-mysql] [-u USERNAME | -r FOR_RESELLER] [-d DOMAIN] [-m MAX] - [-o ORDER_BY] + [-o ORDER_BY] [--domains] ```
@@ -559,6 +579,11 @@ cloudlinux-top [-h] [-v] [-j] [--hide-mysql] * `-d DOMAIN`, `--domain DOMAIN` – show data only for a specific domain. Can be used to filter the output; returns users with domain `%DOMAIN%` * `-m MAX`, `--max MAX` – show up to `N` records. If `--max` key is omitted. By default will show top 25 users * `-o ORDER_BY`, `--order-by ORDER_BY` – sort output by resource usage; available options: `cpu`, `mysql_cpu`, `io`, `mysql_io`, `iops`, `ep`, `nproc`, `pmem` +* `--domains` – populate the `domains` array on each user with the current usage and limits of that account's isolated domains. Requires [CloudLinux Isolates](/cloudlinuxos/isolates/#lve-per-domain). Without the flag the array is emitted empty, so existing consumers see unchanged output + +:::warning The --domains and --domain options are different +`-d`/`--domain` is a *filter*: it restricts the output to users whose primary domain matches the given pattern, and has nothing to do with CloudLinux Isolates. `--domains` (plural, no short form) is the one that adds the per-domain breakdown. +::: #### **Output format** @@ -588,14 +613,44 @@ cloudlinux-top [-h] [-v] [-j] [--hide-mysql] "limit": , # limits for last 5 seconds "reseller": "reseler1", # user’s reseller (from control panel) "usage": , # usage for last 5 seconds - "username": "user" # username from /etc/passwd file or “N/A” if user + "username": "user", # username from /etc/passwd file or “N/A” if user # with such id does not exist + "domains": [ # isolated domains of this account; populated + # only with --domains, otherwise an empty list + { + "id": 60057, # domain LVE id (not a uid) + "name": "site.com", # domain name; absent if the panel cannot name it + "docroot": "/home/user/public_html", + "usage": , + "limit": + } + ] } ] } ```
+The structure of ``: + +
+ +``` +{ + "cpu": {"all": 0.0}, + "io": {"all": 0.0}, + "iops": 0.0, + "ep": 0.0, + "mem": 0.0, + "pno": 0.0 +} +``` +
+ +:::tip Note +`` deliberately carries no `mysql` sub-key. MySQL Governor accounting is per account, so there is no per-domain figure to report and emitting a zero would misstate one. +::: + The structure * of ``:
@@ -719,7 +774,7 @@ cloudlinux-statistics [-h] [-j] [-v] [--by-usage BY_USAGE] [--limit LIMIT] [--show COLUMN_NAME [COLUMN_NAME ...]] [-o ORDER_BY] [--id ID] [--time-unit TIME_UNIT] - [-r FOR_RESELLER] + [-r FOR_RESELLER] [--with-domains] [--domain DOMAIN] ```
@@ -767,6 +822,29 @@ cloudlinux-statistics [-h] [-j] [-v] [--by-usage BY_USAGE] |`vmem_faults`|total number of out of virtual memory faults| * `-r FOR_RESELLER`, `--for-reseller FOR_RESELLER` – show statistics only for given reseller and his users +* `--with-domains` – include a per-domain breakdown for accounts that have [CloudLinux Isolates](/cloudlinuxos/isolates/#lve-per-domain) enabled, as a `domains` array nested inside the account object whose usage it decomposes. Accounts with no isolated domains produce byte-identical output to before +* `--domain DOMAIN` – restrict the per-domain breakdown to one domain, selected by domain name, document root, or numeric domain LVE id. Implies `--with-domains` + +A `domains[]` entry has the same metric shape as the account object that encloses it, so `usage.cpu.lve` means the same thing at either level: + +
+ +``` +{ + "id": 60057, # domain LVE id + "name": "site.com", # domain name, else its docroot, else "N/A" + "usage": {"cpu": {"lve": 0.0}, ...}, + "limits": {"cpu": {"lve": 0.0}, ...}, + "faults": {"cpu": {"lve": 0}, ...} +} +``` +
+ +:::tip Note +A `domains[]` entry carries no `mysql` sub-key (MySQL Governor accounting is per account) and no `parent_uid` (the enclosing object already identifies the account). + +When the requested range reaches further back than per-domain retention, the response's `warning` field says so — the nested `domains` then cover less of the range than the account figures do. See [LVE-Stats 2 configuration](/cloudlinuxos/cloudlinux_os_components/#configuration) (`/etc/sysconfig/lvestats2`). +::: Filter items by resource usage. @@ -2771,6 +2849,23 @@ cldeploy --hostinglimits # update httpd and install m | `set-reseller-default` |set default limits for resellers users| | `remove-reseller` |delete LVE container and the record in the config, move LVE containers to the host container| +**Per-domain commands** + +These manage [CloudLinux Isolates](/cloudlinuxos/isolates/#lve-per-domain) — resource limits for an individual website rather than for the whole account. They require a kernel with per-domain LVE support; on a kernel without it every one of them exits with code `38` and the message `Domain limits are not supported by this kernel`. + +| | | +|--|--| +| `list-domains ` |list the domain LVEs inside the user LVP of the account with the given numeric UID. Reports `UID ... does not exist` for an unknown account and `No domain limits configured for UID ...` for a known one that has none| +| `allow-domain-limits ` |create the user LVP and allow per-domain limits for the named user (idempotent)| +| `deny-domain-limits ` |remove the user LVP and disallow per-domain limits for the named user| +| `enable-domain-limits ` |register a domain LVE under its owner's LVP. The owner and document root are resolved from the control panel, so only the domain name is given| +| `disable-domain-limits ` |unregister the domain LVE and remove its registry entry| +| `regenerate-domains --username [--domain ] [--old-domain ] [--old-docroot ]` |update the domain configuration and id mapping after a domain rename, a document root change, or a user rename. `--username` is required| + +:::tip Note +Under a control panel you normally do not call these directly — `cagefsctl --site-isolation-allow`, `--site-isolation-deny`, `--site-isolation-enable` and `--site-isolation-disable` invoke the matching `lvectl` command for you, and the panel hooks call `regenerate-domains` on rename and document-root changes. Use `lvectl` directly for integration scripts and for inspecting or repairing state. See [CloudLinux Isolates](/cloudlinuxos/isolates/#lve-per-domain). +::: + **Options** | | | diff --git a/docs/cloudlinuxos/isolates/README.md b/docs/cloudlinuxos/isolates/README.md index c97b8157b..079527849 100644 --- a/docs/cloudlinuxos/isolates/README.md +++ b/docs/cloudlinuxos/isolates/README.md @@ -1,5 +1,10 @@ # CloudLinux Isolates (BETA) +CloudLinux Isolates isolates the individual websites of a single hosting account from one another. It has two layers, which are described in turn below: + +* **[CageFS per domain](#cagefs-per-domain)** — *filesystem* isolation, so that a compromised website cannot reach another site's files. +* **[LVE per domain](#lve-per-domain)** — *resource* isolation, so that one website's CPU, memory and I/O usage is limited and accounted for on its own. + ## CageFS Per Domain CloudLinux Isolates is a security feature that provides domain-level isolation within CageFS. It allows server administrators to isolate individual websites from each other, even when they belong to the same hosting account. This prevents cross-site attacks where a compromised website could access files or data from other websites on the same account. @@ -676,6 +681,56 @@ $ isolatectl limits apply --domain example.com ``` +#### Per-Domain Statistics + +``` +isolatectl stats [--domain ] [--period ] +``` + +Shows resource usage for the calling account's isolated domains. Like the rest of `isolatectl`, it is run by the account owner rather than by root, identifies the caller automatically, and returns JSON. + +**Parameters:** + +| Parameter | Description | +| --------- | ----------- | +| `--domain` | (Optional) Report a single domain only | +| `--period` | (Optional) Time window to report over; default `10m` | + +The period grammar is `lveinfo`'s: `s`, `m`, `h`, `d`, plus `today`. **`1m` is one minute, not one month** — a month is `30d`. + +**Example:** + +``` +$ isolatectl stats --domain example.com --period 1d +{ + "result": "success", + "scope": { + "owner_uid": 1000, + "period": "1d", + "note": "only domains active during the window are recorded" + }, + "domains": [ + { + "name": "example.com", + "lve_id": 60057, + "owner_uid": 1000, + "usage": {"cpu": 120, "ep": 2, "vmem": 0, "pmem": 4096, "nproc": 5, "io": 0, "iops": 0}, + "peak": {"cpu": 900, "ep": 5, "vmem": 0, "pmem": 9012, "nproc": 9, "io": 0, "iops": 0}, + "limits": {"cpu": 5000, "ep": 20, "vmem": 0, "pmem": 65536, "nproc": 30, "io": 2048, "iops": 500}, + "faults": {"cpu": 0, "ep": 3, "vmem": 0, "pmem": 0, "nproc": 0, "io": 0, "iops": 0} + } + ] +} +``` + +`usage` is the average over the window, `peak` the highest sample in it, and `limits` the caps in force. + +:::warning An idle website is absent, not zero +Only domains that were active during the period are recorded at all, so a quiet website does not appear in `domains` rather than appearing with zeroes. An empty `domains` list is an ordinary answer, not an error — the `scope` object is always returned so that "quiet" can be told apart from "no such account". +::: + +*** + ### Executing Commands in an Isolated Site Context The `cagefs_enter_site` utility allows executing a command inside CageFS in the context of a specific isolated website. This can be useful for debugging or running site-specific operations. @@ -794,3 +849,173 @@ CloudLinux Isolates integrates automatically with supported control panels. When * **Renamed**: Isolation configuration is automatically updated * **Deleted**: Isolation configuration is automatically cleaned up * **Document root changed**: Configuration is regenerated via hooks + +*** + +## LVE Per Domain + +CloudLinux Isolates also allows resource limits — CPU, memory, I/O, processes and entry processes — to be applied to an *individual website* rather than to the hosting account as a whole. A single busy or misbehaving site is then throttled on its own, without consuming the resources its sibling sites on the same account depend on. + +:::warning BETA +Per-domain LVE limits are a BETA feature, supported on CloudLinux OS 8 and 9. +::: + +### How it relates to CageFS per domain + +The two halves of CloudLinux Isolates are separate layers and can be reasoned about separately: + +| | | +|-|-| +|[CageFS per domain](#cagefs-per-domain) | *Filesystem* isolation — a compromised website cannot read another site's files. Always available where CageFS is.| +|LVE per domain | *Resource* isolation — a website has its own CPU, memory, I/O and process limits. Requires CloudLinux OS 8 or 9 and the package versions listed under [Per-Domain Prerequisites](#per-domain-prerequisites).| + +In practice you do not enable them separately. The `cagefsctl --site-isolation-*` commands documented above drive both: each one invokes the matching `lvectl` per-domain command for you when the prerequisites are met, and silently skips that step when they are not. So on a server that does not support per-domain LVEs, website isolation still works — you get the filesystem separation without the resource limits, rather than an error. + +### Per-Domain Prerequisites + +Per-domain LVE limits are supported on CloudLinux OS 8 and 9. CloudLinux OS 7 predates the required kernel interface; on it, commands that need per-domain support fail with exit code `38` and the message `Domain limits are not supported by this kernel`. + +In addition to the [CloudLinux Isolates prerequisites](#prerequisites), per-domain LVE limits require: + +| Package | Minimum Version | +| ---------- | --------------- | +| lve-stats3 | 5.1.0-1 | +| lve-utils | 6.6.40-1 | + +To check the installed versions: + +``` +rpm -q lve-stats3 lve-utils +``` + +### How the containers are arranged + +Understanding the container hierarchy explains most of what the statistics show: + +``` +ROOT +└── LVP (reseller, when reseller limits are in use) + └── LVP (the hosting account) <-- reported as "the account" + ├── LVE (the account's own processes — cron, SSH, non-isolated sites) + ├── LVE (site1.com) + └── LVE (site2.com) +``` + +The account's container is the **parent** of its websites', and the kernel keeps +the parent's counters as the sum of its children's. So the figure the statistics +tools report for an account is the total for everything beneath it — its own +processes *and* every isolated website. The account's own processes are a +separate container at the same level as the websites, and are never reported on +their own. + +Because the websites are siblings of the account's own container rather than nested inside it, work done by an isolated website is charged to that website and to the account total, but never to the account's own processes — and the reverse holds too, so an account's cron jobs are never absorbed by one of its websites. + +**Limits nest, even though usage does not.** A domain is bounded by its account's limits, which are in turn bounded by the reseller's; raising a domain's limit above its account's does not grant it more than the account has. A domain with no explicit limits of its own is simply bounded by its account's — registering a domain does not, by itself, restrict it. + +### Enabling per-domain limits + +Under a control panel, use the [`cagefsctl --site-isolation-*` commands](#command-reference) — they enable both isolation layers together and are the supported administrator path. + +The underlying `lvectl` commands are available for integration scripts, and for inspecting or repairing state: + +| | | +|-|-| +|`lvectl allow-domain-limits ` | Create the account's LVP and allow per-domain limits for it. Idempotent.| +|`lvectl deny-domain-limits ` | Remove the account's LVP and disallow per-domain limits.| +|`lvectl enable-domain-limits ` | Register a domain LVE. The owner and document root are resolved from the control panel.| +|`lvectl disable-domain-limits ` | Unregister the domain LVE and remove its registry entry.| +|`lvectl list-domains ` | List the domain LVEs of the account with the given numeric UID.| +|`lvectl regenerate-domains --username ...` | Refresh the domain configuration and id mapping after a rename or document root change.| + +See [lvectl](/cloudlinuxos/command-line_tools/#lvectl) for the full syntax. + +:::tip Note +`lvectl list-domains` lists the members of an account's LVP. For a *reseller*, that LVP holds the reseller's member accounts rather than domains, so the command's output alone does not tell you whether an account is isolated. A member account resolves in `/etc/passwd`; a domain LVE id never does. +::: + +The domain renaming, document root changes and account renames performed through a supported control panel are handled by the panel hooks, which call `lvectl regenerate-domains` automatically. Run it by hand only after changing these outside the panel. + +### Setting per-domain limits + +Per-domain limits are set by the account owner with [`isolatectl limits`](#per-domain-resource-limits), not by the administrator: there is no `lvectl` command that sets an individual domain's limits. Administrators control the account-level limits, which bound every domain underneath them. + +Where the state lives: + +| | | +|-|-| +|`~/.lve/domains.json` | The account's per-domain limits and its list of isolated domains. This is the file `isolatectl limits apply` reads when re-applying limits to the kernel.| +|`/etc/container/lvd_ids/` | The account's domain-name-to-LVE-id registry.| + +### Viewing per-domain usage + +Per-domain statistics are collected by default once the feature is active. Every statistics tool can report them: + +| | | +|-|-| +|[`isolatectl stats`](#per-domain-statistics) | For the **account owner** — usage for their own isolated domains.| +|`lveinfo --with-domains`, `lveinfo --domain ` | Historical per-domain usage, with the `domain_id`, `domain` and `parent_uid` columns added.| +|`cloudlinux-statistics --with-domains` | A `domains` array nested inside each account object.| +|`cloudlinux-top --domains` | Current per-domain usage. Note the plural: `-d`/`--domain` on this tool is an unrelated filter.| +|`lvechart --domain ` | A usage chart for one domain instead of the account.| + +Each `--domain` selector accepts a domain name, a document root, or a numeric domain LVE id. See [Command Line Tools](/cloudlinuxos/command-line_tools/#lveinfo) for full syntax. + +:::tip Note +On an account with no isolated domains, these options are accepted and change nothing — the output is identical to the same command without them. +::: + +### Reading per-domain figures + +Three properties of the numbers regularly surprise people reading them for the first time. None of them indicates a fault. + +**A website's usage is part of its account's, not additional to it.** The per-domain rows break the account's figure down; they do not add to it: + +
+ +``` +account = the account's own work + site1.com + site2.com + ... + (cron, SSH, non-isolated + sites — everything outside + an isolated website) +``` +
+ +**Faults are counted per container, then rolled up.** The kernel records a fault only against the container whose limit refused the request. lve-stats then rolls a website's faults into its account's total, so an account read *without* a per-domain option already includes its websites' faults; passing `--with-domains` splits them apart again. The [user notification email](/cloudlinuxos/cloudlinux_os_components/#customize-lve-stats2-notifications) is the one place that subtracts them instead, so that the same refusal is not reported twice in a message that already lists the site. + +**Per-domain history is kept for fewer days than per-account history** — 7 days against 30, by default. A report covering a longer range returns correspondingly less per-domain data than account data, without the rows themselves indicating why. Both windows are administrator-configurable; see `keep_history_days_domain` in [LVE-Stats 2 configuration](/cloudlinuxos/cloudlinux_os_components/#configuration) (`/etc/sysconfig/lvestats2`). + +### Fault notifications + +When a website hits one of its own limits, the notification sent to the account owner names the website that faulted, alongside the limit it hit. Notifications continue to be addressed per account, and the thresholds and period that govern the account-level notification govern the per-domain section too — so enabling per-domain limits does not, by itself, change who is emailed or how often. + +Administrators customising the email templates should see the `domain_faults` variable in [Customize LVE-stats2 notifications](/cloudlinuxos/cloudlinux_os_components/#customize-lve-stats2-notifications). + +### Troubleshooting per-domain limits + +**"Domain limits are not supported by this kernel (requires lve_lvp_create2)"** + +The kernel predates per-domain LVE support. Per-domain limits require CloudLinux OS 8 or 9; on CloudLinux OS 7 the [CageFS half](#cagefs-per-domain) of CloudLinux Isolates is still available. + +**Isolation was enabled, but no domain LVEs were created** + +The `cagefsctl --site-isolation-*` commands always apply the filesystem layer, and add the per-domain LVE only when the [prerequisites](#per-domain-prerequisites) are met. Check the installed versions: + +``` +rpm -q lve-stats3 lve-utils +``` + +If either is below the minimum, update it and then re-run `cagefsctl --site-isolation-enable `. Removing isolation is never gated this way, so any containers created by an earlier version can always be torn down. + +**"No domain limits configured for UID *N*"** + +The account exists but has no isolated domains. Enable isolation for a domain first — `cagefsctl --site-isolation-enable `. A genuinely unknown account reports `UID N does not exist` instead. + +**A domain's statistics stopped after a rename or a document root change** + +The domain's registry entry is keyed on its document root. Changes made through a supported control panel are handled by the panel hooks; if the change was made outside the panel, refresh the mapping by hand: + +``` +lvectl regenerate-domains --username --domain --old-domain +``` + +***