hostdisk.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
  4. *
  5. * GRUB is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GRUB is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <config-util.h>
  19. #include <grub/disk.h>
  20. #include <grub/partition.h>
  21. #include <grub/msdos_partition.h>
  22. #include <grub/types.h>
  23. #include <grub/err.h>
  24. #include <grub/emu/misc.h>
  25. #include <grub/emu/hostdisk.h>
  26. #include <grub/emu/getroot.h>
  27. #include <grub/misc.h>
  28. #include <grub/i18n.h>
  29. #include <grub/list.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <ctype.h>
  34. #include <assert.h>
  35. #include <unistd.h>
  36. #include <sys/types.h>
  37. #include <sys/stat.h>
  38. #include <fcntl.h>
  39. #include <errno.h>
  40. #include <limits.h>
  41. # include <sys/ioctl.h>
  42. # include <sys/disklabel.h> /* struct disklabel */
  43. # include <sys/disk.h> /* struct dkwedge_info */
  44. # ifdef HAVE_GETRAWPARTITION
  45. # include <util.h> /* getrawpartition */
  46. # endif /* HAVE_GETRAWPARTITION */
  47. # if defined(__NetBSD__)
  48. # include <sys/fdio.h>
  49. # endif
  50. # if defined(__OpenBSD__)
  51. # include <sys/dkio.h>
  52. # endif
  53. #if defined(__NetBSD__)
  54. # ifndef RAW_FLOPPY_MAJOR
  55. # define RAW_FLOPPY_MAJOR 9
  56. # endif /* ! RAW_FLOPPY_MAJOR */
  57. /* Adjust device driver parameters. This function should be called just
  58. after successfully opening the device. For now, it simply prevents the
  59. floppy driver from retrying operations on failure, as otherwise the
  60. driver takes a while to abort when there is no floppy in the drive. */
  61. static void
  62. configure_device_driver (grub_util_fd_t fd)
  63. {
  64. struct stat st;
  65. if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
  66. return;
  67. if (major(st.st_rdev) == RAW_FLOPPY_MAJOR)
  68. {
  69. int floppy_opts;
  70. if (ioctl (fd, FDIOCGETOPTS, &floppy_opts) == -1)
  71. return;
  72. floppy_opts |= FDOPT_NORETRY;
  73. if (ioctl (fd, FDIOCSETOPTS, &floppy_opts) == -1)
  74. return;
  75. }
  76. }
  77. grub_util_fd_t
  78. grub_util_fd_open (const char *os_dev, int flags)
  79. {
  80. grub_util_fd_t ret;
  81. #ifdef O_LARGEFILE
  82. flags |= O_LARGEFILE;
  83. #endif
  84. #ifdef O_BINARY
  85. flags |= O_BINARY;
  86. #endif
  87. ret = open (os_dev, flags, S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR);
  88. if (ret >= 0)
  89. configure_device_driver (ret);
  90. return ret;
  91. }
  92. #endif
  93. grub_int64_t
  94. grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
  95. {
  96. struct disklabel label;
  97. unsigned sector_size, log_sector_size;
  98. #if defined(__NetBSD__)
  99. configure_device_driver (fd);
  100. #endif
  101. if (ioctl (fd, DIOCGDINFO, &label) == -1)
  102. return -1;
  103. sector_size = label.d_secsize;
  104. if (sector_size & (sector_size - 1) || !sector_size)
  105. return -1;
  106. log_sector_size = grub_log2ull (sector_size);
  107. if (log_secsize)
  108. *log_secsize = log_sector_size;
  109. return (grub_uint64_t) label.d_secperunit << log_sector_size;
  110. }
  111. void
  112. grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
  113. {
  114. }