- // SPDX-License-Identifier: GPL-2.0-or-later
- // Helper functions used to identify the boot device
-
- // adapted from /lib/functions.sh
- let cmdline_get_var = function(var) {
- let cmdline = fs.open("/proc/cmdline", "r");
- let allargs = cmdline.read("all");
- cmdline.close();
- let ret = null;
- for (let arg in split(allargs, /[ \t\n]/)) {
- let el = split(arg, "=");
- if (shift(el) == var)
- return join("=", el);
- }
- return ret;
- };
-
- // adapted from /lib/upgrade/common.sh
- let get_blockdevs = function() {
- let devs = [];
- for (let dev in fs.glob('/dev/*'))
- if (fs.stat(dev).type == "block")
- push(devs, split(dev, '/')[-1]);
-
- return devs;
- };
-
- // adapted from /lib/upgrade/common.sh
- let get_uevent_major_minor = function(file) {
- let uevf = fs.open(file, "r");
- if (!uevf)
- return null;
-
- let r = {};
- let evl;
- while ((evl = uevf.read("line"))) {
- let ev = split(evl, '=');
- if (ev[0] == "MAJOR")
- r.major = +ev[1];
- if (ev[0] == "MINOR")
- r.minor = +ev[1];
- }
- uevf.close();
- return r;
- };
-
- // adapted from /lib/upgrade/common.sh
- let get_bootdev = function(void) {
- let rootpart = cmdline_get_var("root");
- let uevent = null;
-
- 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]")) {
- let uuidarg = split(substr(rootpart, 9), '-')[0];
- for (let bd in get_blockdevs()) {
- let bdf = fs.open(sprintf("/dev/%s", bd), "r");
- bdf.seek(440);
- let bduuid = bdf.read(4);
- bdf.close();
- if (uuidarg == sprintf("%x%x%x%x", ord(bduuid, 3), ord(bduuid, 2), ord(bduuid, 1), ord(bduuid, 0))) {
- uevent = sprintf("/sys/class/block/%s/uevent", bd);
- break;
- }
- }
- } else if (wildcard(rootpart, "PARTUUID=????????-????-????-????-??????????0?/PARTNROFF=*") ||
- wildcard(rootpart, "PARTUUID=????????-????-????-????-??????????02")) {
- let uuidarg = substr(split(substr(rootpart, 9), '/')[0], 0, -2) + "00";
- for (let bd in get_blockdevs()) {
- let bdf = fs.open(sprintf("/dev/%s", bd), "r");
- bdf.seek(568);
- let bduuid = bdf.read(16);
- bdf.close();
- if (!bduuid)
- continue;
-
- let uuid = sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- ord(bduuid, 3), ord(bduuid, 2), ord(bduuid, 1), ord(bduuid, 0),
- ord(bduuid, 5), ord(bduuid, 4),
- ord(bduuid, 7), ord(bduuid, 6),
- ord(bduuid, 8), ord(bduuid, 9),
- ord(bduuid, 10), ord(bduuid, 11), ord(bduuid, 12), ord(bduuid, 13), ord(bduuid, 14), ord(bduuid, 15));
-
- if (uuidarg == uuid) {
- uevent = sprintf("/sys/class/block/%s/uevent", bd);
- break;
- }
- }
- } else if (wildcard(rootpart, "0x[a-f0-9][a-f0-9][a-f0-9]") ||
- wildcard(rootpart, "0x[a-f0-9][a-f0-9][a-f0-9][a-f0-9]") ||
- wildcard(rootpart, "[a-f0-9][a-f0-9][a-f0-9]") ||
- wildcard(rootpart, "[a-f0-9][a-f0-9][a-f0-9][a-f0-9]")) {
- let devid = rootpart;
- if (substr(devid, 0, 2) == "0x")
- devid = substr(devid, 2);
-
- devid = hex(devid);
- for (let bd in get_blockdevs()) {
- let r = get_uevent_major_minor(sprintf("/sys/class/block/%s/uevent", bd));
- if (r && (r.major == devid / 256) && (r.minor == devid % 256)) {
- uevent = sprintf("/sys/class/block/%s/../uevent", bd);
- break;
- }
- }
- } else if (wildcard(rootpart, "/dev/*")) {
- uevent = sprintf("/sys/class/block/%s/../uevent", split(rootpart, '/')[-1]);
- }
- return get_uevent_major_minor(uevent);
- };
-
- // adapted from /lib/upgrade/common.sh
- let get_partition = function(dev, num) {
- if (!dev)
- return null;
-
- for (let bd in get_blockdevs()) {
- let r = get_uevent_major_minor(sprintf("/sys/class/block/%s/uevent", bd));
- if (r.major == dev.major && r.minor == dev.minor + num) {
- return bd;
- break;
- }
- }
- return null;
- };
-
- blockdev_common = {};
- blockdev_common.get_partition = get_partition;
- blockdev_common.get_bootdev = get_bootdev;
|