diff options
author | dilpreet <none@none> | 2005-12-07 10:04:23 -0800 |
---|---|---|
committer | dilpreet <none@none> | 2005-12-07 10:04:23 -0800 |
commit | 7ee93e3bbce920c0d0742deb6632b0939e30b783 (patch) | |
tree | e839ee42f46f4481a309b203d658f11a14fb3a34 | |
parent | d1a180b0452ce86577a43be3245d2eacdeec1a34 (diff) | |
download | illumos-joyent-7ee93e3bbce920c0d0742deb6632b0939e30b783.tar.gz |
6356155 fmdump -e cross-references are broken when logs move across filesystems
-rw-r--r-- | usr/src/cmd/fm/fmd/common/fmd.c | 2 | ||||
-rw-r--r-- | usr/src/cmd/fm/fmd/common/fmd_log.c | 100 | ||||
-rw-r--r-- | usr/src/cmd/fm/fmd/common/fmd_log.h | 4 | ||||
-rw-r--r-- | usr/src/cmd/fm/fmdump/common/fmdump.c | 1 | ||||
-rw-r--r-- | usr/src/lib/fm/libfmd_log/common/fmd_log.c | 47 | ||||
-rw-r--r-- | usr/src/lib/fm/libfmd_log/common/fmd_log.h | 5 | ||||
-rw-r--r-- | usr/src/lib/fm/libfmd_log/common/fmd_log_impl.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/sys/exacct_catalog.h | 3 |
8 files changed, 121 insertions, 44 deletions
diff --git a/usr/src/cmd/fm/fmd/common/fmd.c b/usr/src/cmd/fm/fmd/common/fmd.c index a350139f43..658b7432f1 100644 --- a/usr/src/cmd/fm/fmd/common/fmd.c +++ b/usr/src/cmd/fm/fmd/common/fmd.c @@ -62,7 +62,7 @@ extern const nv_alloc_ops_t fmd_nv_alloc_ops; /* see fmd_nv.c */ -const char _fmd_version[] = "1.0"; /* daemon version string */ +const char _fmd_version[] = "1.1"; /* daemon version string */ static char _fmd_plat[MAXNAMELEN]; /* native platform string */ static char _fmd_isa[MAXNAMELEN]; /* native instruction set */ static struct utsname _fmd_uts; /* native uname(2) info */ diff --git a/usr/src/cmd/fm/fmd/common/fmd_log.c b/usr/src/cmd/fm/fmd/common/fmd_log.c index 3e11ffff27..66fb0f3612 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_log.c +++ b/usr/src/cmd/fm/fmd/common/fmd_log.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -44,14 +44,17 @@ * the fmd code below. Our exacct file management uses the following grammar: * * file := hdr toc event* - * hdr := EXD_FMA_LABEL EXD_FMA_VERSION EXD_FMA_OSREL EXD_FMA_OSVER EXD_FMA_PLAT + * hdr := EXD_FMA_LABEL EXD_FMA_VERSION EXD_FMA_OSREL EXD_FMA_OSVER + * EXD_FMA_PLAT EXD_FMA_UUID * toc := EXD_FMA_OFFSET - * event := EXD_FMA_TODSEC EXD_FMA_TODNSEC EXD_FMA_NVLIST evref* - * evref := EXD_FMA_MAJOR EXD_FMA_MINOR EXD_FMA_INODE EXD_FMA_OFFSET + * event := EXD_FMA_TODSEC EXD_FMA_TODNSEC EXD_FMA_NVLIST evref* or legacy evref + * evref := EXD_FMA_UUID EXD_FMA_OFFSET + * legacy evref := EXD_FMA_MAJOR EXD_FMA_MINOR EXD_FMA_INODE EXD_FMA_OFFSET * * Any event can be uniquely identified by the tuple (file, offset) where file - * is encoded as (major, minor, inode) when we are cross-linking files. Note - * that we break out of the file's dev_t into its two 32-bit components to + * is encoded as (uuid) when we are cross-linking files. For legacy file + * formats we still support encoding the reference as (major, minor, inode). + * Note that we break out of the file's dev_t into its two 32-bit components to * permit development of either 32-bit or 64-bit log readers and writers; the * LFS APIs do not yet export a 64-bit dev_t to fstat64(), so there is no way * for a 32-bit application to retrieve and store a 64-bit dev_t. @@ -69,6 +72,7 @@ #include <sys/statvfs.h> #include <sys/fm/protocol.h> #include <sys/exacct_impl.h> +#include <uuid/uuid.h> #include <unistd.h> #include <limits.h> @@ -94,6 +98,7 @@ #define CAT_FMA_OSREL (EXT_STRING | EXC_DEFAULT | EXD_FMA_OSREL) #define CAT_FMA_OSVER (EXT_STRING | EXC_DEFAULT | EXD_FMA_OSVER) #define CAT_FMA_PLAT (EXT_STRING | EXC_DEFAULT | EXD_FMA_PLAT) +#define CAT_FMA_UUID (EXT_STRING | EXC_DEFAULT | EXD_FMA_UUID) #define CAT_FMA_TODSEC (EXT_UINT64 | EXC_DEFAULT | EXD_FMA_TODSEC) #define CAT_FMA_TODNSEC (EXT_UINT64 | EXC_DEFAULT | EXD_FMA_TODNSEC) #define CAT_FMA_NVLIST (EXT_RAW | EXC_DEFAULT | EXD_FMA_NVLIST) @@ -127,14 +132,20 @@ fmd_log_write(fmd_log_t *lp, const void *buf, size_t n) static int fmd_log_write_hdr(fmd_log_t *lp, const char *tag) { - ea_object_t hdr, toc, i0, i1, i2, i3, i4, i5; + ea_object_t hdr, toc, i0, i1, i2, i3, i4, i5, i6; const char *osrel, *osver, *plat; off64_t off = 0; int err = 0; + uuid_t uuid; (void) fmd_conf_getprop(fmd.d_conf, "osrelease", &osrel); (void) fmd_conf_getprop(fmd.d_conf, "osversion", &osver); (void) fmd_conf_getprop(fmd.d_conf, "platform", &plat); + (void) fmd_conf_getprop(fmd.d_conf, "uuidlen", &lp->log_uuidlen); + + lp->log_uuid = fmd_zalloc(lp->log_uuidlen + 1, FMD_SLEEP); + uuid_generate(uuid); + uuid_unparse(uuid, lp->log_uuid); err |= ea_set_group(&hdr, CAT_FMA_GROUP); err |= ea_set_group(&toc, CAT_FMA_GROUP); @@ -144,14 +155,16 @@ fmd_log_write_hdr(fmd_log_t *lp, const char *tag) err |= ea_set_item(&i2, CAT_FMA_OSREL, osrel, 0); err |= ea_set_item(&i3, CAT_FMA_OSVER, osver, 0); err |= ea_set_item(&i4, CAT_FMA_PLAT, plat, 0); - err |= ea_set_item(&i5, CAT_FMA_OFFSET, &off, 0); + err |= ea_set_item(&i5, CAT_FMA_UUID, lp->log_uuid, 0); + err |= ea_set_item(&i6, CAT_FMA_OFFSET, &off, 0); (void) ea_attach_to_group(&hdr, &i0); (void) ea_attach_to_group(&hdr, &i1); (void) ea_attach_to_group(&hdr, &i2); (void) ea_attach_to_group(&hdr, &i3); (void) ea_attach_to_group(&hdr, &i4); - (void) ea_attach_to_group(&toc, &i5); + (void) ea_attach_to_group(&hdr, &i5); + (void) ea_attach_to_group(&toc, &i6); if (err == 0) { size_t hdr_size = ea_pack_object(&hdr, NULL, 0); @@ -186,6 +199,7 @@ fmd_log_write_hdr(fmd_log_t *lp, const char *tag) (void) ea_free_item(&i3, EUP_ALLOC); (void) ea_free_item(&i4, EUP_ALLOC); (void) ea_free_item(&i5, EUP_ALLOC); + (void) ea_free_item(&i6, EUP_ALLOC); return (err ? fmd_set_errno(err) : 0); } @@ -270,6 +284,11 @@ fmd_log_check_hdr(fmd_log_t *lp, const char *tag) } got_label++; break; + case CAT_FMA_UUID: + lp->log_uuid = fmd_strdup(obj->eo_item.ei_string, + FMD_SLEEP); + lp->log_uuidlen = strlen(lp->log_uuid); + break; } } @@ -439,6 +458,8 @@ fmd_log_close(fmd_log_t *lp) fmd_strfree(lp->log_name); fmd_strfree(lp->log_tag); + if (lp->log_uuid != NULL) + fmd_free(lp->log_uuid, lp->log_uuidlen + 1); fmd_free(lp, sizeof (fmd_log_t)); } @@ -488,7 +509,8 @@ fmd_log_append(fmd_log_t *lp, fmd_event_t *e, fmd_case_t *cp) int err = 0; ea_object_t grp0, grp1, i0, i1, i2, *items; - size_t nvsize, easize, itsize; + ea_object_t **fe = NULL; + size_t nvsize, easize, itsize, frsize; char *nvbuf, *eabuf; statvfs64_t stv; @@ -525,15 +547,14 @@ fmd_log_append(fmd_log_t *lp, fmd_event_t *e, fmd_case_t *cp) * then allocate a block of ea_object_t's and fill in a group for * each event saved in the case's item list. For each such group, * we attach it to grp1, which in turn will be attached to grp0. - * This section of code cannot fail as we only manipulate integer - * objects, which require no underlying libexacct memory allocation. */ if (cp != NULL) { - ea_object_t *egrp, *ip; + ea_object_t *egrp, *ip, **fp; fmd_event_impl_t *eip; fmd_case_item_t *cit; (void) ea_set_group(&grp1, CAT_FMA_GROUP); + frsize = sizeof (ea_object_t *) * cip->ci_nitems; itsize = sizeof (ea_object_t) * cip->ci_nitems * 5; items = ip = fmd_alloc(itsize, FMD_SLEEP); @@ -552,22 +573,35 @@ fmd_log_append(fmd_log_t *lp, fmd_event_t *e, fmd_case_t *cp) (void) ea_set_group(ip, CAT_FMA_GROUP); egrp = ip++; /* first obj is group */ - (void) ea_set_item(ip, CAT_FMA_MAJOR, &maj, 0); - (void) ea_attach_to_group(egrp, ip++); - - (void) ea_set_item(ip, CAT_FMA_MINOR, &min, 0); - (void) ea_attach_to_group(egrp, ip++); - - (void) ea_set_item(ip, CAT_FMA_INODE, - &eip->ev_log->log_stat.st_ino, 0); - (void) ea_attach_to_group(egrp, ip++); - + /* + * If the event log file is in legacy format, + * then write the xref to the file in the legacy + * maj/min/inode method else write it using the + * file uuid. + */ + if (eip->ev_log->log_uuid == NULL) { + (void) ea_set_item(ip, CAT_FMA_MAJOR, &maj, 0); + (void) ea_attach_to_group(egrp, ip++); + (void) ea_set_item(ip, CAT_FMA_MINOR, &min, 0); + (void) ea_attach_to_group(egrp, ip++); + (void) ea_set_item(ip, CAT_FMA_INODE, + &eip->ev_log->log_stat.st_ino, 0); + (void) ea_attach_to_group(egrp, ip++); + } else { + if (ea_set_item(ip, CAT_FMA_UUID, + eip->ev_log->log_uuid, 0) == -1) { + err = EFMD_LOG_EXACCT; + goto exerrcp; + } + if (fe == NULL) + fe = fp = fmd_zalloc(frsize, FMD_SLEEP); + *fp++ = ip; + (void) ea_attach_to_group(egrp, ip++); + } (void) ea_set_item(ip, CAT_FMA_OFFSET, &eip->ev_off, 0); (void) ea_attach_to_group(egrp, ip++); - (void) ea_attach_to_group(&grp1, egrp); } - (void) ea_attach_to_group(&grp0, &grp1); } @@ -624,10 +658,22 @@ fmd_log_append(fmd_log_t *lp, fmd_event_t *e, fmd_case_t *cp) (void) pthread_mutex_unlock(&lp->log_lock); (void) pthread_mutex_unlock(&ep->ev_lock); - if (cp != NULL) + fmd_free(eabuf, easize); + +exerrcp: + if (cp != NULL) { + if (fe != NULL) { + ea_object_t **fp = fe; + int i = 0; + + for (; *fp != NULL && i < cip->ci_nitems; i++) + (void) ea_free_item(*fp++, EUP_ALLOC); + fmd_free(fe, frsize); + } + fmd_free(items, itsize); + } - fmd_free(eabuf, easize); exerr: fmd_free(nvbuf, nvsize); diff --git a/usr/src/cmd/fm/fmd/common/fmd_log.h b/usr/src/cmd/fm/fmd/common/fmd_log.h index 97af9116d3..445f31e401 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_log.h +++ b/usr/src/cmd/fm/fmd/common/fmd_log.h @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -56,6 +56,8 @@ typedef struct fmd_log { off64_t log_off; /* offset at which to append */ off64_t log_skip; /* offset to skip to for replay */ uint64_t log_minfree; /* minimum free bytes for filesystem */ + char *log_uuid; /* uuid string for this log file */ + uint_t log_uuidlen; /* length of log_uuid (not incl. \0) */ } fmd_log_t; #define FMD_LF_EAOPEN 0x1 /* log_ea is open and valid */ diff --git a/usr/src/cmd/fm/fmdump/common/fmdump.c b/usr/src/cmd/fm/fmdump/common/fmdump.c index 4289688e6e..1e794ec120 100644 --- a/usr/src/cmd/fm/fmdump/common/fmdump.c +++ b/usr/src/cmd/fm/fmdump/common/fmdump.c @@ -501,6 +501,7 @@ main(int argc, char *argv[]) (void) printf("EXD_FMA_OSREL = %s\n", log.log_osrelease); (void) printf("EXD_FMA_OSVER = %s\n", log.log_osversion); (void) printf("EXD_FMA_PLAT = %s\n", log.log_platform); + (void) printf("EXD_FMA_UUID = %s\n", log.log_uuid); return (FMDUMP_EXIT_SUCCESS); } diff --git a/usr/src/lib/fm/libfmd_log/common/fmd_log.c b/usr/src/lib/fm/libfmd_log/common/fmd_log.c index c052587099..5be219e406 100644 --- a/usr/src/lib/fm/libfmd_log/common/fmd_log.c +++ b/usr/src/lib/fm/libfmd_log/common/fmd_log.c @@ -50,6 +50,7 @@ #define CAT_FMA_OSREL (EXT_STRING | EXC_DEFAULT | EXD_FMA_OSREL) #define CAT_FMA_OSVER (EXT_STRING | EXC_DEFAULT | EXD_FMA_OSVER) #define CAT_FMA_PLAT (EXT_STRING | EXC_DEFAULT | EXD_FMA_PLAT) +#define CAT_FMA_UUID (EXT_STRING | EXC_DEFAULT | EXD_FMA_UUID) #define CAT_FMA_TODSEC (EXT_UINT64 | EXC_DEFAULT | EXD_FMA_TODSEC) #define CAT_FMA_TODNSEC (EXT_UINT64 | EXC_DEFAULT | EXD_FMA_TODNSEC) #define CAT_FMA_NVLIST (EXT_RAW | EXC_DEFAULT | EXD_FMA_NVLIST) @@ -206,6 +207,7 @@ fmd_log_load_xref(fmd_log_t *lp, uint_t iflags, major_t maj = (major_t)-1L; minor_t min = (minor_t)-1L; ino64_t ino = (ino64_t)-1L; + char *uuid = NULL; for (obj = grp->eo_group.eg_objs; obj != NULL; obj = obj->eo_next) { switch (obj->eo_catalog) { @@ -221,30 +223,43 @@ fmd_log_load_xref(fmd_log_t *lp, uint_t iflags, case CAT_FMA_OFFSET: off = obj->eo_item.ei_uint64; break; + case CAT_FMA_UUID: + uuid = obj->eo_item.ei_string; + break; } } - if (off == (off64_t)-1L || ino == (ino64_t)-1L || - maj == (major_t)-1L || min == (minor_t)-1L) + if (off == (off64_t)-1L || (uuid == NULL && (ino == (ino64_t)-1L || + maj == (major_t)-1L || min == (minor_t)-1L))) return (fmd_log_set_errno(lp, EFDL_BADREF)); - if ((dev = makedev(maj, min)) == NODEV) + if (uuid == NULL && (dev = makedev(maj, min)) == NODEV) return (fmd_log_set_errno(lp, EFDL_BADDEV)); /* - * Search our xref list for matching (dev_t, ino64_t). If we can't - * find one, return silently without doing anything. We expect log - * xrefs to be broken whenever log files are trimmed or removed; their - * only purpose is to help us debug diagnosis engine algorithms. + * Search our xref list for matching (dev_t, ino64_t) or (uuid). + * If we can't find one, return silently without + * doing anything. We expect log xrefs to be broken whenever log + * files are trimmed or removed; their only purpose is to help us + * debug diagnosis engine algorithms. */ for (xlp = lp->log_xrefs; xlp != NULL; xlp = xlp->log_xnext) { - if (xlp->log_stat.st_ino == ino && xlp->log_stat.st_dev == dev) + if (uuid == NULL) { + if (xlp->log_stat.st_ino == ino && + xlp->log_stat.st_dev == dev) + break; + } else if (xlp->log_uuid != NULL && + strcmp(xlp->log_uuid, uuid) == 0) break; } if (xlp == NULL) { - fmd_log_dprintf(lp, "broken xref dev=%lx ino=%llx\n", - (ulong_t)dev, (u_longlong_t)ino); + if (uuid == NULL) + fmd_log_dprintf(lp, "broken xref dev=%lx ino=%llx\n", + (ulong_t)dev, (u_longlong_t)ino); + else + fmd_log_dprintf(lp, "broken xref uuid=%s\n", uuid); + return (0); } @@ -366,7 +381,7 @@ fmd_log_open(int abi, const char *name, int *errp) fmd_log_t *lp; int fd; - if (abi != FMD_LOG_VERSION) + if (abi > FMD_LOG_VERSION) return (fmd_log_open_err(NULL, errp, EFDL_VERSION)); if ((lp = malloc(sizeof (fmd_log_t))) == NULL) @@ -443,6 +458,13 @@ fmd_log_open(int abi, const char *name, int *errp) return (fmd_log_open_err(lp, errp, EFDL_NOMEM)); } break; + case CAT_FMA_UUID: + lp->log_uuid = strdup(obj->eo_item.ei_string); + if (lp->log_uuid == NULL) { + ea_free_object(grp, EUP_ALLOC); + return (fmd_log_open_err(lp, errp, EFDL_NOMEM)); + } + break; } } @@ -498,6 +520,7 @@ fmd_log_close(fmd_log_t *lp) free(lp->log_osrelease); free(lp->log_osversion); free(lp->log_platform); + free(lp->log_uuid); free(lp); } @@ -521,6 +544,8 @@ fmd_log_header(fmd_log_t *lp, fmd_log_header_t *hp) hp->log_osrelease = lp->log_osrelease ? lp->log_osrelease : ""; hp->log_osversion = lp->log_osversion ? lp->log_osversion : ""; hp->log_platform = lp->log_platform ? lp->log_platform : ""; + if (lp->log_abi > 1) + hp->log_uuid = lp->log_uuid ? lp->log_uuid : ""; } /* diff --git a/usr/src/lib/fm/libfmd_log/common/fmd_log.h b/usr/src/lib/fm/libfmd_log/common/fmd_log.h index 55ac0db7d2..9c98d8236a 100644 --- a/usr/src/lib/fm/libfmd_log/common/fmd_log.h +++ b/usr/src/lib/fm/libfmd_log/common/fmd_log.h @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -46,7 +46,7 @@ extern "C" { * purpose until they are publicly documented for use outside of Sun. */ -#define FMD_LOG_VERSION 1 /* library ABI interface version */ +#define FMD_LOG_VERSION 2 /* library ABI interface version */ typedef struct fmd_log fmd_log_t; @@ -65,6 +65,7 @@ typedef struct fmd_log_header { const char *log_osrelease; /* uname(1) -r value at creation time */ const char *log_osversion; /* uname(1) -v value at creation time */ const char *log_platform; /* uname(1) -i value at creation time */ + const char *log_uuid; /* fmd(1M) log file uuid */ } fmd_log_header_t; extern void fmd_log_header(fmd_log_t *, fmd_log_header_t *); diff --git a/usr/src/lib/fm/libfmd_log/common/fmd_log_impl.h b/usr/src/lib/fm/libfmd_log/common/fmd_log_impl.h index 5450b05c10..9ea5eb644e 100644 --- a/usr/src/lib/fm/libfmd_log/common/fmd_log_impl.h +++ b/usr/src/lib/fm/libfmd_log/common/fmd_log_impl.h @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -47,6 +47,7 @@ struct fmd_log { char *log_osrelease; /* uname -r at log creation time */ char *log_osversion; /* uname -v at log creation time */ char *log_platform; /* uname -i at log creation time */ + char *log_uuid; /* log file uuid string */ int log_abi; /* abi version of library client */ int log_errno; /* err from last library call */ int log_fd; /* file descriptor for log */ diff --git a/usr/src/uts/common/sys/exacct_catalog.h b/usr/src/uts/common/sys/exacct_catalog.h index 24595e529c..0911344382 100644 --- a/usr/src/uts/common/sys/exacct_catalog.h +++ b/usr/src/uts/common/sys/exacct_catalog.h @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -202,6 +202,7 @@ extern "C" { #define EXD_FMA_MINOR 0x004009 #define EXD_FMA_INODE 0x00400A #define EXD_FMA_OFFSET 0x00400B +#define EXD_FMA_UUID 0x00400C #ifdef __cplusplus } |