4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 #include "cfga_conf.h"
33 * This file supports adding/deleting/listing services from IBCONF_FILE.
37 * function prototypes:
39 static ib_service_type_t
ib_get_var_type(char *);
40 static ib_token_t
ib_lex(char *, char **);
41 static void ib_find_eol();
42 static int ib_get_string(char **, char *);
43 static int ib_service_record_add(char *,
45 static ib_token_t
ib_get_services(char **);
46 static boolean_t
ib_cmp_service();
47 static void ib_free_service_recs(void);
48 static int ib_cleanup_file(int);
49 static int ib_init_file(char **);
50 int ib_add_service(char **);
51 int ib_delete_service(char **);
52 int ib_list_services(struct cfga_msg
*, char **);
53 static cfga_ib_ret_t
ib_conf_control_ioctl(char *, uint_t
);
54 static int ib_service_record_valid(char *);
56 extern void cfga_msg(struct cfga_msg
*, const char *);
59 /* Global variables */
62 * supported "name=value" pairs from IBCONF_FILE
64 static ibcfg_var_t ibcfg_varlist
[] = {
66 { "class", IB_CLASS
},
67 { "port-svc-list", IB_PORT_SERVICE
},
68 { "vppa-svc-list", IB_VPPA_SERVICE
},
69 { "hca-svc-list", IB_HCASVC_SERVICE
},
73 static char ibconf_file
[] = IBCONF_FILE
; /* file being read */
74 static int ibcfg_linenum
= 1; /* track line#s */
75 static int ibcfg_cntr
= 0; /* current char read */
76 static int ibcfg_brec
= 0; /* beginning of rec */
77 static int bvpparec
= 0; /* begin of vppa rec */
78 static int bportrec
= 0; /* begin of port rec */
79 static int bhcarec
= 0; /* begin of HCA rec */
80 static int ibcfg_btoken
= 0; /* begin of new token */
81 static mutex_t ibcfg_lock
= DEFAULTMUTEX
; /* lock for the file */
82 static int ibcfg_fd
= -1; /* file descriptor */
83 static int ibcfg_tmpfd
= 0; /* tmp file "fd" */
84 static char *file_buf
= NULL
; /* read file into buf */
85 static char *tmpnamef
= NULL
; /* tmp file name */
86 static boolean_t wrote_tmp
= B_FALSE
; /* tmp file write in */
87 /* progress indicator */
88 static struct stat ibcfg_st
; /* file stat struct */
90 static int ibcfg_nport_services
; /* # of PORT services */
91 static int ibcfg_nvppa_services
; /* # of VPPA services */
92 static int ibcfg_nhca_services
; /* # of HCA services */
93 static ib_svc_rec_t
*ibcfg_vppa_head
; /* VPPA service recs */
94 static ib_svc_rec_t
*ibcfg_port_head
; /* PORT service recs */
95 static ib_svc_rec_t
*ibcfg_hca_head
; /* HCA service recs */
97 extern char *service_name
; /* service name */
98 extern ib_service_type_t service_type
; /* service type */
105 * str - A parsed string from IBCONF_FILE
111 * Returns the field from the token
113 static ib_service_type_t
114 ib_get_var_type(char *str
)
116 register ibcfg_var_t
*cfgvar
;
118 cfgvar
= &ibcfg_varlist
[0];
119 while (cfgvar
->type
!= IB_NONE
) {
120 if (strcasecmp(cfgvar
->name
, str
) == 0)
125 return (cfgvar
->type
);
135 * val - value just read
136 * errmsg - pointer to error message string, if there are any errors
140 * Read tokens from the IBCONF_FILE and parse them
144 ib_lex(char *val
, char **errmsg
)
146 int ch
, oval
, badquote
;
150 while ((ch
= GETC(file_buf
, ibcfg_cntr
)) == ' ' || ch
== '\t')
153 /* make a note of the beginning of token */
154 ibcfg_btoken
= ibcfg_cntr
- 1;
188 while ((ch
= GETC(file_buf
, ibcfg_cntr
)) == ' ' ||
189 ch
== '\t' || ch
== '\f')
191 (void) UNGETC(ibcfg_cntr
);
201 while (!badquote
&& (ch
= GETC(file_buf
, ibcfg_cntr
)) != '"') {
205 (void) snprintf(*errmsg
, MAXPATHLEN
,
210 /* since we consumed the newline/EOF */
211 (void) UNGETC(ibcfg_cntr
);
215 ch
= (char)GETC(file_buf
, ibcfg_cntr
);
217 /* escape the character */
222 while (ch
>= '0' && ch
<= '7') {
224 oval
= (oval
<< 3) + ch
;
225 ch
= (char)GETC(file_buf
, ibcfg_cntr
);
227 (void) UNGETC(ibcfg_cntr
);
228 /* check for character overflow? */
230 (void) snprintf(*errmsg
, MAXPATHLEN
,
231 "Character overflow detected.\n");
248 * detect a lone '-' (including at the end of a line), and
249 * identify it as a 'name'
252 *cp
++ = (char)(ch
= GETC(file_buf
, ibcfg_cntr
));
253 if (iswhite(ch
) || (ch
== '\n')) {
254 (void) UNGETC(ibcfg_cntr
);
259 } else if (isunary(ch
)) {
260 *cp
++ = (char)(ch
= GETC(file_buf
, ibcfg_cntr
));
265 if ((ch
= GETC(file_buf
, ibcfg_cntr
)) == 'x') {
267 ch
= GETC(file_buf
, ibcfg_cntr
);
268 while (isxdigit(ch
)) {
270 ch
= GETC(file_buf
, ibcfg_cntr
);
272 (void) UNGETC(ibcfg_cntr
);
278 ch
= GETC(file_buf
, ibcfg_cntr
);
280 while (isdigit(ch
)) {
282 ch
= GETC(file_buf
, ibcfg_cntr
);
284 (void) UNGETC(ibcfg_cntr
);
287 } else if (isalpha(ch
) || ch
== '\\') {
289 ch
= GETC(file_buf
, ibcfg_cntr
);
292 * if the character was a backslash,
293 * back up so we can overwrite it with
294 * the next (i.e. escaped) character.
299 while (isnamechar(ch
) || ch
== '\\') {
301 ch
= GETC(file_buf
, ibcfg_cntr
);
303 ch
= GETC(file_buf
, ibcfg_cntr
);
305 (void) UNGETC(ibcfg_cntr
);
326 * Leave NEWLINE as the next character.
333 while ((ch
= GETC(file_buf
, ibcfg_cntr
)) != -1) {
335 (void) UNGETC(ibcfg_cntr
);
346 * tchar - name of the string
348 * llptr - Valid string
350 * 1 for success, NULL for errors.
352 * The next item on the line is a string value. Allocate memory for
353 * it and copy the string. Return 1, and set arg ptr to newly allocated
354 * and initialized buffer, or NULL if an error occurs.
357 ib_get_string(char **llptr
, char *tchar
)
359 int tlen
= strlen(tchar
);
365 if ((cp
= (char *)calloc(tlen
+ 1, sizeof (char))) == NULL
) {
372 for (; tlen
> 0; tlen
--) {
373 /* convert some common escape sequences */
374 if (*start
== '\\') {
375 switch (*(start
+ 1)) {
410 * ib_service_record_add
412 * service - name of the service
413 * type - type of the service
415 * rec - one valid service record
417 * CFGA_IB_OK on success or an appropriate error
419 * Add one record to internal data structures
422 ib_service_record_add(char *service
, ib_service_type_t type
)
424 ib_svc_rec_t
*tmp
, *recp
;
426 DPRINTF("ib_service_record_add: (%x, %s) "
427 "(#port = %d #vppa = %d #hca = %d)\n", type
, service
,
428 ibcfg_nport_services
, ibcfg_nvppa_services
,
429 ibcfg_nhca_services
);
430 recp
= (ib_svc_rec_t
*)calloc(1, sizeof (ib_svc_rec_t
));
432 return (CFGA_IB_ALLOC_FAIL
);
435 recp
->name
= strdup((char *)service
);
436 if (type
== IB_PORT_SERVICE
) {
437 if (ibcfg_port_head
) {
438 for (tmp
= ibcfg_port_head
; tmp
->next
!= NULL
; )
442 ibcfg_port_head
= recp
;
443 ibcfg_nport_services
++;
444 } else if (type
== IB_VPPA_SERVICE
) {
445 if (ibcfg_vppa_head
) {
446 for (tmp
= ibcfg_vppa_head
; tmp
->next
!= NULL
; )
450 ibcfg_vppa_head
= recp
;
451 ibcfg_nvppa_services
++;
452 } else if (type
== IB_HCASVC_SERVICE
) {
453 if (ibcfg_hca_head
) {
454 for (tmp
= ibcfg_hca_head
; tmp
->next
!= NULL
; )
458 ibcfg_hca_head
= recp
;
459 ibcfg_nhca_services
++;
470 * errmsg - Error message filled in case of a failure
472 * rec - one valid service record
474 * CFGA_IB_OK on success or an appropriate error
476 * Fetch one record from the IBCONF_FILE
479 ib_get_services(char **errmsg
)
481 char tokval
[MAXLINESIZE
];
483 boolean_t sor
= B_TRUE
;
485 ib_service_type_t cfgvar
;
486 ib_parse_state_t parse_state
= IB_NEWVAR
;
488 token
= ib_lex(tokval
, errmsg
);
489 while ((token
!= EOF
) && (token
!= SEMICOLON
)) {
490 if (token
== STAR
|| token
== POUND
) {
493 } else if (token
== NEWLINE
) {
495 } else if (token
== NAME
|| token
== STRING
) {
496 if (parse_state
== IB_NEWVAR
) {
497 cfgvar
= ib_get_var_type(tokval
);
498 if (cfgvar
== IB_NONE
) {
499 parse_state
= IB_ERROR
;
500 (void) snprintf(*errmsg
, MAXPATHLEN
,
501 "Syntax Error: Invalid type %s",
504 /* Note the beginning of the entry */
506 ibcfg_brec
= ibcfg_btoken
;
509 parse_state
= IB_CONFIG_VAR
;
510 if (cfgvar
== IB_PORT_SERVICE
)
511 bportrec
= ibcfg_cntr
+ 1;
512 else if (cfgvar
== IB_VPPA_SERVICE
)
513 bvpparec
= ibcfg_cntr
+ 1;
514 else if (cfgvar
== IB_HCASVC_SERVICE
)
515 bhcarec
= ibcfg_cntr
+ 1;
518 } else if (parse_state
== IB_VAR_VALUE
) {
520 if (ib_get_string(&llptr
, tokval
)) {
521 if ((cfgvar
== IB_PORT_SERVICE
) ||
522 (cfgvar
== IB_VPPA_SERVICE
) ||
523 (cfgvar
== IB_HCASVC_SERVICE
)) {
524 if (ib_service_record_valid(
526 ib_service_record_add(
527 (char *)llptr
, cfgvar
) !=
534 } else if ((cfgvar
== IB_NAME
) ||
535 (cfgvar
== IB_CLASS
)) {
537 parse_state
= IB_NEWVAR
;
540 parse_state
= IB_ERROR
;
543 parse_state
= IB_ERROR
;
544 (void) snprintf(*errmsg
, MAXPATHLEN
,
545 "Syntax Error: Invalid value %s "
546 "for type: %s\n", tokval
,
547 ibcfg_varlist
[cfgvar
].name
);
549 } else if (parse_state
== IB_ERROR
) {
551 DPRINTF("ib_get_services: ERROR\n");
553 parse_state
= IB_ERROR
;
554 (void) snprintf(*errmsg
, MAXPATHLEN
,
555 "Syntax Error: at %s", tokval
);
557 } else if (token
== COMMA
|| token
== EQUALS
) {
558 if (parse_state
== IB_CONFIG_VAR
) {
559 if (cfgvar
== IB_NONE
) {
560 parse_state
= IB_ERROR
;
561 (void) snprintf(*errmsg
, MAXPATHLEN
,
562 "Syntax Error: unexpected '='");
564 parse_state
= IB_VAR_VALUE
;
566 } else if (parse_state
!= IB_ERROR
) {
567 (void) snprintf(*errmsg
, MAXPATHLEN
,
568 "Syntax Error: unexpected '='");
569 parse_state
= IB_ERROR
;
572 (void) snprintf(*errmsg
, MAXPATHLEN
,
573 "Syntax Error: at: %s", tokval
);
574 parse_state
= IB_ERROR
;
576 token
= ib_lex(tokval
, errmsg
);
577 if (ib_get_var_type(tokval
) != IB_NONE
)
578 parse_state
= IB_NEWVAR
;
591 * B_TRUE if this service is already seen. B_FALSE if not.
593 * Compare the service just read from the services already seen.
594 * Check if this service was already seen or not.
601 DPRINTF("ib_cmp_service: (%x, %s) "
602 "(#port = %d #vppa = %d #hca = %d)\n", service_type
,
603 service_name
, ibcfg_nport_services
, ibcfg_nvppa_services
,
604 ibcfg_nhca_services
);
606 for (recp
= ibcfg_port_head
; recp
!= NULL
; recp
= recp
->next
) {
607 DPRINTF("ib_cmp_service:P usvc = %s, usvc_name = %s\n",
608 service_name
, recp
->name
? recp
->name
: "NONE");
609 if (recp
->name
&& strcmp(recp
->name
, service_name
) == 0)
612 for (recp
= ibcfg_vppa_head
; recp
!= NULL
; recp
= recp
->next
) {
613 DPRINTF("ib_cmp_service:V utype = %x, usvc_name = %s\n",
614 recp
->type
, recp
->name
? recp
->name
: "NONE");
615 if (recp
->name
&& strcmp(recp
->name
, service_name
) == 0)
618 for (recp
= ibcfg_hca_head
; recp
!= NULL
; recp
= recp
->next
) {
619 DPRINTF("ib_cmp_service:V utype = %x, usvc_name = %s\n",
620 recp
->type
, recp
->name
? recp
->name
: "NONE");
621 if (recp
->name
&& strcmp(recp
->name
, service_name
) == 0)
631 * ib_free_service_recs
637 * CFGA_IB_OK on success or an appropriate error
639 * Free the service records allocated in ib_get_services
642 ib_free_service_recs(void)
644 ib_svc_rec_t
*tmp
, *recp
;
646 DPRINTF("ib_free_service_recs: "
647 "#port_services = %d, #vppa_services = %d, #hca_services = %d\n",
648 ibcfg_nport_services
, ibcfg_nvppa_services
, ibcfg_nhca_services
);
650 for (recp
= ibcfg_port_head
; recp
!= NULL
; ) {
651 if (recp
&& strlen(recp
->name
))
658 for (recp
= ibcfg_vppa_head
; recp
!= NULL
; ) {
659 if (recp
&& strlen(recp
->name
))
666 for (recp
= ibcfg_hca_head
; recp
!= NULL
; ) {
667 if (recp
&& strlen(recp
->name
))
680 * rval - error return value
684 * CFGA_IB_OK on success or an appropriate error
686 * Cleanup IBCONF_FILE etc.
689 ib_cleanup_file(int rval
)
693 ib_free_service_recs();
694 if (lockf(ibcfg_fd
, F_ULOCK
, 0) == -1) {
695 DPRINTF("ib_cleanup_file: unlock file %s failed\n",
697 rv
= CFGA_IB_UNLOCK_FILE_ERR
;
702 if (ibcfg_tmpfd
&& wrote_tmp
== B_TRUE
) {
703 DPRINTF("ib_cleanup_file: tmpfile %s being renamed to %s\n",
704 tmpnamef
, IBCONF_FILE
);
706 rename((const char *)tmpnamef
, (const char *)IBCONF_FILE
);
709 (void) mutex_unlock(&ibcfg_lock
);
720 * errmsg - Error message filled in case of a failure
722 * CFGA_IB_OK on success or an appropriate error
724 * Initialize IBCONF_FILE for reading
727 ib_init_file(char **errmsg
)
729 (void) mutex_lock(&ibcfg_lock
);
731 if (*errmsg
== NULL
) {
732 if ((*errmsg
= calloc(MAXPATHLEN
, 1)) == NULL
) {
733 (void) mutex_unlock(&ibcfg_lock
);
734 DPRINTF("ib_init_file: calloc errmsg failed\n");
735 return (CFGA_IB_CONFIG_FILE_ERR
);
739 /* Open the .conf file */
740 if ((ibcfg_fd
= open(ibconf_file
, O_RDWR
, 0666)) == -1) {
741 (void) snprintf(*errmsg
, MAXPATHLEN
,
742 "failed to open %s file\n", ibconf_file
);
743 (void) mutex_unlock(&ibcfg_lock
);
744 return (CFGA_IB_CONFIG_FILE_ERR
);
747 /* Lock the file so that another cfgadm instance doesn't modify it */
748 if (lockf(ibcfg_fd
, F_TLOCK
, 0) == -1) {
749 (void) snprintf(*errmsg
, MAXPATHLEN
,
750 "failed to lock %s file\n", ibconf_file
);
753 (void) mutex_unlock(&ibcfg_lock
);
754 return (CFGA_IB_LOCK_FILE_ERR
);
757 if (fstat(ibcfg_fd
, &ibcfg_st
) != 0) {
758 DPRINTF("ib_init_file: failed to fstat %s file\n", ibconf_file
);
759 return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR
));
762 /* Allocate a buffer for the file */
763 if ((file_buf
= (char *)malloc(ibcfg_st
.st_size
)) == NULL
) {
764 DPRINTF("ib_init_file: failed to fstat %s file\n",
766 return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL
));
769 /* Check if size matches */
770 if (ibcfg_st
.st_size
!= read(ibcfg_fd
, file_buf
, ibcfg_st
.st_size
)) {
771 DPRINTF("ib_init_file: failed to read %s file\n", ibconf_file
);
772 return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR
));
776 * These variables need to be reinitialized here as they may
777 * have been modified by a previous thread that called this
785 ibcfg_nport_services
= 0;
786 ibcfg_nvppa_services
= 0;
787 ibcfg_nhca_services
= 0;
788 ibcfg_port_head
= (ib_svc_rec_t
*)NULL
;
789 ibcfg_vppa_head
= (ib_svc_rec_t
*)NULL
;
790 ibcfg_hca_head
= (ib_svc_rec_t
*)NULL
;
801 * errmsg - Error message filled in case of a failure
803 * CFGA_IB_OK on success or an appropriate error
805 * open IBCONF_FILE and add "service_name".
808 ib_add_service(char **errmsg
)
812 boolean_t found
= B_FALSE
;
813 ib_token_t token
= NEWLINE
;
815 DPRINTF("ib_add_service: type = %x, service_name=%s\n", service_type
,
817 if ((rval
= ib_init_file(errmsg
)) != CFGA_IB_OK
) {
818 DPRINTF("ib_add_service: initializing file failed\n");
822 /* Start reading the file */
823 while (token
!= EOF
) {
824 token
= ib_get_services(errmsg
);
825 found
= ib_cmp_service();
826 if (found
== B_TRUE
) {
827 DPRINTF("ib_add_service: token=%x, found=%x\n",
833 /* Service shouldn't already exist while adding */
835 (void) snprintf(*errmsg
, MAXPATHLEN
, "service entry %s exists ",
837 DPRINTF("ib_add_service: invalid add operation\n");
838 return (ib_cleanup_file(CFGA_IB_SVC_EXISTS_ERR
));
841 DPRINTF("!FOUND and adding\n");
842 switch (service_type
) {
843 case IB_PORT_SERVICE
:
844 ibcfg_brec
= bportrec
;
846 case IB_VPPA_SERVICE
:
847 ibcfg_brec
= bvpparec
;
849 case IB_HCASVC_SERVICE
:
850 ibcfg_brec
= bhcarec
;
853 DPRINTF("ib_add_service: invalid add operation\n");
854 return (ib_cleanup_file(CFGA_IB_SVC_INVAL_ERR
));
858 if ((sbuf
= (char *)calloc(12, sizeof (char))) == NULL
) {
859 DPRINTF("ib_add_service: failed to calloc sbuf %s file\n",
861 return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL
));
863 if (file_buf
[ibcfg_brec
] == '"' && file_buf
[ibcfg_brec
+ 1] == '"') {
864 (void) snprintf(sbuf
, 9, "%s", service_name
);
867 (void) snprintf(sbuf
, 9, "\"%s\", ", service_name
);
870 /* Seek to the beginning of the file */
871 if (lseek(ibcfg_fd
, ibcfg_brec
, SEEK_SET
) == -1) {
872 DPRINTF("ib_add_service: lseek %s file failed\n", ibconf_file
);
873 return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR
));
876 /* Add service to w/ IBNEX */
877 if (ib_conf_control_ioctl(service_name
, IBNEX_CONF_ENTRY_ADD
)) {
878 DPRINTF("ib_add_service: ioctl add failed %d\n", errno
);
879 (void) snprintf(*errmsg
, MAXPATHLEN
, "failed to add "
880 "%s service incore ", service_name
);
881 return (ib_cleanup_file(CFGA_IB_SVC_EXISTS_ERR
));
884 /* Write the modified file */
885 if (write(ibcfg_fd
, sbuf
, strlen(sbuf
)) == -1) {
886 DPRINTF("ib_add_service: write %s file failed\n", ibconf_file
);
887 return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR
));
890 /* Write the rest of the file as it was */
891 if (write(ibcfg_fd
, file_buf
+ ibcfg_brec
,
892 ibcfg_st
.st_size
- ibcfg_brec
) == -1) {
893 DPRINTF("ib_add_service: write %s file failed 2\n",
895 return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR
));
898 return (ib_cleanup_file(rval
));
908 * errmsg - Error message filled in case of a failure
910 * CFGA_IB_OK on success or an appropriate error
912 * open ib.conf file and delete "service_name"
915 ib_delete_service(char **errmsg
)
924 boolean_t found
= B_FALSE
;
925 ib_token_t token
= NEWLINE
;
928 DPRINTF("ib_delete_service: type = %x, service_name=%s\n",
929 service_type
, service_name
);
930 if ((rval
= ib_init_file(errmsg
)) != CFGA_IB_OK
) {
931 DPRINTF("ib_delete_service: initializing file failed\n");
935 /* Start reading the file */
936 while (token
!= EOF
) {
937 token
= ib_get_services(errmsg
);
938 found
= ib_cmp_service(); /* search for a match */
939 if (found
== B_TRUE
) {
940 DPRINTF("ib_delete_service: token=%x, found=%x\n",
946 /* No service found, return */
948 DPRINTF("ib_delete_service: invalid delete operation\n");
949 (void) snprintf(*errmsg
, MAXPATHLEN
, "service entry %s "
950 "does not exist ", service_name
);
951 return (ib_cleanup_file(CFGA_IB_SVC_NO_EXIST_ERR
));
954 DPRINTF("FOUND and deleting \n");
956 switch (service_type
) {
957 case IB_PORT_SERVICE
:
958 ibcfg_brec
= bportrec
;
959 num_svcs
= ibcfg_nport_services
;
961 case IB_VPPA_SERVICE
:
962 ibcfg_brec
= bvpparec
;
963 num_svcs
= ibcfg_nvppa_services
;
965 case IB_HCASVC_SERVICE
:
966 ibcfg_brec
= bhcarec
;
967 num_svcs
= ibcfg_nhca_services
;
970 DPRINTF("ib_delete_service: invalid delete "
972 return (ib_cleanup_file(CFGA_IB_SVC_INVAL_ERR
));
975 if ((sbuf
= (char *)calloc(num_svcs
* 8, sizeof (char))) == NULL
) {
976 DPRINTF("ib_delete_service: sbuf alloc failed %s\n",
978 return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL
));
982 (void) snprintf(sbuf
, 9, "\"\"");
986 if (service_type
== IB_PORT_SERVICE
) {
987 for (recp
= ibcfg_port_head
; recp
; recp
= recp
->next
) {
988 if (strcmp(recp
->name
, service_name
) == 0)
990 (void) snprintf(tmp
, 9, "\"%s\", ", recp
->name
);
991 (void) strcat(sbuf
, tmp
);
994 } else if (service_type
== IB_VPPA_SERVICE
) {
995 for (recp
= ibcfg_vppa_head
; recp
; recp
= recp
->next
) {
996 if (strcmp(recp
->name
, service_name
) == 0)
998 (void) snprintf(tmp
, 9, "\"%s\", ", recp
->name
);
999 (void) strcat(sbuf
, tmp
);
1002 for (recp
= ibcfg_hca_head
; recp
; recp
= recp
->next
) {
1003 if (strcmp(recp
->name
, service_name
) == 0)
1005 (void) snprintf(tmp
, 9, "\"%s\", ", recp
->name
);
1006 (void) strcat(sbuf
, tmp
);
1010 sbuf_len
= strlen(sbuf
);
1011 sbuf
[sbuf_len
- 2] = '\0';
1015 tot_len
= strlen(service_name
) + skip_len
;
1017 tmpnamef
= tmpnam(ibconf_file
);
1018 DPRINTF("ib_delete_service: tmpnamef = %s\n", tmpnamef
);
1019 if ((ibcfg_tmpfd
= creat(tmpnamef
, 0666)) == -1) {
1020 (void) snprintf(*errmsg
, MAXPATHLEN
,
1021 "failed to creat %s file\n", ibconf_file
);
1022 DPRINTF("ib_delete_service: failed to creat tmpnamef\n");
1023 return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL
));
1026 /* Delete service from IBNEX */
1027 if (ib_conf_control_ioctl(service_name
, IBNEX_CONF_ENTRY_DEL
)) {
1028 DPRINTF("ib_delete_service: ioctl delete failed %d\n", errno
);
1029 (void) snprintf(*errmsg
, MAXPATHLEN
, "failed to delete "
1030 "in core %s entry ", service_name
);
1033 return (ib_cleanup_file(CFGA_IB_SVC_EXISTS_ERR
));
1036 /* write till ibcfg_brec */
1037 if (write(ibcfg_tmpfd
, file_buf
, ibcfg_brec
) == -1) {
1038 DPRINTF("ib_delete_service: write %s file failed 1\n",
1042 return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR
));
1045 /* write modified buffer */
1046 if (write(ibcfg_tmpfd
, sbuf
, sbuf_len
) == -1) {
1047 DPRINTF("ib_delete_service: write %s file failed 2\n",
1051 return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR
));
1054 /* Write the rest of the file as it was */
1055 if (write(ibcfg_tmpfd
, file_buf
+ ibcfg_brec
+ sbuf_len
+ tot_len
,
1056 ibcfg_st
.st_size
- ibcfg_brec
- sbuf_len
- tot_len
) == -1) {
1057 DPRINTF("ib_delete_service: write %s file failed 3\n",
1061 return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR
));
1065 /* No error encountered */
1066 return (ib_cleanup_file(rval
));
1074 * msgp - CFGADM message pointer
1076 * errmsg - Error message filled in case of a failure
1078 * CFGA_IB_OK on success or an appropriate error
1080 * open IBCONF_FILE and list services.
1083 ib_list_services(struct cfga_msg
*msgp
, char **errmsg
)
1085 int rval
= CFGA_IB_OK
;
1086 char pbuf
[IBCONF_SERVICE_HDR_LEN
];
1087 ib_token_t token
= NEWLINE
;
1090 DPRINTF("ib_list_services:\n");
1091 if ((rval
= ib_init_file(errmsg
)) != CFGA_IB_OK
) {
1092 DPRINTF("ib_list_services: initializing file failed\n");
1096 /* start reading the file */
1097 while (token
!= EOF
)
1098 token
= ib_get_services(errmsg
);
1100 DPRINTF("ib_list_services: #port_services = %d, #vppa_services = %d,"
1101 " #hca_services = %d\n", ibcfg_nport_services
,
1102 ibcfg_nvppa_services
, ibcfg_nhca_services
);
1104 bzero(pbuf
, IBCONF_SERVICE_HDR_LEN
);
1105 if (ibcfg_nport_services
) {
1106 (void) snprintf(pbuf
, IBCONF_SERVICE_HDR_LEN
,
1107 IBCONF_PORT_SERVICE_HDR
);
1108 cfga_msg(msgp
, pbuf
);
1109 for (recp
= ibcfg_port_head
; recp
; recp
= recp
->next
) {
1110 DPRINTF("ib_list_services: svc_name = %s\n",
1111 recp
->name
? recp
->name
: "NONE");
1112 (void) snprintf(pbuf
, 14, "\t\t%s\n", recp
->name
);
1113 cfga_msg(msgp
, pbuf
);
1115 (void) snprintf(pbuf
, 2, "\n");
1116 cfga_msg(msgp
, pbuf
);
1119 if (ibcfg_nvppa_services
) {
1120 (void) snprintf(pbuf
, IBCONF_SERVICE_HDR_LEN
,
1121 IBCONF_VPPA_SERVICE_HDR
);
1122 cfga_msg(msgp
, pbuf
);
1123 for (recp
= ibcfg_vppa_head
; recp
; recp
= recp
->next
) {
1124 DPRINTF("ib_list_services: svc_name = %s\n",
1125 strlen(recp
->name
) > 0 ? recp
->name
: "NONE");
1126 (void) snprintf(pbuf
, 14, "\t\t%s\n", recp
->name
);
1127 cfga_msg(msgp
, pbuf
);
1131 if (ibcfg_nhca_services
) {
1132 (void) snprintf(pbuf
, IBCONF_SERVICE_HDR_LEN
,
1133 IBCONF_HCA_SERVICE_HDR
);
1134 cfga_msg(msgp
, pbuf
);
1135 for (recp
= ibcfg_hca_head
; recp
; recp
= recp
->next
) {
1136 DPRINTF("ib_list_services: svc_name = %s\n",
1137 strlen(recp
->name
) > 0 ? recp
->name
: "NONE");
1138 (void) snprintf(pbuf
, 14, "\t\t%s\n", recp
->name
);
1139 cfga_msg(msgp
, pbuf
);
1142 return (ib_cleanup_file(CFGA_IB_OK
));
1148 * ib_conf_control_ioctl
1150 * svc - Service being added/deleted
1151 * cmd - Command to DEVCTL_AP_CONTROL devctl
1155 * CFGA_IB_OK if it succeeds or an appropriate error.
1157 * Issues DEVCTL_AP_CONTROL devctl with cmd
1159 static cfga_ib_ret_t
1160 ib_conf_control_ioctl(char *svc
, uint_t cmd
)
1163 cfga_ib_ret_t rv
= CFGA_IB_OK
;
1164 struct ibnex_ioctl_data ioctl_data
;
1166 DPRINTF("Service = %s len = %x, type = %x\n", svc
,
1167 strlen(svc
), service_type
);
1169 /* try to open the static IB ap_id */
1170 if ((apid_fd
= open(IB_STATIC_APID
, O_RDONLY
)) == -1) {
1171 DPRINTF("ib_conf_control_ioctl: open failed: errno = %d\n",
1173 /* Provides a more useful error msg */
1174 rv
= (errno
== EBUSY
) ? CFGA_IB_BUSY_ERR
: CFGA_IB_OPEN_ERR
;
1178 ioctl_data
.cmd
= cmd
;
1179 ioctl_data
.misc_arg
= (uint_t
)service_type
;
1180 ioctl_data
.buf
= (caddr_t
)svc
;
1181 ioctl_data
.bufsiz
= strlen(svc
);
1182 ioctl_data
.ap_id
= (caddr_t
)IB_STATIC_APID
;
1183 ioctl_data
.ap_id_len
= strlen(IB_STATIC_APID
);
1185 if (ioctl(apid_fd
, DEVCTL_AP_CONTROL
, &ioctl_data
) != 0) {
1186 DPRINTF("ib_conf_control_ioctl: size ioctl ERR, errno: %d\n",
1188 rv
= (errno
== EBUSY
) ? CFGA_IB_BUSY_ERR
: CFGA_IB_IOCTL_ERR
;
1190 (void) close(apid_fd
);
1195 * This functions checks if the service name is valid. Valid
1196 * service names have :
1197 * 0 < strlen(name) <= 4
1198 * Service name is unique
1199 * Returns: 0 - Name is not valid, 1 - Name is valid
1202 ib_service_record_valid(char *sname
)
1205 char *tmp_service_name
;
1207 tmp_service_name
= service_name
;
1208 service_name
= strdup(sname
);
1209 len
= strlen(sname
);
1210 if (len
== 0 || len
> 4) {
1211 S_FREE(service_name
);
1212 service_name
= tmp_service_name
;
1215 if (ib_cmp_service() == B_TRUE
)
1217 S_FREE(service_name
);
1218 service_name
= tmp_service_name
;