Skip to content

Commit d5b1262

Browse files
committed
make_ext4fs: add command-line -u option for UUID
As the ability to easily determine or specify the UUID of the file-system eases working with some bootloaders, this patch adds printing of the UUID upon file system creation with the other information and allows for the UUID to be specified as a command-line parameter. Whether specified or automatically generated, the UUID is now printed with the Label and other creation information. The parsing of command-line supplied UUIDs is relatively forgiving, allowing dash-separated values or not. The default UUID generation remains unchanged as the hash of the file-system label. Signed-off-by: Eric Herman <[email protected]>
1 parent 5c201be commit d5b1262

File tree

6 files changed

+104
-4
lines changed

6 files changed

+104
-4
lines changed

ext4_sb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#include <errno.h>
18+
#include <string.h>
1819

1920
#include "ext4_sb.h"
2021

@@ -38,6 +39,7 @@ int ext4_parse_sb(struct ext4_super_block *sb, struct fs_info *info)
3839
info->feat_incompat = sb->s_feature_incompat;
3940
info->bg_desc_reserve_blocks = sb->s_reserved_gdt_blocks;
4041
info->label = sb->s_volume_name;
42+
memcpy(info->uuid, sb->s_uuid, 16);
4143

4244
len_blocks = ((uint64_t)sb->s_blocks_count_hi << 32) +
4345
sb->s_blocks_count_lo;

ext4_sb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct fs_info {
4242
uint32_t reserve_pcnt;
4343
const char *label;
4444
uint8_t no_journal;
45+
uint8_t uuid[16];
4546
};
4647

4748
int ext4_parse_sb(struct ext4_super_block *sb, struct fs_info *info);

ext4_utils.c

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
*/
1616

1717
#include "ext4_utils.h"
18-
#include "uuid.h"
1918
#include "allocate.h"
2019
#include "indirect.h"
2120
#include "extent.h"
2221

2322
#include <sparse/sparse.h>
2423

24+
#include <assert.h>
25+
#include <ctype.h>
2526
#include <fcntl.h>
2627
#include <inttypes.h>
2728
#include <sys/stat.h>
@@ -42,6 +43,7 @@ int force = 0;
4243
struct fs_info info;
4344
struct fs_aux_info aux_info;
4445
struct sparse_file *ext4_sparse_file;
46+
int uuid_user_specified = 0;
4547

4648
jmp_buf setjmp_env;
4749

@@ -221,7 +223,7 @@ void ext4_fill_in_sb()
221223
sb->s_feature_compat = info.feat_compat;
222224
sb->s_feature_incompat = info.feat_incompat;
223225
sb->s_feature_ro_compat = info.feat_ro_compat;
224-
generate_uuid("extandroid/make_ext4fs", info.label, sb->s_uuid);
226+
memcpy(sb->s_uuid, info.uuid, 16);
225227
memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
226228
strncpy(sb->s_volume_name, info.label, sizeof(sb->s_volume_name));
227229
memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
@@ -490,10 +492,86 @@ u64 parse_num(const char *arg)
490492
return num;
491493
}
492494

