Sfoglia il codice sorgente

[block] Allow SAN retry count to be reconfigured

Allow the SAN retry count to be configured via the ${san-retry}
setting, defaulting to the current value of 10 retries if not
specified.

Note that setting a retry count of zero is inadvisable, since iSCSI
targets in particular will often report spurious errors such as "power
on occurred" for the first few commands.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 7 anni fa
parent
commit
6b385c9da3
3 ha cambiato i file con 61 aggiunte e 17 eliminazioni
  1. 52
    17
      src/core/sanboot.c
  2. 7
    0
      src/include/ipxe/dhcp.h
  3. 2
    0
      src/include/ipxe/sanboot.h

+ 52
- 17
src/core/sanboot.c Vedi File

65
 #define SAN_COMMAND_TIMEOUT ( 15 * TICKS_PER_SEC )
65
 #define SAN_COMMAND_TIMEOUT ( 15 * TICKS_PER_SEC )
66
 
66
 
67
 /**
67
 /**
68
- * Number of times to retry commands
68
+ * Default number of times to retry commands
69
  *
69
  *
70
  * We may need to retry commands.  For example, the underlying
70
  * We may need to retry commands.  For example, the underlying
71
  * connection may be closed by the SAN target due to an inactivity
71
  * connection may be closed by the SAN target due to an inactivity
72
  * timeout, or the SAN target may return pointless "error" messages
72
  * timeout, or the SAN target may return pointless "error" messages
73
  * such as "SCSI power-on occurred".
73
  * such as "SCSI power-on occurred".
74
  */
74
  */
75
-#define SAN_COMMAND_MAX_RETRIES 10
75
+#define SAN_DEFAULT_RETRIES 10
76
 
76
 
77
 /** List of SAN devices */
77
 /** List of SAN devices */
78
 LIST_HEAD ( san_devices );
78
 LIST_HEAD ( san_devices );
79
 
79
 
80
+/** Number of times to retry commands */
81
+static unsigned long san_retries = SAN_DEFAULT_RETRIES;
82
+
80
 /**
83
 /**
81
  * Find SAN device by drive number
84
  * Find SAN device by drive number
82
  *
85
  *
101
 static void sandev_free ( struct refcnt *refcnt ) {
104
 static void sandev_free ( struct refcnt *refcnt ) {
102
 	struct san_device *sandev =
105
 	struct san_device *sandev =
103
 		container_of ( refcnt, struct san_device, refcnt );
106
 		container_of ( refcnt, struct san_device, refcnt );
104
-	struct san_path *sanpath;
107
+	unsigned int i;
105
 
108
 
106
 	assert ( ! timer_running ( &sandev->timer ) );
109
 	assert ( ! timer_running ( &sandev->timer ) );
107
 	assert ( ! sandev->active );
110
 	assert ( ! sandev->active );
108
 	assert ( list_empty ( &sandev->opened ) );
111
 	assert ( list_empty ( &sandev->opened ) );
109
-	list_for_each_entry ( sanpath, &sandev->closed, list )
110
-		uri_put ( sanpath->uri );
112
+	for ( i = 0 ; i < sandev->paths ; i++ )
113
+		uri_put ( sandev->path[i].uri );
111
 	free ( sandev );
114
 	free ( sandev );
112
 }
115
 }
113
 
116
 
469
 		 int ( * command ) ( struct san_device *sandev,
472
 		 int ( * command ) ( struct san_device *sandev,
470
 				     const union san_command_params *params ),
473
 				     const union san_command_params *params ),
471
 		 const union san_command_params *params ) {
474
 		 const union san_command_params *params ) {
472
-	unsigned int retries;
475
+	unsigned int retries = 0;
473
 	int rc;
476
 	int rc;
474
 
477
 
475
 	/* Sanity check */
478
 	/* Sanity check */
476
 	assert ( ! timer_running ( &sandev->timer ) );
479
 	assert ( ! timer_running ( &sandev->timer ) );
477
 
480
 
478
 	/* (Re)try command */
481
 	/* (Re)try command */
