Переглянути джерело

[fc] Add Fibre Channel management commands

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 роки тому
джерело
коміт
bf2657075d

+ 24
- 0
src/config/config_fc.c Переглянути файл

@@ -0,0 +1,24 @@
1
+/*
2
+ * This program is free software; you can redistribute it and/or
3
+ * modify it under the terms of the GNU General Public License as
4
+ * published by the Free Software Foundation; either version 2, or (at
5
+ * your option) any later version.
6
+ */
7
+
8
+FILE_LICENCE ( GPL2_OR_LATER );
9
+
10
+#include <config/general.h>
11
+
12
+/** @file
13
+ *
14
+ * Fibre Channel configuration options
15
+ *
16
+ */
17
+
18
+/*
19
+ * Drag in Fibre Channel-specific commands
20
+ *
21
+ */
22
+#ifdef FCMGMT_CMD
23
+REQUIRE_OBJECT ( fcmgmt_cmd );
24
+#endif

+ 1
- 0
src/config/general.h Переглянути файл

@@ -112,6 +112,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
112 112
 #define	CONFIG_CMD		/* Option configuration console */
113 113
 #define	IFMGMT_CMD		/* Interface management commands */
114 114
 #define	IWMGMT_CMD		/* Wireless interface management commands */
115
+#define FCMGMT_CMD		/* Fibre Channel management commands */
115 116
 #define	ROUTE_CMD		/* Routing table management commands */
116 117
 #define IMAGE_CMD		/* Image management commands */
117 118
 #define DHCP_CMD		/* DHCP management commands */

+ 189
- 0
src/hci/commands/fcmgmt_cmd.c Переглянути файл

