/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Creates and maintains a short-term cache of live upgrade slices. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "libdiskmgt.h" #include "disks_private.h" #define TMPNM_SIZE 25 /* * The list of live upgrade slices in use. */ struct lu_list { struct lu_list *next; char *slice; char *name; }; static struct lu_list *lu_listp = NULL; static time_t timestamp = 0; static mutex_t lu_lock = DEFAULTMUTEX; static int add_use_record(char *devname, char *name); static void free_lu(struct lu_list *listp); static int load_lu(); static int lustatus(int fd); static int lufslist(int fd); static int run_cmd(char *path, char *cmd, char *arg, int fd); /* * Search the list of devices under live upgrade for the specified device. */ int inuse_lu(char *slice, nvlist_t *attrs, int *errp) { int found = 0; time_t curr_time; *errp = 0; if (slice == NULL) { return (found); } /* * We don't want to have to re-read the live upgrade config for * every slice, but we can't just cache it since there is no event * when this changes. So, we'll keep the config in memory for * a short time (1 minute) before reloading it. */ (void) mutex_lock(&lu_lock); curr_time = time(NULL); if (timestamp < curr_time && (curr_time - timestamp) > 60) { free_lu(lu_listp); /* free old entries */ lu_listp = NULL; *errp = load_lu(); /* load the cache */ timestamp = curr_time; } if (*errp == 0) { struct lu_list *listp; listp = lu_listp; while (listp != NULL) { if (strcmp(slice, listp->slice) == 0) { libdiskmgt_add_str(attrs, DM_USED_BY, DM_USE_LU, errp); libdiskmgt_add_str(attrs, DM_USED_NAME, listp->name, errp); found = 1; break; } listp = listp->next; } } (void) mutex_unlock(&lu_lock); return (found); } static int add_use_record(char *devname, char *name) { struct lu_list *sp; sp = (struct lu_list *)malloc(sizeof (struct lu_list)); if (sp == NULL) { return (ENOMEM); } if ((sp->slice = strdup(devname)) == NULL) { free(sp); return (ENOMEM); } if ((sp->name = strdup(name)) == NULL) { free(sp->slice); free(sp); return (ENOMEM); } sp->next = lu_listp; lu_listp = sp; return (0); } /* * Free the list of liveupgrade entries. */ static void free_lu(struct lu_list *listp) { struct lu_list *nextp; while (listp != NULL) { nextp = listp->next; free((void *)listp->slice); free((void *)listp->name); free((void *)listp); listp = nextp; } } /* * Create a list of live upgrade devices. */ static int load_lu() { char tmpname[TMPNM_SIZE]; int fd; int status = 0; (void) strlcpy(tmpname, "/var/run/dm_lu_XXXXXX", TMPNM_SIZE); if ((fd = mkstemp(tmpname)) != -1) { (void) unlink(tmpname); if (run_cmd("/usr/sbin/lustatus", "lustatus", NULL, fd)) { status = lustatus(fd); } else { (void) close(fd); } } return (status); } /* * The XML generated by the live upgrade commands is not parseable by the * standard Solaris XML parser, so we have to do it ourselves. */ static int lufslist(int fd) { FILE *fp; char line[MAXPATHLEN]; int status; if ((fp = fdopen(fd, "r")) == NULL) { (void) close(fd); return (0); } (void) fseek(fp, 0L, SEEK_SET); while (fgets(line, sizeof (line), fp) == line) { char *devp; char *nmp; char *ep; if (strncmp(line, "