495+
static char nibble_to_hex_char(uint8_t nibble)
496+
{
497+
const char *hexchars = "0123456789abcdef";
498+
499+
assert(nibble < 16);
500+
501+
return hexchars[nibble];
502+
}
503+
504+
static uint8_t hex_char_to_nibble(char c)
505+
{
506+
assert(isxdigit(c));
507+
508+
if (c >= '0' && c <= '9') {
509+
return c - '0';
510+
}
511+
512+
if (c >= 'a' && c <= 'f') {
513+
return 10 + c - 'a';
514+
}
515+
516+
assert(c >= 'A' && c <= 'F');
517+
return 10 + c - 'A';
518+
}
519+
520+
uint8_t *parse_uuid(uint8_t bytes[16], const char *str, size_t len)
521+
{
522+
size_t i, pos;
523+
uint8_t hi_nibble, lo_nibble;
524+
525+
assert(str);
526+
527+
for (i = 0, pos = 0; i < 16; ++i) {
528+
while (pos < len && (ispunct(str[pos]) || isspace(str[pos]))) {
529+
++pos;
530+
}
531+
532+
if (pos >= len || !isxdigit(str[pos])) {
533+
return NULL;
534+
}
535+
hi_nibble = hex_char_to_nibble(str[pos++]);
536+
537+
if (pos >= len || !isxdigit(str[pos])) {
538+
return NULL;
539+
}
540+
lo_nibble = hex_char_to_nibble(str[pos++]);
541+
542+
bytes[i] = ((hi_nibble << 4) | lo_nibble);
543+
}
544+
return bytes;
545+
}
546+
547+
/* 00000000-0000-0000-0000-000000000000 */
548+
char *uuid_bin_to_str(char *buf, size_t buf_size, const uint8_t bytes[16])
549+
{
550+
const size_t uuid_str_size = ((16 * 2) + 4) + 1;
551+
size_t i, pos;
552+
uint8_t hi_nibble, lo_nibble;
553+
554+
assert(buf);
555+
assert(buf_size >= uuid_str_size);
556+
557+
memset(buf, 0x00, buf_size);
558+
for (i = 0, pos = 0; i < 16; ++i) {
559+
hi_nibble = ((bytes[i] & 0xF0) >> 4);
560+
lo_nibble = (bytes[i] & 0x0F);
561+
buf[pos++] = nibble_to_hex_char(hi_nibble);
562+
buf[pos++] = nibble_to_hex_char(lo_nibble);
563+
if (i == 3 || i == 5 || i == 7 || i == 9) {
564+
buf[pos++] = '-';
565+
}
566+
}
567+
return buf;
568+
}
569+
493570
int read_ext(int fd, int verbose)
494571
{
495572
off_t ret;
496573
struct ext4_super_block sb;
574+
char buf[40];
497575

498576
read_sb(fd, &sb);
499577

@@ -521,6 +599,7 @@ int read_ext(int fd, int verbose)
521599
printf(" Inodes per group: %d\n", info.inodes_per_group);
522600
printf(" Inode size: %d\n", info.inode_size);
523601
printf(" Label: %s\n", info.label);
602+
printf(" UUID: %s\n", uuid_bin_to_str(buf, sizeof(buf), info.uuid));
524603
printf(" Blocks: %"PRIu64"\n", aux_info.len_blocks);
525604
printf(" Block groups: %d\n", aux_info.groups);
526605
printf(" Reserved block group size: %d\n", info.bg_desc_reserve_blocks);

ext4_utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ struct fs_aux_info {
113113
extern struct fs_info info;
114114
extern struct fs_aux_info aux_info;
115115
extern struct sparse_file *ext4_sparse_file;
116+
extern int uuid_user_specified;
116117

117118
extern jmp_buf setjmp_env;
118119

@@ -145,6 +146,8 @@ u64 get_file_size(int fd);
145146
u64 parse_num(const char *arg);
146147
void ext4_parse_sb_info(struct ext4_super_block *sb);
147148
u16 ext4_crc16(u16 crc_in, const void *buf, int size);
149+
uint8_t *parse_uuid(uint8_t bytes[16], const char *str, size_t len);
150+
char *uuid_bin_to_str(char *buf, size_t buf_size, const uint8_t bytes[16]);
148151

149152
typedef int (*fs_config_func_t)(const char *path, int dir, unsigned *uid, unsigned *gid,
150153
unsigned *mode, uint64_t *capabilities);

make_ext4fs.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ int make_ext4fs_internal(int fd, const char *_directory,
384384
u32 root_inode_num;
385385
u16 root_mode;
386386
char *directory = NULL;
387+
char buf[40];
387388

388389
if (setjmp(setjmp_env))
389390
return EXIT_FAILURE; /* Handle a call to longjmp() */
@@ -443,6 +444,10 @@ int make_ext4fs_internal(int fd, const char *_directory,
443444

444445
info.bg_desc_reserve_blocks = compute_bg_desc_reserve_blocks();
445446

447+
if (!uuid_user_specified) {
448+
generate_uuid("extandroid/make_ext4fs", info.label, info.uuid);
449+
}
450+
446451
printf("Creating filesystem with parameters:\n");
447452
printf(" Size: %"PRIu64"\n", info.len);
448453
printf(" Block size: %d\n", info.block_size);
@@ -451,6 +456,7 @@ int make_ext4fs_internal(int fd, const char *_directory,
451456
printf(" Inode size: %d\n", info.inode_size);
452457
printf(" Journal blocks: %d\n", info.journal_blocks);
453458
printf(" Label: %s\n", info.label);
459+
printf(" UUID: %s\n", uuid_bin_to_str(buf, sizeof(buf), info.uuid));
454460

455461
ext4_create_fs_aux_info();
456462

make_ext4fs_main.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@
2929
#include "canned_fs_config.h"
3030

3131
extern struct fs_info info;
32+
extern int uuid_user_specified;
3233

3334

3435
static void usage(char *path)
3536
{
3637
fprintf(stderr, "%s [ -l <len> ] [ -j <journal size> ] [ -b <block_size> ]\n", basename(path));
3738
fprintf(stderr, " [ -g <blocks per group> ] [ -i <inodes> ] [ -I <inode size> ]\n");
38-
fprintf(stderr, " [ -m <reserved blocks percent> ] [ -L <label> ] [ -f ]\n");
39+
fprintf(stderr, " [ -m <reserved blocks percent> ] [ -L <label> ] [ -u <uuid>] [ -f ]\n");
3940
fprintf(stderr, " [ -S file_contexts ] [ -C fs_config ] [ -T timestamp ]\n");
4041
fprintf(stderr, " [ -z | -s ] [ -w ] [ -c ] [ -J ] [ -v ] [ -B <block_list_file> ]\n");
4142
fprintf(stderr, " <filename> [<directory>]\n");
@@ -58,7 +59,7 @@ int main(int argc, char **argv)
5859
time_t fixed_time = -1;
5960
FILE* block_list_file = NULL;
6061

61-
while ((opt = getopt(argc, argv, "l:j:b:g:i:I:L:T:C:B:m:fwzJsctv")) != -1) {
62+
while ((opt = getopt(argc, argv, "l:j:b:g:i:I:L:u:T:C:B:m:fwzJsctv")) != -1) {
6263
switch (opt) {
6364
case 'l':
6465
info.len = parse_num(optarg);
@@ -81,6 +82,14 @@ int main(int argc, char **argv)
8182
case 'L':
8283
info.label = optarg;
8384
break;
85+
case 'u':
86+
if (!parse_uuid(info.uuid, optarg, strlen(optarg))) {
87+
fprintf(stderr, "failed to parse UUID: '%s'\n",
88+
optarg);
89+
exit(EXIT_FAILURE);
90+
}
91+
uuid_user_specified = 1;
92+
break;
8493
case 'f':
8594
force = 1;
8695
break;

0 commit comments

Comments
 (0)