summaryrefslogtreecommitdiff
path: root/src/initrd/menu-select
blob: 8347c280e968abeaad056b7469ee43d693f55e48 (plain)
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/bin/sh
# usage:
#  $0 boot-ram                                             - use memory-only overlay
#  $0 boot-new          [dev name] [loop file] [megabytes] - create new luks-encrypted overlay
#  $0 boot-overwrite    [dev name] [loop file] [megabytes] - overwrite with new luks overlay
#  $0 boot-luks         [dev name] [loop file]             - boot existing luks-encrypted overlay
#  $0 boot-destroy-disk [dev-name]                         - install to a fresh hard disk
#  $0 boot-gpg          [key id] [gnupg homedir] [???]     - boot any device signed with the key

. btrfs-create.sh
. common.sh
exec 4>&1
debug_log

error()
{
  local sleep=3

  clear >&4
  echo "error -- ${*:-:(}" >&4

  if [ $sleep -gt 0 ]; then
    echo "will try again in $sleep seconds..." >&4
    sleep $sleep
  fi
  bootmenu do_trigger no_panic
  exit
}

badopts=
fs=
while [ $# -ge 1 ]; do
  case $1 in
    --fs=*) fs="${1#--fs=}"; shift; continue ;;
    --*) echo "error: unknown option $1"; badopts=true; shift; continue ;;
  esac
  break
done
[ -z "$badopts" ] || error 'usage error'

[ $# -ge 2 -o "$1" = 'boot-ram' -o "$1" = boot-destroy-disk ] || error 'usage error'

remountrw()
{
  local fs="$1" dev="$2" loopfile="$3"
  if [ "$fs" = hfsplus ]; then
    mountpoint="/mnt/${dev##*/}"
    umount "$dev" || error
    fsck.hfsplus -q "$dev" || error
    mount -o force "$dev" "$mountpoint" || error
  else
    mount -o remount,rw "$dev" || error
  fi
}

hwclock_to_system()
{
  local fs="$1" UTC=UTC
  case "$fs" in ntfs|vfat) UTC=LOCAL ;; esac
  printf '0.0 0 0.0\n0\n%s' $UTC > /etc/adjtime
  hwclock --hctosys
}

case "$1" in
  boot-ram)
    read _ memtotal_kb _ < /proc/meminfo
    # This doesn't make sense to me, but setting rd_size _lower_ than total
    # memory seems to be what breaks things ('btrfs device add' hangs forever).
    # Somehow you can fill up the filesystem and there's still space for
    # programs and btrfs does not complain. I don't know what is going on here.

    # BTW, I verified with blockdev that the device size really is being
    # specified in KB here. I did not really believe it.
    modprobe brd rd_nr=1 rd_size=$memtotal_kb

    init_gpg || error
    init_samizdat /dev/ram0 '' || {
        umount /root/cdrom
        umount /root/outerfs
        umount /root
        error
    }
    bootdone root-mounted
  ;;
  boot-destroy-disk)
    dev="$2"

    partition_new_hard_drive_DESTROYING_EVERYTHING "$dev" || error

    mkfs.btrfs -f "$dev"2                                 || error
    mkdir /plaintext
    mount "$dev"2 /plaintext                              || error
    init_gpg                                              || error

    init_samizdat_blockdev "$dev"3 /plaintext/disk.key    || error
    init_samizdat /dev/mapper/samizdatcrypt ''            || error

    mark_partitions_as_complete "$dev"

    bootdone root-mounted
  ;;
  boot-native)
    dev="$2"
    init_gpg                                           || error
    mkdir /plaintext
    mount "$dev"2 /plaintext                           || error
    open_samizdat_blockdev "$dev"3 /plaintext/disk.key || error
    open_samizdat                                      || error
    bootdone root-mounted
  ;;
  boot-overwrite|boot-new|boot-luks)
    dev="$2"
    loopfile="$3"
    megs="$4"

    [ "$1" != 'boot-new' -o ! -e "$loopfile" ] || error

    remountrw "$fs" "$dev" "$loopfile" || error

    hwclock_to_system "$fs"

    if [ "$1" = 'boot-overwrite' ]; then
      rm "$loopfile" "$loopfile"k
    fi

    init_gpg || error

    if [ "$1" = 'boot-luks' ]; then
      open_samizdat_blockdev_from_loop "$loopfile" "$loopfile"k || error
      open_samizdat || error
      bootdone root-mounted
      exit
    fi

    start_meter "Allocating ${megs}MB in '$loopfile' on $dev..."

    if newdev=$(init_samizdat_lodev "$loopfile" "$megs") &&
        init_samizdat_blockdev "$newdev" "$loopfile"k &&
            init_samizdat /dev/mapper/samizdatcrypt "$loopfile"; then
      stop_meter done.
      bootdone root-mounted
    else
      stop_meter error!
      rm "$loopfile" "$loopfile"k
      dmsetup remove samizdatcrypt
      # TODO: more teardown
      error
    fi
  ;;
  *)
    error "Unimplemented boot command: $*"
  ;;
esac

# vim:ts=2 sw=2 et