hostdisk.c 4.2 KB

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