4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 #pragma ident "%Z%%M% %I% %E% SMI"
34 * devfree key [device [...]]
37 #include <sys/types.h>
38 #include <sys/param.h>
51 * TRUE Boolean TRUE value
52 * FALSE Boolean FALSE value
65 * EX_OK Exit code for all went well
66 * EX_ERROR Exit code for something failed
67 * EX_TBLERR Exit code for errors relating to device or lock tables
68 * EX_NOFREE Exit code for free failed
80 * M_INVKEY Invalid key specified
81 * M_NOTRSVD Attempting to free something not alloc'd
82 * M_NOTONKEY Attempting to free with wrong key
83 * M_DEVTAB Error opening the device table
84 * M_RSVTAB Error opening the device-reservation table
85 * M_ERROR Some internal error
88 #define M_USAGE "usage: devfree key [device [...]]"
89 #define M_INVKEY "Invalid key: %s"
90 #define M_NOTRSVD "Device not reserved: %s"
91 #define M_NOTONKEY "Cannot unreserve device: %s"
92 #define M_DEVTAB "Cannot open the device table: %s"
93 #define M_RSVTAB "Cannot open the device-reservation table: %s"
94 #define M_ERROR "Internal error, errno=%d"
98 * Local functions and static data
99 * stdmsg(r,l,s,m) Macro for standard message generation
100 * r MM_NRECOV or MM_RECOV (recoverability)
104 * lbl Buffer for the label-component of a message.
105 * msg Buffer for the text-component of a message.
108 #define stdmsg(r,l,s,m) (void) fmtmsg(MM_PRINT|MM_UTIL|r,l,s,m,MM_NULLACT,MM_NULLTAG)
110 static char lbl
[MM_MXLABELLN
+1];
111 static char msg
[MM_MXTXTLN
+1];
114 * devfree key [device [device [...]]]
116 * This command frees devices that have been reserved using
117 * the devreserv command (or the devreserv() function).
122 * key The key on which the device to free was allocated on.
123 * If omitted, all keys are assumed.
124 * device The device to free. If omitted, all devices allocated
125 * using the key are freed.
128 * EX_OK 0 Device(s) successfully freed
129 * EX_ERROR 1 A syntax error or other error occurred
130 * EX_TBLERR 2 A problem with device management tables
131 * EX_NOFREE 3 A requested device couldn't be freed
135 main(int argc
, char *argv
[])
138 char **argp
; /* Ptr to current argument */
139 struct reservdev
**rsvd
; /* Ptr to list of locks */
140 struct reservdev
**plk
; /* Running ptr to locks */
141 char *devtab
; /* Ptr to device table name */
142 char *rsvtab
; /* Ptr to dev-rsv-tbl name */
143 char *p
; /* Temp char pointer */
144 int argcount
; /* Number of args on cmd */
145 long lkey
; /* Key for locking (long) */
146 int key
; /* Key for locking */
147 int halt
; /* TRUE if we need to stop */
148 int sev
; /* Message severity */
149 int exitcode
; /* Value of command */
150 int syntaxerr
; /* Flag, TRUE if syntax error */
151 int exitcd
; /* Value for exit() */
152 int c
; /* Option character */
159 /* Build a message label */
160 if (p
= strrchr(argv
[0], '/')) p
++;
162 (void) strlcat(strcpy(lbl
, "UX:"), p
, sizeof(lbl
));
164 /* Make only the text component of messages appear (remove this in SVR4.1) */
165 (void) putenv("MSGVERB=text");
169 * Parse the options from the command line
174 while ((c
= getopt(argc
, argv
, "")) != EOF
) switch(c
) {
181 /* Argument initializations */
182 argp
= &argv
[optind
];
183 if ((argcount
= argc
-optind
) < 1) syntaxerr
= TRUE
;
186 /* If there's (an obvious) syntax error, write a message and quit */
188 stdmsg(MM_NRECOV
, lbl
, MM_ERROR
, M_USAGE
);
196 * Free all devices that have been reserved using the key "key".
201 /* Extract the key from the command */
202 lkey
= strtol(*argp
, &p
, 10);
203 if (*p
|| (lkey
<= 0) || (lkey
> MAXINT
)) {
204 (void) snprintf(msg
, sizeof (msg
), M_INVKEY
, *argp
);
205 stdmsg(MM_NRECOV
, lbl
, MM_ERROR
, msg
);
210 /* Get the list of devices currently reserved */
211 if (rsvd
= reservdev()) {
213 for (plk
= rsvd
; *plk
; plk
++) {
214 if ((*plk
)->key
== key
)
215 if (devfree(key
, (*plk
)->devname
) != 0)
219 if (((errno
== ENOENT
) || (errno
== EACCES
)) && (rsvtab
= _rsvtabpath())) {
220 (void) snprintf(msg
, sizeof(msg
), M_RSVTAB
, rsvtab
);
224 (void) snprintf(msg
, sizeof (msg
), M_ERROR
, errno
);
228 stdmsg(MM_NRECOV
, lbl
, sev
, msg
);
237 * devfree key device [...]
239 * Free specific devices
242 /* Open the device file (if there's one to be opened) */
243 if (!_opendevtab("r")) {
244 if (devtab
= _devtabpath()) {
245 (void) snprintf(msg
, sizeof(msg
), M_DEVTAB
, devtab
);
249 (void) snprintf(msg
, sizeof (msg
), M_ERROR
, errno
);
253 stdmsg(MM_NRECOV
, lbl
, sev
, msg
);
257 /* Extract the key from the command */
258 lkey
= strtol(*argp
, &p
, 10);
259 if (*p
|| (lkey
<= 0) || (lkey
> MAXINT
)) {
260 (void) snprintf(msg
, sizeof(msg
), M_INVKEY
, *argp
);
261 stdmsg(MM_NRECOV
, lbl
, MM_ERROR
, msg
);
267 /* Loop through the list of devices to free */
270 while (!halt
&& *argp
) {
272 /* Try to free the device */
273 if (devfree(key
, *argp
) != 0) {
274 if ((errno
== EACCES
) || (errno
== ENOENT
)) {
276 /* Can't get at reservation file */
277 if (rsvtab
= _rsvtabpath()) {
278 exitcode
= EX_TBLERR
;
279 (void) snprintf(msg
, sizeof(msg
), M_RSVTAB
, rsvtab
);
284 (void) snprintf(msg
, sizeof (msg
), M_ERROR
, errno
);
287 stdmsg(MM_NRECOV
, lbl
, sev
, msg
);
290 else if (errno
== EPERM
) {
293 (void) snprintf(msg
, sizeof(msg
), M_NOTONKEY
, *argp
);
294 stdmsg(MM_NRECOV
, lbl
, MM_ERROR
, msg
);
295 exitcode
= EX_NOFREE
;
297 else if (errno
== EINVAL
) {
299 /* Device not reserved */
300 (void) snprintf(msg
, sizeof(msg
), M_NOTRSVD
, *argp
);
301 stdmsg(MM_NRECOV
, lbl
, MM_ERROR
, msg
);
302 exitcode
= EX_NOFREE
;
307 /* Some other strange error occurred */
308 (void) snprintf(msg
, sizeof (msg
), M_ERROR
, errno
);
309 stdmsg(MM_NRECOV
, lbl
, MM_HALT
, msg
);
318 /* Exit with the appropriate code */