fix: share smb client persist — write a real .automount unit
x-systemd.automount in a unit file's Options= is only honored when read from /etc/fstab, so persisted mounts never armed an automount; the unit was also static (no [Install]) so enable was a no-op. Result: after a reboot the share sat inactive and the disk never mounted on access. persist now writes both <name>.mount and <name>.automount units (the automount with WantedBy=multi-user.target) and enables/starts the automount; unpersist stops/disables/removes both units.
This commit is contained in:
@@ -604,7 +604,7 @@ Use conventional prefixes: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`
|
||||
| `bin/pos-network-scan` | 271 | Parallel ping sweep of CIDR |
|
||||
| `bin/pos-share-nfs-client` | 138 | Mount NFS shares (ephemeral or persistent systemd mount units) |
|
||||
| `bin/pos-share-nfs-server` | 134 | Manage the NFS kernel server (status, share/unshare exports, enable/disable) |
|
||||
| `bin/pos-share-smb-client` | 202 | Mount SMB/CIFS shares (ephemeral or persistent systemd mount units) |
|
||||
| `bin/pos-share-smb-client` | 217 | Mount SMB/CIFS shares (ephemeral or persistent systemd mount units) |
|
||||
| `bin/pos-share-smb-server` | 253 | Manage the Samba server (status, share/unshare exports, users, enable/disable) |
|
||||
| `bin/pos-share-usb-server` | 218 | USB Redirector server control (--ls, --share; prompts when args omitted) |
|
||||
| `bin/pos-ssh-load-keys` | 31 | Load all SSH keys into the agent |
|
||||
|
||||
+1
-1
@@ -255,7 +255,7 @@ Subcommands that need input prompt interactively when args are omitted.
|
||||
| `pos share nfs server <cmd>` | `bin/pos-share-nfs-server` | Manage the NFS kernel server: `status`, `share <path> [client]`, `unshare <path>`, `list`, `reload`, `enable`, `disable` | Requires `nfs-kernel-server` (added to `preinstall.sh` PACKAGES). Exports live in `/etc/exports`; `share` is idempotent (replaces any existing line for the path) and runs `exportfs -ra`. Default client `*(rw,sync,no_subtree_check)` — the tool warns you to restrict it; help prints Tailscale CGNAT (`100.64.0.0/10`), WireGuard (`10.10.0.0/24`) and LAN examples. Mutating commands announce via `lib/notify.sh` |
|
||||
| `pos share nfs client <cmd>` | `bin/pos-share-nfs-client` | Mount and manage NFS shares: `mount <server:export> <local-dir>`, `unmount <local-dir>`, `list`, `persist <server:export> <local-dir>`, `unpersist <local-dir>` | Requires `nfs-common` (added to `preinstall.sh` PACKAGES). `persist` writes a systemd `.mount` unit (`systemd-escape --path --suffix=mount`) with `After=network-online.target` / `Wants=network-online.target` — mounts only once all interfaces are up, no fstab edits to break boot — then `daemon-reload` + `enable --now`. `unpersist` stops/disables/removes the unit. `mount`/`persist` announce via `lib/notify.sh` |
|
||||
| `pos share smb server <cmd>` | `bin/pos-share-smb-server` | Manage the Samba server: `status`, `share <path> [name] [--read-only|--guest|--users u1,u2]`, `unshare <name>`, `list`, `adduser <user>`, `deluser <user>`, `reload`, `enable`, `disable` | Requires `samba` (added to `preinstall.sh` PACKAGES). Shares are idempotent marker blocks (`# >>> pos-managed share: <name>` … `# <<< end pos-managed share`) in `/etc/samba/smb.conf` — hand edits outside the markers survive; `share` validates with `testparm` before applying and hot-reloads via `smbcontrol smbd reload-config`. Defaults rw + browsable; warns when unrestricted (guest or no `valid users`). `adduser`/`deluser` manage Samba accounts via `smbpasswd`. Mutating commands announce via `lib/notify.sh` |
|
||||
| `pos share smb client <cmd>` | `bin/pos-share-smb-client` | Mount and manage SMB/CIFS shares: `mount <//server/share> <local-dir> [user]`, `unmount <local-dir>`, `list`, `persist <//server/share> <local-dir> [user]`, `unpersist <local-dir>` | Requires `cifs-utils` (added to `preinstall.sh` PACKAGES). With a user you are prompted for the Samba password — one-shot mounts use a throwaway chmod-600 credentials file, `persist` keeps one at `/etc/samba/credentials/<name>` (chmod 600). `persist` writes a systemd `.mount` unit (`systemd-escape --path --suffix=mount`) with `x-systemd.automount` + `_netdev` — mounts on first access, never blocks boot — then `daemon-reload` + `enable --now`. `unpersist` stops/disables/removes the unit + credentials. `list` shows active mounts (`findmnt -t cifs`) **and** persistent units (as automount shares aren't mounted until first access, they'd otherwise be invisible). `mount`/`persist` announce via `lib/notify.sh` |
|
||||
| `pos share smb client <cmd>` | `bin/pos-share-smb-client` | Mount and manage SMB/CIFS shares: `mount <//server/share> <local-dir> [user]`, `unmount <local-dir>`, `list`, `persist <//server/share> <local-dir> [user]`, `unpersist <local-dir>` | Requires `cifs-utils` (added to `preinstall.sh` PACKAGES). With a user you are prompted for the Samba password — one-shot mounts use a throwaway chmod-600 credentials file, `persist` keeps one at `/etc/samba/credentials/<name>` (chmod 600). `persist` writes systemd `.mount` **and** `.automount` units (`systemd-escape --path --suffix=mount`) with `_netdev` — the automount defers the actual mount until first access, never blocks boot — then `daemon-reload` + `enable --now` the automount. `unpersist` stops/disables/removes both units + credentials. `list` shows active mounts (`findmnt -t cifs`) **and** persistent units (as automount shares aren't mounted until first access, they'd otherwise be invisible). `mount`/`persist` announce via `lib/notify.sh` |
|
||||
|
||||
### communication
|
||||
|
||||
|
||||
+3
-2
@@ -231,8 +231,9 @@ mounts use a throwaway chmod-600 credentials file, `persist` keeps one at
|
||||
`/etc/samba/credentials/<name>` (chmod 600) and references it from the unit.
|
||||
|
||||
**Persistent mounts use systemd, not fstab.** `persist` writes a
|
||||
`/etc/systemd/system/<mnt-name>.mount` unit (`systemd-escape`) with
|
||||
`x-systemd.automount` + `_netdev`: the share is mounted **on first access**
|
||||
`/etc/systemd/system/<mnt-name>.mount` unit (**and** a matching
|
||||
`<mnt-name>.automount` unit, both `systemd-escape`d) with `_netdev`: the
|
||||
automount is enabled and armed, and the share is mounted **on first access**
|
||||
instead of at boot, so an unreachable SMB server can never hang boot (with
|
||||
fstab it could). `enable --now` arms the automount immediately.
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ Commands:
|
||||
mount <//server/share> <local-dir> [user] One-shot mount (creates local-dir if needed)
|
||||
unmount <local-dir> Unmount the share
|
||||
list Show active + persistent SMB mounts
|
||||
persist <//server/share> <local-dir> [user] Persistent mount via a systemd .mount unit
|
||||
(automount — never blocks boot)
|
||||
unpersist <local-dir> Stop, disable and remove the mount unit
|
||||
persist <//server/share> <local-dir> [user] Persistent mount via systemd .mount + .automount
|
||||
units (mounts on first access — never blocks boot)
|
||||
unpersist <local-dir> Stop, disable and remove the mount/automount units
|
||||
|
||||
With no user, guest access is attempted. With a user, you are prompted for
|
||||
the Samba password — one-shot mounts use a throwaway chmod-600 credentials
|
||||
@@ -143,8 +143,10 @@ case "$cmd" in
|
||||
validate_dir "$where"
|
||||
|
||||
unit="$(systemd-escape --path --suffix=mount "$where")"
|
||||
auto_unit="${unit%.mount}.automount"
|
||||
unit_file="${UNIT_DIR}/${unit}"
|
||||
opts="$(mount_opts "$user"),_netdev,noexec,x-systemd.automount"
|
||||
auto_file="${UNIT_DIR}/${auto_unit}"
|
||||
opts="$(mount_opts "$user"),_netdev,noexec"
|
||||
if [ -n "$user" ]; then
|
||||
creds_file="$SMB_CREDS_DIR/$(basename "$where")"
|
||||
sudo mkdir -p "$SMB_CREDS_DIR"
|
||||
@@ -169,10 +171,20 @@ What=${what}
|
||||
Where=${where}
|
||||
Type=cifs
|
||||
Options=${opts}
|
||||
UNIT
|
||||
cat <<UNIT | sudo tee "$auto_file" >/dev/null
|
||||
[Unit]
|
||||
Description=Automount of SMB share ${what} at ${where}
|
||||
|
||||
[Automount]
|
||||
Where=${where}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
UNIT
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now "$unit"
|
||||
log "Persistent SMB mount: ${what} → ${where} (${unit})"
|
||||
sudo systemctl enable --now "$auto_unit"
|
||||
log "Persistent SMB mount (automount): ${what} → ${where} (${auto_unit})"
|
||||
notify_send "SMB mount persisted: ${what} → ${where}"
|
||||
;;
|
||||
|
||||
@@ -182,17 +194,20 @@ UNIT
|
||||
validate_dir "$where"
|
||||
|
||||
unit="$(systemd-escape --path --suffix=mount "$where")"
|
||||
auto_unit="${unit%.mount}.automount"
|
||||
unit_file="${UNIT_DIR}/${unit}"
|
||||
auto_file="${UNIT_DIR}/${auto_unit}"
|
||||
|
||||
if [ ! -f "$unit_file" ]; then
|
||||
if [ ! -f "$unit_file" ] && [ ! -f "$auto_file" ]; then
|
||||
warn "No systemd mount unit for $where (${unit})"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
sudo systemctl disable "$auto_unit" 2>/dev/null || true
|
||||
sudo systemctl stop "$auto_unit" 2>/dev/null || true
|
||||
sudo systemctl disable "$unit" 2>/dev/null || true
|
||||
sudo systemctl stop "$unit" 2>/dev/null || true
|
||||
sudo systemctl stop "${unit%.mount}.automount" 2>/dev/null || true
|
||||
sudo rm -f "$unit_file"
|
||||
sudo rm -f "$unit_file" "$auto_file"
|
||||
sudo rm -f "$SMB_CREDS_DIR/$(basename "$where")"
|
||||
sudo rmdir "$SMB_CREDS_DIR" 2>/dev/null || true
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
Reference in New Issue
Block a user