once.rs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. use lazy_static::lazy_static;
  2. use crate::{cfg, env, mount};
  3. use crate::log::{logger};
  4. use std::sync::atomic::{AtomicBool, Ordering};
  5. use nix::mount::MsFlags;
  6. use crate::op::makesure::mkdir_p;
  7. use crate::swap::swap_on;
  8. lazy_static!{
  9. static ref PREPARE_OK_SYSFS: AtomicBool = AtomicBool::new(false);
  10. static ref PREPARE_OK_PROC: AtomicBool = AtomicBool::new(false);
  11. static ref PREPARE_OK_BOOTFS: AtomicBool = AtomicBool::new(false);
  12. static ref PREPARE_OK_TMP_DEVTMPFS: AtomicBool = AtomicBool::new(false);
  13. static ref PREPARE_OK_DEVTMPFS: AtomicBool = AtomicBool::new(false);
  14. static ref PREPARE_OK_DEVPTS: AtomicBool = AtomicBool::new(false);
  15. static ref PREPARE_OK_RUNFS: AtomicBool = AtomicBool::new(false);
  16. static ref PREPARE_OK_MOVE_SYSFS: AtomicBool = AtomicBool::new(false);
  17. static ref PREPARE_OK_MOVE_PROC: AtomicBool = AtomicBool::new(false);
  18. static ref PREPARE_OK_MOVE_BOOTFS: AtomicBool = AtomicBool::new(false);
  19. static ref PREPARE_OK_MOVE_TMP_DEVTMPFS: AtomicBool = AtomicBool::new(false);
  20. static ref PREPARE_OK_MOVE_RUNFS: AtomicBool = AtomicBool::new(false);
  21. static ref PREPARE_OK_SWAPON: AtomicBool = AtomicBool::new(false);
  22. }
  23. pub fn mount_sysfs() {
  24. if PREPARE_OK_SYSFS.load(Ordering::Relaxed) {
  25. logger().warn("mount", "The sysfs is already mounted and cannot be repeated.");
  26. return;
  27. }
  28. match mount::mount_sysfs() {
  29. Ok(_) => {
  30. logger().info("mount", "sysfs mounted at '/sys'.");
  31. }
  32. Err(err) => {
  33. logger().fatal("mount", format!("mount sysfs error: {:?}", err).as_str());
  34. }
  35. }
  36. PREPARE_OK_SYSFS.store(true, Ordering::Relaxed);
  37. }
  38. pub fn mount_proc() {
  39. if PREPARE_OK_PROC.load(Ordering::Relaxed) {
  40. logger().warn("mount", "The proc is already mounted and cannot be repeated.");
  41. return;
  42. }
  43. match mount::mount_proc() {
  44. Ok(_) => {
  45. logger().info("mount", "sysfs mounted at '/sys'.");
  46. }
  47. Err(err) => {
  48. logger().fatal("mount", format!("mount sysfs error: {:?}", err).as_str());
  49. }
  50. }
  51. PREPARE_OK_PROC.store(true, Ordering::Relaxed);
  52. }
  53. pub fn mount_bootfs() {
  54. if PREPARE_OK_BOOTFS.load(Ordering::Relaxed) {
  55. logger().warn("mount", "The '/boot' is already mounted and cannot be repeated.");
  56. return;
  57. }
  58. let bootdev = env::get_bootdev();
  59. let bootfs = env::get_bootfs();
  60. logger().info("mount", format!("boot_device={}, fstype={}", bootdev, bootfs).as_str());
  61. match mount::mount_custom(Some(bootdev.as_str()), "/boot", Some(bootfs.as_str()), None, MsFlags::MS_RDONLY) {
  62. Ok(_) => {
  63. logger().info("mount", format!("dev '{}' ({}) mounted at '/boot'", bootdev, bootfs).as_str());
  64. }
  65. Err(err) => {
  66. logger().fatal("mount", format!("mount '/boot' error: {:?}", err).as_str());
  67. }
  68. }
  69. PREPARE_OK_BOOTFS.store(true, Ordering::Relaxed);
  70. }
  71. pub fn mount_temporary_devtmpfs() {
  72. if PREPARE_OK_TMP_DEVTMPFS.load(Ordering::Relaxed) {
  73. logger().warn("mount", "The devtmpfs for initrd temporary usage is already mounted and cannot be repeated.");
  74. return;
  75. }
  76. match mount::mount_devtmpfs("/dev","1M", "0755") {
  77. Ok(_) => {
  78. logger().info("mount", "devtmpfs mounted at '/dev'.");
  79. }
  80. Err(err) => {
  81. logger().fatal("mount", format!("mount devtmpfs for initrd temporary usage error: {:?}", err).as_str());
  82. }
  83. }
  84. PREPARE_OK_TMP_DEVTMPFS.store(true, Ordering::Relaxed);
  85. }
  86. pub fn mount_runfs(opt: &str) {
  87. if PREPARE_OK_RUNFS.load(Ordering::Relaxed) {
  88. logger().warn("mount", "The '/run' is already mounted and cannot be repeated.");
  89. return;
  90. }
  91. match mount::mount_runfs(opt) {
  92. Ok(_) => {
  93. logger().info("mount", "'/run' mounted.");
  94. }
  95. Err(err) => {
  96. logger().fatal("mount", format!("mount '/run' error: {:?}", err).as_str());
  97. }
  98. }
  99. PREPARE_OK_RUNFS.store(true, Ordering::Relaxed);
  100. }
  101. pub fn mount_runfs_from_cfg() {
  102. let opt = cfg::CFG.get().get_cfg().get_runfs_option();
  103. mount_runfs(opt.as_str())
  104. }
  105. pub fn move_sysfs(target: &str) {
  106. if PREPARE_OK_MOVE_SYSFS.load(Ordering::Relaxed) {
  107. logger().warn("mount", "The sysfs is already moved and cannot be repeated.");
  108. return;
  109. }
  110. mkdir_p(target);
  111. match mount::move_mount("/sys", target) {
  112. Ok(_) => {
  113. logger().info("mount", format!("sysfs mount point moved to '{}'.", target).as_str());
  114. }
  115. Err(err) => {
  116. logger().fatal("mount", format!("move sysfs mount error: {:?}", err).as_str());
  117. }
  118. }
  119. PREPARE_OK_MOVE_SYSFS.store(true, Ordering::Relaxed);
  120. }
  121. pub fn move_proc(target: &str) {
  122. if PREPARE_OK_MOVE_PROC.load(Ordering::Relaxed) {
  123. logger().warn("mount", "The proc is already moved and cannot be repeated.");
  124. return;
  125. }
  126. mkdir_p(target);
  127. match mount::move_mount("/proc", target) {
  128. Ok(_) => {
  129. logger().info("mount", format!("proc mount point moved to '{}'.", target).as_str());
  130. }
  131. Err(err) => {
  132. logger().fatal("mount", format!("move proc mount error: {:?}", err).as_str());
  133. }
  134. }
  135. PREPARE_OK_MOVE_PROC.store(true, Ordering::Relaxed);
  136. }
  137. pub fn move_bootfs(target: &str) {
  138. if PREPARE_OK_MOVE_BOOTFS.load(Ordering::Relaxed) {
  139. logger().warn("mount", "The '/boot' is already moved and cannot be repeated.");
  140. return;
  141. }
  142. mkdir_p(target);
  143. match mount::move_mount("/boot", target) {
  144. Ok(_) => {
  145. logger().info("mount", format!("'/boot' mount point moved to '{}'.", target).as_str());
  146. }
  147. Err(err) => {
  148. logger().fatal("mount", format!("move '/boot' mount error: {:?}", err).as_str());
  149. }
  150. }
  151. PREPARE_OK_MOVE_BOOTFS.store(true, Ordering::Relaxed);
  152. }
  153. pub fn move_temporary_devtmpfs(newroot: &str) {
  154. if PREPARE_OK_MOVE_TMP_DEVTMPFS.load(Ordering::Relaxed) {
  155. logger().warn("mount", "The temporary devtmpfs for initrd is already moved and cannot be repeated.");
  156. return;
  157. }
  158. if !PREPARE_OK_TMP_DEVTMPFS.load(Ordering::Relaxed) {
  159. logger().warn("mount", "The temporary devtmpfs for initrd has been never mounted.");
  160. return;
  161. }
  162. let move_target = format!("{}/mnt/old-dev", newroot);
  163. mkdir_p(move_target.as_str());
  164. match mount::move_mount("/dev", move_target.as_str()) {
  165. Ok(_) => {
  166. logger().info("mount", format!("'/dev' mount point moved to '{}'.", move_target).as_str());
  167. PREPARE_OK_MOVE_TMP_DEVTMPFS.store(true, Ordering::Relaxed);
  168. }
  169. Err(err) => {
  170. logger().warn("mount", format!("move '/dev' mount error: {:?}", err).as_str());
  171. }
  172. }
  173. }
  174. pub fn move_run(target: &str) {
  175. if PREPARE_OK_MOVE_RUNFS.load(Ordering::Relaxed) {
  176. logger().warn("mount", "The '/run' is already moved and cannot be repeated.");
  177. return;
  178. }
  179. mkdir_p(target);
  180. match mount::move_mount("/run", target) {
  181. Ok(_) => {
  182. logger().info("mount", format!("'/run' mount point moved to '{}'.", target).as_str());
  183. }
  184. Err(err) => {
  185. logger().fatal("mount", format!("move '/run' mount error: {:?}", err).as_str());
  186. }
  187. }
  188. PREPARE_OK_MOVE_RUNFS.store(true, Ordering::Relaxed);
  189. }
  190. pub fn turn_on_swap() {
  191. if PREPARE_OK_SWAPON.load(Ordering::Relaxed) {
  192. logger().warn("swap", "swap is already turned on and cannot be repeated.");
  193. return;
  194. }
  195. let swap_dev = cfg::CFG.get().get_cfg().get_swap_dev();
  196. match swap_dev {
  197. None => {
  198. logger().info("swap", "no swap specified in config file. ignored.")
  199. }
  200. Some(sw) => {
  201. logger().info("swap", format!("turn on swap on '{}'...", sw.as_str()).as_str());
  202. swap_on(sw.as_str());
  203. PREPARE_OK_SWAPON.store(true, Ordering::Relaxed);
  204. }
  205. }
  206. }