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 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * Creates and maintains a short-term cache of live upgrade slices.
38 #include <sys/errno.h>
39 #include <sys/param.h>
40 #include <sys/types.h>
43 #include <sys/types.h>
46 #include "libdiskmgt.h"
47 #include "disks_private.h"
52 * The list of live upgrade slices in use.
61 static struct lu_list
*lu_listp
= NULL
;
62 static time_t timestamp
= 0;
63 static mutex_t lu_lock
= DEFAULTMUTEX
;
65 static int add_use_record(char *devname
, char *name
);
66 static void free_lu(struct lu_list
*listp
);
68 static int lustatus(int fd
);
69 static int lufslist(int fd
);
70 static int run_cmd(char *path
, char *cmd
, char *arg
, int fd
);
73 * Search the list of devices under live upgrade for the specified device.
76 inuse_lu(char *slice
, nvlist_t
*attrs
, int *errp
)
88 * We don't want to have to re-read the live upgrade config for
89 * every slice, but we can't just cache it since there is no event
90 * when this changes. So, we'll keep the config in memory for
91 * a short time (1 minute) before reloading it.
93 (void) mutex_lock(&lu_lock
);
95 curr_time
= time(NULL
);
96 if (timestamp
< curr_time
&& (curr_time
- timestamp
) > 60) {
97 free_lu(lu_listp
); /* free old entries */
99 *errp
= load_lu(); /* load the cache */
100 timestamp
= curr_time
;
104 struct lu_list
*listp
;
107 while (listp
!= NULL
) {
108 if (strcmp(slice
, listp
->slice
) == 0) {
109 libdiskmgt_add_str(attrs
, DM_USED_BY
, DM_USE_LU
, errp
);
110 libdiskmgt_add_str(attrs
, DM_USED_NAME
, listp
->name
, errp
);
118 (void) mutex_unlock(&lu_lock
);
124 add_use_record(char *devname
, char *name
)
128 sp
= (struct lu_list
*)malloc(sizeof (struct lu_list
));
133 if ((sp
->slice
= strdup(devname
)) == NULL
) {
138 if ((sp
->name
= strdup(name
)) == NULL
) {
151 * Free the list of liveupgrade entries.
154 free_lu(struct lu_list
*listp
) {
156 struct lu_list
*nextp
;
158 while (listp
!= NULL
) {
160 free((void *)listp
->slice
);
161 free((void *)listp
->name
);
168 * Create a list of live upgrade devices.
173 char tmpname
[TMPNM_SIZE
];
177 (void) strlcpy(tmpname
, "/var/run/dm_lu_XXXXXX", TMPNM_SIZE
);
178 if ((fd
= mkstemp(tmpname
)) != -1) {
179 (void) unlink(tmpname
);
180 if (run_cmd("/usr/sbin/lustatus", "lustatus", NULL
, fd
)) {
181 status
= lustatus(fd
);
191 * The XML generated by the live upgrade commands is not parseable by the
192 * standard Solaris XML parser, so we have to do it ourselves.
198 char line
[MAXPATHLEN
];
201 if ((fp
= fdopen(fd
, "r")) == NULL
) {
206 (void) fseek(fp
, 0L, SEEK_SET
);
207 while (fgets(line
, sizeof (line
), fp
) == line
) {
212 if (strncmp(line
, "<beFsComponent ", 15) != 0) {
216 if ((devp
= strstr(line
, "fsDevice=\"")) == NULL
) {
222 if ((ep
= strchr(devp
, '"')) == NULL
) {
228 /* try to get the mountpoint name */
229 if ((nmp
= strstr(ep
+ 1, "mountPoint=\"")) != NULL
) {
232 if ((ep
= strchr(nmp
, '"')) != NULL
) {
242 if ((status
= add_use_record(devp
, nmp
)) != 0) {
256 char line
[MAXPATHLEN
];
259 if ((fp
= fdopen(fd
, "r")) == NULL
) {
264 (void) fseek(fp
, 0L, SEEK_SET
);
265 while (fgets(line
, sizeof (line
), fp
) == line
) {
268 char tmpname
[TMPNM_SIZE
];
271 if (strncmp(line
, "<beStatus ", 10) != 0) {
275 if ((sp
= strstr(line
, "name=\"")) == NULL
) {
281 if ((ep
= strchr(sp
, '"')) == NULL
) {
287 (void) strlcpy(tmpname
, "/var/run/dm_lu_XXXXXX", TMPNM_SIZE
);
288 if ((ffd
= mkstemp(tmpname
)) != -1) {
289 (void) unlink(tmpname
);
291 if (run_cmd("/usr/sbin/lufslist", "lufslist", sp
, ffd
) == 0) {
296 if ((status
= lufslist(ffd
)) != 0) {
308 run_cmd(char *path
, char *cmd
, char *arg
, int fd
)
313 /* create the server process */
314 switch ((pid
= fork1())) {
322 (void) execl(path
, cmd
, "-X", arg
, NULL
);
334 (void) waitpid(pid
, &loc
, 0);
336 /* printf("got 0x%x %d %d\n", loc, WIFEXITED(loc), WEXITSTATUS(loc)); */
338 if (WIFEXITED(loc
) && WEXITSTATUS(loc
) == 0) {