File: zfs-lib.sh.in

package info (click to toggle)
zfs-linux 2.1.11-1%2Bdeb12u1
  • links: PTS, VCS
  • area: contrib
  • in suites: bookworm
  • size: 77,344 kB
  • sloc: ansic: 376,447; sh: 59,625; python: 7,872; asm: 6,476; makefile: 5,812; perl: 770; sed: 41; awk: 5
file content (119 lines) | stat: -rwxr-xr-x 3,272 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/bin/sh
# shellcheck disable=SC2034

command -v getarg >/dev/null || . /lib/dracut-lib.sh || . /usr/lib/dracut/modules.d/99base/dracut-lib.sh

TAB="	"

ZPOOL_IMPORT_OPTS=
if getargbool 0 zfs_force -y zfs.force -y zfsforce; then
    warn "ZFS: Will force-import pools if necessary."
    ZPOOL_IMPORT_OPTS=-f
fi

_mount_dataset_cb() {
    mount -o zfsutil -t zfs "${1}" "${NEWROOT}${2}"
}

# mount_dataset DATASET
#   mounts the given zfs dataset.
mount_dataset() {
    dataset="${1}"
    mountpoint="$(zfs get -H -o value mountpoint "${dataset}")"
    ret=0

    # We need zfsutil for non-legacy mounts and not for legacy mounts.
    if [ "${mountpoint}" = "legacy" ] ; then
        mount -t zfs "${dataset}" "${NEWROOT}" || ret=$?
    else
        mount -o zfsutil -t zfs "${dataset}" "${NEWROOT}" || ret=$?

        if [ "$ret" = "0" ]; then
            for_relevant_root_children "${dataset}" _mount_dataset_cb || ret=$?
        fi
    fi

    return ${ret}
}

# for_relevant_root_children DATASET EXEC
#   Runs "EXEC dataset mountpoint" for all children of DATASET that are needed for system bringup
#   Used by zfs-nonroot-necessities.service and friends, too!
for_relevant_root_children() {
    dataset="${1}"
    exec="${2}"

    zfs list -t filesystem -Ho name,mountpoint,canmount -r "${dataset}" |
        (
            _ret=0
            while IFS="${TAB}" read -r dataset mountpoint canmount; do
                [ "$canmount" != "on" ] && continue

                case "$mountpoint" in
                    /etc|/bin|/lib|/lib??|/libx32|/usr)
                        # If these aren't mounted we may not be able to get to the real init at all, or pollute the dataset holding the rootfs
                        "${exec}" "${dataset}" "${mountpoint}" || _ret=$?
                        ;;
                    *)
                        # Up to the real init to remount everything else it might need
                        ;;
                esac
            done
            exit ${_ret}
        )
}

# Parse root=, rootfstype=, return them decoded and normalised to zfs:AUTO for auto, plain dset for explicit
#
# True if ZFS-on-root, false if we shouldn't
#
# Supported values:
#   root=
#   root=zfs
#   root=zfs:
#   root=zfs:AUTO
#
#   root=ZFS=data/set
#   root=zfs:data/set
#   root=zfs:ZFS=data/set (as a side-effect; allowed but undocumented)
#
#   rootfstype=zfs AND root=data/set <=> root=data/set
#   rootfstype=zfs AND root=         <=> root=zfs:AUTO
#
# '+'es in explicit dataset decoded to ' 's.
decode_root_args() {
    if [ -n "$rootfstype" ]; then
        [ "$rootfstype" = zfs ]
        return
    fi

    root=$(getarg root=)
    rootfstype=$(getarg rootfstype=)

    # shellcheck disable=SC2249
    case "$root" in
        ""|zfs|zfs:|zfs:AUTO)
            root=zfs:AUTO
            rootfstype=zfs
            return 0
            ;;

        ZFS=*|zfs:*)
            root="${root#zfs:}"
            root="${root#ZFS=}"
            root=$(echo "$root" | tr '+' ' ')
            rootfstype=zfs
            return 0
            ;;
    esac

    if [ "$rootfstype" = "zfs" ]; then
        case "$root" in
            "") root=zfs:AUTO ;;
            *)  root=$(echo "$root" | tr '+' ' ') ;;
        esac
        return 0
    fi

    return 1
}