endef
define Package/uvol/install
- $(INSTALL_DIR) $(1)/etc/init.d $(1)/usr/uvol/backends $(1)/usr/sbin $(1)/etc/uci-defaults
+ $(INSTALL_DIR) $(1)/etc/init.d $(1)/usr/lib/uvol/backends $(1)/usr/sbin $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/uvol.init $(1)/etc/init.d/uvol
$(INSTALL_DATA) ./files/blockdev_common.uc $(1)/usr/lib/uvol/
$(INSTALL_DATA) ./files/uci.uc $(1)/usr/lib/uvol/
-{%
// 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]);
+// 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;
+};
- return devs;
- };
+// 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]);
- // adapted from /lib/upgrade/common.sh
- let get_uevent_major_minor = function(file) {
- let uevf = fs.open(file, "r");
- if (!uevf)
- return null;
+ return devs;
+};
- 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_uevent_major_minor = function(file) {
+ let uevf = fs.open(file, "r");
+ if (!uevf)
+ return null;
- // adapted from /lib/upgrade/common.sh
- let get_bootdev = function(void) {
- let rootpart = cmdline_get_var("root");
- let uevent = 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;
+};
- 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;
+// 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=*") ||
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);
+ 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));
- 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;
- }
+ if (uuidarg == uuid) {
+ 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);
- };
+ } 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);
- // adapted from /lib/upgrade/common.sh
- let get_partition = function(dev, num) {
+ devid = hex(devid);
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;
+ if (r && (r.major == devid / 256) && (r.minor == devid % 256)) {
+ uevent = sprintf("/sys/class/block/%s/../uevent", bd);
break;
}
}
- return null;
- };
+ } 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) {
+ 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;
-%}
+blockdev_common = {};
+blockdev_common.get_partition = get_partition;
+blockdev_common.get_bootdev = get_bootdev;
-{%
// SPDX-License-Identifier: GPL-2.0-or-later
// LVM2 backend for uvol
// (c) 2022 Daniel Golle <daniel@makrotopia.org>
// By setting the UCI option 'vg_name' in the 'uvol' section in /etc/config/fstab
// you may set an arbitrary LVM2 volume group to back uvol instad.
- let lvm_exec = "/sbin/lvm";
-
- function lvm(cmd, ...args) {
- let lvm_json_cmds = [ "lvs", "pvs", "vgs" ];
- try {
- let json_param = "";
- if (cmd in lvm_json_cmds)
- json_param = "--reportformat json --units b ";
- let stdout = fs.popen(sprintf("LVM_SUPPRESS_FD_WARNINGS=1 %s %s %s%s", lvm_exec, cmd, json_param, join(" ", args)));
- let tmp;
- if (stdout) {
- tmp = stdout.read("all");
- let ret = {};
- ret.retval = stdout.close();
- if (json_param) {
- let data = json(tmp);
- if (data.report)
- ret.report = data.report[0];
- } else {
- ret.stdout = trim(tmp);
- }
- return ret;
+let lvm_exec = "/sbin/lvm";
+
+function lvm(cmd, ...args) {
+ let lvm_json_cmds = [ "lvs", "pvs", "vgs" ];
+ try {
+ let json_param = "";
+ if (cmd in lvm_json_cmds)
+ json_param = "--reportformat json --units b ";
+ let stdout = fs.popen(sprintf("LVM_SUPPRESS_FD_WARNINGS=1 %s %s %s%s", lvm_exec, cmd, json_param, join(" ", args)));
+ let tmp;
+ if (stdout) {
+ tmp = stdout.read("all");
+ let ret = {};
+ ret.retval = stdout.close();
+ if (json_param) {
+ let data = json(tmp);
+ if (data.report)
+ ret.report = data.report[0];
} else {
- printf("lvm cli command failed: %s\n", fs.error());
+ ret.stdout = trim(tmp);
}
- } catch(e) {
- printf("Failed to parse lvm cli output: %s\n%s\n", e, e.stacktrace[0].context);
+ return ret;
+ } else {
+ printf("lvm cli command failed: %s\n", fs.error());
}
- return null;
+ } catch(e) {
+ printf("Failed to parse lvm cli output: %s\n%s\n", e, e.stacktrace[0].context);
}
+ return null;
+}
- function pvs() {
- let fstab = cursor.get_all('fstab');
- for (let k, section in fstab) {
- if (section['.type'] != 'uvol' || !section.vg_name)
- continue;
+function pvs() {
+ let fstab = cursor.get_all('fstab');
+ for (let k, section in fstab) {
+ if (section['.type'] != 'uvol' || !section.vg_name)
+ continue;
- return section.vg_name;
- }
- include("/usr/lib/uvol/blockdev_common.uc");
- let rootdev = blockdev_common.get_partition(blockdev_common.get_bootdev(), 0);
- let tmp = lvm("pvs", "-o", "vg_name", "-S", sprintf("\"pv_name=~^/dev/%s.*\$\"", rootdev));
- if (tmp.report.pv)
- return tmp.report.pv[0].vg_name;
- else
- return null;
+ return section.vg_name;
}
-
- function vgs(vg_name) {
- let tmp = lvm("vgs", "-o", "vg_extent_size,vg_extent_count,vg_free_count", "-S", sprintf("\"vg_name=%s\"", vg_name));
- let ret = null;
- if (tmp && tmp.report.vg) {
- ret = tmp.report.vg;
- for (let r in ret) {
- r.vg_extent_size = +(rtrim(r.vg_extent_size, "B"));
- r.vg_extent_count = +r.vg_extent_count;
- r.vg_free_count = +r.vg_free_count;
- }
+ include("/usr/lib/uvol/blockdev_common.uc");
+ let rootdev = blockdev_common.get_partition(blockdev_common.get_bootdev(), 0);
+ let tmp = lvm("pvs", "-o", "vg_name", "-S", sprintf("\"pv_name=~^/dev/%s.*\$\"", rootdev));
+ if (tmp.report.pv)
+ return tmp.report.pv[0].vg_name;
+ else
+ return null;
+}
+
+function vgs(vg_name) {
+ let tmp = lvm("vgs", "-o", "vg_extent_size,vg_extent_count,vg_free_count", "-S", sprintf("\"vg_name=%s\"", vg_name));
+ let ret = null;
+ if (tmp && tmp.report.vg) {
+ ret = tmp.report.vg;
+ for (let r in ret) {
+ r.vg_extent_size = +(rtrim(r.vg_extent_size, "B"));
+ r.vg_extent_count = +r.vg_extent_count;
+ r.vg_free_count = +r.vg_free_count;
}
- if (ret)
- return ret[0];
- else
- return null;
}
-
- function lvs(vg_name, vol_name, extra_exp) {
- let ret = [];
- if (!vol_name)
- vol_name = ".*";
-
- let lvexpr = sprintf("\"lvname=~^[rw][owp]_%s\$ && vg_name=%s%s%s\"",
- vol_name, vg_name, extra_exp?" && ":"", extra_exp?extra_exp:"");
- let tmp = lvm("lvs", "-o", "lv_active,lv_name,lv_full_name,lv_size,lv_path,lv_dm_path", "-S", lvexpr);
- if (tmp && tmp.report.lv) {
- ret = tmp.report.lv;
- for (let r in ret) {
- r.lv_size = +(rtrim(r.lv_size, "B"));
- r.lv_active = (r.lv_active == "active");
- }
+ if (ret)
+ return ret[0];
+ else
+ return null;
+}
+
+function lvs(vg_name, vol_name, extra_exp) {
+ let ret = [];
+ if (!vol_name)
+ vol_name = ".*";
+
+ let lvexpr = sprintf("\"lvname=~^[rw][owp]_%s\$ && vg_name=%s%s%s\"",
+ vol_name, vg_name, extra_exp?" && ":"", extra_exp?extra_exp:"");
+ let tmp = lvm("lvs", "-o", "lv_active,lv_name,lv_full_name,lv_size,lv_path,lv_dm_path", "-S", lvexpr);
+ if (tmp && tmp.report.lv) {
+ ret = tmp.report.lv;
+ for (let r in ret) {
+ r.lv_size = +(rtrim(r.lv_size, "B"));
+ r.lv_active = (r.lv_active == "active");
}
- return ret;
}
+ return ret;
+}
- function getdev(lv) {
- if (!lv)
- return null;
+function getdev(lv) {
+ if (!lv)
+ return null;
- for (let dms in fs.glob("/sys/devices/virtual/block/dm-*")) {
- let f = fs.open(sprintf("%s/dm/name", dms), "r");
- if (!f)
- continue;
+ for (let dms in fs.glob("/sys/devices/virtual/block/dm-*")) {
+ let f = fs.open(sprintf("%s/dm/name", dms), "r");
+ if (!f)
+ continue;
- let dm_name = trim(f.read("all"));
- f.close();
- if ( split(lv.lv_dm_path, '/')[-1] == dm_name )
- return split(dms, '/')[-1]
- }
- return null;
+ let dm_name = trim(f.read("all"));
+ f.close();
+ if ( split(lv.lv_dm_path, '/')[-1] == dm_name )
+ return split(dms, '/')[-1]
}
+ return null;
+}
- function lvm_init(ctx) {
- cursor = ctx.cursor;
- fs = ctx.fs;
- if (!fs.access(lvm_exec, "x"))
- return false;
-
- vg_name = pvs();
- if (!vg_name)
- return false;
-
- vg = vgs(vg_name);
- uvol_uci_add = ctx.uci_add;
- uvol_uci_commit = ctx.uci_commit;
- uvol_uci_remove = ctx.uci_remove;
- uvol_uci_init = ctx.uci_init;
- return true;
- }
+function lvm_init(ctx) {
+ cursor = ctx.cursor;
+ fs = ctx.fs;
+ if (!fs.access(lvm_exec, "x"))
+ return false;
- function lvm_free() {
- if (!vg || !vg.vg_free_count || !vg.vg_extent_size)
- return 2;
+ vg_name = pvs();
+ if (!vg_name)
+ return false;
- return sprintf("%d", vg.vg_free_count * vg.vg_extent_size);
- }
+ vg = vgs(vg_name);
+ uvol_uci_add = ctx.uci_add;
+ uvol_uci_commit = ctx.uci_commit;
+ uvol_uci_remove = ctx.uci_remove;
+ uvol_uci_init = ctx.uci_init;
+ return true;
+}
- function lvm_total() {
- if (!vg || !vg.vg_extent_count || !vg.vg_extent_size)
- return 2;
+function lvm_free() {
+ if (!vg || !vg.vg_free_count || !vg.vg_extent_size)
+ return 2;
- return sprintf("%d", vg.vg_extent_count * vg.vg_extent_size);
- }
+ return sprintf("%d", vg.vg_free_count * vg.vg_extent_size);
+}
- function lvm_align() {
- if (!vg || !vg.vg_extent_size)
- return 2;
+function lvm_total() {
+ if (!vg || !vg.vg_extent_count || !vg.vg_extent_size)
+ return 2;
- return sprintf("%d", vg.vg_extent_size);
- }
+ return sprintf("%d", vg.vg_extent_count * vg.vg_extent_size);
+}
- function lvm_list(vol_name) {
- let vols = [];
-
- if (!vg_name)
- return vols;
-
- let res = lvs(vg_name, vol_name);
- for (let lv in res) {
- let vol = {};
- if (substr(lv.lv_name, 3, 1) == ".")
- continue;
-
- vol.name = substr(lv.lv_name, 3);
- vol.mode = substr(lv.lv_name, 0, 2);
- if (!lv.lv_active) {
- if (vol.mode == "ro")
- vol.mode = "rd";
- if (vol.mode == "rw")
- vol.mode = "wd";
- }
- vol.size = lv.lv_size;
- push(vols, vol);
- }
+function lvm_align() {
+ if (!vg || !vg.vg_extent_size)
+ return 2;
- return vols;
- }
+ return sprintf("%d", vg.vg_extent_size);
+}
- function lvm_size(vol_name) {
- if (!vol_name || !vg_name)
- return 2;
+function lvm_list(vol_name) {
+ let vols = [];
- let res = lvs(vg_name, vol_name);
- if (!res[0])
- return 2;
+ if (!vg_name)
+ return vols;
- return sprintf("%d", res[0].lv_size);
+ let res = lvs(vg_name, vol_name);
+ for (let lv in res) {
+ let vol = {};
+ if (substr(lv.lv_name, 3, 1) == ".")
+ continue;
+
+ vol.name = substr(lv.lv_name, 3);
+ vol.mode = substr(lv.lv_name, 0, 2);
+ if (!lv.lv_active) {
+ if (vol.mode == "ro")
+ vol.mode = "rd";
+ if (vol.mode == "rw")
+ vol.mode = "wd";
+ }
+ vol.size = lv.lv_size;
+ push(vols, vol);
}
- function lvm_status(vol_name) {
- if (!vol_name || !vg_name)
- return 22;
+ return vols;
+}
- let res = lvs(vg_name, vol_name);
- if (!res[0])
- return 2;
+function lvm_size(vol_name) {
+ if (!vol_name || !vg_name)
+ return 2;
- let mode = substr(res[0].lv_name, 0, 2);
- if ((mode != "ro" && mode != "rw") || !res[0].lv_active)
- return 1;
+ let res = lvs(vg_name, vol_name);
+ if (!res[0])
+ return 2;
- return 0;
- }
+ return sprintf("%d", res[0].lv_size);
+}
- function lvm_device(vol_name) {
- if (!vol_name || !vg_name)
- return 22;
+function lvm_status(vol_name) {
+ if (!vol_name || !vg_name)
+ return 22;
- let res = lvs(vg_name, vol_name);
- if (!res[0])
- return 2;
+ let res = lvs(vg_name, vol_name);
+ if (!res[0])
+ return 2;
- let mode = substr(res[0].lv_name, 0, 2);
- if ((mode != "ro" && mode != "rw") || !res[0].lv_active)
- return 22;
+ let mode = substr(res[0].lv_name, 0, 2);
+ if ((mode != "ro" && mode != "rw") || !res[0].lv_active)
+ return 1;
- return getdev(res[0]);
- }
+ return 0;
+}
- function lvm_updown(vol_name, up) {
- if (!vol_name || !vg_name)
- return 22;
+function lvm_device(vol_name) {
+ if (!vol_name || !vg_name)
+ return 22;
- let res = lvs(vg_name, vol_name);
- if (!res[0])
- return 2;
+ let res = lvs(vg_name, vol_name);
+ if (!res[0])
+ return 2;
- let lv = res[0];
- if (!lv.lv_path)
- return 2;
+ let mode = substr(res[0].lv_name, 0, 2);
+ if ((mode != "ro" && mode != "rw") || !res[0].lv_active)
+ return 22;
- if (up && (wildcard(lv.lv_path, "/dev/*/wo_*") ||
- wildcard(lv.lv_path, "/dev/*/wp_*")))
- return 22;
+ return getdev(res[0]);
+}
- if (up)
- uvol_uci_commit(vol_name);
+function lvm_updown(vol_name, up) {
+ if (!vol_name || !vg_name)
+ return 22;
- if (lv.lv_active == up)
- return 0;
+ let res = lvs(vg_name, vol_name);
+ if (!res[0])
+ return 2;
- if (!up) {
- let devname = getdev(lv);
- if (devname)
- system(sprintf("umount /dev/%s", devname));
- }
+ let lv = res[0];
+ if (!lv.lv_path)
+ return 2;
- let lvchange_r = lvm("lvchange", up?"-k":"-a", "n", lv.lv_full_name);
- if (up && lvchange_r.retval != 0)
- return lvchange_r.retval;
+ if (up && (wildcard(lv.lv_path, "/dev/*/wo_*") ||
+ wildcard(lv.lv_path, "/dev/*/wp_*")))
+ return 22;
- lvchange_r = lvm("lvchange", up?"-a":"-k", "y", lv.lv_full_name);
- if (lvchange_r.retval != 0)
- return lvchange_r.retval;
+ if (up)
+ uvol_uci_commit(vol_name);
- return 0
- }
+ if (lv.lv_active == up)
+ return 0;
- function lvm_up(vol_name) {
- return lvm_updown(vol_name, true);
+ if (!up) {
+ let devname = getdev(lv);
+ if (devname)
+ system(sprintf("umount /dev/%s", devname));
}
- function lvm_down(vol_name) {
- return lvm_updown(vol_name, false);
+ let lvchange_r = lvm("lvchange", up?"-k":"-a", "n", lv.lv_full_name);
+ if (up && lvchange_r.retval != 0)
+ return lvchange_r.retval;
+
+ lvchange_r = lvm("lvchange", up?"-a":"-k", "y", lv.lv_full_name);
+ if (lvchange_r.retval != 0)
+ return lvchange_r.retval;
+
+ return 0
+}
+
+function lvm_up(vol_name) {
+ return lvm_updown(vol_name, true);
+}
+
+function lvm_down(vol_name) {
+ return lvm_updown(vol_name, false);
+}
+
+function lvm_create(vol_name, vol_size, vol_mode) {
+ if (!vol_name || !vg_name)
+ return 22;
+
+ vol_size = +vol_size;
+ if (vol_size <= 0)
+ return 22;
+
+ let res = lvs(vg_name, vol_name);
+ if (res[0])
+ return 17;
+
+ let size_ext = vol_size / vg.vg_extent_size;
+ if (vol_size % vg.vg_extent_size)
+ ++size_ext;
+ let lvmode, mode;
+ if (vol_mode == "ro" || vol_mode == "wo") {
+ lvmode = "r";
+ mode = "wo";
+ } else if (vol_mode == "rw") {
+ lvmode = "rw";
+ mode = "wp";
+ } else {
+ return 22;
}
- function lvm_create(vol_name, vol_size, vol_mode) {
- if (!vol_name || !vg_name)
- return 22;
-
- vol_size = +vol_size;
- if (vol_size <= 0)
- return 22;
-
- let res = lvs(vg_name, vol_name);
- if (res[0])
- return 17;
-
- let size_ext = vol_size / vg.vg_extent_size;
- if (vol_size % vg.vg_extent_size)
- ++size_ext;
- let lvmode, mode;
- if (vol_mode == "ro" || vol_mode == "wo") {
- lvmode = "r";
- mode = "wo";
- } else if (vol_mode == "rw") {
- lvmode = "rw";
- mode = "wp";
- } else {
- return 22;
+ let ret = lvm("lvcreate", "-p", lvmode, "-a", "n", "-y", "-W", "n", "-Z", "n", "-n", sprintf("%s_%s", mode, vol_name), "-l", size_ext, vg_name);
+ if (ret.retval != 0 || lvmode == "r")
+ return ret.retval;
+
+ let lv = lvs(vg_name, vol_name);
+ if (!lv[0] || !lv[0].lv_full_name)
+ return 22;
+
+ lv = lv[0];
+ let ret = lvm("lvchange", "-a", "y", lv.lv_full_name);
+ if (ret.retval != 0)
+ return ret.retval;
+
+ let use_f2fs = (lv.lv_size > (100 * 1024 * 1024));
+ if (use_f2fs) {
+ let mkfs_ret = system(sprintf("/usr/sbin/mkfs.f2fs -f -l \"%s\" \"%s\"", vol_name, lv.lv_path));
+ if (mkfs_ret != 0 && mkfs_ret != 134) {
+ lvchange_r = lvm("lvchange", "-a", "n", lv.lv_full_name);
+ if (lvchange_r.retval != 0)
+ return lvchange_r.retval;
+ return mkfs_ret;
}
+ } else {
+ let mkfs_ret = system(sprintf("/usr/sbin/mke2fs -F -L \"%s\" \"%s\"", vol_name, lv.lv_path));
+ if (mkfs_ret != 0) {
+ lvchange_r = lvm("lvchange", "-a", "n", lv.lv_full_name);
+ if (lvchange_r.retval != 0)
+ return lvchange_r.retval;
+ return mkfs_ret;
+ }
+ }
+ uvol_uci_add(vol_name, sprintf("/dev/%s", getdev(lv)), "rw");
+
+ ret = lvm("lvchange", "-a", "n", lv.lv_full_name);
+ if (ret.retval != 0)
+ return ret.retval;
+
+ ret = lvm("lvrename", vg_name, sprintf("wp_%s", vol_name), sprintf("rw_%s", vol_name));
+ if (ret.retval != 0)
+ return ret.retval;
+
+ return 0;
+}
+
+function lvm_remove(vol_name) {
+ if (!vol_name || !vg_name)
+ return 22;
+
+ let res = lvs(vg_name, vol_name);
+ if (!res[0])
+ return 2;
+
+ if (res[0].lv_active)
+ return 16;
+
+ let ret = lvm("lvremove", "-y", res[0].lv_full_name);
+ if (ret.retval != 0)
+ return ret.retval;
+
+ uvol_uci_remove(vol_name);
+ uvol_uci_commit(vol_name);
+ return 0;
+}
+
+function lvm_dd(in_fd, out_fd, vol_size) {
+ let rem = vol_size;
+ let buf;
+ while ((buf = in_fd.read(vg.vg_extent_size)) && (rem > 0)) {
+ rem -= length(buf);
+ if (rem < 0) {
+ buf = substr(buf, 0, rem);
+ }
+ out_fd.write(buf);
+ }
+ return rem;
+}
- let ret = lvm("lvcreate", "-p", lvmode, "-a", "n", "-y", "-W", "n", "-Z", "n", "-n", sprintf("%s_%s", mode, vol_name), "-l", size_ext, vg_name);
- if (ret.retval != 0 || lvmode == "r")
- return ret.retval;
+function lvm_write(vol_name, vol_size) {
+ if (!vol_name || !vg_name)
+ return 22;
- let lv = lvs(vg_name, vol_name);
- if (!lv[0] || !lv[0].lv_full_name)
- return 22;
+ let lv = lvs(vg_name, vol_name);
+ if (!lv[0] || !lv[0].lv_full_name)
+ return 2;
- lv = lv[0];
- let ret = lvm("lvchange", "-a", "y", lv.lv_full_name);
- if (ret.retval != 0)
- return ret.retval;
+ lv = lv[0];
+ vol_size = +vol_size;
+ if (vol_size > lv.lv_size)
+ return 27;
- let use_f2fs = (lv.lv_size > (100 * 1024 * 1024));
- if (use_f2fs) {
- let mkfs_ret = system(sprintf("/usr/sbin/mkfs.f2fs -f -l \"%s\" \"%s\"", vol_name, lv.lv_path));
- if (mkfs_ret != 0 && mkfs_ret != 134) {
- lvchange_r = lvm("lvchange", "-a", "n", lv.lv_full_name);
- if (lvchange_r.retval != 0)
- return lvchange_r.retval;
- return mkfs_ret;
- }
- } else {
- let mkfs_ret = system(sprintf("/usr/sbin/mke2fs -F -L \"%s\" \"%s\"", vol_name, lv.lv_path));
- if (mkfs_ret != 0) {
- lvchange_r = lvm("lvchange", "-a", "n", lv.lv_full_name);
- if (lvchange_r.retval != 0)
- return lvchange_r.retval;
- return mkfs_ret;
- }
- }
- uvol_uci_add(vol_name, sprintf("/dev/%s", getdev(lv)), "rw");
-
- ret = lvm("lvchange", "-a", "n", lv.lv_full_name);
+ if (wildcard(lv.lv_path, "/dev/*/wo_*")) {
+ let ret = lvm("lvchange", "-p", "rw", lv.lv_full_name);
if (ret.retval != 0)
return ret.retval;
- ret = lvm("lvrename", vg_name, sprintf("wp_%s", vol_name), sprintf("rw_%s", vol_name));
+ let ret = lvm("lvchange", "-a", "y", lv.lv_full_name);
if (ret.retval != 0)
return ret.retval;
- return 0;
- }
+ let volfile = fs.open(lv.lv_path, "w");
+ let ret = lvm_dd(fs.stdin, volfile, vol_size);
+ volfile.close();
+ if (ret < 0) {
+ printf("more %d bytes data than given size!\n", -ret);
+ }
- function lvm_remove(vol_name) {
- if (!vol_name || !vg_name)
- return 22;
+ if (ret > 0) {
+ printf("reading finished %d bytes before given size!\n", ret);
+ }
- let res = lvs(vg_name, vol_name);
- if (!res[0])
- return 2;
+ uvol_uci_add(vol_name, sprintf("/dev/%s", getdev(lv)), "ro");
- if (res[0].lv_active)
- return 16;
+ let ret = lvm("lvchange", "-a", "n", lv.lv_full_name);
+ if (ret.retval != 0)
+ return ret.retval;
- let ret = lvm("lvremove", "-y", res[0].lv_full_name);
+ let ret = lvm("lvchange", "-p", "r", lv.lv_full_name);
if (ret.retval != 0)
return ret.retval;
- uvol_uci_remove(vol_name);
- uvol_uci_commit(vol_name);
- return 0;
- }
+ let ret = lvm("lvrename", vg_name, sprintf("wo_%s", vol_name), sprintf("ro_%s", vol_name));
+ if (ret.retval != 0)
+ return ret.retval;
- function lvm_dd(in_fd, out_fd, vol_size) {
- let rem = vol_size;
- let buf;
- while ((buf = in_fd.read(vg.vg_extent_size)) && (rem > 0)) {
- rem -= length(buf);
- if (rem < 0) {
- buf = substr(buf, 0, rem);
- }
- out_fd.write(buf);
- }
- return rem;
+ } else {
+ return 22;
}
-
- function lvm_write(vol_name, vol_size) {
- if (!vol_name || !vg_name)
- return 22;
-
- let lv = lvs(vg_name, vol_name);
- if (!lv[0] || !lv[0].lv_full_name)
- return 2;
-
- lv = lv[0];
- vol_size = +vol_size;
- if (vol_size > lv.lv_size)
- return 27;
-
- if (wildcard(lv.lv_path, "/dev/*/wo_*")) {
- let ret = lvm("lvchange", "-p", "rw", lv.lv_full_name);
- if (ret.retval != 0)
- return ret.retval;
-
- let ret = lvm("lvchange", "-a", "y", lv.lv_full_name);
- if (ret.retval != 0)
- return ret.retval;
-
- let volfile = fs.open(lv.lv_path, "w");
- let ret = lvm_dd(fs.stdin, volfile, vol_size);
- volfile.close();
- if (ret < 0) {
- printf("more %d bytes data than given size!\n", -ret);
- }
-
- if (ret > 0) {
- printf("reading finished %d bytes before given size!\n", ret);
- }
-
- uvol_uci_add(vol_name, sprintf("/dev/%s", getdev(lv)), "ro");
-
- let ret = lvm("lvchange", "-a", "n", lv.lv_full_name);
- if (ret.retval != 0)
- return ret.retval;
-
- let ret = lvm("lvchange", "-p", "r", lv.lv_full_name);
- if (ret.retval != 0)
- return ret.retval;
-
- let ret = lvm("lvrename", vg_name, sprintf("wo_%s", vol_name), sprintf("ro_%s", vol_name));
- if (ret.retval != 0)
- return ret.retval;
-
- } else {
- return 22;
- }
- return 0;
+ return 0;
+}
+
+function lvm_detect() {
+ let temp_up = [];
+ let inactive_lv = lvs(vg_name, null, "lv_skip_activation!=0");
+ for (let lv in inactive_lv) {
+ lvm("lvchange", "-k", "n", lv.lv_full_name);
+ lvm("lvchange", "-a", "y", lv.lv_full_name);
+ push(temp_up, lv.lv_full_name);
}
-
- function lvm_detect() {
- let temp_up = [];
- let inactive_lv = lvs(vg_name, null, "lv_skip_activation!=0");
- for (let lv in inactive_lv) {
- lvm("lvchange", "-k", "n", lv.lv_full_name);
- lvm("lvchange", "-a", "y", lv.lv_full_name);
- push(temp_up, lv.lv_full_name);
- }
- sleep(1000);
- uvol_uci_init();
- for (let lv in lvs(vg_name)) {
- let vol_name = substr(lv.lv_name, 3);
- let vol_mode = substr(lv.lv_name, 0, 2);
- uvol_uci_add(vol_name, sprintf("/dev/%s", getdev(lv)), vol_mode);
- }
- uvol_uci_commit();
- for (let lv_full_name in temp_up) {
- lvm("lvchange", "-a", "n", lv_full_name);
- lvm("lvchange", "-k", "y", lv_full_name);
- }
- return 0;
+ sleep(1000);
+ uvol_uci_init();
+ for (let lv in lvs(vg_name)) {
+ let vol_name = substr(lv.lv_name, 3);
+ let vol_mode = substr(lv.lv_name, 0, 2);
+ uvol_uci_add(vol_name, sprintf("/dev/%s", getdev(lv)), vol_mode);
}
-
- function lvm_boot() {
- return 0;
+ uvol_uci_commit();
+ for (let lv_full_name in temp_up) {
+ lvm("lvchange", "-a", "n", lv_full_name);
+ lvm("lvchange", "-k", "y", lv_full_name);
}
-
- backend.backend = "LVM";
- backend.priority = 50;
- backend.init = lvm_init;
- backend.boot = lvm_boot;
- backend.detect = lvm_detect;
- backend.free = lvm_free;
- backend.align = lvm_align;
- backend.total = lvm_total;
- backend.list = lvm_list;
- backend.size = lvm_size;
- backend.status = lvm_status;
- backend.device = lvm_device;
- backend.up = lvm_up;
- backend.down = lvm_down;
- backend.create = lvm_create;
- backend.remove = lvm_remove;
- backend.write = lvm_write;
-%}
+ return 0;
+}
+
+function lvm_boot() {
+ return 0;
+}
+
+backend.backend = "LVM";
+backend.priority = 50;
+backend.init = lvm_init;
+backend.boot = lvm_boot;
+backend.detect = lvm_detect;
+backend.free = lvm_free;
+backend.align = lvm_align;
+backend.total = lvm_total;
+backend.list = lvm_list;
+backend.size = lvm_size;
+backend.status = lvm_status;
+backend.device = lvm_device;
+backend.up = lvm_up;
+backend.down = lvm_down;
+backend.create = lvm_create;
+backend.remove = lvm_remove;
+backend.write = lvm_write;
-{%
// SPDX-License-Identifier: GPL-2.0-or-later
// UBI backend for uvol
// (c) 2022 Daniel Golle <daniel@makrotopia.org>
//
// This plugin uses UBI on NAND flash as a storage backend for uvol.
- function read_file(file) {
- let fp = fs.open(file);
- if (!fp)
- return null;
-
- let var = rtrim(fp.read("all"));
- fp.close();
- return var;
- }
-
- function mkdtemp() {
- math = require("math");
- let r1 = math.rand();
- let r2 = math.rand();
- let randbytes = chr((r1 >> 24) & 0xff, (r1 >> 16) & 0xff, (r1 >> 8) & 0xff, r1 & 0xff,
- (r2 >> 24) & 0xff, (r2 >> 16) & 0xff, (r2 >> 8) & 0xff, r2 & 0xff);
-
- let randstr = replace(b64enc(randbytes), /[\/-_.=]/g, "");
- let dirname = sprintf("/tmp/uvol-%s", randstr);
- fs.mkdir(dirname, 0700);
- return dirname;
- }
-
- function ubi_get_dev(vol_name) {
- let wcstring = sprintf("uvol-[rw][owpd]-%s", vol_name);
- for (vol_dir in fs.glob(sprintf("/sys/devices/virtual/ubi/%s/%s_*", ubidev, ubidev))) {
- let vol_ubiname = read_file(sprintf("%s/name", vol_dir));
- if (wildcard(vol_ubiname, wcstring))
- return fs.basename(vol_dir);
- }
+function read_file(file) {
+ let fp = fs.open(file);
+ if (!fp)
return null;
- }
- function vol_get_mode(vol_dev, mode) {
- let vol_name = read_file(sprintf("/sys/devices/virtual/ubi/%s/%s/name", ubidev, vol_dev));
- return substr(vol_name, 5, 2);
+ let var = rtrim(fp.read("all"));
+ fp.close();
+ return var;
+}
+
+function mkdtemp() {
+ math = require("math");
+ let r1 = math.rand();
+ let r2 = math.rand();
+ let randbytes = chr((r1 >> 24) & 0xff, (r1 >> 16) & 0xff, (r1 >> 8) & 0xff, r1 & 0xff,
+ (r2 >> 24) & 0xff, (r2 >> 16) & 0xff, (r2 >> 8) & 0xff, r2 & 0xff);
+
+ let randstr = replace(b64enc(randbytes), /[\/-_.=]/g, "");
+ let dirname = sprintf("/tmp/uvol-%s", randstr);
+ fs.mkdir(dirname, 0700);
+ return dirname;
+}
+
+function ubi_get_dev(vol_name) {
+ let wcstring = sprintf("uvol-[rw][owpd]-%s", vol_name);
+ for (vol_dir in fs.glob(sprintf("/sys/devices/virtual/ubi/%s/%s_*", ubidev, ubidev))) {
+ let vol_ubiname = read_file(sprintf("%s/name", vol_dir));
+ if (wildcard(vol_ubiname, wcstring))
+ return fs.basename(vol_dir);
}
-
- function mkubifs(vol_dev) {
- let temp_mp = mkdtemp();
- system(sprintf("mount -t ubifs /dev/%s %s", vol_dev, temp_mp));
- system(sprintf("umount %s", temp_mp));
- fs.rmdir(temp_mp);
+ return null;
+}
+
+function vol_get_mode(vol_dev, mode) {
+ let vol_name = read_file(sprintf("/sys/devices/virtual/ubi/%s/%s/name", ubidev, vol_dev));
+ return substr(vol_name, 5, 2);
+}
+
+function mkubifs(vol_dev) {
+ let temp_mp = mkdtemp();
+ system(sprintf("mount -t ubifs /dev/%s %s", vol_dev, temp_mp));
+ system(sprintf("umount %s", temp_mp));
+ fs.rmdir(temp_mp);
+ return 0;
+}
+
+function block_hotplug(action, devname) {
+ return system(sprintf("ACTION=%s DEVNAME=%s /sbin/block hotplug", action, devname));
+}
+
+function ubi_init(ctx) {
+ cursor = ctx.cursor;
+ fs = ctx.fs;
+
+ let ubiver = read_file("/sys/class/ubi/version");
+ if (ubiver != 1)
+ return false;
+
+ let ubidevpath = null;
+ for (ubidevpath in fs.glob("/sys/devices/virtual/ubi/*"))
+ break;
+
+ if (!ubidevpath)
+ return false;
+
+ ubidev = fs.basename(ubidevpath);
+ ebsize = read_file(sprintf("%s/eraseblock_size", ubidevpath));
+
+ uvol_uci_add = ctx.uci_add;
+ uvol_uci_commit = ctx.uci_commit;
+ uvol_uci_remove = ctx.uci_remove;
+ uvol_uci_init = ctx.uci_init;
+
+ return true;
+}
+
+function ubi_free() {
+ let availeb = read_file(sprintf("/sys/devices/virtual/ubi/%s/avail_eraseblocks", ubidev));
+ return sprintf("%d", availeb * ebsize);
+}
+
+function ubi_align() {
+ return sprintf("%d", ebsize);
+}
+
+function ubi_total() {
+ let totaleb = read_file(sprintf("/sys/devices/virtual/ubi/%s/total_eraseblocks", ubidev));
+ return sprintf("%d", totaleb * ebsize);
+}
+
+function ubi_status(vol_name) {
+ let vol_dev = ubi_get_dev(vol_name);
+ if (!vol_dev)
+ return 2;
+
+ let vol_mode = vol_get_mode(vol_dev);
+ if (vol_mode == "wo") return 22;
+ if (vol_mode == "wp") return 16;
+ if (vol_mode == "wd") return 1;
+ if (vol_mode == "ro" &&
+ !fs.access(sprintf("/dev/ubiblock%s", substr(vol_dev, 3)), "r")) return 1;
+
+ return 0;
+}
+
+function ubi_size(vol_name) {
+ let vol_dev = ubi_get_dev(vol_name);
+ if (!vol_dev)
+ return 2;
+
+ let vol_size = read_file(sprintf("/sys/devices/virtual/ubi/%s/%s/data_bytes", ubidev, vol_dev));
+ return sprintf("%d", vol_size);
+}
+
+function ubi_device(vol_name) {
+ let vol_dev = ubi_get_dev(vol_name);
+ if (!vol_dev)
+ return 2;
+
+ let vol_mode = vol_get_mode(vol_dev);
+ if (vol_mode == "ro")
+ return sprintf("/dev/ubiblock%s", substr(vol_dev, 3));
+ else if (vol_mode == "rw")
+ return sprintf("/dev/%s", vol_dev);
+
+ return null;
+}
+
+function ubi_create(vol_name, vol_size, vol_mode) {
+ let vol_dev = ubi_get_dev(vol_name);
+ if (vol_dev)
+ return 17;
+
+ let mode;
+ if (vol_mode == "ro" || vol_mode == "wo")
+ mode = "wo";
+ else if (vol_mode == "rw")
+ mode = "wp";
+ else
+ return 22;
+
+ let vol_size = +vol_size;
+ if (vol_size <= 0)
+ return 22;
+ let ret = system(sprintf("ubimkvol /dev/%s -N \"uvol-%s-%s\" -s %d", ubidev, mode, vol_name, vol_size));
+ if (ret != 0)
+ return ret;
+
+ let vol_dev = ubi_get_dev(vol_name);
+ if (!vol_dev)
+ return 2;
+
+ let ret = system(sprintf("ubiupdatevol -t /dev/%s", vol_dev));
+ if (ret != 0)
+ return ret;
+
+ if (mode != "wp")
return 0;
- }
- function block_hotplug(action, devname) {
- return system(sprintf("ACTION=%s DEVNAME=%s /sbin/block hotplug", action, devname));
- }
+ let ret = mkubifs(vol_dev);
+ if (ret != 0)
+ return ret;
- function ubi_init(ctx) {
- cursor = ctx.cursor;
- fs = ctx.fs;
+ uvol_uci_add(vol_name, sprintf("/dev/%s", vol_dev), "rw");
- let ubiver = read_file("/sys/class/ubi/version");
- if (ubiver != 1)
- return false;
+ let ret = system(sprintf("ubirename /dev/%s \"uvol-wp-%s\" \"uvol-wd-%s\"", ubidev, vol_name, vol_name));
+ if (ret != 0)
+ return ret;
- let ubidevpath = null;
- for (ubidevpath in fs.glob("/sys/devices/virtual/ubi/*"))
- break;
+ return 0;
+}
- if (!ubidevpath)
- return false;
+function ubi_remove(vol_name) {
+ let vol_dev = ubi_get_dev(vol_name);
+ if (!vol_dev)
+ return 2;
- ubidev = fs.basename(ubidevpath);
- ebsize = read_file(sprintf("%s/eraseblock_size", ubidevpath));
+ let vol_mode = vol_get_mode(vol_dev);
+ if (vol_mode == "rw" || vol_mode == "ro")
+ return 16;
- uvol_uci_add = ctx.uci_add;
- uvol_uci_commit = ctx.uci_commit;
- uvol_uci_remove = ctx.uci_remove;
- uvol_uci_init = ctx.uci_init;
+ let volnum = split(vol_dev, "_")[1];
- return true;
- }
-
- function ubi_free() {
- let availeb = read_file(sprintf("/sys/devices/virtual/ubi/%s/avail_eraseblocks", ubidev));
- return sprintf("%d", availeb * ebsize);
- }
-
- function ubi_align() {
- return sprintf("%d", ebsize);
- }
+ let ret = system(sprintf("ubirmvol /dev/%s -n %d", ubidev, volnum));
+ if (ret != 0)
+ return ret;
- function ubi_total() {
- let totaleb = read_file(sprintf("/sys/devices/virtual/ubi/%s/total_eraseblocks", ubidev));
- return sprintf("%d", totaleb * ebsize);
- }
+ uvol_uci_remove(vol_name);
+ uvol_uci_commit(vol_name);
- function ubi_status(vol_name) {
- let vol_dev = ubi_get_dev(vol_name);
- if (!vol_dev)
- return 2;
+ return 0;
+}
- let vol_mode = vol_get_mode(vol_dev);
- if (vol_mode == "wo") return 22;
- if (vol_mode == "wp") return 16;
- if (vol_mode == "wd") return 1;
- if (vol_mode == "ro" &&
- !fs.access(sprintf("/dev/ubiblock%s", substr(vol_dev, 3)), "r")) return 1;
+function ubi_up(vol_name) {
+ let vol_dev = ubi_get_dev(vol_name);
+ if (!vol_dev)
+ return 2;
+ let vol_mode = vol_get_mode(vol_dev);
+ if (vol_mode == "rw" || vol_mode == "ro")
return 0;
- }
-
- function ubi_size(vol_name) {
- let vol_dev = ubi_get_dev(vol_name);
- if (!vol_dev)
- return 2;
-
- let vol_size = read_file(sprintf("/sys/devices/virtual/ubi/%s/%s/data_bytes", ubidev, vol_dev));
- return sprintf("%d", vol_size);
- }
-
- function ubi_device(vol_name) {
- let vol_dev = ubi_get_dev(vol_name);
- if (!vol_dev)
- return 2;
-
- let vol_mode = vol_get_mode(vol_dev);
- if (vol_mode == "ro")
- return sprintf("/dev/ubiblock%s", substr(vol_dev, 3));
- else if (vol_mode == "rw")
- return sprintf("/dev/%s", vol_dev);
-
- return null;
- }
-
- function ubi_create(vol_name, vol_size, vol_mode) {
- let vol_dev = ubi_get_dev(vol_name);
- if (vol_dev)
- return 17;
-
- let mode;
- if (vol_mode == "ro" || vol_mode == "wo")
- mode = "wo";
- else if (vol_mode == "rw")
- mode = "wp";
- else
- return 22;
-
- let vol_size = +vol_size;
- if (vol_size <= 0)
- return 22;
- let ret = system(sprintf("ubimkvol /dev/%s -N \"uvol-%s-%s\" -s %d", ubidev, mode, vol_name, vol_size));
+ else if (vol_mode == "wo")
+ return 22;
+ else if (vol_mode == "wp")
+ return 16;
+
+ uvol_uci_commit(vol_name);
+ if (vol_mode == "rd") {
+ let ret = system(sprintf("ubirename /dev/%s \"uvol-rd-%s\" \"uvol-ro-%s\"", ubidev, vol_name, vol_name));
if (ret != 0)
return ret;
- let vol_dev = ubi_get_dev(vol_name);
- if (!vol_dev)
- return 2;
-
- let ret = system(sprintf("ubiupdatevol -t /dev/%s", vol_dev));
- if (ret != 0)
- return ret;
-
- if (mode != "wp")
- return 0;
-
- let ret = mkubifs(vol_dev);
- if (ret != 0)
- return ret;
-
- uvol_uci_add(vol_name, sprintf("/dev/%s", vol_dev), "rw");
-
- let ret = system(sprintf("ubirename /dev/%s \"uvol-wp-%s\" \"uvol-wd-%s\"", ubidev, vol_name, vol_name));
+ return system(sprintf("ubiblock --create /dev/%s", vol_dev));
+ } else if (vol_mode == "wd") {
+ let ret = system(sprintf("ubirename /dev/%s \"uvol-wd-%s\" \"uvol-rw-%s\"", ubidev, vol_name, vol_name));
if (ret != 0)
return ret;
- return 0;
+ return block_hotplug("add", vol_dev);
}
+ return 0;
+}
- function ubi_remove(vol_name) {
- let vol_dev = ubi_get_dev(vol_name);
- if (!vol_dev)
- return 2;
-
- let vol_mode = vol_get_mode(vol_dev);
- if (vol_mode == "rw" || vol_mode == "ro")
- return 16;
-
- let volnum = split(vol_dev, "_")[1];
-
- let ret = system(sprintf("ubirmvol /dev/%s -n %d", ubidev, volnum));
- if (ret != 0)
- return ret;
-
- uvol_uci_remove(vol_name);
- uvol_uci_commit(vol_name);
+function ubi_down(vol_name) {
+ let vol_dev = ubi_get_dev(vol_name);
+ if (!vol_dev)
+ return 2;
+ let vol_mode = vol_get_mode(vol_dev);
+ if (vol_mode == "rd" || vol_mode == "wd")
return 0;
+ else if (vol_mode == "wo")
+ return 22;
+ else if (vol_mode == "wp")
+ return 16;
+ else if (vol_mode == "ro") {
+ system(sprintf("umount /dev/ubiblock%s 2>&1 >/dev/null", substr(vol_dev, 3)));
+ system(sprintf("ubiblock --remove /dev/%s", vol_dev));
+ let ret = system(sprintf("ubirename /dev/%s \"uvol-ro-%s\" \"uvol-rd-%s\"", ubidev, vol_name, vol_name));
+ return ret;
+ } else if (vol_mode == "rw") {
+ system(sprintf("umount /dev/%s 2>&1 >/dev/null", vol_dev));
+ let ret = system(sprintf("ubirename /dev/%s \"uvol-rw-%s\" \"uvol-wd-%s\"", ubidev, vol_name, vol_name));
+ block_hotplug("remove", vol_dev);
+ return ret;
}
-
- function ubi_up(vol_name) {
- let vol_dev = ubi_get_dev(vol_name);
- if (!vol_dev)
- return 2;
-
- let vol_mode = vol_get_mode(vol_dev);
- if (vol_mode == "rw" || vol_mode == "ro")
- return 0;
- else if (vol_mode == "wo")
- return 22;
- else if (vol_mode == "wp")
- return 16;
-
- uvol_uci_commit(vol_name);
- if (vol_mode == "rd") {
- let ret = system(sprintf("ubirename /dev/%s \"uvol-rd-%s\" \"uvol-ro-%s\"", ubidev, vol_name, vol_name));
- if (ret != 0)
- return ret;
-
- return system(sprintf("ubiblock --create /dev/%s", vol_dev));
- } else if (vol_mode == "wd") {
- let ret = system(sprintf("ubirename /dev/%s \"uvol-wd-%s\" \"uvol-rw-%s\"", ubidev, vol_name, vol_name));
- if (ret != 0)
- return ret;
-
- return block_hotplug("add", vol_dev);
- }
- return 0;
- }
-
- function ubi_down(vol_name) {
- let vol_dev = ubi_get_dev(vol_name);
- if (!vol_dev)
- return 2;
-
- let vol_mode = vol_get_mode(vol_dev);
- if (vol_mode == "rd" || vol_mode == "wd")
- return 0;
- else if (vol_mode == "wo")
- return 22;
- else if (vol_mode == "wp")
- return 16;
- else if (vol_mode == "ro") {
- system(sprintf("umount /dev/ubiblock%s 2>&1 >/dev/null", substr(vol_dev, 3)));
- system(sprintf("ubiblock --remove /dev/%s", vol_dev));
- let ret = system(sprintf("ubirename /dev/%s \"uvol-ro-%s\" \"uvol-rd-%s\"", ubidev, vol_name, vol_name));
- return ret;
- } else if (vol_mode == "rw") {
- system(sprintf("umount /dev/%s 2>&1 >/dev/null", vol_dev));
- let ret = system(sprintf("ubirename /dev/%s \"uvol-rw-%s\" \"uvol-wd-%s\"", ubidev, vol_name, vol_name));
- block_hotplug("remove", vol_dev);
- return ret;
- }
- return 0;
- }
-
- function ubi_list(search_name) {
- let volumes = [];
- for (vol_dir in fs.glob(sprintf("/sys/devices/virtual/ubi/%s/%s_*", ubidev, ubidev))) {
- let vol = {};
- let vol_ubiname = read_file(sprintf("%s/name", vol_dir));
- if (!wildcard(vol_ubiname, "uvol-[rw][wod]-*"))
- continue;
-
- let vol_mode = substr(vol_ubiname, 5, 2);
- let vol_name = substr(vol_ubiname, 8);
- let vol_size = read_file(sprintf("%s/data_bytes", vol_dir));
- if (substr(vol_name, 0, 1) == ".")
- continue;
-
- vol.name = vol_name;
- vol.mode = vol_mode;
- vol.size = vol_size;
- push(volumes, vol);
- }
- return volumes;
+ return 0;
+}
+
+function ubi_list(search_name) {
+ let volumes = [];
+ for (vol_dir in fs.glob(sprintf("/sys/devices/virtual/ubi/%s/%s_*", ubidev, ubidev))) {
+ let vol = {};
+ let vol_ubiname = read_file(sprintf("%s/name", vol_dir));
+ if (!wildcard(vol_ubiname, "uvol-[rw][wod]-*"))
+ continue;
+
+ let vol_mode = substr(vol_ubiname, 5, 2);
+ let vol_name = substr(vol_ubiname, 8);
+ let vol_size = read_file(sprintf("%s/data_bytes", vol_dir));
+ if (substr(vol_name, 0, 1) == ".")
+ continue;
+
+ vol.name = vol_name;
+ vol.mode = vol_mode;
+ vol.size = vol_size;
+ push(volumes, vol);
}
+ return volumes;
+}
- function ubi_detect() {
- let tmpdev = [];
- for (vol_dir in fs.glob(sprintf("/sys/devices/virtual/ubi/%s/%s_*", ubidev, ubidev))) {
- let vol_ubiname = read_file(sprintf("%s/name", vol_dir));
+function ubi_detect() {
+ let tmpdev = [];
+ for (vol_dir in fs.glob(sprintf("/sys/devices/virtual/ubi/%s/%s_*", ubidev, ubidev))) {
+ let vol_ubiname = read_file(sprintf("%s/name", vol_dir));
- if (!wildcard(vol_ubiname, "uvol-r[od]-*"))
- continue;
+ if (!wildcard(vol_ubiname, "uvol-r[od]-*"))
+ continue;
- let vol_name = substr(vol_ubiname, 8);
- let vol_mode = substr(vol_ubiname, 5, 2);
- let vol_dev = fs.basename(vol_dir);
+ let vol_name = substr(vol_ubiname, 8);
+ let vol_mode = substr(vol_ubiname, 5, 2);
+ let vol_dev = fs.basename(vol_dir);
- ret = system(sprintf("ubiblock --create /dev/%s", vol_dev));
- if (ret)
- continue;
-
- if (vol_mode == "rd")
- push(tmpdev, vol_dev);
- }
-
- uvol_uci_init();
-
- for (vol_dir in fs.glob(sprintf("/sys/devices/virtual/ubi/%s/%s_*", ubidev, ubidev))) {
- let vol_ubiname = read_file(sprintf("%s/name", vol_dir));
- if (!wildcard(vol_ubiname, "uvol-[rw][wod]-*"))
- continue;
+ ret = system(sprintf("ubiblock --create /dev/%s", vol_dev));
+ if (ret)
+ continue;
- let vol_dev = fs.basename(vol_dir);
- let vol_name = substr(vol_ubiname, 8);
- let vol_mode = substr(vol_ubiname, 5, 2);
+ if (vol_mode == "rd")
+ push(tmpdev, vol_dev);
+ }
- if (vol_mode == "ro" || vol_mode == "rd")
- uvol_uci_add(vol_name, sprintf("/dev/ubiblock%s", substr(vol_dev, 3)), "ro");
- else if (vol_mode == "rw" || vol_mode == "wd")
- uvol_uci_add(vol_name, sprintf("/dev/%s", vol_dev), "rw");
- }
+ uvol_uci_init();
- uvol_uci_commit();
+ for (vol_dir in fs.glob(sprintf("/sys/devices/virtual/ubi/%s/%s_*", ubidev, ubidev))) {
+ let vol_ubiname = read_file(sprintf("%s/name", vol_dir));
+ if (!wildcard(vol_ubiname, "uvol-[rw][wod]-*"))
+ continue;
- for (vol_dev in tmpdev)
- system(sprintf("ubiblock --remove /dev/%s", vol_dev));
+ let vol_dev = fs.basename(vol_dir);
+ let vol_name = substr(vol_ubiname, 8);
+ let vol_mode = substr(vol_ubiname, 5, 2);
- return 0;
+ if (vol_mode == "ro" || vol_mode == "rd")
+ uvol_uci_add(vol_name, sprintf("/dev/ubiblock%s", substr(vol_dev, 3)), "ro");
+ else if (vol_mode == "rw" || vol_mode == "wd")
+ uvol_uci_add(vol_name, sprintf("/dev/%s", vol_dev), "rw");
}
- function ubi_boot() {
- for (vol_dir in fs.glob(sprintf("/sys/devices/virtual/ubi/%s/%s_*", ubidev, ubidev))) {
- let vol_dev = fs.basename(vol_dir);
- let vol_ubiname = read_file(sprintf("%s/name", vol_dir));
-
- if (!wildcard(vol_ubiname, "uvol-ro-*"))
- continue;
-
- system(sprintf("ubiblock --create /dev/%s", vol_dev));
- }
- }
+ uvol_uci_commit();
- function ubi_write(vol_name, write_size) {
- let vol_dev = ubi_get_dev(vol_name);
- if (!vol_dev)
- return 2;
+ for (vol_dev in tmpdev)
+ system(sprintf("ubiblock --remove /dev/%s", vol_dev));
- write_size = +write_size;
- if (write_size <= 0)
- return 22;
+ return 0;
+}
- let vol_mode = vol_get_mode(vol_dev);
- if (vol_mode != "wo")
- return 22;
+function ubi_boot() {
+ for (vol_dir in fs.glob(sprintf("/sys/devices/virtual/ubi/%s/%s_*", ubidev, ubidev))) {
+ let vol_dev = fs.basename(vol_dir);
+ let vol_ubiname = read_file(sprintf("%s/name", vol_dir));
- let ret = system(sprintf("ubiupdatevol -s %s /dev/%s -", write_size, vol_dev));
- if (ret)
- return ret;
+ if (!wildcard(vol_ubiname, "uvol-ro-*"))
+ continue;
system(sprintf("ubiblock --create /dev/%s", vol_dev));
- uvol_uci_add(vol_name, sprintf("/dev/ubiblock%s", substr(vol_dev, 3)), "ro");
- system(sprintf("ubiblock --remove /dev/%s", vol_dev));
- system(sprintf("ubirename /dev/%s \"uvol-wo-%s\" \"uvol-rd-%s\"", ubidev, vol_name, vol_name));
-
- return 0;
}
-
- backend.backend = "UBI";
- backend.priority = 20;
- backend.init = ubi_init;
- backend.boot = ubi_boot;
- backend.detect = ubi_detect;
- backend.free = ubi_free;
- backend.align = ubi_align;
- backend.total = ubi_total;
- backend.list = ubi_list;
- backend.size = ubi_size;
- backend.status = ubi_status;
- backend.device = ubi_device;
- backend.up = ubi_up;
- backend.down = ubi_down;
- backend.create = ubi_create;
- backend.remove = ubi_remove;
- backend.write = ubi_write;
-%}
+}
+
+function ubi_write(vol_name, write_size) {
+ let vol_dev = ubi_get_dev(vol_name);
+ if (!vol_dev)
+ return 2;
+
+ write_size = +write_size;
+ if (write_size <= 0)
+ return 22;
+
+ let vol_mode = vol_get_mode(vol_dev);
+ if (vol_mode != "wo")
+ return 22;
+
+ let ret = system(sprintf("ubiupdatevol -s %s /dev/%s -", write_size, vol_dev));
+ if (ret)
+ return ret;
+
+ system(sprintf("ubiblock --create /dev/%s", vol_dev));
+ uvol_uci_add(vol_name, sprintf("/dev/ubiblock%s", substr(vol_dev, 3)), "ro");
+ system(sprintf("ubiblock --remove /dev/%s", vol_dev));
+ system(sprintf("ubirename /dev/%s \"uvol-wo-%s\" \"uvol-rd-%s\"", ubidev, vol_name, vol_name));
+
+ return 0;
+}
+
+backend.backend = "UBI";
+backend.priority = 20;
+backend.init = ubi_init;
+backend.boot = ubi_boot;
+backend.detect = ubi_detect;
+backend.free = ubi_free;
+backend.align = ubi_align;
+backend.total = ubi_total;
+backend.list = ubi_list;
+backend.size = ubi_size;
+backend.status = ubi_status;
+backend.device = ubi_device;
+backend.up = ubi_up;
+backend.down = ubi_down;
+backend.create = ubi_create;
+backend.remove = ubi_remove;
+backend.write = ubi_write;
-{%
// SPDX-License-Identifier: GPL-2.0-or-later
// UCI tools for uvol
// (c) 2022 Daniel Golle <daniel@makrotopia.org>
return 0;
}
};
-%}
#!/usr/bin/ucode
-{%
// SPDX-License-Identifier: GPL-2.0-or-later
// uvol - storage volume manager for OpenWrt
// (c) 2022 Daniel Golle <daniel@makrotopia.org>
- function help() {
- %}
-uvol storage volume manager
-
+let help_output = "uvol storage volume manager
syntax: uvol command ...
commands:
1 - volume is not ready for use
2 - volume doesn'y exist
write volname size write to volume from stdin, size in bytes
-{%
+"
+
+function help() {
+ printf("%s", help_output);
+);
+
+let fs = require("fs");
+let uci = require("uci");
+let cursor = uci ? uci.cursor() : null;
+
+let ctx = {};
+ctx.cursor = cursor;
+ctx.fs = fs;
+include("/usr/lib/uvol/uci.uc");
+ctx.uci_add = uvol_uci.uvol_uci_add;
+ctx.uci_remove = uvol_uci.uvol_uci_remove;
+ctx.uci_commit = uvol_uci.uvol_uci_commit;
+ctx.uci_init = uvol_uci.uvol_uci_init;
+
+let backend = null;
+let tried_backends = [];
+for (plugin in fs.glob("/usr/lib/uvol/backends/*.uc")) {
+ let current_backend = {};
+ include(plugin, { backend: current_backend });
+ push(tried_backends, current_backend.backend);
+ if (type(backend) == "object" &&
+ type(backend.priority) == "int" &&
+ type(current_backend.priority) == "int" &&
+ backend.priority > current_backend.priority)
+ continue;
+ if (type(current_backend.init) == "function" &&
+ current_backend.init(ctx)) {
+ backend = current_backend;
+ break;
}
+}
- let fs = require("fs");
- let uci = require("uci");
- let cursor = uci ? uci.cursor() : null;
+if (!backend) {
+ printf("No backend available. (tried: %s)\n", join(" ", tried_backends));
+ printf("To setup devices with block storage install 'autopart'.\n");
+ exit(2);
+}
- let ctx = {};
- ctx.cursor = cursor;
- ctx.fs = fs;
- include("/usr/lib/uvol/uci.uc");
- ctx.uci_add = uvol_uci.uvol_uci_add;
- ctx.uci_remove = uvol_uci.uvol_uci_remove;
- ctx.uci_commit = uvol_uci.uvol_uci_commit;
- ctx.uci_init = uvol_uci.uvol_uci_init;
+let cmd = shift(ARGV);
- let backend = null;
- let tried_backends = [];
- for (plugin in fs.glob("/usr/lib/uvol/backends/*.uc")) {
- let current_backend = {};
- include(plugin, { backend: current_backend });
- push(tried_backends, current_backend.backend);
- if (type(backend) == "object" &&
- type(backend.priority) == "int" &&
- type(current_backend.priority) == "int" &&
- backend.priority > current_backend.priority)
- continue;
+if (!cmd || cmd == "-h" || cmd == "help") {
+ help();
+ return cmd?0:22;
+}
- if (type(current_backend.init) == "function" &&
- current_backend.init(ctx)) {
- backend = current_backend;
- break;
- }
- }
-
- if (!backend) {
- printf("No backend available. (tried: %s)\n", join(" ", tried_backends));
- printf("To setup devices with block storage install 'autopart'.\n");
- exit(2);
- }
+if (!(cmd in keys(backend))) {
+ printf("command %s not found\n", cmd);
+ return 22;
+}
+let json_output = false;
+if (ARGV[0] == "-j") {
+ json_output = true;
shift(ARGV);
- shift(ARGV);
- let cmd = shift(ARGV);
-
- if (!cmd || cmd == "-h" || cmd == "help") {
- help();
- return cmd?0:22;
- }
+}
- if (!(cmd in keys(backend))) {
- printf("command %s not found\n", cmd);
- return 22;
- }
-
- let json_output = false;
- if (ARGV[0] == "-j") {
- json_output = true;
- shift(ARGV);
- }
-
- let legacy_output = function(var) {
- let out = "";
- if (type(var) == "array") {
- for (let line in var) {
- out += join(" ", values(line));
- out += "\n";
- }
- } else if (type(var) == "object") {
+let legacy_output = function(var) {
+ let out = "";
+ if (type(var) == "array") {
+ for (let line in var) {
out += join(" ", values(line));
out += "\n";
}
- return out;
- };
-
- if (type(backend[cmd]) == "string") {
- printf("%s\n", backend[cmd]);
- } else if (type(backend[cmd]) == "function") {
- let ret = backend[cmd](...ARGV);
- if (type(ret) == "int")
- exit(ret);
-
- if (type(ret) == "string") {
- printf("%s\n", ret);
- } else {
- if (json_output)
- printf("%.J\n", ret);
- else
- printf("%s", legacy_output(ret));
- }
+ } else if (type(var) == "object") {
+ out += join(" ", values(line));
+ out += "\n";
+ }
+ return out;
+};
+
+if (type(backend[cmd]) == "string") {
+ printf("%s\n", backend[cmd]);
+} else if (type(backend[cmd]) == "function") {
+ let ret = backend[cmd](...ARGV);
+ if (type(ret) == "int")
+ exit(ret);
+
+ if (type(ret) == "string") {
+ printf("%s\n", ret);
} else {
if (json_output)
- printf("%.J\n", backend[cmd]);
+ printf("%.J\n", ret);
else
- printf("%s\n", legacy_output(backend[cmd]));
+ printf("%s", legacy_output(ret));
}
-
- return 0;
-%}
+} else {
+ if (json_output)
+ printf("%.J\n", backend[cmd]);
+ else
+ printf("%s\n", legacy_output(backend[cmd]));
+}
+
+exit(0);