uuid.patch 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. # DP: Add support for specifying the root device using UUIDs on the
  2. # DP: kernel command line like this without the need for an initrd:
  3. # DP: linux ... root=UUID=ce40d6b2-18eb-4a75-aefe-7ddb0995ce63
  4. # DP:
  5. # DP: Written © 2010 by Thorsten Glaser <tg@debian.org>
  6. # DP: Idea from 1999 by David Balazic <david.balazic@uni-mb.si>
  7. --- linux-2.6.36/block/genhd.c~ Wed Oct 20 22:30:22 2010
  8. +++ linux-2.6.36/block/genhd.c Sat Nov 20 23:14:03 2010
  9. @@ -35,7 +35,7 @@ struct kobject *block_depr;
  10. static DEFINE_MUTEX(ext_devt_mutex);
  11. static DEFINE_IDR(ext_devt_idr);
  12. -static struct device_type disk_type;
  13. +struct device_type disk_type;
  14. /**
  15. * disk_get_part - get partition
  16. @@ -1019,7 +1019,7 @@ static char *block_devnode(struct device *dev, mode_t
  17. return NULL;
  18. }
  19. -static struct device_type disk_type = {
  20. +struct device_type disk_type = {
  21. .name = "disk",
  22. .groups = disk_attr_groups,
  23. .release = disk_release,
  24. --- linux-2.6.36/init/do_mounts.c~ Wed Oct 20 22:30:22 2010
  25. +++ linux-2.6.36/init/do_mounts.c Sat Nov 20 23:16:07 2010
  26. @@ -32,6 +32,84 @@ static int __initdata root_wait;
  27. dev_t ROOT_DEV;
  28. +#ifdef CONFIG_EXT2_FS
  29. +/* support for root=UUID=ce40d6b2-18eb-4a75-aefe-7ddb0995ce63 bootargs */
  30. +
  31. +#include <linux/buffer_head.h>
  32. +#include <linux/ext2_fs.h>
  33. +
  34. +__u8 root_dev_label[16];
  35. +int root_dev_type; /* 0 = normal (/dev/hda1, 0301); 1 = UUID; 3 = bad */
  36. +
  37. +/* imported from block/genhd.c after removing its static qualifier */
  38. +extern struct device_type disk_type;
  39. +
  40. +static __u8 __init fromhex(char c)
  41. +{
  42. + if (c >= '0' && c <= '9')
  43. + return (c - '0');
  44. + c &= ~32;
  45. + if (c >= 'A' && c <= 'F')
  46. + return (c - 'A' + 10);
  47. + return (0xFF);
  48. +}
  49. +
  50. +static void __init parse_uuid(const char *s)
  51. +{
  52. + int i;
  53. + __u8 j, k;
  54. +
  55. + if (strlen(s) != 36 || s[8] != '-' || s[13] != '-' ||
  56. + s[18] != '-' || s[23] != '-')
  57. + goto bad_uuid;
  58. + for (i = 0; i < 16; i++) {
  59. + if (*s == '-')
  60. + ++s;
  61. + j = fromhex(*s++);
  62. + k = fromhex(*s++);
  63. + if (j == 0xFF || k == 0xFF)
  64. + goto bad_uuid;
  65. + root_dev_label[i] = (j << 4) | k;
  66. + }
  67. + return;
  68. + bad_uuid:
  69. + /* we cannot panic here, defer */
  70. + root_dev_type = 3;
  71. +}
  72. +
  73. +static int __init check_dev(dev_t devt, int blocksize)
  74. +{
  75. + /* most of this taken from fs/ext2/super.c */
  76. +
  77. + struct buffer_head * bh;
  78. + struct ext2_super_block * es;
  79. + struct block_device *bdev;
  80. + unsigned long sb_block = 1;
  81. + unsigned long logic_sb_block;
  82. + unsigned long offset = 0;
  83. + int rv = 0;
  84. +
  85. + bdev = bdget(devt);
  86. +
  87. + if (blocksize != BLOCK_SIZE) {
  88. + logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;
  89. + offset = (sb_block*BLOCK_SIZE) % blocksize;
  90. + } else {
  91. + logic_sb_block = sb_block;
  92. + }
  93. +
  94. + if (!(bh = __bread(bdev, logic_sb_block, blocksize)))
  95. + return (0);
  96. + es = (struct ext2_super_block *)(((char *)bh->b_data) + offset);
  97. + if (le16_to_cpu(es->s_magic) == EXT2_SUPER_MAGIC) {
  98. + if (!memcmp(es->s_uuid, root_dev_label, 16))
  99. + rv = 1;
  100. + }
  101. + brelse(bh);
  102. + return (rv);
  103. +}
  104. +#endif /* CONFIG_EXT2_FS for UUID support */
  105. +
  106. static int __init load_ramdisk(char *str)
  107. {
  108. rd_doload = simple_strtol(str,NULL,0) & 3;
  109. @@ -148,6 +226,13 @@ done:
  110. static int __init root_dev_setup(char *line)
  111. {
  112. strlcpy(saved_root_name, line, sizeof(saved_root_name));
  113. +#ifdef CONFIG_EXT2_FS
  114. + root_dev_type = 0;
  115. + if (!strncmp(line, "UUID=", 5)) {
  116. + root_dev_type = 1;
  117. + parse_uuid(line + 5);
  118. + }
  119. +#endif /* CONFIG_EXT2_FS for UUID support */
  120. return 1;
  121. }
  122. @@ -333,6 +418,45 @@ void __init change_floppy(char *fmt, ...)
  123. void __init mount_root(void)
  124. {
  125. +#ifdef CONFIG_EXT2_FS
  126. + /* UUID support */
  127. + if (root_dev_type == 1) {
  128. + int blocksize;
  129. +
  130. + /* from block/genhd.c printk_all_partitions */
  131. + struct class_dev_iter iter;
  132. + struct device *dev;
  133. +
  134. + class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
  135. + while (root_dev_type && (dev = class_dev_iter_next(&iter))) {
  136. + struct gendisk *disk = dev_to_disk(dev);
  137. + struct disk_part_iter piter;
  138. + struct hd_struct *part;
  139. + if (get_capacity(disk) == 0 ||
  140. + (disk->flags & GENHD_FL_SUPPRESS_PARTITION_INFO))
  141. + continue;
  142. + blocksize = queue_logical_block_size(disk->queue);
  143. +
  144. + disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0);
  145. + while (root_dev_type && (part = disk_part_iter_next(&piter))) {
  146. + /* avoid empty or too small partitions */
  147. + if (part->nr_sects < 8)
  148. + continue;
  149. + if (check_dev(part_devt(part), blocksize)) {
  150. + ROOT_DEV = part_devt(part);
  151. + root_dev_type = 0;
  152. + }
  153. + }
  154. + disk_part_iter_exit(&piter);
  155. + }
  156. + class_dev_iter_exit(&iter);
  157. + }
  158. + if (root_dev_type == 1)
  159. + printk(KERN_ERR "VFS: Unable to find root by UUID %s.\n", saved_root_name + 5);
  160. + else if (root_dev_type == 3)
  161. + panic("Badly formatted UUID %s was supplied as kernel parameter root", saved_root_name + 5);
  162. +#endif /* CONFIG_EXT2_FS for UUID support */
  163. +
  164. #ifdef CONFIG_ROOT_NFS
  165. if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
  166. if (mount_nfs_root())