On Wednesday, 19 April 2017 18:43:41 CEST Richard W.M. Jones wrote:
Instead of specifying a device name (eg. root=/dev/sdb), this
permits
specifying an ext4 volume UUID (root=UUID=12345678-...). This allows
the appliance to be robust against the non-determinism of SCSI device
enumeration.
---
[...]
+
+ for (delay_ns = 250000;
+ delay_ns <= MAX_ROOT_WAIT * UINT64_C(1000000000);
+ delay_ns *= 2) {
+ if (parse_dev_file (path, &major, &minor) != -1) {
+ if (!quiet)
+ fprintf (stderr, "supermin: picked %s (%d:%d) as root device\n",
+ path, major, minor);
+ break;
}
+
+ virtio_warning (delay_ns, path);
+ NANOSLEEP (delay_ns);
}
This code for busy waiting could be factored in a common function --
printing either the /dev/path or the UUID.
+static void
+parse_root_uuid (const char *root, unsigned char *raw_uuid)
+{
+ size_t i;
+
+ i = 0;
+ while (i < 16) {
+ if (*root == '-') {
+ ++root;
+ continue;
+ }
+ if (!isxdigit (root[0]) || !isxdigit (root[1])) {
+ fprintf (stderr, "supermin: root UUID is not a 16 byte UUID string\n");
+ exit (EXIT_FAILURE);
+ }
+ raw_uuid[i++] = hexdigit (root[0]) * 0x10 + hexdigit (root[1]);
+ root += 2;
+ }
+
+ if (i < 16) {
+ fprintf (stderr, "supermin: root UUID should be 16 bytes\n");
+ exit (EXIT_FAILURE);
+ }
Is this check actually ever going to be true? It looks to me that the
while loop above can be broken only in two cases:
a) the any of the isxdigit checks fails
b) the condition of the while becomes false
In case of (a), there's exit() already, so it will not execute anything
else anyway; in case of (b), then i will always be >= 16, and thus
never going to satisfy the check above.
Also, parse_root_uuid does not fail when the uuid string has more
character than the ones needed. I'd suggest changing the last check
to something like:
if (*root) {
fprintf (stderr, "supermin: root UUID contains more than 16 bytes\n");
exit (EXIT_FAILURE);
}
Thanks,
--
Pino Toscano