]> git.scottworley.com Git - nixos-qemu-vm-isolation/blob - overlays/squashfs-labels/squashfs-tools-label.patch
Put squashfs-label patch overlays in a separate file
[nixos-qemu-vm-isolation] / overlays / squashfs-labels / squashfs-tools-label.patch
1 # Initially from https://github.com/plougher/squashfs-tools/pull/264
2 # Ported from squashfs-tools 4.6 → 4.7
3 diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c
4 --- a/squashfs-tools/mksquashfs.c
5 +++ b/squashfs-tools/mksquashfs.c
6 @@ -207,6 +207,12 @@ int mem_options_disabled = FALSE;
7 /* Is filesystem stored at an offset from the start of the block device/file? */
8 long long start_offset = 0;
9
10 +/* Do we have an extra_info metadata block? */
11 +int extra_info = FALSE;
12 +/* parameters for the extra_info block */
13 +char *volume_label = NULL;
14 +char *uuid = NULL;
15 +
16 /* Is Mksquashfs streaming the output filesystem to stdout? */
17 int streaming = FALSE;
18
19 @@ -378,7 +384,7 @@ char *option_table[] = { "comp", "b", "mkfs-time", "fstime", "inode-time",
20 "mem-percent", "-pd", "-pseudo-dir", "help-option", "ho", "help-section",
21 "hs", "info-file", "force-file-mode", "force-dir-mode",
22 "small-readers", "block-readers", "uid-gid-offset", "all-time",
23 - "overcommit", "repro-time", "cols", NULL
24 + "overcommit", "repro-time", "cols", "label", "uuid", NULL
25 };
26
27 char *sqfstar_option_table[] = { "comp", "b", "mkfs-time", "fstime",
28 @@ -6546,6 +6552,68 @@ static void fix_file(char *filename)
29 BAD_ERROR("Failed to truncate file \"%s\" because %s\n", filename, strerror(errno));
30 }
31
32 +void *info_dump(int *psize) {
33 + int bytes = 0, pos = 0;
34 + unsigned char *buf;
35 + const int UUID_LEN = 16; /* avoid depending on uuid-dev for now */
36 + int label_len;
37 +
38 + /* The extra_info section contains one or more entries of the form:
39 + TAG byte
40 + LEN byte
41 + VAL byte_1 ... byte_len
42 +
43 + Terminated by the tag: SQUASHFS_EXTRA_INFO_TAG_END
44 + */
45 + if (volume_label) {
46 + label_len = strlen(volume_label);
47 + if (label_len > 255) label_len = 255;
48 + bytes += 1 + 1 + label_len;
49 + }
50 + if (uuid)
51 + bytes += 1 + 1 + UUID_LEN;
52 + if (!bytes)
53 + return NULL;
54 + bytes += 1; /* TAG_END */
55 +
56 + buf = malloc(bytes);
57 +
58 + if (volume_label) {
59 + buf[pos++] = SQUASHFS_EXTRA_INFO_TAG_LABEL;
60 + buf[pos++] = label_len;
61 + memcpy(&buf[pos], volume_label, label_len);
62 + pos += label_len;
63 + }
64 + if (uuid) {
65 + char *puuid = uuid;
66 + buf[pos++] = SQUASHFS_EXTRA_INFO_TAG_UUID;
67 + buf[pos++] = UUID_LEN;
68 + /* poor man's uuid_parse() */
69 + for (int i = 0; i < UUID_LEN; i++) {
70 + char hex[3] = {};
71 + char *endptr = NULL;
72 + if (*puuid == '-') {
73 + puuid++;
74 + }
75 + if (puuid[0] && puuid[1]) {
76 + memcpy(&hex[0], puuid, 2);
77 + buf[pos++] = strtoul(hex, &endptr, 16);
78 + }
79 + if (endptr != hex + 2) {
80 + ERROR("invalid UUID: %s\n", uuid);
81 + exit(1);
82 + }
83 + puuid += 2;
84 + }
85 + }
86 + buf[pos++] = SQUASHFS_EXTRA_INFO_TAG_END;
87 + if (pos != bytes) {
88 + ERROR("extra_info legth mismatch\n");
89 + exit(1);
90 + }
91 + *psize = bytes;
92 + return buf;
93 +}
94
95 static int sqfstar(int argc, char *argv[])
96 {
97 @@ -6563,7 +6631,7 @@ static int sqfstar(int argc, char *argv[])
98 int Xhelp = FALSE;
99 int dest_index;
100 struct file_buffer **fragment = NULL;
101 - int size;
102 + int comp_size;
103 void *comp_data;
104 int overcommit = OVERCOMMIT_DEFAULT;
105 int repro_opt = FALSE;
106 @@ -7404,7 +7472,10 @@ static int sqfstar(int argc, char *argv[])
107 memset(dupl_block, 0, 1048576 * sizeof(struct file_info *));
108 memset(dupl_frag, 0, block_size * sizeof(struct file_info *));
109
110 - comp_data = compressor_dump_options(comp, block_size, &size);
111 + comp_data = compressor_dump_options(comp, block_size, &comp_size);
112 +
113 + int info_size;
114 + void *info_data = info_dump(&info_size);
115
116 if(!quiet)
117 printf("Creating %d.%d filesystem on %s, block size %d.\n",
118 @@ -7426,18 +7497,28 @@ static int sqfstar(int argc, char *argv[])
119 * and set the COMP_OPT flag to show that the filesystem has
120 * compressor specfic options
121 */
122 + long long super_end = sizeof(struct squashfs_super_block);
123 if(comp_data) {
124 - unsigned short c_byte = size | SQUASHFS_COMPRESSED_BIT;
125 + unsigned short c_byte = comp_size | SQUASHFS_COMPRESSED_BIT;
126
127 SQUASHFS_INSWAP_SHORTS(&c_byte, 1);
128 - write_destination(fd, sizeof(struct squashfs_super_block),
129 - sizeof(c_byte), &c_byte);
130 - write_destination(fd, sizeof(struct squashfs_super_block) +
131 - sizeof(c_byte), size, comp_data);
132 - set_pos(sizeof(struct squashfs_super_block) + sizeof(c_byte) + size);
133 + write_destination(fd, super_end, sizeof(c_byte), &c_byte);
134 + super_end += sizeof(c_byte);
135 + write_destination(fd, super_end, comp_size, comp_data);
136 + super_end += comp_size;
137 comp_opts = TRUE;
138 - } else
139 - set_pos(sizeof(struct squashfs_super_block));
140 + }
141 + if (info_data) {
142 + unsigned short i_byte = info_size | SQUASHFS_COMPRESSED_BIT;
143 +
144 + SQUASHFS_INSWAP_SHORTS(&i_byte, 1);
145 + write_destination(fd, super_end, sizeof(i_byte), &i_byte);
146 + super_end += sizeof(i_byte);
147 + write_destination(fd, super_end, info_size, info_data);
148 + super_end += info_size;
149 + extra_info = TRUE;
150 + }
151 + set_pos(super_end);
152
153 if(path)
154 paths = add_subdir(paths, path);
155 @@ -7458,7 +7539,7 @@ static int sqfstar(int argc, char *argv[])
156 sBlk.block_log = block_log;
157 sBlk.flags = SQUASHFS_MKFLAGS(noI, noD, noF, noX, noId, no_fragments,
158 always_use_fragments, duplicate_checking, exportable,
159 - no_xattrs, comp_opts);
160 + no_xattrs, comp_opts, extra_info);
161 if(mkfs_time_opt)
162 sBlk.mkfs_time = mkfs_time;
163 else if(mkfs_inode_opt)
164 @@ -7513,7 +7594,6 @@ static int sqfstar(int argc, char *argv[])
165 return 0;
166 }
167
168 -
169 int main(int argc, char *argv[])
170 {
171 struct stat buf, source_buf;
172 @@ -8337,6 +8417,20 @@ int main(int argc, char *argv[])
173 !parse_number(argv[i], &overcommit, 2) ||
174 (overcommit > 100))
175 mksquashfs_option_help(argv[i - 1], "mksquashfs: -overcommit missing or invalid percentage: it should be 0 - 100%%\n");
176 + } else if (strcmp(argv[i], "-label") == 0) {
177 + if(++i == argc) {
178 + ERROR("%s: -label: missing label\n",
179 + argv[0]);
180 + exit(1);
181 + }
182 + volume_label = argv[i];
183 + } else if (strcmp(argv[i], "-uuid") == 0) {
184 + if(++i == argc) {
185 + ERROR("%s: -uuid: missing uuid\n",
186 + argv[0]);
187 + exit(1);
188 + }
189 + uuid = argv[i];
190 } else
191 mksquashfs_invalid_option(argv[i]);
192 }
193 @@ -8706,6 +8800,7 @@ int main(int argc, char *argv[])
194 exportable = SQUASHFS_EXPORTABLE(sBlk.flags);
195 no_xattrs = SQUASHFS_NO_XATTRS(sBlk.flags);
196 comp_opts = SQUASHFS_COMP_OPTS(sBlk.flags);
197 + extra_info = SQUASHFS_EXTRA_INFO(sBlk.flags);
198 }
199
200 initialise_threads(readq, fragq, bwriteq, fwriteq, !appending,
201 @@ -8721,9 +8816,12 @@ int main(int argc, char *argv[])
202 memset(dupl_frag, 0, block_size * sizeof(struct file_info *));
203
204 if(!appending) {
205 - int size;
206 + int comp_size;
207 void *comp_data = compressor_dump_options(comp, block_size,
208 - &size);
209 + &comp_size);
210 +
211 + int info_size;
212 + void *info_data = info_dump(&info_size);
213
214 if(!quiet)
215 printf("Creating %d.%d filesystem on %s, block size %d.\n",
216 @@ -8746,18 +8844,28 @@ int main(int argc, char *argv[])
217 * and set the COMP_OPT flag to show that the filesystem has
218 * compressor specfic options
219 */
220 + long long super_end = sizeof(struct squashfs_super_block);
221 if(comp_data) {
222 - unsigned short c_byte = size | SQUASHFS_COMPRESSED_BIT;
223 + unsigned short c_byte = comp_size | SQUASHFS_COMPRESSED_BIT;
224
225 SQUASHFS_INSWAP_SHORTS(&c_byte, 1);
226 - write_destination(fd, sizeof(struct squashfs_super_block),
227 - sizeof(c_byte), &c_byte);
228 - write_destination(fd, sizeof(struct squashfs_super_block) +
229 - sizeof(c_byte), size, comp_data);
230 - set_pos(sizeof(struct squashfs_super_block) + sizeof(c_byte) + size);
231 + write_destination(fd, super_end, sizeof(c_byte), &c_byte);
232 + super_end += sizeof(c_byte);
233 + write_destination(fd, super_end, comp_size, comp_data);
234 + super_end += comp_size;
235 comp_opts = TRUE;
236 - } else
237 - set_pos(sizeof(struct squashfs_super_block));
238 + }
239 + if (info_data) {
240 + unsigned short i_byte = info_size | SQUASHFS_COMPRESSED_BIT;
241 +
242 + SQUASHFS_INSWAP_SHORTS(&i_byte, 1);
243 + write_destination(fd, super_end, sizeof(i_byte), &i_byte);
244 + super_end += sizeof(i_byte);
245 + write_destination(fd, super_end, info_size, info_data);
246 + super_end += info_size;
247 + extra_info = TRUE;
248 + }
249 + set_pos(super_end);
250 } else {
251 unsigned int last_directory_block, inode_dir_file_size,
252 root_inode_size, inode_dir_start_block,
253 @@ -8913,7 +9021,7 @@ int main(int argc, char *argv[])
254 sBlk.block_log = block_log;
255 sBlk.flags = SQUASHFS_MKFLAGS(noI, noD, noF, noX, noId, no_fragments,
256 always_use_fragments, duplicate_checking, exportable,
257 - no_xattrs, comp_opts);
258 + no_xattrs, comp_opts, extra_info);
259 if(mkfs_time_opt)
260 sBlk.mkfs_time = mkfs_time;
261 else if(mkfs_inode_opt)
262 diff --git a/squashfs-tools/mksquashfs_help.c b/squashfs-tools/mksquashfs_help.c
263 --- a/squashfs-tools/mksquashfs_help.c
264 +++ b/squashfs-tools/mksquashfs_help.c
265 @@ -243,6 +243,8 @@ static char *mksquashfs_text[]={
266 "-keep-as-directory\tif one source directory is specified, create a "
267 "root directory containing that directory, rather than the "
268 "contents of the directory\n",
269 + "-label <volume-label>\tSet the volume label\n",
270 + "-uuid <UUID>\tSet the volume UUID\n"
271 "\n", "Filesystem time options:", "\n",
272 "-mkfs-time <time>\tset filesystem creation timestamp to <time>. "
273 "<time> can be \"inode\", which means use the latest inode "
274 diff --git a/squashfs-tools/squashfs_fs.h b/squashfs-tools/squashfs_fs.h
275 --- a/squashfs-tools/squashfs_fs.h
276 +++ b/squashfs-tools/squashfs_fs.h
277 @@ -74,6 +74,7 @@
278 #define SQUASHFS_NO_XATTR 9
279 #define SQUASHFS_COMP_OPT 10
280 #define SQUASHFS_NOID 11
281 +#define SQUASHFS_INFO 12
282
283 #define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
284
285 @@ -110,12 +111,16 @@
286 #define SQUASHFS_UNCOMPRESSED_IDS(flags) SQUASHFS_BIT(flags, \
287 SQUASHFS_NOID)
288
289 +#define SQUASHFS_EXTRA_INFO(flags) SQUASHFS_BIT(flags, \
290 + SQUASHFS_INFO)
291 +
292 #define SQUASHFS_MKFLAGS(noi, nod, nof, nox, noid, no_frag, always_frag, \
293 - duplicate_checking, exportable, no_xattr, comp_opt) (noi | \
294 + duplicate_checking, exportable, no_xattr, comp_opt, \
295 + extra_info) (noi | \
296 (nod << 1) | (nof << 3) | (no_frag << 4) | \
297 (always_frag << 5) | (duplicate_checking << 6) | \
298 (exportable << 7) | (nox << 8) | (no_xattr << 9) | \
299 - (comp_opt << 10) | (noid << 11))
300 + (comp_opt << 10) | (noid << 11) | (extra_info << 12))
301
302 /* Max number of types and file types */
303 #define SQUASHFS_DIR_TYPE 1
304 @@ -291,6 +296,10 @@ typedef long long squashfs_inode;
305 #define LZ4_COMPRESSION 5
306 #define ZSTD_COMPRESSION 6
307
308 +#define SQUASHFS_EXTRA_INFO_TAG_END 0
309 +#define SQUASHFS_EXTRA_INFO_TAG_LABEL 1
310 +#define SQUASHFS_EXTRA_INFO_TAG_UUID 2
311 +
312 struct squashfs_super_block {
313 unsigned int s_magic;
314 unsigned int inodes;