hostdisk.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include <config-util.h>
  2. #include <grub/disk.h>
  3. #include <grub/partition.h>
  4. #include <grub/msdos_partition.h>
  5. #include <grub/types.h>
  6. #include <grub/err.h>
  7. #include <grub/emu/misc.h>
  8. #include <grub/emu/hostdisk.h>
  9. #include <grub/emu/getroot.h>
  10. #include <grub/misc.h>
  11. #include <grub/i18n.h>
  12. #include <grub/list.h>
  13. #include <grub/osdep/major.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #include <assert.h>
  19. #include <unistd.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <fcntl.h>
  23. #include <errno.h>
  24. #include <limits.h>
  25. #ifdef HAVE_DEVICE_MAPPER
  26. # include <libdevmapper.h>
  27. static void device_mapper_null_log (int level __attribute__ ((unused)),
  28. const char *file __attribute__ ((unused)),
  29. int line __attribute__ ((unused)),
  30. int dm_errno __attribute__ ((unused)),
  31. const char *f __attribute__ ((unused)),
  32. ...)
  33. {
  34. }
  35. int
  36. grub_device_mapper_supported (void)
  37. {
  38. static int supported = -1;
  39. if (supported == -1)
  40. {
  41. struct dm_task *dmt;
  42. /* Suppress annoying log messages. */
  43. dm_log_with_errno_init (&device_mapper_null_log);
  44. dmt = dm_task_create (DM_DEVICE_VERSION);
  45. supported = (dmt != NULL);
  46. if (dmt)
  47. dm_task_destroy (dmt);
  48. /* Restore the original logger. */
  49. dm_log_with_errno_init (NULL);
  50. }
  51. return supported;
  52. }
  53. int
  54. grub_util_device_is_mapped (const char *dev)
  55. {
  56. struct stat st;
  57. if (!grub_device_mapper_supported ())
  58. return 0;
  59. if (stat (dev, &st) < 0)
  60. return 0;
  61. #if GRUB_DISK_DEVS_ARE_CHAR
  62. if (! S_ISCHR (st.st_mode))
  63. #else
  64. if (! S_ISBLK (st.st_mode))
  65. #endif
  66. return 0;
  67. return dm_is_dm_major (major (st.st_rdev));
  68. }
  69. int
  70. grub_util_device_is_mapped_stat (struct stat *st)
  71. {
  72. #if GRUB_DISK_DEVS_ARE_CHAR
  73. if (! S_ISCHR (st->st_mode))
  74. #else
  75. if (! S_ISBLK (st->st_mode))
  76. #endif
  77. return 0;
  78. if (!grub_device_mapper_supported ())
  79. return 0;
  80. return dm_is_dm_major (major (st->st_rdev));
  81. }
  82. int
  83. grub_util_get_dm_node_linear_info (dev_t dev,
  84. int *maj, int *min,
  85. grub_disk_addr_t *st)
  86. {
  87. struct dm_task *dmt;
  88. void *next = NULL;
  89. uint64_t length, start;
  90. char *target, *params;
  91. const char *ptr;
  92. int major = 0, minor = 0;
  93. int first = 1;
  94. grub_disk_addr_t partstart = 0;
  95. const char *node_uuid;
  96. major = major (dev);
  97. minor = minor (dev);
  98. while (1)
  99. {
  100. dmt = dm_task_create(DM_DEVICE_TABLE);
  101. if (!dmt)
  102. break;
  103. if (! (dm_task_set_major_minor (dmt, major, minor, 0)))
  104. {
  105. dm_task_destroy (dmt);
  106. break;
  107. }
  108. dm_task_no_open_count(dmt);
  109. if (!dm_task_run(dmt))
  110. {
  111. dm_task_destroy (dmt);
  112. break;
  113. }
  114. node_uuid = dm_task_get_uuid (dmt);
  115. if (node_uuid && (strncmp (node_uuid, "LVM-", 4) == 0
  116. || strncmp (node_uuid, "mpath-", 6) == 0))
  117. {
  118. dm_task_destroy (dmt);
  119. break;
  120. }
  121. next = dm_get_next_target(dmt, next, &start, &length,
  122. &target, &params);
  123. if (grub_strcmp (target, "linear") != 0)
  124. {
  125. dm_task_destroy (dmt);
  126. break;
  127. }
  128. major = grub_strtoul (params, &ptr, 10);
  129. if (grub_errno)
  130. {
  131. dm_task_destroy (dmt);
  132. grub_errno = GRUB_ERR_NONE;
  133. return 0;
  134. }
  135. if (*ptr != ':')
  136. {
  137. dm_task_destroy (dmt);
  138. return 0;
  139. }
  140. ptr++;
  141. minor = grub_strtoul (ptr, &ptr, 10);
  142. if (grub_errno)
  143. {
  144. grub_errno = GRUB_ERR_NONE;
  145. dm_task_destroy (dmt);
  146. return 0;
  147. }
  148. if (*ptr != ' ')
  149. {
  150. dm_task_destroy (dmt);
  151. return 0;
  152. }
  153. ptr++;
  154. partstart += grub_strtoull (ptr, &ptr, 10);
  155. if (grub_errno)
  156. {
  157. grub_errno = GRUB_ERR_NONE;
  158. dm_task_destroy (dmt);
  159. return 0;
  160. }
  161. dm_task_destroy (dmt);
  162. first = 0;
  163. if (!dm_is_dm_major (major))
  164. break;
  165. }
  166. if (first)
  167. return 0;
  168. if (maj)
  169. *maj = major;
  170. if (min)
  171. *min = minor;
  172. if (st)
  173. *st = partstart;
  174. return 1;
  175. }
  176. #else
  177. int
  178. grub_util_device_is_mapped (const char *dev __attribute__ ((unused)))
  179. {
  180. return 0;
  181. }
  182. int
  183. grub_util_get_dm_node_linear_info (dev_t dev __attribute__ ((unused)),
  184. int *maj __attribute__ ((unused)),
  185. int *min __attribute__ ((unused)),
  186. grub_disk_addr_t *st __attribute__ ((unused)))
  187. {
  188. return 0;
  189. }
  190. int
  191. grub_util_device_is_mapped_stat (struct stat *st __attribute__ ((unused)))
  192. {
  193. return 0;
  194. }
  195. #endif