@@ -0,0 +1,189 @@
1
+/*
2
+ * Copyright (C) 2010 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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+#include <stdio.h>
22
+#include <getopt.h>
23
+#include <strings.h>
24
+#include <ipxe/fc.h>
25
+#include <ipxe/fcels.h>
26
+#include <ipxe/command.h>
27
+#include <ipxe/tables.h>
28
+#include <usr/fcmgmt.h>
29
+
30
+/** @file
31
+ *
32
+ * Fibre Channel management commands
33
+ *
34
+ */
35
+
36
+static void fcstat_syntax ( char **argv ) {
37
+	printf ( "Usage:\n  %s\n", argv[0] );
38
+}
39
+
40
+static int fcstat_exec ( int argc, char **argv ) {
41
+	static struct option fcstat_opts[] = {
42
+		{ "help", 0, NULL, 'h' },
43
+		{ NULL, 0, NULL, 0 },
44
+	};
45
+	struct fc_port *port;
46
+	struct fc_peer *peer;
47
+	int c;
48
+
49
+	/* Parse options */
50
+	while ( ( c = getopt_long ( argc, argv, "h", fcstat_opts,
51
+				    NULL ) ) >= 0 ) {
52
+		switch ( c ) {
53
+		case 'h':
54
+			/* Display help text */
55
+		default:
56
+			/* Unrecognised/invalid option */
57
+			fcstat_syntax ( argv );
58
+			return 1;
59
+		}
60
+	}
61
+
62
+	if ( optind != argc ) {
63
+		fcstat_syntax ( argv );
64
+		return 1;
65
+	}
66
+
67
+	list_for_each_entry ( port, &fc_ports, list )
68
+		fcportstat ( port );
69
+	list_for_each_entry ( peer, &fc_peers, list )
70
+		fcpeerstat ( peer );
71
+
72
+	return 0;
73
+}
74
+
75
+static void fcels_syntax ( char **argv ) {
76
+	printf ( "Usage:\n  %s [--port <port>] [--id <peer port id>]"
77
+		 " <command>\n", argv[0] );
78
+}
79
+
80
+static struct fc_els_handler * fcels_find_handler ( const char *name ) {
81
+	struct fc_els_handler *handler;
82
+
83
+	for_each_table_entry ( handler, FC_ELS_HANDLERS ) {
84
+		if ( strcasecmp ( handler->name, name ) == 0 )
85
+			return handler;
86
+	}
87
+	return NULL;
88
+}
89
+
90
+static int fcels_exec ( int argc, char **argv ) {
91
+	static struct option fcels_opts[] = {
92
+		{ "help", 0, NULL, 'h' },
93
+		{ "port", required_argument, NULL, 'p' },
94
+		{ "id", required_argument, NULL, 'i' },
95
+		{ NULL, 0, NULL, 0 },
96
+	};
97
+	const char *handler_text;
98
+	const char *port_text = NULL;
99
+	const char *id_text = NULL;
100
+	struct fc_els_handler *handler;
101
+	struct fc_port *port;
102
+	struct fc_port_id id_buf;
103
+	struct fc_port_id *id;
104
+	int c;
105
+
106
+	/* Parse options */
107
+	while ( ( c = getopt_long ( argc, argv, "hp:i:", fcels_opts,
108
+				    NULL ) ) >= 0 ) {
109
+		switch ( c ) {
110
+		case 'p':
111
+			port_text = optarg;
112
+			break;
113
+		case 'i':
114
+			id_text = optarg;
115
+			break;
116
+		case 'h':
117
+			/* Display help text */
118
+		default:
119
+			/* Unrecognised/invalid option */
120
+			fcels_syntax ( argv );
121
+			return 1;
122
+		}
123
+	}
124
+
125
+	/* Identify ELS */
126
+	if ( optind != ( argc - 1 ) ) {
127
+		fcels_syntax ( argv );
128
+		return 1;
129
+	}
130
+	handler_text = argv[optind];
131
+	handler = fcels_find_handler ( handler_text );
132
+	if ( ! handler ) {
133
+		printf ( "%s: unrecognised ELS\n", handler_text );
134
+		return 1;
135
+	}
136
+
137
+	/* Identify port */
138
+	if ( port_text ) {
139
+		/* Use specified port */
140
+		port = fc_port_find ( port_text );
141
+		if ( ! port ) {
142
+			printf ( "%s: no such port\n", port_text );
143
+			return 1;
144
+		}
145
+	} else {
146
+		/* Use first port */
147
+		if ( list_empty ( &fc_ports ) ) {
148
+			printf ( "No ports\n" );
149
+			return 1;
150
+		}
151
+		list_for_each_entry ( port, &fc_ports, list )
152
+			break;
153
+	}
154
+	assert ( port != NULL );
155
+
156
+	/* Identify port ID */
157
+	if ( id_text ) {
158
+		if ( fc_id_aton ( id_text, &id_buf ) != 0 ) {
159
+			printf ( "%s: invalid port ID\n", id_text );
160
+			return 1;
161
+		}
162
+		id = &id_buf;
163
+	} else {
164
+		if ( fc_link_ok ( &port->link ) &&
165
+		     ! ( port->flags & FC_PORT_HAS_FABRIC ) ) {
166
+			id = &port->ptp_link_port_id;
167
+		} else {
168
+			id = &fc_f_port_id;
169
+		}
170
+	}
171
+	assert ( id != NULL );
172
+
173
+	if ( fcels ( port, id, handler ) != 0 )
174
+		return 1;
175
+
176
+	return 0;
177
+}
178
+
179
+/** Fibre Channel management commands */
180
+struct command fcmgmt_commands[] __command = {
181
+	{
182
+		.name = "fcstat",
183
+		.exec = fcstat_exec,
184
+	},
185
+	{
186
+		.name = "fcels",
187
+		.exec = fcels_exec,
188
+	},
189
+};

+ 21
- 0
src/include/usr/fcmgmt.h Переглянути файл

@@ -0,0 +1,21 @@
1
+#ifndef _USR_FCMGMT_H
2
+#define _USR_FCMGMT_H
3
+
4
+/** @file
5
+ *
6
+ * Fibre Channel management
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+struct fc_port;
13
+struct fc_peer;
14
+struct fc_els_handler;
15
+
16
+extern void fcportstat ( struct fc_port *port );
17
+extern void fcpeerstat ( struct fc_peer *peer );
18
+extern int fcels ( struct fc_port *port, struct fc_port_id *peer_port_id,
19
+		   struct fc_els_handler *handler );
20
+
21
+#endif /* _USR_FCMGMT_H */

+ 117
- 0
src/usr/fcmgmt.c Переглянути файл

