You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
3.7 KiB

  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. // Helper functions used to identify the boot device
  3. // adapted from /lib/functions.sh
  4. let cmdline_get_var = function(var) {
  5. let cmdline = fs.open("/proc/cmdline", "r");
  6. let allargs = cmdline.read("all");
  7. cmdline.close();
  8. let ret = null;
  9. for (let arg in split(allargs, /[ \t\n]/)) {
  10. let el = split(arg, "=");
  11. if (shift(el) == var)
  12. return join("=", el);
  13. }
  14. return ret;
  15. };
  16. // adapted from /lib/upgrade/common.sh
  17. let get_blockdevs = function() {
  18. let devs = [];
  19. for (let dev in fs.glob('/dev/*'))
  20. if (fs.stat(dev).type == "block")
  21. push(devs, split(dev, '/')[-1]);
  22. return devs;
  23. };
  24. // adapted from /lib/upgrade/common.sh
  25. let get_uevent_major_minor = function(file) {
  26. let uevf = fs.open(file, "r");
  27. if (!uevf)
  28. return null;
  29. let r = {};
  30. let evl;
  31. while ((evl = uevf.read("line"))) {
  32. let ev = split(evl, '=');
  33. if (ev[0] == "MAJOR")
  34. r.major = +ev[1];
  35. if (ev[0] == "MINOR")
  36. r.minor = +ev[1];
  37. }
  38. uevf.close();
  39. return r;
  40. };
  41. // adapted from /lib/upgrade/common.sh
  42. let get_bootdev = function(void) {
  43. let rootpart = cmdline_get_var("root");
  44. let uevent = null;
  45. if (wildcard(rootpart, "PARTUUID=[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9]")) {
  46. let uuidarg = split(substr(rootpart, 9), '-')[0];
  47. for (let bd in get_blockdevs()) {
  48. let bdf = fs.open(sprintf("/dev/%s", bd), "r");
  49. bdf.seek(440);
  50. let bduuid = bdf.read(4);
  51. bdf.close();
  52. if (uuidarg == sprintf("%x%x%x%x", ord(bduuid, 3), ord(bduuid, 2), ord(bduuid, 1), ord(bduuid, 0))) {
  53. uevent = sprintf("/sys/class/block/%s/uevent", bd);
  54. break;
  55. }
  56. }
  57. } else if (wildcard(rootpart, "PARTUUID=????????-????-????-????-??????????0?/PARTNROFF=*") ||
  58. wildcard(rootpart, "PARTUUID=????????-????-????-????-??????????02")) {
  59. let uuidarg = substr(split(substr(rootpart, 9), '/')[0], 0, -2) + "00";
  60. for (let bd in get_blockdevs()) {
  61. let bdf = fs.open(sprintf("/dev/%s", bd), "r");
  62. bdf.seek(568);
  63. let bduuid = bdf.read(16);
  64. bdf.close();
  65. if (!bduuid)
  66. continue;
  67. let uuid = sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  68. ord(bduuid, 3), ord(bduuid, 2), ord(bduuid, 1), ord(bduuid, 0),
  69. ord(bduuid, 5), ord(bduuid, 4),
  70. ord(bduuid, 7), ord(bduuid, 6),
  71. ord(bduuid, 8), ord(bduuid, 9),
  72. ord(bduuid, 10), ord(bduuid, 11), ord(bduuid, 12), ord(bduuid, 13), ord(bduuid, 14), ord(bduuid, 15));
  73. if (uuidarg == uuid) {
  74. uevent = sprintf("/sys/class/block/%s/uevent", bd);
  75. break;
  76. }
  77. }
  78. } else if (wildcard(rootpart, "0x[a-f0-9][a-f0-9][a-f0-9]") ||
  79. wildcard(rootpart, "0x[a-f0-9][a-f0-9][a-f0-9][a-f0-9]") ||
  80. wildcard(rootpart, "[a-f0-9][a-f0-9][a-f0-9]") ||
  81. wildcard(rootpart, "[a-f0-9][a-f0-9][a-f0-9][a-f0-9]")) {
  82. let devid = rootpart;
  83. if (substr(devid, 0, 2) == "0x")
  84. devid = substr(devid, 2);
  85. devid = hex(devid);
  86. for (let bd in get_blockdevs()) {
  87. let r = get_uevent_major_minor(sprintf("/sys/class/block/%s/uevent", bd));
  88. if (r && (r.major == devid / 256) && (r.minor == devid % 256)) {
  89. uevent = sprintf("/sys/class/block/%s/../uevent", bd);
  90. break;
  91. }
  92. }
  93. } else if (wildcard(rootpart, "/dev/*")) {
  94. uevent = sprintf("/sys/class/block/%s/../uevent", split(rootpart, '/')[-1]);
  95. }
  96. return get_uevent_major_minor(uevent);
  97. };
  98. // adapted from /lib/upgrade/common.sh
  99. let get_partition = function(dev, num) {
  100. if (!dev)
  101. return null;
  102. for (let bd in get_blockdevs()) {
  103. let r = get_uevent_major_minor(sprintf("/sys/class/block/%s/uevent", bd));
  104. if (r.major == dev.major && r.minor == dev.minor + num) {
  105. return bd;
  106. break;
  107. }
  108. }
  109. return null;
  110. };
  111. blockdev_common = {};
  112. blockdev_common.get_partition = get_partition;
  113. blockdev_common.get_bootdev = get_bootdev;