init 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. #!/bin/sh
  2. #
  3. # Simple init script that should handle both
  4. # livecd/livedisk, thinclient and hdd boot
  5. #
  6. PATH=/usr/sbin:/usr/bin:/sbin:/bin
  7. INITRAMFSCONF="/etc/initramfs.conf"
  8. ROOT_LINKS="bin sbin lib boot usr opt"
  9. ROOT_TREES="etc root home var run"
  10. TMPFS_DIRS="dev mnt mnt/cdrom mnt/livecd mnt/thin tmp sys proc media"
  11. LOOPBACKFILE="/boot/pisi.sqfs"
  12. NORESUME=0
  13. LIVE=0
  14. NFSROOT=0
  15. QUIET=0
  16. RAID_INCREMENTAL=1
  17. RAID=0
  18. LVM=0
  19. COPYTORAM=0
  20. SPLASH=0
  21. WIPEMEM=0
  22. HOTPLUG="/sbin/hotplug"
  23. MNTDIR=""
  24. FS_TYPE=""
  25. INITRAMFS=""
  26. ROOT_FLAGS=""
  27. ROOT_DEVICE=""
  28. ROOT_TARGET=""
  29. RESUME_DEVICE=""
  30. WIPEMEM_OPTS="-llv"
  31. ###########################
  32. # Miscellaneous functions #
  33. ###########################
  34. info() {
  35. echo "<6>initramfs: $1" > /dev/kmsg
  36. }
  37. log_output() {
  38. $@ | echo "<6>`sed 's#^\(.*\)$#initramfs:\1#g'`" > /dev/kmsg
  39. }
  40. fall2sh() {
  41. # Kill any possible plymouth instances
  42. test -x /bin/plymouth && /bin/plymouth quit &> /dev/null
  43. kill -9 $(pidof plymouthd) &> /dev/null
  44. echo "--> $*"
  45. echo "Reboot with initramfs=shell(noprobe) to further debug the issue."
  46. # Use a login shell for sourcing /etc/profile
  47. /bin/sh -l
  48. }
  49. run_dhcpc() {
  50. udhcpc -C -i eth0 -s /etc/udhcpc.script
  51. }
  52. ##################
  53. # Device probers #
  54. ##################
  55. probe_devices() {
  56. # Set hotplug helper for firmware loading
  57. echo $HOTPLUG > /proc/sys/kernel/hotplug
  58. if [ "x$1" = "x--with-kms" ]; then
  59. probe_kms
  60. test -x /bin/plymouth && /bin/plymouth show-splash
  61. fi
  62. probe_pci_devices
  63. probe_virtio_devices
  64. probe_usb_devices
  65. # Unset hotplug helper
  66. echo > /proc/sys/kernel/hotplug
  67. [ "${RAID}" -eq "1" ] && probe_raid
  68. [ "${LVM}" -eq "1" ] && probe_lvm
  69. }
  70. probe_kms() {
  71. for device in /sys/bus/pci/devices/*/boot_vga; do
  72. [ -f $device ] || continue
  73. info "Loading KMS driver"
  74. grep -q 1 $device && modprobe -bq `cat ${device%boot_vga}modalias`
  75. done
  76. if [ ! -c /dev/fb0 ]; then
  77. echo "options uvesafb scroll=ywrap mtrr=0 nocrtc=1 mode_option=1024x768-32" > /etc/modprobe.d/uvesafb.conf
  78. modprobe -bq uvesafb
  79. fi
  80. }
  81. probe_pci_devices() {
  82. info "Probing PCI devices"
  83. local MODULES=""
  84. for module in /sys/bus/pci/devices/*/modalias; do
  85. [ -f $module ] || continue
  86. MODULES="$MODULES $(cat $module)"
  87. done
  88. modprobe -bqa $MODULES
  89. }
  90. probe_usb_devices() {
  91. info "Probing USB devices"
  92. local MODULES=""
  93. for module in /sys/bus/usb/devices/*/modalias; do
  94. [ -f $module ] || continue
  95. MODULES="$MODULES $(cat $module)"
  96. done
  97. modprobe -bqa $MODULES
  98. }
  99. probe_raid() {
  100. info "Probing RAID devices"
  101. modprobe -bqa dm-mod raid0 raid1 raid10 raid456
  102. if [ -x /sbin/mdadm ]
  103. then
  104. /sbin/mdadm --examine --scan > /etc/mdadm.conf
  105. /sbin/mdadm -As
  106. fi
  107. }
  108. probe_lvm() {
  109. info "Probing LVM devices"
  110. modprobe -qa dm-mod
  111. if [ -x /sbin/lvm ]
  112. then
  113. /sbin/lvm vgscan --ignorelockingfailure &> /dev/null
  114. /sbin/lvm vgchange -ay --sysinit --ignorelockingfailure &> /dev/null
  115. /sbin/lvm vgmknodes --ignorelockingfailure &> /dev/null
  116. fi
  117. }
  118. probe_virtio_devices() {
  119. local MODULES=""
  120. for module in /sys/bus/virtio/devices/*/modalias; do
  121. [ -f $module ] || continue
  122. MODULES="$MODULES $(cat $module)"
  123. done
  124. modprobe -bqa $MODULES
  125. }
  126. #################################
  127. # Filesystem specific functions #
  128. #################################
  129. mount_rootfs() {
  130. FS_TYPE=`disktype $ROOT_DEVICE | grep KERNELMODULE | awk '{print $2}'`
  131. info "Mounting rootfs: $ROOT_DEVICE ($FS_TYPE)"
  132. mount -r -t $FS_TYPE -n ${ROOT_FLAGS} ${ROOT_DEVICE} /newroot
  133. }
  134. find_live_mount() {
  135. modprobe -bqa usb-storage udf
  136. if [ "$#" -gt "0" ]
  137. then
  138. for x in $*
  139. do
  140. # this is used for non Linux fs detection
  141. FS_TYPE=`disktype $1 | grep KERNELMODULE | awk '{print $2}'`
  142. if [ -n "$FS_TYPE" -a -f /lib/modules/*/$FS_TYPE.ko ]
  143. then
  144. modprobe $FS_TYPE 1> /dev/null 2>&1
  145. fi
  146. mount -r ${x} /newroot/mnt/cdrom > /dev/null 2>&1
  147. if [ "$?" = "0" ]
  148. then
  149. # Check for cdroot image
  150. if [ -e /newroot/mnt/cdrom/${LOOPBACKFILE} ]
  151. then
  152. ROOT_DEVICE="/newroot${x}"
  153. if [ "$COPYTORAM" == "1" ]
  154. then
  155. info "Copying Live Media files to RAM"
  156. mkdir /newroot/mnt/cdromtemp
  157. cp -af /newroot/mnt/cdrom/* /newroot/mnt/cdromtemp/
  158. umount /newroot/mnt/cdrom
  159. rmdir /newroot/mnt/cdrom
  160. mv /newroot/mnt/cdromtemp /newroot/mnt/cdrom
  161. fi
  162. break
  163. else
  164. umount /newroot/mnt/cdrom
  165. fi
  166. fi
  167. done
  168. fi
  169. }
  170. manage_tmpfs() {
  171. mount -t tmpfs tmpfs /newroot
  172. for d in ${TMPFS_DIRS}; do
  173. mkdir -p "/newroot/${d}"
  174. done
  175. }
  176. mount_nfs() {
  177. FS_LOCATION='mnt/thin'
  178. # Change directory to /newroot
  179. cd /newroot
  180. # FIXME: busybox mount does not load automatically
  181. modprobe -q nfs
  182. # mount nfs
  183. if [ -z "/etc/udhcpc.info" ]
  184. then
  185. fall2sh "/etc/udhcpc.info not found"
  186. fi
  187. . /etc/udhcpc.info
  188. if [ -z "${ROOTPATH}" ]
  189. then
  190. fall2sh "NFS rootpath not found"
  191. fi
  192. echo "Mounting NFS from $ROOTPATH"
  193. mount -o tcp,nolock,ro $ROOTPATH /newroot/mnt/thin
  194. if [ "$?" != '0' ]
  195. then
  196. fall2sh "Could not nfs root"
  197. fi
  198. # Create necessary links
  199. for x in ${ROOT_LINKS}; do
  200. ln -s "${FS_LOCATION}/${x}" "${x}"
  201. done
  202. if [ -e "${FS_LOCATION}/lib32" ]
  203. then
  204. ln -s "${FS_LOCATION}/lib32" "lib32"
  205. fi
  206. # We need this for x86_64
  207. ln -s "${FS_LOCATION}/lib" "lib64"
  208. chmod 1777 tmp
  209. (cd /newroot/${FS_LOCATION}; cp -a ${ROOT_TREES} /newroot)
  210. # Needed for ltspfs mechanism
  211. echo "$IP $HOSTNAME" >> /newroot/etc/hosts
  212. }
  213. mount_cdroot() {
  214. FS_LOCATION="mnt/livecd"
  215. # Change directory to /newroot
  216. cd /newroot
  217. # These are not loaded automatically
  218. modprobe -q squashfs
  219. # Loop type squashfs
  220. mount -t squashfs -o loop,ro /newroot/mnt/cdrom/${LOOPBACKFILE} /newroot/mnt/livecd
  221. if [ "$?" != "0" ]
  222. then
  223. fall2sh "Could not mount root image"
  224. fi
  225. # Create necessary links
  226. for x in ${ROOT_LINKS}; do
  227. ln -s "${FS_LOCATION}/${x}" "${x}"
  228. done
  229. if [ -e "${FS_LOCATION}/lib32" ]
  230. then
  231. ln -s "${FS_LOCATION}/lib32" "lib32"
  232. fi
  233. # We need this for x86_64
  234. ln -s "${FS_LOCATION}/lib" "lib64"
  235. chmod 1777 tmp
  236. (cd /newroot/${FS_LOCATION}; cp -a ${ROOT_TREES} /newroot)
  237. # FIXME: the device list is taken from udev, we can't rely on sys entries since pluggable means different
  238. # in kernel world. Suggestions that do not include this kind of regexp mania are welcome
  239. # for userspace applications
  240. REAL_ROOT_TYPE=`echo "${ROOT_DEVICE}" | sed -e 's/^\/newroot\/dev\///' | grep -qE '^sr[0-9]*|^hd[a-z]|^pcd[0-9]|^xvd*' && echo "optical" || echo "harddisk"`
  241. echo "${REAL_ROOT_TYPE}" > /newroot/run/pisilinux/livemedia
  242. # this is needed for yali
  243. MNTDIR=`grep \/mnt\/cdrom\ /proc/mounts|sed 's/\/newroot//g'`
  244. echo "$MNTDIR" >> /newroot/etc/fstab
  245. }
  246. ##############################
  247. # Config and cmdline parsers #
  248. ##############################
  249. # FIXME: maybe we should just source the file instead of parsing
  250. # also consider merging conf parser and cmdline parser
  251. parse_config() {
  252. while read inputline;
  253. do
  254. case "${inputline}" in
  255. raid=*)
  256. RAID=$(echo $inputline|cut -f2- -d=)
  257. ;;
  258. lvm=*)
  259. LVM=$(echo $inputline|cut -f2- -d=)
  260. ;;
  261. thin=*)
  262. NFSROOT=$(echo $inputline|cut -f2- -d=)
  263. ;;
  264. root=*)
  265. ROOT_TARGET=$(echo $inputline|cut -f2- -d=)
  266. ;;
  267. rootflags=*)
  268. ROOT_FLAGS=$(echo $inputline|cut -f2- -d=)
  269. ;;
  270. liveroot=*)
  271. # Installation or livecd, enable RAID by default
  272. # to be able to read existing RAID installations
  273. LIVE=1
  274. RAID_INCREMENTAL=0
  275. LIVEROOT=$(echo $inputline|cut -f2- -d=)
  276. ;;
  277. resume=*)
  278. RESUME_DEVICE="${inputline#resume=}"
  279. ;;
  280. noresume)
  281. NORESUME=1
  282. ;;
  283. copytoram)
  284. COPYTORAM=1
  285. ;;
  286. wipemem)
  287. WIPEMEM=1
  288. ;;
  289. wipememopts=*)
  290. WIPEMEM=1
  291. WIPEMEM_OPTS=$(echo $inputline|cut -f2- -d=)
  292. ;;
  293. splash)
  294. SPLASH=1
  295. ;;
  296. init=*)
  297. INIT="${inputline#INIT=}"
  298. ;;
  299. esac
  300. done < $INITRAMFSCONF
  301. }
  302. parse_cmdline() {
  303. for x in `cat /proc/cmdline`; do
  304. case "${x}" in
  305. [0123456Ss])
  306. # Normalize 'S' to 's'
  307. LEVEL=`echo ${x}|tr A-Z a-z`
  308. ;;
  309. mudur=*)
  310. for m in `echo ${x}|cut -f2 -d=|sed 's/,/ /g'`; do
  311. case "${m}" in
  312. livecd)
  313. LIVE=1
  314. ;;
  315. livedisk)
  316. LIVE=1
  317. ;;
  318. raid)
  319. RAID=1
  320. ;;
  321. lvm)
  322. LVM=1
  323. ;;
  324. thin)
  325. NFSROOT=1
  326. ;;
  327. esac
  328. done
  329. ;;
  330. initramfs=*)
  331. INITRAMFS=`echo ${x}|cut -f2- -d=`
  332. ;;
  333. root=*)
  334. ROOT_TARGET=`echo ${x}|cut -f2- -d=`
  335. ;;
  336. rootflags=*)
  337. ROOT_FLAGS="-o ${x#rootflags=}"
  338. ;;
  339. liveroot=*)
  340. LIVE=1
  341. LIVEROOT=$(echo ${x}|cut -f2- -d=)
  342. ;;
  343. resume=*)
  344. RESUME_DEVICE="${x#resume=}"
  345. ;;
  346. noresume)
  347. NORESUME=1
  348. ;;
  349. init=*)
  350. INIT="${x#init=}"
  351. ;;
  352. copytoram)
  353. COPYTORAM=1
  354. ;;
  355. wipemem)
  356. WIPEMEM=1
  357. ;;
  358. wipememopts=*)
  359. WIPEMEM=1
  360. WIPEMEM_OPTS=$(echo $x|cut -f2- -d=)
  361. ;;
  362. splash)
  363. SPLASH=1
  364. ;;
  365. single)
  366. LEVEL="s"
  367. ;;
  368. quiet)
  369. QUIET=1
  370. ;;
  371. blacklist=*)
  372. modules=${x#blacklist=}
  373. for module in ${modules//,/ }; do
  374. echo "blacklist $module" >> /etc/modprobe.d/cmdline.conf
  375. done
  376. ;;
  377. esac
  378. done
  379. if [ -f /etc/modprobe.d/cmdline.conf ]; then
  380. cp /etc/modprobe.d/cmdline.conf /dev/.modprobe.initramfs.conf
  381. fi
  382. }
  383. ####################
  384. # init starts here #
  385. ####################
  386. info "Starting init on initramfs"
  387. # Mount needed filesystems
  388. mount -n -t proc proc /proc
  389. mount -n -t sysfs sysfs /sys
  390. # Added to start udev properly
  391. #mkdir -m 0755 /run
  392. #mount -t tmpfs tmpfs /run
  393. # Prepare /dev (Needs kernel >= 2.6.32)
  394. mount -t devtmpfs devtmpfs /dev
  395. mkdir -m 0755 /dev/pts
  396. mount -t devpts -o gid=5,mode=620 devpts /dev/pts
  397. # First parse config file, then cmdline to allow overwriting internal config
  398. if [ -f "$INITRAMFSCONF" ]
  399. then
  400. #. $INITRAMFSCONF
  401. parse_config
  402. fi
  403. # Parse command line parameters
  404. parse_cmdline
  405. # Minimize printk log
  406. test "x$QUIET" = "x1" && echo "1" > /proc/sys/kernel/printk
  407. # Initialize plymouth daemon if found and splash is true
  408. # Don't even launch plymouthd if we're in single-user mode
  409. if [ "$LEVEL" != "s" -a "$SPLASH" = "1" -a -x /sbin/plymouthd ]; then
  410. /sbin/plymouthd --attach-to-session
  411. fi
  412. # Handle initramfs= parameter
  413. if [ "${INITRAMFS}" == "shellnoprobe" ]
  414. then
  415. fall2sh "Starting up a shell without probing"
  416. elif [ "${INITRAMFS}" == "shell" ]
  417. then
  418. probe_devices --with-kms
  419. fall2sh "Starting up a shell"
  420. fi
  421. if [ "${WIPEMEM}" = "1" ]
  422. then
  423. info "Wiping out memory, system will be shutdown after completion"
  424. sdmem ${WIPEMEM_OPTS}
  425. poweroff -f
  426. fi
  427. # Probe devices
  428. probe_devices --with-kms
  429. if [ -x /usr/sbin/resume -a -b "$RESUME_DEVICE" -a "x$NORESUME" != "x1" ]
  430. then
  431. if [ "x$SPLASH" == "x1" ]
  432. then
  433. SPLASHPARAM="-P splash=y"
  434. else
  435. SPLASHPARAM="-P splash=n"
  436. fi
  437. # FIXME: This will fail if resume= contains LABEL/UUID
  438. info "Attempting to resume from hibernation"
  439. /usr/sbin/resume $SPLASHPARAM $RESUME_DEVICE
  440. fi
  441. echo 0x0100 > /proc/sys/kernel/real-root-dev
  442. if [ "${LIVE}" -eq "1" ]
  443. then
  444. ROOT_DEVICE=""
  445. manage_tmpfs
  446. # modprobe filesystems that are not in kernel, for live disks
  447. modprobe -qa nls_cp857 nls_utf8 vfat
  448. for i in `seq 50`
  449. do
  450. t=`findfs ${LIVEROOT} 2>/dev/null`
  451. find_live_mount "$t"
  452. if [ "${ROOT_DEVICE}" != "" ]
  453. then
  454. break
  455. else
  456. probe_devices
  457. usleep 200000
  458. fi
  459. done
  460. if [ "${ROOT_DEVICE}" == "" ]
  461. then
  462. fall2sh "Could not find mount media"
  463. fi
  464. mount_cdroot
  465. elif [ "${NFSROOT}" -eq "1" ]
  466. then
  467. run_dhcpc
  468. manage_tmpfs
  469. mount_nfs
  470. # set hostname for mudur
  471. hostname $HOSTNAME
  472. else
  473. # Wait until ROOT_DEVICE appears
  474. for i in `seq 50`
  475. do
  476. # let findfs handle all conversion
  477. ROOT_DEVICE=`findfs ${ROOT_TARGET} 2>/dev/null`
  478. if [ ! -b "${ROOT_DEVICE}" ]
  479. then
  480. probe_devices
  481. usleep 200000
  482. else
  483. break
  484. fi
  485. done
  486. if [ ! -b "${ROOT_DEVICE}" ]
  487. then
  488. fall2sh "Could not find boot device"
  489. else
  490. mount_rootfs
  491. fi
  492. fi
  493. [ "${INIT}" == "" ] && INIT="/sbin/init";
  494. # This stops /lib/udev/rules.d/65-md-incremental.rules from medling with mdraid sets.
  495. [ "${RAID_INCREMENTAL}" -eq "0" ] && touch /dev/.in_sysinit
  496. # Move mounts instead of umount/mount
  497. mount --move /dev /newroot/dev
  498. mount --move /proc /newroot/proc
  499. mount --move /sys /newroot/sys
  500. # Added to start udev properly
  501. #mount --move /run /newroot/run
  502. # And we start
  503. info "Switching to the real root"
  504. test -x /bin/plymouth && /bin/plymouth update-root-fs --new-root-dir=/newroot
  505. exec /bin/switch_root -c /dev/console /newroot ${INIT} ${LEVEL}