@@ -0,0 +1,117 @@
1
+/*
2
+ * Copyright (C) 2010 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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+#include <string.h>
22
+#include <stdio.h>
23
+#include <errno.h>
24
+#include <ipxe/fc.h>
25
+#include <ipxe/fcels.h>
26
+#include <ipxe/monojob.h>
27
+#include <usr/fcmgmt.h>
28
+
29
+/** @file
30
+ *
31
+ * Fibre Channel management
32
+ *
33
+ */
34
+
35
+/**
36
+ * Print status of Fibre Channel port
37
+ *
38
+ * @v port		Fibre Channel port
39
+ */
40
+void fcportstat ( struct fc_port *port ) {
41
+	printf ( "%s: %s", port->name, fc_ntoa ( &port->node_wwn ) );
42
+	printf ( " port %s id %s\n  [Link:", fc_ntoa ( &port->port_wwn ),
43
+		 fc_id_ntoa ( &port->port_id ) );
44
+	if ( fc_link_ok ( &port->link ) ) {
45
+		printf ( " up, %s", fc_ntoa ( &port->link_node_wwn ) );
46
+		printf ( " port %s", fc_ntoa ( &port->link_port_wwn ) );
47
+		if ( ( port->flags & FC_PORT_HAS_FABRIC ) ) {
48
+			printf ( " fabric" );
49
+		} else {
50
+			printf ( " id %s",
51
+				 fc_id_ntoa ( &port->ptp_link_port_id ) );
52
+		}
53
+		printf ( "]\n" );
54
+	} else {
55
+		printf ( " down: %s]\n", strerror ( port->link.rc ) );
56
+	}
57
+}
58
+
59
+/**
60
+ * Print status of Fibre Channel peer
61
+ *
62
+ * @v peer		Fibre Channel peer
63
+ */
64
+void fcpeerstat ( struct fc_peer *peer ) {
65
+	struct fc_ulp *ulp;
66
+	uint8_t *param;
67
+	unsigned int i;
68
+
69
+	printf ( "%s:\n  [Link:", fc_ntoa ( &peer->node_wwn ) );
70
+	if ( fc_link_ok ( &peer->link ) ) {
71
+		printf ( " up, port %s id %s]\n", peer->port->name,
72
+			 fc_id_ntoa ( &peer->port_id ) );
73
+	} else {
74
+		printf ( " down: %s]\n", strerror ( peer->link.rc ) );
75
+	}
76
+
77
+	list_for_each_entry ( ulp, &peer->ulps, list ) {
78
+		printf ( "  [Type %02x usage %d link:",
79
+			 ulp->type, ulp->usage );
80
+		if ( fc_link_ok ( &ulp->link ) ) {
81
+			printf ( " up, params" );
82
+			param = ulp->param;
83
+			for ( i = 0 ; i < ulp->param_len ; i++ ) {
84
+				printf ( "%c%02x", ( ( i == 0 ) ? ' ' : ':' ),
85
+					 param[i] );
86
+			}
87
+		} else {
88
+			printf ( " down: %s", strerror ( ulp->link.rc ) );
89
+		}
90
+		printf ( "]\n" );
91
+	}
92
+}
93
+
94
+/**
95
+ * Issue Fibre Channel ELS
96
+ *
97
+ * @v port		Fibre Channel port
98
+ * @v peer_port_id	Peer port ID
99
+ * @v handler		ELS handler
100
+ * @ret rc		Return status code
101
+ */
102
+int fcels ( struct fc_port *port, struct fc_port_id *peer_port_id,
103
+	    struct fc_els_handler *handler ) {
104
+	int rc;
105
+
106
+	/* Initiate ELS */
107
+	printf ( "%s %s to %s...",
108
+		 port->name, handler->name, fc_id_ntoa ( peer_port_id ) );
109
+	if ( ( rc = fc_els_request ( &monojob, port, peer_port_id,
110
+				     handler ) ) != 0 ) {
111
+		printf ( "%s\n", strerror ( rc ) );
112
+		return rc;
113
+	}
114
+
115
+	/* Wait for ELS to complete */
116
+	return monojob_wait ( "" );
117
+}

Завантаження…
Відмінити
Зберегти