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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2013 Joyent, Inc. All rights reserved.
28 #include "libscf_impl.h"
38 #include <sys/machelf.h>
45 static struct scf_error_info
{
49 {SCF_ERROR_NONE
, "no error"},
50 {SCF_ERROR_NOT_BOUND
, "handle not bound"},
51 {SCF_ERROR_NOT_SET
, "cannot use unset argument"},
52 {SCF_ERROR_NOT_FOUND
, "entity not found"},
53 {SCF_ERROR_TYPE_MISMATCH
, "type does not match value"},
54 {SCF_ERROR_IN_USE
, "cannot modify while in-use"},
55 {SCF_ERROR_CONNECTION_BROKEN
, "connection to repository broken"},
56 {SCF_ERROR_INVALID_ARGUMENT
, "invalid argument"},
57 {SCF_ERROR_NO_MEMORY
, "no memory available"},
58 {SCF_ERROR_CONSTRAINT_VIOLATED
, "required constraint not met"},
59 {SCF_ERROR_EXISTS
, "object already exists"},
60 {SCF_ERROR_NO_SERVER
, "repository server unavailable"},
61 {SCF_ERROR_NO_RESOURCES
, "server has insufficient resources"},
62 {SCF_ERROR_PERMISSION_DENIED
, "insufficient privileges for action"},
63 {SCF_ERROR_BACKEND_ACCESS
, "backend refused access"},
64 {SCF_ERROR_BACKEND_READONLY
, "backend is read-only"},
65 {SCF_ERROR_HANDLE_MISMATCH
, "mismatched SCF handles"},
66 {SCF_ERROR_HANDLE_DESTROYED
, "object bound to destroyed handle"},
67 {SCF_ERROR_VERSION_MISMATCH
, "incompatible SCF version"},
68 {SCF_ERROR_DELETED
, "object has been deleted"},
69 {SCF_ERROR_TEMPLATE_INVALID
, "template data is invalid"},
71 {SCF_ERROR_CALLBACK_FAILED
, "user callback function failed"},
73 {SCF_ERROR_INTERNAL
, "internal error"}
75 #define SCF_NUM_ERRORS (sizeof (scf_errors) / sizeof (*scf_errors))
77 /* a SWAG just in case things get out of sync, we can notice */
78 #define LOOKS_VALID(e) \
79 ((e) >= scf_errors[0].ei_code && \
80 (e) < scf_errors[SCF_NUM_ERRORS - 1].ei_code + 10)
82 static scf_error_t _scf_fallback_error
= SCF_ERROR_NONE
;
84 #if defined(PTHREAD_ONCE_KEY_NP)
86 static pthread_key_t scf_error_key
= PTHREAD_ONCE_KEY_NP
;
91 return (pthread_key_create_once_np(&scf_error_key
, NULL
) == 0);
94 #else /* PTHREAD_ONCE_KEY_NP */
97 * This old code is here to enable the building of a native version
98 * of libscf.so when the build machine has not yet been upgraded
99 * to a version of libc that provides pthread_key_create_once_np().
100 * It should be deleted when solaris_nevada ships.
101 * This code is not MT-safe in a relaxed memory model.
104 static pthread_key_t scf_error_key
= 0;
107 scf_setup_error(void)
109 static pthread_mutex_t scf_key_lock
= PTHREAD_MUTEX_INITIALIZER
;
110 static volatile int scf_error_key_setup
= 0;
112 if (scf_error_key_setup
== 0) {
113 (void) pthread_mutex_lock(&scf_key_lock
);
114 if (scf_error_key_setup
== 0) {
115 if (pthread_key_create(&scf_error_key
, NULL
) == 0)
116 scf_error_key_setup
= 1;
118 (void) pthread_mutex_unlock(&scf_key_lock
);
121 return (scf_error_key_setup
== 1);
124 #endif /* PTHREAD_ONCE_KEY_NP */
127 scf_set_error(scf_error_t code
)
129 assert(LOOKS_VALID(code
));
131 if (scf_setup_error())
132 (void) pthread_setspecific(scf_error_key
, (void *)code
);
134 _scf_fallback_error
= code
;
143 ret
= (scf_error_t
)pthread_getspecific(scf_error_key
);
145 return (_scf_fallback_error
);
146 assert(LOOKS_VALID(ret
));
151 scf_strerror(scf_error_t code
)
153 struct scf_error_info
*cur
, *end
;
156 end
= cur
+ SCF_NUM_ERRORS
;
158 for (; cur
< end
; cur
++)
159 if (code
== cur
->ei_code
)
160 return (dgettext(TEXT_DOMAIN
, cur
->ei_desc
));
162 return (dgettext(TEXT_DOMAIN
, "unknown error"));
166 scf_get_msg(scf_msg_t msg
)
169 case SCF_MSG_ARGTOOLONG
:
170 return (dgettext(TEXT_DOMAIN
,
171 "Argument '%s' is too long, ignoring\n"));
173 case SCF_MSG_PATTERN_NOINSTANCE
:
174 return (dgettext(TEXT_DOMAIN
,
175 "Pattern '%s' doesn't match any instances\n"));
177 case SCF_MSG_PATTERN_NOINSTSVC
:
178 return (dgettext(TEXT_DOMAIN
,
179 "Pattern '%s' doesn't match any instances or services\n"));
181 case SCF_MSG_PATTERN_NOSERVICE
:
182 return (dgettext(TEXT_DOMAIN
,
183 "Pattern '%s' doesn't match any services\n"));
185 case SCF_MSG_PATTERN_NOENTITY
:
186 return (dgettext(TEXT_DOMAIN
,
187 "Pattern '%s' doesn't match any entities\n"));
189 case SCF_MSG_PATTERN_MULTIMATCH
:
190 return (dgettext(TEXT_DOMAIN
,
191 "Pattern '%s' matches multiple instances:\n"));
193 case SCF_MSG_PATTERN_POSSIBLE
:
194 return (dgettext(TEXT_DOMAIN
, " %s\n"));
196 case SCF_MSG_PATTERN_LEGACY
:
197 return (dgettext(TEXT_DOMAIN
,
198 "Operation not supported for legacy service '%s'\n"));
200 case SCF_MSG_PATTERN_MULTIPARTIAL
:
201 return (dgettext(TEXT_DOMAIN
,
202 "Partial FMRI matches multiple instances\n"));