LFCS Practice Tasks
There is no multiple choice on this exam, so there is no multiple choice on this page either. Below are 20 performance-style tasks — the same shape as the real thing: a short scenario, an end state you must produce, and nothing telling you which commands to use to get there. They're split across the five official domains in the same proportion the Linux Foundation weights them — 5 Operations Deployment, 5 Networking, 4 Storage, 4 Essential Commands, 2 Users and Groups, tracking 25/25/20/20/10% — so time spent here mirrors time spent on exam day. Read LFCS — the exam first if you haven't, since these tasks assume you already know what each domain covers; this page is where that knowledge becomes typing. Every task includes a full worked solution and a verification step, because on a performance-based exam, checking your own work is half the skill being tested. Once this bank stops surprising you, move on to a full timed run: Mock Exam · Set 1, Set 2, or Set 3.
Some driving tests just ask you questions about road signs. This one hands you actual keys to an actual car with something actually wrong with it — a flat tyre, a dead headlight, a door that won't lock — and two hours to fix as many as you can, for real, with real tools. Nobody gives you credit for saying "I would check the tyre pressure." They walk around the car afterward and check whether the tyre is actually holding air. This page is twenty of those broken cars, one at a time, each with the fix written out afterward so you can compare what you did to what actually works — and however many of the twenty feel new to you right now is roughly how much more garage time you still need before test day.
How this bank works — and how to use it
☺ Like you're 10: Cover the solution with your hand, try the whole task for real on a spare machine first, and only then peek — the peeking is where the actual learning happens.
Each task below states an end state — what the machine should look like when you're done — the way the real exam's task sheet does. It deliberately does not say which tool to use, because the real one doesn't either: nft or a firewall front-end, nmcli or a raw config file, they're your choice as long as the graded state at the end is correct. Attempt each task cold, on a throwaway Linux VM you can become root on, before opening the worked solution — a local VM under Multipass, VirtualBox or libvirt/KVM works fine, and since one Operations Deployment competency names SELinux specifically, a Fedora-family distro (Fedora, Rocky, AlmaLinux) is the safer practice target than a Debian/Ubuntu box running AppArmor by default.
Every task below was written for this course against the LFCS's published domains and competencies. None of it is drawn from, or claims to reproduce, the real proctored exam, which the Linux Foundation does not release publicly. Solving all twenty tells you the shape of your own gaps; it isn't a guarantee of the real paper's exact difficulty or phrasing. Duration, task count and the 67% pass mark referenced throughout this bank are per the official LFCS page and candidate instructions as of writing — verify all of it officially before you book, since Linux Foundation exams change these numbers over time.
This bank contains no Kubernetes whatsoever, on purpose — LFCS tests the layer underneath it, not the cluster itself. If you want the equivalent performance-based drilling for the cluster layer this course assumes you already hold, that lives on the Kubernetes course's own practice pages, for example the CKA practice tasks.
Operations Deployment — Tasks 1–5 (25% of the exam)
☺ Like you're 10: This pile is "keep the machine's programs running, on schedule, and inside a budget" — the engine room.
-
Task 1. A monitoring binary already exists at
/usr/local/bin/telemetry-agentand reads its config from/etc/telemetry/agent.yaml. Create and enable a systemd service unit namedtelemetry-agent.servicethat: runs the agent as the unprivileged usertelemetry; restarts automatically 5 seconds after any failure; is capped at 256M of memory and 50% of one CPU; and is both running right now and still running after every future reboot.Show worked solution
# /etc/systemd/system/telemetry-agent.service [Unit] Description=Telemetry agent After=network-online.target Wants=network-online.target [Service] Type=simple User=telemetry ExecStart=/usr/local/bin/telemetry-agent --config /etc/telemetry/agent.yaml Restart=on-failure RestartSec=5s MemoryMax=256M CPUQuota=50% [Install] WantedBy=multi-user.target
sudo systemctl daemon-reload sudo systemctl enable --now telemetry-agent.service # starts it AND marks it for boot, in one command systemctl is-enabled telemetry-agent.service # confirm it survives a reboot systemctl status telemetry-agent.service # confirm it's actually running now
enable --nowis the one command that satisfies "running right now" and "running after reboot" at once — runningsystemctl startalone would leave the unit disabled, passing half the task and failing the other half. -
Task 2. The existing service
billing-sync.servicewas working yesterday and is now failing to start after a colleague's change. Diagnose why, and fix it using the officially supported override mechanism — do not directly edit the vendor unit file at/etc/systemd/system/billing-sync.service, since a future package update would silently overwrite hand-edits made there.Show worked solution
systemctl status billing-sync.service # failed, exit code, last lines journalctl -u billing-sync.service -p err --since "10 min ago" --no-pager # → "config file /etc/billing-sync.yaml: no such file or directory" ls /etc/billing-sync/ # the file actually lives here now: config.yaml sudo systemctl edit billing-sync.service # opens a drop-in editor at # /etc/systemd/system/billing-sync.service.d/override.conf# written inside the drop-in editor [Service] ExecStart= ExecStart=/usr/local/bin/billing-sync --config /etc/billing-sync/config.yaml
sudo systemctl daemon-reload sudo systemctl restart billing-sync.service systemctl status billing-sync.service systemctl cat billing-sync.service # shows the EFFECTIVE unit: vendor file + your drop-in, merged
The empty
ExecStart=line on its own is not decorative —ExecStart=can be set multiple times and normally accumulates, so without first clearing it your drop-in would add a second command rather than replace the vendor's. This is the single most common mistake when overriding a unit this way. -
Task 3. This host will act as a router between two internal networks. Enable IPv4 forwarding so it survives a reboot — not just for the current running kernel.
Show worked solution
sudo sysctl -w net.ipv4.ip_forward=1 # live, right now — lost on reboot alone echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-ip-forward.conf sudo sysctl --system # reload every file under sysctl.d sysctl net.ipv4.ip_forward # confirm = 1 cat /proc/sys/net/ipv4/ip_forward # same value, read straight from the kernel
Keep Task 3's parameter in mind for Task 8 below — a NAT rule with forwarding still disabled at the kernel level drops every packet silently, and looks exactly like a broken firewall rule until you check this file.
-
Task 4. The shell script
/usr/local/bin/nightly-report.shneeds to run every day at 02:15, using a systemd timer rather than a crontab entry. If the machine happens to be powered off at exactly 02:15 on a given night, the job should still run once, as soon as the machine boots back up, rather than being silently skipped for that day.Show worked solution
# /etc/systemd/system/nightly-report.service [Unit] Description=Nightly report generator [Service] Type=oneshot ExecStart=/usr/local/bin/nightly-report.sh # /etc/systemd/system/nightly-report.timer [Unit] Description=Run nightly-report.service daily at 02:15 [Timer] OnCalendar=*-*-* 02:15:00 Persistent=true [Install] WantedBy=timers.target
sudo systemctl daemon-reload sudo systemctl enable --now nightly-report.timer systemctl list-timers --all | grep nightly-report # confirm NEXT and LEFT columns look right
Persistent=trueis the whole answer to the "machine was off" half of the task: it makes systemd record whether a run was missed and fire it once at the next boot, instead of just waiting silently for the following day's 02:15. Note the timer unit is what gets enabled — the paired.servicestays disabled and is only ever triggered by its timer. -
Task 5. Run the image
registry.internal/web:2.4as a rootless Podman container namedweb, publishing container port 8080 to host port 8080, and make sure the container comes back automatically after a host reboot — using systemd, not Podman's own--restartflag alone, since only a systemd-managed unit is visible to this host's existing monitoring.Show worked solution
podman run -d --name web -p 8080:8080 registry.internal/web:2.4 podman ps mkdir -p ~/.config/systemd/user cd ~/.config/systemd/user podman generate systemd --new --name web --files --restart-policy=on-failure # writes container-web.service into the current directory systemctl --user daemon-reload systemctl --user enable --now container-web.service loginctl enable-linger "$(whoami)" # lets the --user unit run without an active login session systemctl --user status container-web.service
loginctl enable-lingeris the step people forget: without it, asystemctl --userunit only runs while that user has an active session, and dies the moment they log out — which defeats "comes back after a reboot" entirely. (Newer Podman releases also offer Quadlet, a native.containerunit format that skips the generate step; the underlying idea — a real systemd unit managing the container, not Podman's own restart flag — is the same either way.)
Networking — Tasks 6–10 (25% of the exam)
☺ Like you're 10: This pile is "make machines talk to each other, safely, and know what time it is" — wires, addresses, and locks on the door.
-
Task 6. Interface
eth0currently gets its address via DHCP. Reconfigure it with a static IPv4 address of10.0.20.15/24, gateway10.0.20.1, and DNS server10.0.20.53— the change must survive a reboot, and must not be a hand-edit of a config file.Show worked solution
nmcli con show # find the profile name bound to eth0, e.g. "Wired connection 1" nmcli con mod "Wired connection 1" ipv4.method manual nmcli con mod "Wired connection 1" ipv4.addresses 10.0.20.15/24 nmcli con mod "Wired connection 1" ipv4.gateway 10.0.20.1 nmcli con mod "Wired connection 1" ipv4.dns 10.0.20.53 nmcli con up "Wired connection 1" ip -br addr show eth0 ip route resolvectl status eth0
nmcliwrites to NetworkManager's own connection profile (typically under/etc/NetworkManager/system-connections/) rather than a file you touch directly, and the profile is reapplied automatically on every boot — which is exactly what "must not be a hand-edit" and "must survive a reboot" are both testing. -
Task 7. This host already reaches
10.0.20.0/24directly. Add a persistent static route so it can also reach192.168.77.0/24, via a gateway at10.0.20.254on that same interface.Show worked solution
sudo ip route add 192.168.77.0/24 via 10.0.20.254 # live now — does NOT survive a reboot on its own nmcli con mod "Wired connection 1" +ipv4.routes "192.168.77.0/24 10.0.20.254" nmcli con up "Wired connection 1" ip route show | grep 192.168.77
The plain
ip route addis worth running first anyway — it proves the route actually works before you commit to a persistent form. The+ipv4.routessyntax adds to the profile's route list rather than replacing it, which matters if other static routes are already configured on the same connection. -
Task 8. This host has two interfaces:
eth0facing the internet,eth1facing an internal10.0.30.0/24network. Configure it to (a) allow inbound SSH oneth0, (b) drop every other unsolicited inbound connection oneth0by default, and (c) let internal hosts oneth1reach the internet through this box via NAT.Show worked solution
# filtering sudo nft add table inet filter sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; } sudo nft add rule inet filter input iif lo accept sudo nft add rule inet filter input ct state established,related accept sudo nft add rule inet filter input iif eth0 tcp dport 22 accept # NAT sudo nft add table ip nat sudo nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; } sudo nft add rule ip nat postrouting oif eth0 masquerade sudo nft list ruleset # make it survive a reboot (naming varies by distro packaging) sudo sh -c 'nft list ruleset > /etc/nftables.conf' sudo systemctl enable --now nftablesTwo easy ways to fail this task even with a correct ruleset: forgetting
ct state established,related accept, which silently breaks every outbound connection this host itself makes (including your own SSH session's return traffic); and forgetting Task 3'snet.ipv4.ip_forward=1— without it, the kernel drops routed packets before the NAT rule ever sees them, and the ruleset looks completely correct while nothing forwards at all. -
Task 9. Convert SSH access to this host from password-based to key-only for the existing user
dot, and make surerootcan no longer log in over SSH at all.Show worked solution
# on the CLIENT ssh-keygen -t ed25519 -f ~/.ssh/mission_ed25519 ssh-copy-id -i ~/.ssh/mission_ed25519.pub dot@10.0.20.15
# on the SERVER — /etc/ssh/sshd_config PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes
sudo sshd -t # validate syntax BEFORE restarting — do not skip this sudo systemctl restart sshd # verify from a SECOND, still-open session — never close your only one first ssh -i ~/.ssh/mission_ed25519 dot@10.0.20.15 # should succeed ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no dot@10.0.20.15 # should be refused
sshd -tis the step that separates a five-minute task from a locked-out grading host: a typo insshd_configthat passes on save but fails on restart leaves the daemon down entirely, with no way back in over the network it was just supervising. -
Task 10. Confirm this host is actually synchronizing its clock against a real time source — not just claiming to — and if it isn't, point it at time servers
10.0.0.1and10.0.0.2and get it synced.Show worked solution
chronyc tracking # check "Leap status" (should read Normal) and the offset chronyc sources -v # which servers is it actually reaching, and how good is each reading
# /etc/chrony.conf (RHEL family) or /etc/chrony/chrony.conf (Debian family) — # replace any existing pool/server lines with: server 10.0.0.1 iburst server 10.0.0.2 iburst
sudo systemctl restart chronyd # 'chrony' on Debian-family systems chronyc tracking # re-check — Leap status: Normal timedatectl status # "NTP service: active" / "System clock synchronized: yes"
Clock skew is the failure this competency exists for: a few minutes of drift silently breaks TLS certificate validation and any Kerberos-style time-sensitive auth, and the symptom at that point looks nothing like "the clock is wrong" — it looks like a broken certificate or a rejected login.
Storage — Tasks 11–14 (20% of the exam)
☺ Like you're 10: This pile is "where things are actually kept, how much room is left, and what happens when a server disappears."
-
Task 11. Two raw, unused disks are attached as
/dev/sdband/dev/sdc. Combine them into one volume group nameddata_vg, carve out a 20G logical volume namedapp_lv, format it XFS, and mount it at/srv/app— persistently, without you runningmountby hand after a reboot.Show worked solution
sudo pvcreate /dev/sdb /dev/sdc sudo vgcreate data_vg /dev/sdb /dev/sdc sudo lvcreate -n app_lv -L 20G data_vg sudo mkfs.xfs /dev/data_vg/app_lv sudo mkdir -p /srv/app blkid /dev/data_vg/app_lv # grab the UUID — safer in fstab than a /dev/mapper path echo "UUID=
/srv/app xfs defaults 0 2" | sudo tee -a /etc/fstab sudo mount -a # tests the fstab line NOW, instead of finding out at next reboot df -hT /srv/app Testing the fstab entry with
mount -abefore you're graded matters: a typo'd UUID or a missing mount point directory won't show up as an error at all until the box actually reboots, which on a timed exam you may not get to do. -
Task 12. The
app_lvvolume from Task 11 is now at 95% capacity, anddata_vgstill has 15G of free extents. Grow the logical volume by 10G and grow the XFS filesystem on top of it in the same step, without unmounting/srv/app.Show worked solution
vgs data_vg # confirm free PE covers the request sudo lvextend -r -L +10G /dev/data_vg/app_lv df -hT /srv/app # confirm the new size, live, no unmount required
The
-rflag is what makes this one command instead of two — it calls the right filesystem-resize tool (xfs_growfshere;resize2fsfor ext4) automatically after the volume resize. Worth knowing for exam day: XFS can only ever grow online — there is no supported way to shrink an XFS filesystem in place, unlike ext4. -
Task 13. Add 4G of swap to this host, backed by a new logical volume named
swap_lvinsidedata_vg(which still has room), active immediately and after every future boot.Show worked solution
sudo lvcreate -n swap_lv -L 4G data_vg sudo mkswap /dev/data_vg/swap_lv sudo swapon /dev/data_vg/swap_lv echo "/dev/data_vg/swap_lv none swap sw 0 0" | sudo tee -a /etc/fstab swapon --show free -h
Two separate steps are both required and easy to forget one of:
swaponactivates it for the running system right now, and the/etc/fstabline is what makes it come back after the next reboot. Skip the fstab line and the task looks complete until the machine restarts. -
Task 14. Instead of a hard
fstabmount at boot — which would hang this host's startup if the NFS server is ever unreachable — configure the export10.0.0.20:/export/datato mount on demand under/mnt/auto/datawhenever it's accessed, and unmount itself automatically once idle.Show worked solution
sudo dnf install -y autofs # 'apt install autofs' on Debian-family systems
# /etc/auto.master /mnt/auto /etc/auto.data # /etc/auto.data data -fstype=nfs,rw 10.0.0.20:/export/data
sudo systemctl enable --now autofs ls /mnt/auto/data # the access itself triggers the mount mount | grep auto.data # confirm it's there # after the default 5-minute idle timeout: mount | grep auto.data # → nothing. it unmounted itself.
This is precisely the "remote filesystems" and "filesystem automounters" competencies working together: a plain
fstabNFS entry blocks the whole boot sequence waiting for a server that might be down, whileautofsonly ever mounts on access and cleans up after itself — the safer default for any share that isn't guaranteed to always be reachable.
Essential Commands — Tasks 15–18 (20% of the exam)
☺ Like you're 10: This pile is a grab-bag every real sysadmin reaches for daily — version control, finding missing disk space, and proving a certificate is what it claims to be.
-
Task 15. A bare Git repository already exists at
git@git.internal:platform/configs.git. Clone it, create a new branch namedadd-nginx-upstream, add a filenginx/upstream.confcontaining a one-lineproxy_passdirective tohttp://127.0.0.1:8080, commit it, and push the branch upstream.Show worked solution
git clone git@git.internal:platform/configs.git cd configs git checkout -b add-nginx-upstream mkdir -p nginx printf 'location / { proxy_pass http://127.0.0.1:8080; }\n' > nginx/upstream.conf git add nginx/upstream.conf git commit -m "add nginx upstream config" git push -u origin add-nginx-upstream git status # clean tree, branch tracking origin/add-nginx-upstream git log --oneline -3-uon the push isn't cosmetic — it sets the upstream tracking branch, which is what letsgit statusreport "up to date with origin/…" instead of leaving the branch's relationship to the remote unset. -
Task 16.
/varreports 98% full according todf, but manually adding up everything under/varwithduonly accounts for about 60% of that. Find where the missing space actually is, and reclaim it.Show worked solution
df -hT /var du -xhd1 /var | sort -h | tail # doesn't add up to what df reports lsof +L1 # files with a link count of 0 — deleted, but still open # → rsyslog 812 root 5w REG 253,0 6.2G /var/log/syslog (deleted)
sudo systemctl restart rsyslog # reopens its log file cleanly; releases the deleted one's space # an alternative that avoids a full restart, if the daemon supports it: sudo kill -HUP 812 df -hT /var # space is back
This is the classic "df and du disagree" trap: a process still holds an open file descriptor to a file that was deleted (often by a log rotation gone wrong) — the directory entry is gone, so
ducan't see it, but the kernel won't reclaim the blocks until every process holding it open closes or is restarted.lsof +L1is built for exactly this. -
Task 17. Generate a self-signed TLS certificate and private key for the hostname
api.internal.example, valid for 365 days, and confirm both its expiry date and its Common Name / Subject Alternative Name are correct — without opening the file in a text editor.Show worked solution
openssl req -x509 -newkey rsa:2048 -keyout api.key -out api.crt -days 365 -nodes \ -subj "/CN=api.internal.example" \ -addext "subjectAltName=DNS:api.internal.example" chmod 600 api.key # a private key has no business being world-readable openssl x509 -in api.crt -noout -dates -subject -ext subjectAltName # notBefore / notAfter (365 days apart), subject=CN=api.internal.example, # X509v3 Subject Alternative Name: DNS:api.internal.example
If this certificate is later bound to a live service, the same inspection works over the wire without ever touching the file on disk:
openssl s_client -connect api.internal.example:443 -servername api.internal.example </dev/null 2>/dev/null | openssl x509 -noout -dates -subject— worth knowing, because that's how you'd actually verify someone else's certificate deployment, not just your own. -
Task 18. Users report this host feels sluggish. Identify which single process is responsible for the load — without guessing — and determine whether the real bottleneck is CPU or something else, such as disk I/O wait.
Show worked solution
uptime # load average — compare against nproc nproc ps -eo pid,ppid,cmd,%cpu,%mem --sort=-%cpu | head -6 # or: top -o %CPU vmstat 1 5 # watch the 'us'/'sy' columns vs the 'wa' column iostat -xz 1 5 # if 'wa' is high, which device is actually busy
The distinction between columns is the actual point of this task, not just running the commands: high us/sy means a process is genuinely burning CPU cycles, and the fix is to renice, limit, or kill it; high wa (I/O wait) means the CPU is mostly idle, sitting around waiting on a slow disk or a saturated volume, and the fix is entirely different — chasing the wrong one wastes the two hours you don't have to spare.
Users and Groups — Tasks 19–20 (10% of the exam)
☺ Like you're 10: The smallest pile at 10%, but still worth two full tasks — who's allowed to do what, and exactly how much of the machine they're allowed to use.
-
Task 19. Create a new local user named
dot, with an auto-created home directory, secondary membership in bothdevelopersandplatform-admins, and/bin/bashas the shell. This user's processes must never be able to open more than 4096 file descriptors at once, even under load, and that limit must survivedotlogging out and back in.Show worked solution
sudo groupadd developers 2>/dev/null # ignore "already exists" if a group is already present sudo groupadd platform-admins 2>/dev/null sudo useradd -m -G developers,platform-admins -s /bin/bash dot sudo passwd dot id dot groups dot
# /etc/security/limits.conf dot soft nofile 4096 dot hard nofile 4096
# the limit is applied by PAM at LOGIN time — it will NOT retroactively affect an already-open session su - dot -c "ulimit -Sn; ulimit -Hn" # log in fresh as dot and confirm both read 4096
Setting both soft and hard to the same value is what actually enforces a hard ceiling — a soft-only entry just changes the default, which
dot's own processes could still raise back up to the (unset, effectively unlimited) hard limit. And this is a PAM-enforced limit, not a live kernel toggle: it only takes effect for a session that logs in after the file is edited. -
Task 20. The directory
/srv/reportsis ownedroot:root, mode750. Without changing the owner, the group, or the base permission bits, grant the single userdotread+execute access, and make sure any new file created inside/srv/reportsby anyone else automatically grantsdotthe same access too.Show worked solution
getfacl /srv/reports # baseline — no extended ACL yet sudo setfacl -m u:dot:rx /srv/reports # access ACL: dot can enter and list THIS directory sudo setfacl -d -m u:dot:rx /srv/reports # default ACL: new children inherit the same entry getfacl /srv/reports ls -ld /srv/reports # note the trailing '+' — confirms an ACL is attached sudo touch /srv/reports/test.txt getfacl /srv/reports/test.txt # dot:r-x should appear, inherited from the default ACL
One genuine gotcha worth knowing before it costs you marks: a default ACL entry is copied onto new files verbatim, but the resulting effective permission is still trimmed by that file's own ACL mask —
getfaclwill print an explicit#effective:annotation whenever the entry you set and the entry that actually applies differ. Never assume the default ACL you configured is the permission a new file ends up with; always confirm withgetfaclon the actual file, not just on the parent directory.
Turning a failed task into a fact
☺ Like you're 10: The score isn't the point. What matters is why a task went wrong — because "I didn't know that tool existed" and "I typed the right idea in the wrong order" need completely different fixes.
When a task doesn't come out right, be honest about which of two things happened. If you genuinely didn't know the mechanism — you'd never heard of a systemd drop-in, or didn't know ACLs existed as a concept — that's a content gap, and the fix is rereading the matching section of LFCS — the exam until you can explain it in your own words, not just recognise the commands here. If you knew the concept but the final state still came out wrong, that's almost always a missed verification step — you ran the command but never checked getfacl, df, or systemctl status afterward to confirm it actually did what you intended. On a graded machine, an unverified fix and no fix at all score identically.
"Task 8's NAT rule — I built the exact ruleset above, checked it three times with nft list ruleset, and traffic still didn't route. Twenty minutes gone before I thought to check net.ipv4.ip_forward, which was still 0 from a fresh VM image. The firewall rule was never the problem. The kernel was refusing to forward the packet to the NAT table in the first place, and no amount of staring at nft syntax was ever going to show me that, because the ruleset itself was completely correct the whole time."
(Composite, illustrative account — not a specific person's story.)
Pick your three lowest-confidence tasks from the bank above and re-run them from a freshly reset VM snapshot, cold, with a timer running — six minutes each, matching roughly the two-hour, 17-to-20-task pace of the real exam. Don't open the worked solution until the timer ends or you're stuck for real. Then diff what you actually typed against the solution above, not just whether the end state matched — a task you solved a slower or clumsier way still counts as solved on exam day, but noticing the faster path now is free speed you keep forever.
Foxy: Twenty tasks and not one of them gives you four options to pick from? That feels so much harder than a normal exam.
Sol: It's harder to fake, Foxy. Not harder to pass, if you've actually built each thing once before.
Benny: And you can't half-do a task and hope for partial credit either. Either getfacl shows the entry you meant to set, or it doesn't.
Gizmo: Pfft, skip the verification step, who's got time. If the command didn't print an error, it worked. 😈
Timmy: Task 20 says otherwise, Gizmo — setfacl ran without a single error and still didn't give you the permission you thought it did. Silence isn't proof. Checking is.
Sol: Which is why every task above ends the same way — not "and then I'm done," but "and then I confirmed it."
Remy: Say it back: 20 tasks, weighted 5/5/4/4/2 across the five domains, no partial credit for describing a fix, only for a state you actually verified.
Read the full domain breakdown and exam logistics on LFCS — the exam, follow the day-by-day calendar on the LFCS study plan, or go deeper on any one mechanism at systemd & journald and LVM & Linux Storage Tools. Once every task above feels routine, sit a full timed run: Mock Exam · Set 1, Set 2, Set 3.
1. This bank has 20 tasks split 5/5/4/4/2 across the five domains — which two domains get the most tasks, and why those two specifically? 2. In Task 2, why is an empty ExecStart= line required on its own line before setting the real override? 3. In Task 9, what's the one command you must run before restarting sshd after editing its config, and what happens if you skip it? 4. In Task 14, why is autofs a better fit than a plain fstab entry for a remote NFS share? 5. In Task 20, why might getfacl show a default ACL entry you set, but an "effective" permission that's actually lower? 6. What's the practical difference between the 'us'/'sy' columns and the 'wa' column in vmstat output, and why does that difference change how you'd fix a slow host? 7. True or false: on this exam, correctly describing in words how you would fix a broken unit earns partial credit even if you run out of time to actually type the commands.
Check your answers
- Operations Deployment and Networking, 5 tasks each — because they're the two domains the Linux Foundation weights at 25% apiece, together half the real exam, so this bank spends half its tasks there too.
- Because
ExecStart=can be declared multiple times and normally accumulates rather than replaces — without first clearing it with a bareExecStart=, your drop-in adds a second command alongside the vendor's instead of overriding it. sshd -t, which validates the config file's syntax before you touch the running daemon. Skip it and a typo that saves fine can still fail to load on restart, potentially locking out remote access to the very host you were fixing.- A hard
fstabmount blocks the boot sequence until the remote server responds, hanging startup entirely if it's ever unreachable;autofsonly mounts on access and unmounts itself when idle, so an unreachable server never holds up the boot. - A default ACL entry is copied onto new files verbatim, but the file's own ACL mask can still trim what's actually granted —
getfaclprints an explicit#effective:line whenever the set entry and the applied permission differ, so always verify on the actual file rather than assuming the default entry is the final word. - us/sy mean a process is genuinely consuming CPU cycles (fix: renice, limit, or kill it); wa means the CPU is mostly idle, waiting on slow storage (fix: find and address the disk bottleneck instead). Treating one as the other wastes time chasing the wrong fix.
- False. This is a performance-based exam graded on the final state of the machine — a correct explanation with no working result scores exactly the same as no attempt at all.