Skip to content

Instantly share code, notes, and snippets.

@rlaager
Created October 18, 2013 17:07
Show Gist options
  • Save rlaager/7044625 to your computer and use it in GitHub Desktop.
Save rlaager/7044625 to your computer and use it in GitHub Desktop.
ZFS on Linux Improvements
1. `zpool status` can output disk names which are under /dev/disk.
2. `zpool status` outputs the whole disk device for wholedisk pools,
but GRUB needs the partition device.
Before this can be accepted upstream, I am to merge it into the
existing /dev scanning code.
Index: grub/util/getroot.c
===================================================================
--- grub.orig/util/getroot.c 2012-03-08 12:45:57.423086000 -0600
+++ grub/util/getroot.c 2012-03-08 12:46:01.072809000 -0600
@@ -394,7 +394,87 @@ find_root_devices_from_poolname (char *p
if (name[0] == '/')
devices[ndevices++] = xstrdup (name);
else
+#ifdef __linux__
+ {
+ /* The name returned by zpool isn't necessarily directly under /dev. */
+ char *device = xasprintf ("/dev/%s", name);
+ struct stat sb;
+ char *real_device;
+ char *c;
+ char *partition;
+
+ if (stat (device, &sb) != 0)
+ {
+ DIR *dev;
+ struct dirent *subdir;
+
+ free (device);
+ device = NULL;
+ dev = opendir ("/dev/disk");
+ if (dev)
+ {
+ while ((subdir = readdir (dev)))
+ {
+ if (subdir->d_name[0] == '.')
+ continue;
+ if (subdir->d_type == DT_UNKNOWN)
+ {
+ char *subdir_path = xasprintf ("/dev/disk/%s", subdir->d_name);
+ ret = stat (subdir_path, &sb);
+ free (subdir_path);
+ if (ret != 0)
+ continue;
+ if (!S_ISDIR (sb.st_mode))
+ continue;
+ }
+ else if (subdir->d_type != DT_DIR)
+ continue;
+ device = xasprintf ("/dev/disk/%s/%s", subdir->d_name, name);
+ if (stat (device, &sb) == 0)
+ break;
+ else
+ {
+ free (device);
+ device = NULL;
+ }
+ }
+ closedir (dev);
+ if (! device)
+ grub_util_error (_("failed to find device %s"), device);
+ }
+ }
+
+ /* Resolve the symlink to something like /dev/sda. */
+ real_device = canonicalize_file_name (device);
+ if (! real_device)
+ grub_util_error (_("failed to get canonical path of %s"), device);
+ free(device);
+
+ /* It ends in a number; assume it's a partition and stop. */
+ for (c = real_device ; *(c+1) ; c++);
+ if (*c >= '0' && *c <= '9')
+ {
+ devices[ndevices++] = real_device;
+ break;
+ }
+
+ /* Otherwise, it might be a partitioned wholedisk device. */
+ partition = xasprintf ("%s1", real_device);
+ if (stat (partition, &sb) == 0)
+ {
+ free (real_device);
+ devices[ndevices++] = partition;
+ break;
+ }
+ free (partition);
+
+ /* The device is not partitioned. */
+ devices[ndevices++] = real_device;
+ break;
+ }
+#else
devices[ndevices++] = xasprintf ("/dev/%s", name);
+#endif
}
break;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment