components/open-fabrics/infiniband-diags/solaris_set_nodedesc.c
changeset 369 cc8c00719da9
child 636 da28b1dc61e7
equal deleted inserted replaced
368:9a01d3a61f01 369:cc8c00719da9
       
     1 /*
       
     2  * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
       
     3  *
       
     4  * This software is available to you under a choice of one of two
       
     5  * licenses.  You may choose to be licensed under the terms of the GNU
       
     6  * General Public License (GPL) Version 2, available from the file
       
     7  * COPYING in the main directory of this source tree, or the
       
     8  * OpenIB.org BSD license below:
       
     9  *
       
    10  *     Redistribution and use in source and binary forms, with or
       
    11  *     without modification, are permitted provided that the following
       
    12  *     conditions are met:
       
    13  *
       
    14  *      - Redistributions of source code must retain the above
       
    15  *        copyright notice, this list of conditions and the following
       
    16  *        disclaimer.
       
    17  *
       
    18  *      - Redistributions in binary form must reproduce the above
       
    19  *        copyright notice, this list of conditions and the following
       
    20  *        disclaimer in the documentation and/or other materials
       
    21  *        provided with the distribution.
       
    22  *
       
    23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
       
    24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       
    25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
       
    26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
       
    27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
       
    28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
       
    29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
       
    30  * SOFTWARE.
       
    31  */
       
    32 
       
    33 /*
       
    34  * OFED Solaris wrapper
       
    35  */
       
    36 #if defined(__SVR4) && defined(__sun)
       
    37 
       
    38 #pragma ident	"@(#)solaris_set_nodedesc.c	1.2	11/01/25 SMI"
       
    39 
       
    40 #include <stdio.h>
       
    41 #include <stdlib.h>
       
    42 #include <unistd.h>
       
    43 #include <sys/types.h>
       
    44 #include <sys/stat.h>
       
    45 #include <sys/sysmacros.h>
       
    46 #include <sys/queue.h>
       
    47 #include <fcntl.h>
       
    48 #include <ctype.h>
       
    49 #include <string.h>
       
    50 #include <strings.h>
       
    51 #include <getopt.h>
       
    52 #include <libdevinfo.h>
       
    53 #include <sys/utsname.h>
       
    54 
       
    55 #include <infiniband/verbs.h>
       
    56 #include <infiniband/arch.h>
       
    57 
       
    58 #include <sys/ib/adapters/tavor/tavor_ioctl.h>
       
    59 #include <sys/ib/adapters/hermon/hermon_ioctl.h>
       
    60 
       
    61 /*
       
    62  * Local defines for HCA driver IOCTLs, used while
       
    63  * building on build system without the change in
       
    64  * header files.
       
    65  */
       
    66 #ifdef	HERMON_NODEDESC_UPDATE_STR
       
    67 #define	HERMON_NODEDESC_UPDATE_STRING		0x00000001
       
    68 #endif
       
    69 #ifndef	HERMON_NODEDESC_UPDATE_HCA_STRING
       
    70 #define	HERMON_NODEDESC_UPDATE_HCA_STRING	0x00000002
       
    71 #undef	HERMON_NODEDESC_UPDATE_HCA_MAP
       
    72 #endif
       
    73 #ifndef HERMON_IOCTL_GET_NODEDESC
       
    74 #define	HERMON_IOCTL_GET_NODEDESC	(('t' << 8) | 0x31)
       
    75 #endif
       
    76 
       
    77 #ifdef	TAVOR_NODEDESC_UPDATE_STR
       
    78 #define	TAVOR_NODEDESC_UPDATE_STRING		0x00000001
       
    79 #endif
       
    80 #ifndef	TAVOR_NODEDESC_UPDATE_HCA_STRING
       
    81 #define	TAVOR_NODEDESC_UPDATE_HCA_STRING	0x00000002
       
    82 #undef	TAVOR_NODEDESC_UPDATE_HCA_MAP
       
    83 #endif
       
    84 #ifndef TAVOR_IOCTL_GET_NODEDESC
       
    85 #define	TAVOR_IOCTL_GET_NODEDESC	(('t' << 8) | 0x31)
       
    86 #endif
       
    87 
       
    88 #define	NODEDESC_UPDATE_STRING		0x00000001
       
    89 #define	NODEDESC_UPDATE_HCA_STRING	0x00000002
       
    90 #define	NODEDESC_READ			0x80000000
       
    91 
       
    92 #include "ibdiag_common.h"
       
    93 
       
    94 static char *devpath_prefix = "/devices";
       
    95 static char *devpath_suffix = ":devctl";
       
    96 static char *ib_hca_driver_list[] = {
       
    97 	"tavor", "hermon", NULL
       
    98 };
       
    99 static di_node_t	di_rootnode;
       
   100 char *argv0 = "solaris_set_nodedesc";
       
   101 
       
   102 #define	MAX_HCAS	32
       
   103 static struct nodedesc_read_info_s {
       
   104 	boolean_t	info_valid;
       
   105 	uint64_t	guid;
       
   106 	char		nd_string[64];
       
   107 	boolean_t	ofuv_name_valid;
       
   108 	char		ofuv_name[64];
       
   109 } nd_read_info_arr[MAX_HCAS];
       
   110 int	nd_read_info_cnt;
       
   111 
       
   112 static void
       
   113 print_read_info()
       
   114 {
       
   115 	int	j;
       
   116 
       
   117 	for (j = 0; j < nd_read_info_cnt; j++) {
       
   118 		if (nd_read_info_arr[j].info_valid == B_FALSE ||
       
   119 		    nd_read_info_arr[j].ofuv_name_valid == B_FALSE)
       
   120 			continue;
       
   121 		printf("%s: %-16s\n",
       
   122 		    nd_read_info_arr[j].ofuv_name,
       
   123 		    nd_read_info_arr[j].nd_string);
       
   124 	}
       
   125 }
       
   126 
       
   127 static void
       
   128 update_read_info_hwnames()
       
   129 {
       
   130 	struct ibv_device **dev_list;
       
   131 	int num_devices, i;
       
   132 	uint64_t	dev_guid;
       
   133 	char		*dev_name;
       
   134 	size_t		dev_name_len;
       
   135 
       
   136 	dev_list = ibv_get_device_list(&num_devices);
       
   137 	if (!dev_list) {
       
   138 		fprintf(stderr, "No IB devices found\n");
       
   139 		return;
       
   140 	}
       
   141 
       
   142 	for (i = 0; i < num_devices; ++i) {
       
   143 		int	j;
       
   144 
       
   145 		dev_guid = (uint64_t)ntohll(ibv_get_device_guid(dev_list[i]));
       
   146 		dev_name = (char *)ibv_get_device_name(dev_list[i]);
       
   147 		dev_name_len = strlen(dev_name) + 1;
       
   148 		for (j = 0; j < nd_read_info_cnt; j++) {
       
   149 			if (nd_read_info_arr[j].info_valid == B_TRUE &&
       
   150 			    nd_read_info_arr[j].guid == dev_guid) {
       
   151 				memcpy(nd_read_info_arr[j].ofuv_name,
       
   152 				    dev_name, dev_name_len);
       
   153 				nd_read_info_arr[j].ofuv_name_valid = B_TRUE;
       
   154 				break;
       
   155 			}
       
   156 		}
       
   157 	}
       
   158 
       
   159 	ibv_free_device_list(dev_list);
       
   160 }
       
   161 
       
   162 static void
       
   163 add_read_info_arr(char *nd_str, uint64_t guid)
       
   164 {
       
   165 	size_t	nd_len;
       
   166 
       
   167 	nd_len = strlen(nd_str) + 1;
       
   168 	nd_read_info_arr[nd_read_info_cnt].info_valid = B_TRUE;
       
   169 	nd_read_info_arr[nd_read_info_cnt].guid = guid;
       
   170 	memcpy(nd_read_info_arr[nd_read_info_cnt].nd_string, nd_str, nd_len);
       
   171 	nd_read_info_cnt++;
       
   172 
       
   173 }
       
   174 
       
   175 static void
       
   176 do_driver_read_ioctl(char *drivername)
       
   177 {
       
   178 	di_node_t	hcanode, childnode;
       
   179 	char		*devpath;
       
   180 	char		*access_devname;
       
   181 	int		devlength, devfd, rc = -1;
       
   182 	uint64_t	*hca_guid;
       
   183 
       
   184 	if ((hcanode = di_drv_first_node(drivername, di_rootnode))
       
   185 	    == DI_NODE_NIL) {
       
   186 		return;
       
   187 	}
       
   188 
       
   189 	while (hcanode != DI_NODE_NIL) {
       
   190 		childnode = di_child_node(hcanode);
       
   191 		while (childnode != DI_NODE_NIL) {
       
   192 			if (di_prop_lookup_int64(DDI_DEV_T_ANY,
       
   193 			    childnode, "hca-guid",
       
   194 			    (int64_t **)&hca_guid) != 1) {
       
   195 				childnode = di_sibling_node(childnode);
       
   196 				continue;
       
   197 			} else {
       
   198 				break;
       
   199 			}
       
   200 		}
       
   201 		if (childnode == DI_NODE_NIL) {
       
   202 			hcanode = di_drv_next_node(hcanode);
       
   203 			continue;
       
   204 		}
       
   205 
       
   206 		devpath = di_devfs_path(hcanode);
       
   207 		devlength = strlen(devpath_prefix) + strlen(devpath) +
       
   208 		    strlen(devpath_suffix) + 2;
       
   209 		access_devname = malloc(devlength);
       
   210 		(void) snprintf(access_devname, devlength, "%s%s%s",
       
   211 		    devpath_prefix, devpath, devpath_suffix);
       
   212 		if ((devfd = open(access_devname, O_RDONLY)) < 0) {
       
   213 			IBERROR("open device file %s failed", access_devname);
       
   214 			free(access_devname);
       
   215 			hcanode = di_drv_next_node(hcanode);
       
   216 			continue;
       
   217 		}
       
   218 		if (strcmp(drivername, "tavor") == 0) {
       
   219 			tavor_nodedesc_ioctl_t		nodedesc_ioctl;
       
   220 
       
   221 			if ((rc = ioctl(devfd, TAVOR_IOCTL_GET_NODEDESC,
       
   222 			    (void *)&nodedesc_ioctl)) != 0) {
       
   223 				IBERROR("tavor ioctl failure");
       
   224 				free(access_devname);
       
   225 				close(devfd);
       
   226 				hcanode = di_drv_next_node(hcanode);
       
   227 				continue;
       
   228 			}
       
   229 			add_read_info_arr((char *)nodedesc_ioctl.node_desc_str,
       
   230 			    *hca_guid);
       
   231 		} else if (strcmp(drivername, "hermon") == 0) {
       
   232 			hermon_nodedesc_ioctl_t		nodedesc_ioctl;
       
   233 
       
   234 			if ((rc = ioctl(devfd, HERMON_IOCTL_GET_NODEDESC,
       
   235 			    (void *)&nodedesc_ioctl)) != 0) {
       
   236 				IBERROR("hermon ioctl failure");
       
   237 				free(access_devname);
       
   238 				close(devfd);
       
   239 				hcanode = di_drv_next_node(hcanode);
       
   240 				continue;
       
   241 			}
       
   242 			add_read_info_arr((char *)nodedesc_ioctl.node_desc_str,
       
   243 			    *hca_guid);
       
   244 		}
       
   245 
       
   246 		free(access_devname);
       
   247 		close(devfd);
       
   248 		hcanode = di_drv_next_node(hcanode);
       
   249 	}
       
   250 
       
   251 }
       
   252 
       
   253 static int
       
   254 do_driver_update_ioctl(char *drivername, char *node_desc, char *hca_desc,
       
   255     uint64_t inp_hca_guid, uint32_t update_flag)
       
   256 {
       
   257 	di_node_t	hcanode, childnode;
       
   258 	char		*devpath;
       
   259 	char		*access_devname;
       
   260 	int		devlength, devfd, rc = -1;
       
   261 	uint64_t	*hca_guid;
       
   262 	char		*desc_str = (node_desc ? node_desc : hca_desc);
       
   263 
       
   264 	if ((hcanode = di_drv_first_node(drivername, di_rootnode))
       
   265 	    == DI_NODE_NIL) {
       
   266 		return (-1);
       
   267 	}
       
   268 
       
   269 	while (hca_desc && hcanode != DI_NODE_NIL) {
       
   270 		childnode = di_child_node(hcanode);
       
   271 		while (childnode != DI_NODE_NIL) {
       
   272 			if (di_prop_lookup_int64(DDI_DEV_T_ANY,
       
   273 			    childnode, "hca-guid",
       
   274 			    (int64_t **)&hca_guid) != 1) {
       
   275 				childnode = di_sibling_node(childnode);
       
   276 				continue;
       
   277 			} else {
       
   278 				break;
       
   279 			}
       
   280 		}
       
   281 		if (*hca_guid == inp_hca_guid)
       
   282 			break;
       
   283 		hcanode = di_drv_next_node(hcanode);
       
   284 	}
       
   285 
       
   286 	if ((hca_desc && childnode == DI_NODE_NIL) ||
       
   287 	    hcanode == DI_NODE_NIL) {
       
   288 		IBERROR("matching GUID not found");
       
   289 		return (-1);
       
   290 	}
       
   291 
       
   292 	devpath = di_devfs_path(hcanode);
       
   293 	devlength = strlen(devpath_prefix) + strlen(devpath) +
       
   294 	    strlen(devpath_suffix) + 2;
       
   295 	access_devname = malloc(devlength);
       
   296 	(void) snprintf(access_devname, devlength, "%s%s%s",
       
   297 	    devpath_prefix, devpath, devpath_suffix);
       
   298 	if ((devfd = open(access_devname, O_RDONLY)) < 0) {
       
   299 		IBERROR("open device file %s failed", access_devname);
       
   300 		free(access_devname);
       
   301 		return (rc);
       
   302 	}
       
   303 	if (strcmp(drivername, "tavor") == 0) {
       
   304 		tavor_nodedesc_ioctl_t		nodedesc_ioctl;
       
   305 
       
   306 		strncpy(nodedesc_ioctl.node_desc_str, desc_str, 64);
       
   307 		if (update_flag & NODEDESC_UPDATE_STRING)
       
   308 			nodedesc_ioctl.node_desc_update_flag =
       
   309 			    TAVOR_NODEDESC_UPDATE_STRING;
       
   310 		else if (update_flag & NODEDESC_UPDATE_HCA_STRING)
       
   311 			nodedesc_ioctl.node_desc_update_flag =
       
   312 			    TAVOR_NODEDESC_UPDATE_HCA_STRING;
       
   313 		else {
       
   314 			IBERROR("Invalid option");
       
   315 			exit(-1);
       
   316 		}
       
   317 		if ((rc = ioctl(devfd, TAVOR_IOCTL_SET_NODEDESC,
       
   318 		    (void *)&nodedesc_ioctl)) != 0) {
       
   319 			IBERROR("tavor ioctl failure");
       
   320 		}
       
   321 	} else if (strcmp(drivername, "hermon") == 0) {
       
   322 		hermon_nodedesc_ioctl_t		nodedesc_ioctl;
       
   323 
       
   324 		strncpy(nodedesc_ioctl.node_desc_str, desc_str, 64);
       
   325 		if (update_flag & NODEDESC_UPDATE_STRING)
       
   326 			nodedesc_ioctl.node_desc_update_flag =
       
   327 			    HERMON_NODEDESC_UPDATE_STRING;
       
   328 		else if (update_flag & NODEDESC_UPDATE_HCA_STRING)
       
   329 			nodedesc_ioctl.node_desc_update_flag =
       
   330 			    HERMON_NODEDESC_UPDATE_HCA_STRING;
       
   331 		else {
       
   332 			IBERROR("Invalid option");
       
   333 			exit(-1);
       
   334 		}
       
   335 		if ((rc = ioctl(devfd, HERMON_IOCTL_SET_NODEDESC,
       
   336 		    (void *)&nodedesc_ioctl)) != 0) {
       
   337 			IBERROR("hermon ioctl failure");
       
   338 		}
       
   339 	}
       
   340 
       
   341 	free(access_devname);
       
   342 	close(devfd);
       
   343 	return (rc);
       
   344 }
       
   345 
       
   346 static void
       
   347 read_nodedesc()
       
   348 {
       
   349 	int	i;
       
   350 
       
   351 	if ((di_rootnode = di_init("/", DINFOCPYALL | DINFOFORCE))
       
   352 	    == DI_NODE_NIL) {
       
   353 		IBERROR("read_nodedesc di_init failure");
       
   354 		return;
       
   355 	}
       
   356 	for (i = 0; ib_hca_driver_list[i]; i++)
       
   357 		do_driver_read_ioctl(ib_hca_driver_list[i]);
       
   358 	di_fini(di_rootnode);
       
   359 }
       
   360 
       
   361 static int
       
   362 update_nodedesc(char *cmn_nodedesc, char *hca_nodedesc, uint64_t guid,
       
   363     uint32_t update_flag)
       
   364 {
       
   365 	int	i, rc = 0;
       
   366 
       
   367 	if ((di_rootnode = di_init("/", DINFOCPYALL | DINFOFORCE))
       
   368 	    == DI_NODE_NIL) {
       
   369 		IBERROR("di_init failure");
       
   370 		return (-1);
       
   371 	}
       
   372 	for (i = 0; ib_hca_driver_list[i]; i++) {
       
   373 		rc = do_driver_update_ioctl(ib_hca_driver_list[i],
       
   374 		    cmn_nodedesc, hca_nodedesc, guid,
       
   375 		    update_flag);
       
   376 		if (!rc)
       
   377 			break;
       
   378 	}
       
   379 	if (rc)
       
   380 		IBERROR("Updated failed for all HCA drivers");
       
   381 
       
   382 	di_fini(di_rootnode);
       
   383 	return (rc);
       
   384 }
       
   385 
       
   386 static void
       
   387 usage(void)
       
   388 {
       
   389 	char *basename;
       
   390 
       
   391 	if (!(basename = strrchr(argv0, '/')))
       
   392 		basename = argv0;
       
   393 	else
       
   394 		basename++;
       
   395 
       
   396 	fprintf(stderr, "Usage: %s \n", basename);
       
   397 	fprintf(stderr, "\t\t %s [-N(ode_Descriptor) CmnString]\n",
       
   398 	    basename);
       
   399 	fprintf(stderr, "\t\t %s [-H(CA_Description) HCAString "
       
   400 	    "-G(UID) HCA_GUID]\n", basename);
       
   401 	fprintf(stderr, "\t\t %s [-H(CA_Description) HCAString "
       
   402 	    "-G(UID) HCA_GUID -N(ode_Descriptor) CmnString]\n",
       
   403 	    basename);
       
   404 	fprintf(stderr, "\t\t %s [-v]\n", basename);
       
   405 }
       
   406 
       
   407 /*
       
   408  * Return the Node descriptor string by concatinating
       
   409  * many substrings. The first substring is "optarg" and
       
   410  * the index of the last sub-string is "optind".
       
   411  *
       
   412  * For common nodedescription, add a space at the end,
       
   413  * if there is none.
       
   414  */
       
   415 static char *
       
   416 nodedesc_substr_cat(char **argv, int argc, boolean_t space_at_end)
       
   417 {
       
   418 	int	i, start_opt, end_opt;
       
   419 	char	*nodedesc_str;
       
   420 
       
   421 	/* Get the index for first sub-string. */
       
   422 	for (start_opt = 0, i = optind; i; i--) {
       
   423 		if (argv[i] == NULL)
       
   424 			continue;
       
   425 
       
   426 		if (strcmp(argv[i], optarg) == 0) {
       
   427 			start_opt = i;
       
   428 			break;
       
   429 		}
       
   430 	}
       
   431 	if (start_opt == 0)
       
   432 		return (NULL);
       
   433 
       
   434 	/* Get the index for last sub-string */
       
   435 	for (end_opt = 0, i = optind; i <= argc; i++) {
       
   436 		if (i == argc || argv[i][0] == '-') {
       
   437 			end_opt = i - 1;
       
   438 			break;
       
   439 		}
       
   440 	}
       
   441 	if (end_opt == 0)
       
   442 		return (NULL);
       
   443 
       
   444 	nodedesc_str = malloc(64);
       
   445 	strncpy(nodedesc_str, optarg, 64);
       
   446 	start_opt++;
       
   447 
       
   448 	/*
       
   449 	 * strcat a space string and then strcat the
       
   450 	 * next sub-string.
       
   451 	 */
       
   452 	for (i = start_opt; i <= end_opt; i++) {
       
   453 		strncat(nodedesc_str, " ", 64);
       
   454 		strncat(nodedesc_str, argv[i], 64);
       
   455 	}
       
   456 
       
   457 	/*
       
   458 	 * Add a space at the end, if the caller has set
       
   459 	 * space_at_end and the nodedesc string doesn't
       
   460 	 * contain a space at the end.
       
   461 	 */
       
   462 	if (space_at_end == B_TRUE &&
       
   463 	    nodedesc_str[strlen(nodedesc_str)] != ' ')
       
   464 		strncat(nodedesc_str, " ", 64);
       
   465 	return (nodedesc_str);
       
   466 }
       
   467 
       
   468 int
       
   469 main(int argc, char **argv)
       
   470 {
       
   471 	int		rc;
       
   472 	char		*nodedesc = NULL, *hcadesc = NULL;
       
   473 	uint32_t	update_flag = 0;
       
   474 	struct utsname	uts_name;
       
   475 	uint64_t	hca_guid;
       
   476 	boolean_t	guid_inited = B_FALSE;
       
   477 	extern int ibdebug;
       
   478 
       
   479 	static char const str_opts[] = "N:H:G:vd";
       
   480 	static const struct option long_opts[] = {
       
   481 		{ "Node_Descriptor", 1, 0, 'N'},
       
   482 		{ "HCA_Description", 1, 0, 'H'},
       
   483 		{ "GUID", 1, 0, 'G'},
       
   484 		{ "verbose", 0, 0, 'v'},
       
   485 		{ "debug", 0, 0, 'd'},
       
   486 		{ }
       
   487 	};
       
   488 
       
   489 	argv0 = argv[0];
       
   490 	while (1) {
       
   491 		int ch = getopt_long(argc, argv, str_opts,
       
   492 		    long_opts, NULL);
       
   493 		if (ch == -1)
       
   494 			break;
       
   495 		switch (ch) {
       
   496 		case 'N':
       
   497 			nodedesc = nodedesc_substr_cat(argv, argc, B_TRUE);
       
   498 			if (!nodedesc) {
       
   499 				usage();
       
   500 				rc = -1;
       
   501 				goto free_and_ret;
       
   502 			}
       
   503 			update_flag |= NODEDESC_UPDATE_STRING;
       
   504 			break;
       
   505 		case 'H':
       
   506 			hcadesc = nodedesc_substr_cat(argv, argc, B_FALSE);
       
   507 			if (!hcadesc) {
       
   508 				usage();
       
   509 				rc = -1;
       
   510 				goto free_and_ret;
       
   511 			}
       
   512 			update_flag |= NODEDESC_UPDATE_HCA_STRING;
       
   513 			break;
       
   514 		case 'G':
       
   515 			guid_inited = B_TRUE;
       
   516 			hca_guid = (uint64_t)strtoull(optarg, 0, 0);
       
   517 			break;
       
   518 		case 'v' :
       
   519 			update_flag |= NODEDESC_READ;
       
   520 			break;
       
   521 		case 'd':
       
   522 			ibdebug++;
       
   523 			break;
       
   524 		default:
       
   525 			usage();
       
   526 			rc = -1;
       
   527 			goto free_and_ret;
       
   528 		}
       
   529 	}
       
   530 
       
   531 	if (update_flag & NODEDESC_READ) {
       
   532 		if (nodedesc || hcadesc || guid_inited == B_TRUE) {
       
   533 			usage();
       
   534 			rc = -1;
       
   535 			goto free_and_ret;
       
   536 		}
       
   537 
       
   538 		read_nodedesc();
       
   539 		update_read_info_hwnames();
       
   540 		print_read_info();
       
   541 		return (0);
       
   542 	}
       
   543 
       
   544 	if (hcadesc && guid_inited == B_FALSE) {
       
   545 		IBERROR("No GUID specified for HCA Node descriptor");
       
   546 		usage();
       
   547 		rc = -1;
       
   548 		goto free_and_ret;
       
   549 	}
       
   550 
       
   551 	if (nodedesc) {
       
   552 		rc = update_nodedesc(nodedesc, NULL, 0,
       
   553 		    NODEDESC_UPDATE_STRING);
       
   554 		if (rc) {
       
   555 			IBERROR("write common node descriptor "
       
   556 			    "failed");
       
   557 			rc = -1;
       
   558 			goto free_and_ret;
       
   559 		}
       
   560 	}
       
   561 
       
   562 	if (hcadesc) {
       
   563 		rc = update_nodedesc(NULL, hcadesc, hca_guid,
       
   564 		    NODEDESC_UPDATE_HCA_STRING);
       
   565 		if (rc) {
       
   566 			IBERROR("update_hca_noddesc failed");
       
   567 			rc = -1;
       
   568 			goto free_and_ret;
       
   569 		}
       
   570 		return (0);
       
   571 	}
       
   572 
       
   573 
       
   574 	if (nodedesc == NULL) {
       
   575 		if (uname(&uts_name) < 0) {
       
   576 			IBERROR("Node descriptor unspecified"
       
   577 			    "& uts_name failed");
       
   578 			rc = -1;
       
   579 			goto free_and_ret;
       
   580 		}
       
   581 	}
       
   582 
       
   583 	rc = update_nodedesc((char *)uts_name.nodename, NULL,
       
   584 	    0, NODEDESC_UPDATE_STRING);
       
   585 
       
   586 free_and_ret:
       
   587 	if (nodedesc)
       
   588 		free(nodedesc);
       
   589 	if (hcadesc)
       
   590 		free(hcadesc);
       
   591 
       
   592 	return (rc);
       
   593 }
       
   594 
       
   595 #endif