You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sanboot.c 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. /*
  2. * Copyright (C) 2017 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. /**
  25. * @file
  26. *
  27. * SAN booting
  28. *
  29. */
  30. #include <stdint.h>
  31. #include <stdlib.h>
  32. #include <errno.h>
  33. #include <assert.h>
  34. #include <ipxe/xfer.h>
  35. #include <ipxe/open.h>
  36. #include <ipxe/timer.h>
  37. #include <ipxe/process.h>
  38. #include <ipxe/iso9660.h>
  39. #include <ipxe/dhcp.h>
  40. #include <ipxe/settings.h>
  41. #include <ipxe/sanboot.h>
  42. /**
  43. * Default SAN drive number
  44. *
  45. * The drive number is a meaningful concept only in a BIOS
  46. * environment, where it represents the INT13 drive number (0x80 for
  47. * the first hard disk). We retain it in other environments to allow
  48. * for a simple way for iPXE commands to refer to SAN drives.
  49. */
  50. #define SAN_DEFAULT_DRIVE 0x80
  51. /**
  52. * Timeout for block device commands (in ticks)
  53. *
  54. * Underlying devices should ideally never become totally stuck.
  55. * However, if they do, then the blocking SAN APIs provide no means
  56. * for the caller to cancel the operation, and the machine appears to
  57. * hang. Use an overall timeout for all commands to avoid this
  58. * problem and bounce timeout failures to the caller.
  59. */
  60. #define SAN_COMMAND_TIMEOUT ( 15 * TICKS_PER_SEC )
  61. /**
  62. * Number of times to retry commands
  63. *
  64. * We may need to retry commands. For example, the underlying
  65. * connection may be closed by the SAN target due to an inactivity
  66. * timeout, or the SAN target may return pointless "error" messages
  67. * such as "SCSI power-on occurred".
  68. */
  69. #define SAN_COMMAND_MAX_RETRIES 10
  70. /** List of SAN devices */
  71. LIST_HEAD ( san_devices );
  72. /**
  73. * Find SAN device by drive number
  74. *
  75. * @v drive Drive number
  76. * @ret sandev SAN device, or NULL
  77. */
  78. struct san_device * sandev_find ( unsigned int drive ) {
  79. struct san_device *sandev;
  80. list_for_each_entry ( sandev, &san_devices, list ) {
  81. if ( sandev->drive == drive )
  82. return sandev;
  83. }
  84. return NULL;
  85. }
  86. /**
  87. * Free SAN device
  88. *
  89. * @v refcnt Reference count
  90. */
  91. static void sandev_free ( struct refcnt *refcnt ) {
  92. struct san_device *sandev =
  93. container_of ( refcnt, struct san_device, refcnt );
  94. assert ( ! timer_running ( &sandev->timer ) );
  95. uri_put ( sandev->uri );
  96. free ( sandev );
  97. }
  98. /**
  99. * Close SAN device command
  100. *
  101. * @v sandev SAN device
  102. * @v rc Reason for close
  103. */
  104. static void sandev_command_close ( struct san_device *sandev, int rc ) {
  105. /* Stop timer */
  106. stop_timer ( &sandev->timer );
  107. /* Restart interface */
  108. intf_restart ( &sandev->command, rc );
  109. /* Record command status */
  110. sandev->command_rc = rc;
  111. }
  112. /**
  113. * Record SAN device capacity
  114. *
  115. * @v sandev SAN device
  116. * @v capacity SAN device capacity
  117. */
  118. static void sandev_command_capacity ( struct san_device *sandev,
  119. struct block_device_capacity *capacity ) {
  120. /* Record raw capacity information */
  121. memcpy ( &sandev->capacity, capacity, sizeof ( sandev->capacity ) );
  122. }
  123. /** SAN device command interface operations */
  124. static struct interface_operation sandev_command_op[] = {
  125. INTF_OP ( intf_close, struct san_device *, sandev_command_close ),
  126. INTF_OP ( block_capacity, struct san_device *,
  127. sandev_command_capacity ),
  128. };
  129. /** SAN device command interface descriptor */
  130. static struct interface_descriptor sandev_command_desc =
  131. INTF_DESC ( struct san_device, command, sandev_command_op );
  132. /**
  133. * Handle SAN device command timeout
  134. *
  135. * @v retry Retry timer
  136. */
  137. static void sandev_command_expired ( struct retry_timer *timer,
  138. int over __unused ) {
  139. struct san_device *sandev =
  140. container_of ( timer, struct san_device, timer );
  141. sandev_command_close ( sandev, -ETIMEDOUT );
  142. }
  143. /**
  144. * Restart SAN device interface
  145. *
  146. * @v sandev SAN device
  147. * @v rc Reason for restart
  148. */
  149. static void sandev_restart ( struct san_device *sandev, int rc ) {
  150. /* Restart block device interface */
  151. intfs_restart ( rc, &sandev->command, &sandev->block, NULL );
  152. /* Close any outstanding command */
  153. sandev_command_close ( sandev, rc );
  154. /* Record device error */
  155. sandev->block_rc = rc;
  156. }
  157. /**
  158. * (Re)open SAN device
  159. *
  160. * @v sandev SAN device
  161. * @ret rc Return status code
  162. *
  163. * This function will block until the device is available.
  164. */
  165. int sandev_reopen ( struct san_device *sandev ) {
  166. int rc;
  167. /* Close any outstanding command and restart interface */
  168. sandev_restart ( sandev, -ECONNRESET );
  169. /* Mark device as being not yet open */
  170. sandev->block_rc = -EINPROGRESS;
  171. /* Open block device interface */
  172. if ( ( rc = xfer_open_uri ( &sandev->block, sandev->uri ) ) != 0 ) {
  173. DBGC ( sandev, "SAN %#02x could not (re)open URI: %s\n",
  174. sandev->drive, strerror ( rc ) );
  175. return rc;
  176. }
  177. /* Wait for device to become available */
  178. while ( sandev->block_rc == -EINPROGRESS ) {
  179. step();
  180. if ( xfer_window ( &sandev->block ) != 0 ) {
  181. sandev->block_rc = 0;
  182. return 0;
  183. }
  184. }
  185. DBGC ( sandev, "SAN %#02x never became available: %s\n",
  186. sandev->drive, strerror ( sandev->block_rc ) );
  187. return sandev->block_rc;
  188. }
  189. /**
  190. * Handle closure of underlying block device interface
  191. *
  192. * @v sandev SAN device
  193. * @ret rc Reason for close
  194. */
  195. static void sandev_block_close ( struct san_device *sandev, int rc ) {
  196. /* Any closure is an error from our point of view */
  197. if ( rc == 0 )
  198. rc = -ENOTCONN;
  199. DBGC ( sandev, "SAN %#02x went away: %s\n",
  200. sandev->drive, strerror ( rc ) );
  201. /* Close any outstanding command and restart interface */
  202. sandev_restart ( sandev, rc );
  203. }
  204. /**
  205. * Check SAN device flow control window
  206. *
  207. * @v sandev SAN device
  208. */
  209. static size_t sandev_block_window ( struct san_device *sandev __unused ) {
  210. /* We are never ready to receive data via this interface.
  211. * This prevents objects that support both block and stream
  212. * interfaces from attempting to send us stream data.
  213. */
  214. return 0;
  215. }
  216. /** SAN device block interface operations */
  217. static struct interface_operation sandev_block_op[] = {
  218. INTF_OP ( intf_close, struct san_device *, sandev_block_close ),
  219. INTF_OP ( xfer_window, struct san_device *, sandev_block_window ),
  220. };
  221. /** SAN device block interface descriptor */
  222. static struct interface_descriptor sandev_block_desc =
  223. INTF_DESC ( struct san_device, block, sandev_block_op );
  224. /** SAN device read/write command parameters */
  225. struct san_command_rw_params {
  226. /** SAN device read/write operation */
  227. int ( * block_rw ) ( struct interface *control, struct interface *data,
  228. uint64_t lba, unsigned int count,
  229. userptr_t buffer, size_t len );
  230. /** Data buffer */
  231. userptr_t buffer;
  232. /** Starting LBA */
  233. uint64_t lba;
  234. /** Block count */
  235. unsigned int count;
  236. };
  237. /** SAN device command parameters */
  238. union san_command_params {
  239. /** Read/write command parameters */
  240. struct san_command_rw_params rw;
  241. };
  242. /**
  243. * Initiate SAN device read/write command
  244. *
  245. * @v sandev SAN device
  246. * @v params Command parameters
  247. * @ret rc Return status code
  248. */
  249. static int sandev_command_rw ( struct san_device *sandev,
  250. const union san_command_params *params ) {
  251. size_t len = ( params->rw.count * sandev->capacity.blksize );
  252. int rc;
  253. /* Initiate read/write command */
  254. if ( ( rc = params->rw.block_rw ( &sandev->block, &sandev->command,
  255. params->rw.lba, params->rw.count,
  256. params->rw.buffer, len ) ) != 0 ) {
  257. DBGC ( sandev, "SAN %#02x could not initiate read/write: "
  258. "%s\n", sandev->drive, strerror ( rc ) );
  259. return rc;
  260. }
  261. return 0;
  262. }
  263. /**
  264. * Initiate SAN device read capacity command
  265. *
  266. * @v sandev SAN device
  267. * @v params Command parameters
  268. * @ret rc Return status code
  269. */
  270. static int
  271. sandev_command_read_capacity ( struct san_device *sandev,
  272. const union san_command_params *params __unused){
  273. int rc;
  274. /* Initiate read capacity command */
  275. if ( ( rc = block_read_capacity ( &sandev->block,
  276. &sandev->command ) ) != 0 ) {
  277. DBGC ( sandev, "SAN %#02x could not initiate read capacity: "
  278. "%s\n", sandev->drive, strerror ( rc ) );
  279. return rc;
  280. }
  281. return 0;
  282. }
  283. /**
  284. * Execute a single SAN device command and wait for completion
  285. *
  286. * @v sandev SAN device
  287. * @v command Command
  288. * @v params Command parameters (if required)
  289. * @ret rc Return status code
  290. */
  291. static int
  292. sandev_command ( struct san_device *sandev,
  293. int ( * command ) ( struct san_device *sandev,
  294. const union san_command_params *params ),
  295. const union san_command_params *params ) {
  296. unsigned int retries;
  297. int rc;
  298. /* Sanity check */
  299. assert ( ! timer_running ( &sandev->timer ) );
  300. /* (Re)try command */
  301. for ( retries = 0 ; retries < SAN_COMMAND_MAX_RETRIES ; retries++ ) {
  302. /* Reopen block device if applicable */
  303. if ( sandev_needs_reopen ( sandev ) &&
  304. ( ( rc = sandev_reopen ( sandev ) ) != 0 ) ) {
  305. continue;
  306. }
  307. /* Start expiry timer */
  308. start_timer_fixed ( &sandev->timer, SAN_COMMAND_TIMEOUT );
  309. /* Initiate command */
  310. if ( ( rc = command ( sandev, params ) ) != 0 ) {
  311. stop_timer ( &sandev->timer );
  312. continue;
  313. }
  314. /* Wait for command to complete */
  315. while ( timer_running ( &sandev->timer ) )
  316. step();
  317. /* Exit on success */
  318. if ( ( rc = sandev->command_rc ) == 0 )
  319. return 0;
  320. }
  321. /* Sanity check */
  322. assert ( ! timer_running ( &sandev->timer ) );
  323. return rc;
  324. }
  325. /**
  326. * Reset SAN device
  327. *
  328. * @v sandev SAN device
  329. * @ret rc Return status code
  330. */
  331. int sandev_reset ( struct san_device *sandev ) {
  332. int rc;
  333. DBGC ( sandev, "SAN %#02x reset\n", sandev->drive );
  334. /* Close and reopen underlying block device */
  335. if ( ( rc = sandev_reopen ( sandev ) ) != 0 )
  336. return rc;
  337. return 0;
  338. }
  339. /**
  340. * Read from or write to SAN device
  341. *
  342. * @v sandev SAN device
  343. * @v lba Starting logical block address
  344. * @v count Number of logical blocks
  345. * @v buffer Data buffer
  346. * @v block_rw Block read/write method
  347. * @ret rc Return status code
  348. */
  349. int sandev_rw ( struct san_device *sandev, uint64_t lba,
  350. unsigned int count, userptr_t buffer,
  351. int ( * block_rw ) ( struct interface *control,
  352. struct interface *data,
  353. uint64_t lba, unsigned int count,
  354. userptr_t buffer, size_t len ) ) {
  355. union san_command_params params;
  356. unsigned int remaining;
  357. size_t frag_len;
  358. int rc;
  359. /* Initialise command parameters */
  360. params.rw.block_rw = block_rw;
  361. params.rw.buffer = buffer;
  362. params.rw.lba = ( lba << sandev->blksize_shift );
  363. params.rw.count = sandev->capacity.max_count;
  364. remaining = ( count << sandev->blksize_shift );
  365. /* Read/write fragments */
  366. while ( remaining ) {
  367. /* Determine fragment length */
  368. if ( params.rw.count > remaining )
  369. params.rw.count = remaining;
  370. /* Execute command */
  371. if ( ( rc = sandev_command ( sandev, sandev_command_rw,
  372. &params ) ) != 0 )
  373. return rc;
  374. /* Move to next fragment */
  375. frag_len = ( sandev->capacity.blksize * params.rw.count );
  376. params.rw.buffer = userptr_add ( params.rw.buffer, frag_len );
  377. params.rw.lba += params.rw.count;
  378. remaining -= params.rw.count;
  379. }
  380. return 0;
  381. }
  382. /**
  383. * Configure SAN device as a CD-ROM, if applicable
  384. *
  385. * @v sandev SAN device
  386. * @ret rc Return status code
  387. *
  388. * Both BIOS and UEFI require SAN devices to be accessed with a block
  389. * size of 2048. While we could require the user to configure the
  390. * block size appropriately, this is non-trivial and would impose a
  391. * substantial learning effort on the user. Instead, we check for the
  392. * presence of the ISO9660 primary volume descriptor and, if found,
  393. * then we force a block size of 2048 and map read/write requests
  394. * appropriately.
  395. */
  396. static int sandev_parse_iso9660 ( struct san_device *sandev ) {
  397. static const struct iso9660_primary_descriptor_fixed primary_check = {
  398. .type = ISO9660_TYPE_PRIMARY,
  399. .id = ISO9660_ID,
  400. };
  401. union {
  402. struct iso9660_primary_descriptor primary;
  403. char bytes[ISO9660_BLKSIZE];
  404. } *scratch;
  405. unsigned int blksize;
  406. unsigned int blksize_shift;
  407. unsigned int lba;
  408. unsigned int count;
  409. int rc;
  410. /* Calculate required blocksize shift for potential CD-ROM access */
  411. blksize = sandev->capacity.blksize;
  412. blksize_shift = 0;
  413. while ( blksize < ISO9660_BLKSIZE ) {
  414. blksize <<= 1;
  415. blksize_shift++;
  416. }
  417. if ( blksize > ISO9660_BLKSIZE ) {
  418. /* Cannot be a CD-ROM. This is not an error. */
  419. rc = 0;
  420. goto invalid_blksize;
  421. }
  422. lba = ( ISO9660_PRIMARY_LBA << blksize_shift );
  423. count = ( 1 << blksize_shift );
  424. /* Allocate scratch area */
  425. scratch = malloc ( ISO9660_BLKSIZE );
  426. if ( ! scratch ) {
  427. rc = -ENOMEM;
  428. goto err_alloc;
  429. }
  430. /* Read primary volume descriptor */
  431. if ( ( rc = sandev_rw ( sandev, lba, count, virt_to_user ( scratch ),
  432. block_read ) ) != 0 ) {
  433. DBGC ( sandev, "SAN %#02x could not read ISO9660 primary"
  434. "volume descriptor: %s\n",
  435. sandev->drive, strerror ( rc ) );
  436. goto err_rw;
  437. }
  438. /* Configure as CD-ROM if applicable */
  439. if ( memcmp ( &scratch->primary.fixed, &primary_check,
  440. sizeof ( primary_check ) ) == 0 ) {
  441. DBGC ( sandev, "SAN %#02x contains an ISO9660 filesystem; "
  442. "treating as CD-ROM\n", sandev->drive );
  443. sandev->blksize_shift = blksize_shift;
  444. sandev->is_cdrom = 1;
  445. }
  446. err_rw:
  447. free ( scratch );
  448. err_alloc:
  449. invalid_blksize:
  450. return rc;
  451. }
  452. /**
  453. * Allocate SAN device
  454. *
  455. * @ret sandev SAN device, or NULL
  456. */
  457. struct san_device * alloc_sandev ( struct uri *uri, size_t priv_size ) {
  458. struct san_device *sandev;
  459. /* Allocate and initialise structure */
  460. sandev = zalloc ( sizeof ( *sandev ) + priv_size );
  461. if ( ! sandev )
  462. return NULL;
  463. ref_init ( &sandev->refcnt, sandev_free );
  464. sandev->uri = uri_get ( uri );
  465. intf_init ( &sandev->block, &sandev_block_desc, &sandev->refcnt );
  466. sandev->block_rc = -EINPROGRESS;
  467. intf_init ( &sandev->command, &sandev_command_desc, &sandev->refcnt );
  468. timer_init ( &sandev->timer, sandev_command_expired, &sandev->refcnt );
  469. sandev->priv = ( ( ( void * ) sandev ) + sizeof ( *sandev ) );
  470. return sandev;
  471. }
  472. /**
  473. * Register SAN device
  474. *
  475. * @v sandev SAN device
  476. * @ret rc Return status code
  477. */
  478. int register_sandev ( struct san_device *sandev ) {
  479. int rc;
  480. /* Check that drive number is not in use */
  481. if ( sandev_find ( sandev->drive ) != NULL ) {
  482. DBGC ( sandev, "SAN %#02x is already in use\n", sandev->drive );
  483. return -EADDRINUSE;
  484. }
  485. /* Read device capacity */
  486. if ( ( rc = sandev_command ( sandev, sandev_command_read_capacity,
  487. NULL ) ) != 0 )
  488. return rc;
  489. /* Configure as a CD-ROM, if applicable */
  490. if ( ( rc = sandev_parse_iso9660 ( sandev ) ) != 0 )
  491. return rc;
  492. /* Add to list of SAN devices */
  493. list_add_tail ( &sandev->list, &san_devices );
  494. DBGC ( sandev, "SAN %#02x registered\n", sandev->drive );
  495. return 0;
  496. }
  497. /**
  498. * Unregister SAN device
  499. *
  500. * @v sandev SAN device
  501. */
  502. void unregister_sandev ( struct san_device *sandev ) {
  503. /* Sanity check */
  504. assert ( ! timer_running ( &sandev->timer ) );
  505. /* Shut down interfaces */
  506. intfs_shutdown ( 0, &sandev->block, &sandev->command, NULL );
  507. /* Remove from list of SAN devices */
  508. list_del ( &sandev->list );
  509. DBGC ( sandev, "SAN %#02x unregistered\n", sandev->drive );
  510. }
  511. /** The "san-drive" setting */
  512. const struct setting san_drive_setting __setting ( SETTING_SANBOOT_EXTRA,
  513. san-drive ) = {
  514. .name = "san-drive",
  515. .description = "SAN drive number",
  516. .tag = DHCP_EB_SAN_DRIVE,
  517. .type = &setting_type_uint8,
  518. };
  519. /**
  520. * Get default SAN drive number
  521. *
  522. * @ret drive Default drive number
  523. */
  524. unsigned int san_default_drive ( void ) {
  525. unsigned long drive;
  526. /* Use "san-drive" setting, if specified */
  527. if ( fetch_uint_setting ( NULL, &san_drive_setting, &drive ) >= 0 )
  528. return drive;
  529. /* Otherwise, default to booting from first hard disk */
  530. return SAN_DEFAULT_DRIVE;
  531. }