summaryrefslogtreecommitdiff
path: root/draft/other-tools/fog/procsfdisk.awk
diff options
context:
space:
mode:
Diffstat (limited to 'draft/other-tools/fog/procsfdisk.awk')
-rw-r--r--draft/other-tools/fog/procsfdisk.awk361
1 files changed, 361 insertions, 0 deletions
diff --git a/draft/other-tools/fog/procsfdisk.awk b/draft/other-tools/fog/procsfdisk.awk
new file mode 100644
index 0000000..ac18749
--- /dev/null
+++ b/draft/other-tools/fog/procsfdisk.awk
@@ -0,0 +1,361 @@
+#!/usr/bin/awk -f
+
+#$data is the filename of the output of sfdisk -d
+
+#cat $data | awk -F, '\
+
+# For readability, function parameters are on the first line. Locally scoped
+# variables are on the following lines.
+
+function display_output(partition_names, partitions, \
+ pName) {
+ if (!unit) {
+ unit = "sectors";
+ }
+ if (!label) {
+ type = "Id=";
+ } else {
+ type = "type=";
+ }
+ if (label && labelid && device) {
+ printf("label: %s\n", label);
+ printf("label-id: %s\n", labelid);
+ printf("device: %s\n", device);
+ }
+ printf("unit: %s\n\n", unit);
+ for(pName in partition_names) {
+ printf("%s : start=%10d, size=%10d, %s%2s", partitions[pName, "device"], partitions[pName, "start"], partitions[pName, "size"],
+ type, partitions[pName, "type"]);
+ if(label == "dos") {
+ if(partitions[pName, "flags"] != "") {
+ printf("%s", partitions[pName, "flags"]);
+ }
+ } else if (label == "gpt") {
+ if(partitions[pName, "uuid"] != "") {
+ printf(", uuid=%s", partitions[pName, "uuid"]);
+ }
+ if(partitions[pName, "name"] != "") {
+ printf(", name=%s", partitions[pName, "name"]);
+ }
+ if(partitions[pName, "attrs"] != "") {
+ printf(", attrs=%s", partitions[pName, "attrs"]);
+ }
+ } else {
+ if(partitions[pName, "flags"] != "") {
+ printf("%s", partitions[pName, "flags"]);
+ }
+ }
+ printf("\n");
+ }
+}
+
+function check_overlap(partition_names, partitions, new_part_name, new_start, new_size, \
+ extended_margin, new_type, new_part_number, pName, p_type, p_start, p_size, p_part_number) {
+ extended_margin = 2;
+ new_type = partitions[new_part_name, "type"];
+ new_start = new_start + 0;
+ new_size = new_size + 0;
+ new_part_number = partitions[new_part_name, "number"] + 0;
+ for(pName in partition_names) {
+ p_type = partitions[pName, "type"];
+ p_start = partitions[pName, "start"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ p_part_number = partitions[pName, "number"] + 0;
+ # no overlap with self
+ if(new_part_name == pName) { continue; }
+ # ignore empty partitions
+ if(p_size == 0) { continue; }
+ # extended partitions must overlap logical partitions, but leave room for the extended partition table
+ if((p_type == "5" || p_type == "f") && (new_part_number >= 5)) {
+ # new_start is outside of [p_start+margin, p_start + p_size) OR
+ # new_start + new_size is outside of (p_start+margin, p_start + p_size]
+ if((new_start < p_start + extended_margin || new_start >= p_start + p_size) || (new_start + new_size <= p_start + extended_margin || new_start + new_size > p_start + p_size)) {
+ return 1;
+ }
+ }
+ # extended partitions must overlap logical partitions, but leave room for the extended partition table
+ else if((new_type == "5" || new_type == "f") && (p_part_number >= 5)) {
+ # logical partition must be contained in extended partition
+ # p_start is outside of [new_start+margin, new_start + new_size) OR
+ # p_start + p_size is outside of (new_start+margin, new_start + new_size]
+ if((p_start < new_start + extended_margin || p_start >= new_start + new_size) || (p_start + p_size <= new_start + extended_margin || p_start + p_size > new_start + new_size)) {
+ return 1;
+ }
+ }
+ # all other overlap possibilities
+ else {
+ # new_start is inside of [p_start, p_start + p_size) OR
+ # new_start + new_size is inside of (p_start, p_start + p_size]
+ if((new_start >= p_start && new_start < p_start + p_size) || (new_start + new_size > p_start && new_start + new_size <= p_start + p_size)) {
+ return 1;
+ }
+ # p_start is inside of [new_start, new_start + new_size) OR
+ # p_start + p_size is inside of (new_start, new_start + new_size]
+ if((p_start >= new_start && p_start < new_start + new_size) || (p_start + p_size > new_start && p_start + p_size <= new_start + new_size)) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+function check_all_partitions(partition_names, partitions, \
+ pName, p_start, p_size) {
+ for(pName in partition_names) {
+ p_start = partitions[pName, "start"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ if(check_overlap(partition_names, partitions, pName, p_start, p_size) != 0) {
+ printf("ERROR in new partition table, quitting.\n");
+ printf("ERROR: %s has an overlap.\n", pName);
+ #exit(1);
+ }
+ }
+ printf("# Partition table is consistent.\n");
+}
+
+function resize_partition(partition_names, partitions, args, \
+ pName, new_start, new_size) {
+ for(pName in partition_names) {
+ if(pName == target) {
+ if(unit == "sectors") {
+ new_start = partitions[pName, "start"];
+ new_size = sizePos*2;
+ if(check_overlap(partition_names, partitions, target, new_start, new_size) == 0) {
+ partitions[target, "start"] = new_start;
+ partitions[target, "size"] = new_size;
+ }
+ }
+ }
+ }
+}
+
+function move_partition(partition_names, partitions, args, \
+ pName, new_start, new_size) {
+ for(pName in partition_names) {
+ if(pName == target) {
+ if(unit == "sectors") {
+ new_start = (sizePos*2);
+ new_start = new_start - new_start % CHUNK_SIZE;
+ if(new_start < MIN_START) { new_start = MIN_START; }
+ new_size = partitions[pName, "size"];
+ if(check_overlap(partition_names, partitions, target, new_start, new_size) == 0) {
+ partitions[target, "start"] = new_start;
+ partitions[target, "size"] = new_size;
+ }
+ }
+ }
+ }
+}
+
+function fill_disk(partition_names, partitions, args, \
+ disk, disk_size, n, fixed_partitions, original_variable, \
+ original_fixed, new_variable, new_fixed, new_logical, pName, \
+ p_type, p_number, p_size, found, i, partition_starts, \
+ ordered_starts, old_sorted_in, curr_start) {
+ # processSfdisk foo.sfdisk filldisk /dev/sda 100000 1:3:6
+ # foo.sfdisk = sfdisk -d output
+ # filldisk = action
+ # /dev/sda = disk to modify
+ # 100000 = 1024 byte blocks size of disk
+ # 1:3:6 = partition numbers that are fixed in size, : separated
+ disk = target;
+ disk_size = sizePos*2;
+ # add swap partitions to the fixed list
+ for(pName in partition_names) {
+ p_type = partitions[pName, "type"];
+ p_number = partitions[pName, "number"] + "";
+ if(p_type == "82") {
+ fixedList = fixedList ":" p_number;
+ }
+ }
+ n = split(fixedList, fixed_partitions, ":");
+ #
+ # Find the total fixed and variable space
+ #
+ original_variable = 0;
+ original_fixed = MIN_START;
+ for(pName in partition_names) {
+ p_type = partitions[pName, "type"];
+ p_number = partitions[pName, "number"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ partition_starts[partitions[pName, "start"] + 0] = pName;
+ # skip extended partition, only count its logicals and the CHUNK for its partition table
+ if(p_type == "5" || p_type == "f") {
+ original_fixed += CHUNK_SIZE;
+ continue;
+ }
+ # + CHUNK_SIZE to allow for margin after each logical partition (required if 2 or more logical partitions exist)
+ if(p_number >= 5) {
+ original_fixed += CHUNK_SIZE;
+ }
+ if(p_size == 0) { fixed_partitions[pName] = p_number; };
+ found = 0; for(i in fixed_partitions) { if(fixed_partitions[i] == p_number) { found = 1; } };
+ if(found) {
+ original_fixed += partitions[pName, "size"];
+ } else {
+ original_variable += partitions[pName, "size"];
+ }
+ }
+ #
+ # Assign the new sizes to partitions
+ #
+ new_fixed = original_fixed;
+ new_variable = disk_size - original_fixed;
+ new_logical = 0;
+ for(pName in partition_names) {
+ p_type = partitions[pName, "type"];
+ p_number = partitions[pName, "number"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ found = 0;
+ for(i in fixed_partitions) {
+ if(fixed_partitions[i] == p_number) {
+ found = 1;
+ }
+ };
+ if(p_type == "5" || p_type == "f") {
+ partitions[pName, "newsize"] = CHUNK_SIZE;
+ partitions[pName, "size"] = partitions[pName, "newsize"] - partitions[pName, "newsize"] % CHUNK_SIZE;
+ } else if(found) {
+ partitions[pName, "newsize"] = p_size;
+ partitions[pName, "size"] = partitions[pName, "newsize"];
+ } else {
+ partitions[pName, "newsize"] = (new_variable*p_size/original_variable);
+ partitions[pName, "size"] = partitions[pName, "newsize"] - partitions[pName, "newsize"] % CHUNK_SIZE;
+ }
+ if(p_number >= 5) {
+ # + CHUNK_SIZE to allow for margin after each logical partition (required if 2 or more logical partitions exist)
+ new_logical += partitions[pName, "size"] + CHUNK_SIZE;
+ }
+ }
+ #
+ # Assign the new size to the extended partition
+ #
+ for(pName in partition_names) {
+ p_type = partitions[pName, "type"];
+ p_number = partitions[pName, "number"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ if(p_type == "5" || p_type == "f") {
+ partitions[pName, "newsize"] += new_logical;
+ partitions[pName, "size"] = partitions[pName, "newsize"] - partitions[pName, "newsize"] % CHUNK_SIZE;
+ }
+ }
+ #
+ # Assign the new start positions
+ #
+ asort(partition_starts, ordered_starts, "@ind_num_asc");
+ old_sorted_in = PROCINFO["sorted_in"];
+ PROCINFO["sorted_in"] = "@ind_num_asc";
+ curr_start = MIN_START;
+ for(i in ordered_starts) {
+ pName = ordered_starts[i];
+ p_type = partitions[pName, "type"];
+ p_number = partitions[pName, "number"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ p_start = partitions[pName, "start"] + 0;
+ for (j in fixed_partitions) {
+ if (fixed_partitions[j] == p_number) {
+ curr_start = p_start;
+ }
+ }
+ if(p_size > 0) {
+ partitions[pName, "start"] = curr_start;
+ }
+ if(p_type == "5" || p_type == "f") {
+ curr_start += CHUNK_SIZE;
+ } else {
+ curr_start += p_size;
+ }
+ # + CHUNK_SIZE to allow for margin after each logical partition (required if 2 or more logical partitions exist)
+ if(p_number >= 5) {
+ curr_start += CHUNK_SIZE;
+ }
+ }
+ PROCINFO["sorted_in"] = old_sorted_in;
+ check_all_partitions(partition_names, partitions);
+}
+
+BEGIN{
+ #Arguments - Use "-v var=val" when calling this script
+ #CHUNK_SIZE;
+ #MIN_START;
+ #action;
+ #target;
+ #sizePos;
+ #fixedList;
+ label = "";
+ unit = "";
+ partitions[0] = "";
+ partition_names[0] = "";
+}
+
+/^label:/{ label = $2 }
+/^label-id:/{ labelid = $2 }
+/^device:/{ device = $2 }
+/^unit:/{ unit = $2; }
+
+/start=/{
+ # Get Partition Name
+ part_name=$1
+ partitions[part_name, "device"] = part_name
+ partition_names[part_name] = part_name
+
+ # Isolate Partition Number
+ # The regex can handle devices like mmcblk0p3
+ part_number = gensub(/^[^0-9]*[0-9]*[^0-9]+/, "", 1, part_name)
+ partitions[part_name, "number"] = part_number
+
+ # Separate attributes
+ split($0, fields, ",")
+
+ # Get start value
+ gsub(/.*start= */, "", fields[1])
+ partitions[part_name, "start"] = fields[1]
+ # Get size value
+ gsub(/.*size= */, "", fields[2])
+ partitions[part_name, "size"] = fields[2]
+ # Get type/id value
+ gsub(/.*(type|Id)= */, "", fields[3])
+ partitions[part_name, "type"] = fields[3]
+
+ if ( label == "dos" )
+ {
+ split($0, typeList, "type=")
+ part_flags = gensub(/^[^\,$]*/, "",1,typeList[2])
+ partitions[part_name, "flags"] = part_flags;
+ }
+ # GPT elements
+ else if ( label == "gpt" )
+ {
+ # Get uuid value
+ gsub(/.*uuid= */, "", fields[4])
+ partitions[part_name, "uuid"] = fields[4]
+ # Get name value
+ gsub(/.*name= */, "", fields[5])
+ partitions[part_name, "name"] = fields[5]
+ # Get attrs value
+ if (fields[6])
+ {
+ gsub(/.*attrs= */, "", fields[6])
+ partitions[part_name, "attrs"] = fields[6]
+ }
+ }
+ else
+ {
+ split($0, typeList, "Id=")
+ part_flags = gensub(/^[^\,$]*/, "",1,typeList[2])
+ partitions[part_name, "flags"] = part_flags;
+ }
+}
+
+END{
+ delete partitions[0];
+ delete partition_names[0];
+ if(action == "resize") {
+ resize_partition(partition_names, partitions, args);
+ } else if(action == "move") {
+ move_partition(partition_names, partitions, args);
+ } else if(action == "filldisk") {
+ fill_disk(partition_names, partitions, args);
+ }
+ display_output(partition_names, partitions);
+}