479
-	for ( retries = 0 ; retries < SAN_COMMAND_MAX_RETRIES ; retries++ ) {
482
+	do {
480
 
483
 
481
 		/* Reopen block device if applicable */
484
 		/* Reopen block device if applicable */
482
 		if ( sandev_needs_reopen ( sandev ) &&
485
 		if ( sandev_needs_reopen ( sandev ) &&
484
 			continue;
487
 			continue;
485
 		}
488
 		}
486
 
489
 
487
-		/* Start expiry timer */
488
-		start_timer_fixed ( &sandev->timer, SAN_COMMAND_TIMEOUT );
489
-
490
 		/* Initiate command */
490
 		/* Initiate command */
491
-		if ( ( rc = command ( sandev, params ) ) != 0 ) {
492
-			stop_timer ( &sandev->timer );
491
+		if ( ( rc = command ( sandev, params ) ) != 0 )
493
 			continue;
492
 			continue;
494
-		}
493
+
494
+		/* Start expiry timer */
495
+		start_timer_fixed ( &sandev->timer, SAN_COMMAND_TIMEOUT );
495
 
496
 
496
 		/* Wait for command to complete */
497
 		/* Wait for command to complete */
497
 		while ( timer_running ( &sandev->timer ) )
498
 		while ( timer_running ( &sandev->timer ) )
498
 			step();
499
 			step();
499
 
500
 
500
-		/* Exit on success */
501
-		if ( ( rc = sandev->command_rc ) == 0 )
502
-			return 0;
503
-	}
501
+		/* Check command status */
502
+		if ( ( rc = sandev->command_rc ) != 0 )
503
+			continue;
504
+
505
+		return 0;
506
+
507
+	} while ( ++retries <= san_retries );
504
 
508
 
505
 	/* Sanity check */
509
 	/* Sanity check */
506
 	assert ( ! timer_running ( &sandev->timer ) );
510
 	assert ( ! timer_running ( &sandev->timer ) );
676
 	intf_init ( &sandev->command, &sandev_command_desc, &sandev->refcnt );
680
 	intf_init ( &sandev->command, &sandev_command_desc, &sandev->refcnt );
677
 	timer_init ( &sandev->timer, sandev_command_expired, &sandev->refcnt );
681
 	timer_init ( &sandev->timer, sandev_command_expired, &sandev->refcnt );
678
 	sandev->priv = ( ( ( void * ) sandev ) + size );
682
 	sandev->priv = ( ( ( void * ) sandev ) + size );
683
+	sandev->paths = count;
679
 	INIT_LIST_HEAD ( &sandev->opened );
684
 	INIT_LIST_HEAD ( &sandev->opened );
680
 	INIT_LIST_HEAD ( &sandev->closed );
685
 	INIT_LIST_HEAD ( &sandev->closed );
681
 	for ( i = 0 ; i < count ; i++ ) {
686
 	for ( i = 0 ; i < count ; i++ ) {
767
 	/* Otherwise, default to booting from first hard disk */
772
 	/* Otherwise, default to booting from first hard disk */
768
 	return SAN_DEFAULT_DRIVE;
773
 	return SAN_DEFAULT_DRIVE;
769
 }
774
 }
775
+
776
+/** The "san-retries" setting */
777
+const struct setting san_retries_setting __setting ( SETTING_SANBOOT_EXTRA,
778
+						     san-retries ) = {
779
+	.name = "san-retries",
780
+	.description = "SAN retry count",
781
+	.tag = DHCP_EB_SAN_RETRY,
782
+	.type = &setting_type_int8,
783
+};
784
+
785
+/**
786
+ * Apply SAN boot settings
787
+ *
788
+ * @ret rc		Return status code
789
+ */
790
+static int sandev_apply ( void ) {
791
+
792
+	/* Apply "san-retries" setting */
793
+	if ( fetch_uint_setting ( NULL, &san_retries_setting,
794
+				  &san_retries ) < 0 ) {
795
+		san_retries = SAN_DEFAULT_RETRIES;
796
+	}
797
+
798
+	return 0;
799
+}
800
+
801
+/** Settings applicator */
802
+struct settings_applicator sandev_applicator __settings_applicator = {
803
+	.apply = sandev_apply,
804
+};

+ 7
- 0
src/include/ipxe/dhcp.h Vedi File

433
 /** Use cached network settings (obsolete; do not reuse this value) */
433
 /** Use cached network settings (obsolete; do not reuse this value) */
434
 #define DHCP_EB_USE_CACHED DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb2 )
434
 #define DHCP_EB_USE_CACHED DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb2 )
435
 
435
 
436
+/** SAN retry count
437
+ *
438
+ * This is the maximum number of times that SAN operations will be
439
+ * retried.
440
+ */
441
+#define DHCP_EB_SAN_RETRY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbb )
442
+
436
 /** SAN drive number
443
 /** SAN drive number
437
  *
444
  *
438
  * This is the drive number for a SAN-hooked drive.  For BIOS, 0x80 is
445
  * This is the drive number for a SAN-hooked drive.  For BIOS, 0x80 is

+ 2
- 0
src/include/ipxe/sanboot.h Vedi File

71
 	/** Driver private data */
71
 	/** Driver private data */
72
 	void *priv;
72
 	void *priv;
73
 
73
 
74
+	/** Number of paths */
75
+	unsigned int paths;
74
 	/** Current active path */
76
 	/** Current active path */
75
 	struct san_path *active;
77
 	struct san_path *active;
76
 	/** List of opened SAN paths */
78
 	/** List of opened SAN paths */

Loading…
Annulla
Salva