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.

137 lines
3.4 KiB

  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. // UCI tools for uvol
  3. // (c) 2022 Daniel Golle <daniel@makrotopia.org>
  4. let uci_spooldir = "/var/spool/uvol";
  5. let init_spooldir = function(void) {
  6. parentdir = fs.stat(fs.dirname(uci_spooldir));
  7. if (!parentdir || parentdir.type != "directory")
  8. fs.mkdir(fs.dirname(uci_spooldir), 0755);
  9. fs.mkdir(uci_spooldir, 0700);
  10. };
  11. uvol_uci = {
  12. uvol_uci_add: function(vol_name, dev_name, mode) {
  13. try {
  14. let autofs = false;
  15. let uuid;
  16. let target;
  17. if (mode == "ro")
  18. autofs = true;
  19. let uciname = replace(vol_name, /[-.]/g, "_");
  20. uciname = replace(uciname, /!([:alnum:]_)/g, "");
  21. let bdinfo_p = fs.popen("/sbin/block info");
  22. let bdinfo_l;
  23. while (bdinfo_l = bdinfo_p.read("line")) {
  24. if (substr(bdinfo_l, 0, length(dev_name) + 1) != dev_name + ":")
  25. continue;
  26. let bdinfo_e = split(bdinfo_l, " ");
  27. shift(bdinfo_e);
  28. for (let bdinfo_a in bdinfo_e) {
  29. let bdinfo_v = split(bdinfo_a, "=");
  30. if (bdinfo_v[0] && bdinfo_v[0] == "UUID") {
  31. uuid = trim(bdinfo_v[1], "\"");
  32. break;
  33. }
  34. }
  35. break;
  36. }
  37. if (!uuid)
  38. return 22;
  39. if (uciname == "_meta")
  40. target = "/tmp/run/uvol/.meta";
  41. else if (substr(uciname, 0, 1) == "_")
  42. return 1;
  43. else
  44. target = sprintf("/tmp/run/uvol/%s", vol_name);
  45. init_spooldir();
  46. let remspool = sprintf("%s/remove-%s", uci_spooldir, uciname);
  47. if (fs.stat(remspool))
  48. fs.unlink(remspool);
  49. let addobj = {};
  50. addobj.name=uciname;
  51. addobj.uuid=uuid;
  52. addobj.target=target;
  53. addobj.options=mode;
  54. addobj.autofs=autofs;
  55. addobj.enabled=true;
  56. let spoolfile = fs.open(sprintf("%s/add-%s", uci_spooldir, uciname), "w");
  57. spoolfile.write(addobj);
  58. spoolfile.close();
  59. } catch(e) {
  60. printf("adding UCI section to spool failed");
  61. return -1;
  62. }
  63. return 0;
  64. },
  65. uvol_uci_remove: function(vol_name) {
  66. let uciname = replace(vol_name, /[-.]/g, "_");
  67. uciname = replace(uciname, /!([:alnum:]_)/g, "");
  68. let addspool = sprintf("%s/add-%s", uci_spooldir, uciname);
  69. if (fs.stat(addspool)) {
  70. fs.unlink(addspool);
  71. return 0;
  72. }
  73. init_spooldir();
  74. let spoolfile = fs.open(sprintf("%s/remove-%s", uci_spooldir, uciname), "w");
  75. spoolfile.write(uciname);
  76. spoolfile.close();
  77. return 0;
  78. },
  79. uvol_uci_commit: function(vol_name) {
  80. try {
  81. let uciname = null;
  82. if (vol_name) {
  83. uciname = replace(vol_name, /[-.]/g, "_");
  84. uciname = replace(uciname, /!([:alnum:]_)/g, "");
  85. }
  86. for (let file in fs.glob(sprintf("%s/*-%s", uci_spooldir, uciname?uciname:"*"))) {
  87. let action = split(fs.basename(file), "-")[0];
  88. let spoolfd = fs.open(file, "r");
  89. let spoolstr = spoolfd.read("all");
  90. spoolfd.close();
  91. fs.unlink(file);
  92. if (action == "remove") {
  93. cursor.delete("fstab", spoolstr);
  94. } else if (action == "add") {
  95. let spoolobj = json(spoolstr);
  96. cursor.set("fstab", spoolobj.name, "mount");
  97. for (key in keys(spoolobj)) {
  98. if (key == "name")
  99. continue;
  100. cursor.set("fstab", spoolobj.name, key, spoolobj[key]);
  101. }
  102. }
  103. }
  104. cursor.commit();
  105. } catch(e) {
  106. printf("committing UCI spool failed");
  107. return -1;
  108. }
  109. return 0;
  110. },
  111. uvol_uci_init: function () {
  112. cursor.load("fstab");
  113. let f = cursor.get("fstab", "@uvol[0]", "initialized");
  114. if (f == 1)
  115. return 0;
  116. cursor.add("fstab", "uvol");
  117. cursor.set("fstab", "@uvol[-1]", "initialized", true);
  118. cursor.commit();
  119. cursor.unload("fstab");
  120. return 0;
  121. }
  122. };