summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2014-11-14 15:59:13 -0800
committerRobert Mustacchi <rm@joyent.com>2014-11-25 08:07:17 -0800
commit64e4e50ab4bc3670a29e5691e3dd935c94f0a5d7 (patch)
treef003b4de852eb5fa09892e1ff7b84a2d8bb21750 /usr/src
parent9e573dcc6440324d76c37be570afdef86f045685 (diff)
downloadillumos-gate-64e4e50ab4bc3670a29e5691e3dd935c94f0a5d7.tar.gz
5341 gcore fails with "no such file or directory" if write fails ... error is misleading
Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/gcore/gcore.c5
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_err.c3
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_errno.h3
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_proc.c9
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/gcore.c6
-rw-r--r--usr/src/lib/libproc/common/Pgcore.c87
6 files changed, 73 insertions, 40 deletions
diff --git a/usr/src/cmd/gcore/gcore.c b/usr/src/cmd/gcore/gcore.c
index 4966fe0b8e..d9f46494bd 100644
--- a/usr/src/cmd/gcore/gcore.c
+++ b/usr/src/cmd/gcore/gcore.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdlib.h>
#include <stdio.h>
#include <stdio_ext.h>
@@ -139,7 +137,8 @@ gcore(struct ps_prochandle *P, const char *fname, core_content_t content,
(void) printf("%s: %s dumped\n", pname, fname);
} else {
(void) fprintf(stderr, "%s: %s dump failed: %s\n", pname,
- fname, strerror(errno));
+ fname, errno == EBADE ? "unexpected short write" :
+ strerror(errno));
(*errp)++;
}
}
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_err.c b/usr/src/cmd/mdb/common/mdb/mdb_err.c
index beddad2aa2..e0f3f95129 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_err.c
+++ b/usr/src/cmd/mdb/common/mdb/mdb_err.c
@@ -113,7 +113,8 @@ static const char *const _mdb_errlist[] = {
"too many enabled watchpoints for this machine", /* EMDB_WPTOOMANY */
"DTrace is active", /* EMDB_DTACTIVE */
"boot-loaded module cannot be unloaded", /* EMDB_KMODNOUNLOAD */
- "stack frame pointer is invalid" /* EMDB_STKFRAME */
+ "stack frame pointer is invalid", /* EMDB_STKFRAME */
+ "unexpected short write" /* EMDB_SHORTWRITE */
};
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_errno.h b/usr/src/cmd/mdb/common/mdb/mdb_errno.h
index 7dfaff2896..6561173066 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_errno.h
+++ b/usr/src/cmd/mdb/common/mdb/mdb_errno.h
@@ -113,7 +113,8 @@ enum {
EMDB_WPTOOMANY, /* Too many watchpoints */
EMDB_DTACTIVE, /* DTrace is active */
EMDB_KMODNOUNLOAD, /* module can't be unloaded */
- EMDB_STKFRAME /* Bad stack frame pointer */
+ EMDB_STKFRAME, /* Bad stack frame pointer */
+ EMDB_SHORTWRITE /* unexpected short write */
};
#endif /* _MDB */
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_proc.c b/usr/src/cmd/mdb/common/mdb/mdb_proc.c
index e3d9833a6b..4cd0e1efbe 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_proc.c
+++ b/usr/src/cmd/mdb/common/mdb/mdb_proc.c
@@ -24,7 +24,7 @@
* Use is subject to license terms.
*/
/*
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
*/
/*
@@ -1388,6 +1388,13 @@ pt_gcore(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
(void) mdb_snprintf(fname, size, "%s.%d", prefix, (int)pid);
if (Pgcore(t->t_pshandle, fname, content) != 0) {
+ /*
+ * Short writes during dumping are specifically described by
+ * EBADE, just as ZFS uses this otherwise-unused code for
+ * checksum errors. Translate to and mdb errno.
+ */
+ if (errno == EBADE)
+ (void) set_errno(EMDB_SHORTWRITE);
mdb_warn("couldn't dump core");
return (DCMD_ERR);
}
diff --git a/usr/src/cmd/mdb/common/modules/genunix/gcore.c b/usr/src/cmd/mdb/common/modules/genunix/gcore.c
index cd8499b888..567160de8b 100644
--- a/usr/src/cmd/mdb/common/modules/genunix/gcore.c
+++ b/usr/src/cmd/mdb/common/modules/genunix/gcore.c
@@ -67,6 +67,7 @@
#include <stdbool.h>
#include <string.h>
#include <libproc.h>
+#include <errno.h>
#include "avl.h"
@@ -2000,7 +2001,6 @@ gcore_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
char core_name[MAXNAMELEN];
mdb_proc_t p;
mdb_pid_t pid;
- int error;
if (!gcore_initialized) {
mdb_warn("gcore unavailable\n");
@@ -2030,8 +2030,8 @@ gcore_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
(void) snprintf(core_name, sizeof (core_name), "core.%s.%d",
p.p_user.u_comm, pid.pid_id);
- if ((error = Pgcore(P, core_name, CC_CONTENT_DEFAULT)) != 0) {
- mdb_warn("Failed to generate core file: %d", error);
+ if (Pgcore(P, core_name, CC_CONTENT_DEFAULT) != 0) {
+ mdb_warn("Failed to generate core file: %d", errno);
Pfree(P);
return (DCMD_ERR);
}
diff --git a/usr/src/lib/libproc/common/Pgcore.c b/usr/src/lib/libproc/common/Pgcore.c
index bf530be90c..58cc308a17 100644
--- a/usr/src/lib/libproc/common/Pgcore.c
+++ b/usr/src/lib/libproc/common/Pgcore.c
@@ -25,7 +25,7 @@
*/
/*
* Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
*/
@@ -94,6 +94,29 @@ typedef struct {
off64_t *fd_doff;
} fditer_t;
+static int
+gc_pwrite64(int fd, const void *buf, size_t len, off64_t off)
+{
+ int err;
+
+ err = pwrite64(fd, buf, len, off);
+
+ if (err < 0)
+ return (err);
+
+ /*
+ * We will take a page from ZFS's book here and use the otherwise
+ * unused EBADE to mean a short write. Typically this will actually
+ * result from ENOSPC or EDQUOT, but we can't be sure.
+ */
+ if (err < len) {
+ errno = EBADE;
+ return (-1);
+ }
+
+ return (0);
+}
+
static void
shstrtab_init(shstrtab_t *s)
{
@@ -126,13 +149,16 @@ Pgcore(struct ps_prochandle *P, const char *fname, core_content_t content)
{
int fd;
int err;
+ int saved_errno;
if ((fd = creat64(fname, 0666)) < 0)
return (-1);
if ((err = Pfgcore(P, fd, content)) != 0) {
+ saved_errno = errno;
(void) close(fd);
(void) unlink(fname);
+ errno = saved_errno;
return (err);
}
@@ -414,12 +440,12 @@ write_note(int fd, uint_t type, const void *desc, size_t descsz, off64_t *offp)
n.nhdr.n_namesz = 5;
n.nhdr.n_descsz = roundup(descsz, 4);
- if (pwrite64(fd, &n, sizeof (n), *offp) != sizeof (n))
+ if (gc_pwrite64(fd, &n, sizeof (n), *offp) != 0)
return (-1);
*offp += sizeof (n);
- if (pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != n.nhdr.n_descsz)
+ if (gc_pwrite64(fd, desc, n.nhdr.n_descsz, *offp) != 0)
return (-1);
*offp += n.nhdr.n_descsz;
@@ -652,8 +678,8 @@ write_shdr(pgcore_t *pgc, shstrtype_t name, uint_t type, ulong_t flags,
shdr.sh_addralign = addralign;
shdr.sh_entsize = entsize;
- if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
- *pgc->pgc_soff) != sizeof (shdr))
+ if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
+ *pgc->pgc_soff) != 0)
return (-1);
*pgc->pgc_soff += sizeof (shdr);
@@ -673,8 +699,8 @@ write_shdr(pgcore_t *pgc, shstrtype_t name, uint_t type, ulong_t flags,
shdr.sh_addralign = addralign;
shdr.sh_entsize = entsize;
- if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
- *pgc->pgc_soff) != sizeof (shdr))
+ if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
+ *pgc->pgc_soff) != 0)
return (-1);
*pgc->pgc_soff += sizeof (shdr);
@@ -699,8 +725,8 @@ dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym)
return (0);
size = sym->sym_hdr_pri.sh_size;
- if (pwrite64(pgc->pgc_fd, sym->sym_data_pri->d_buf, size,
- *pgc->pgc_doff) != size)
+ if (gc_pwrite64(pgc->pgc_fd, sym->sym_data_pri->d_buf, size,
+ *pgc->pgc_doff) != 0)
return (-1);
if (write_shdr(pgc, symname, symtype, 0, addr, *pgc->pgc_doff, size,
@@ -711,7 +737,7 @@ dump_symtab(pgcore_t *pgc, file_info_t *fptr, uint_t index, int dynsym)
*pgc->pgc_doff += roundup(size, 8);
size = sym->sym_strhdr.sh_size;
- if (pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != size)
+ if (gc_pwrite64(pgc->pgc_fd, sym->sym_strs, size, *pgc->pgc_doff) != 0)
return (-1);
if (write_shdr(pgc, strname, SHT_STRTAB, SHF_STRINGS, addr,
@@ -773,9 +799,8 @@ dump_sections(pgcore_t *pgc)
* Write the CTF data that we've read out of the
* file itself into the core file.
*/
- if (pwrite64(pgc->pgc_fd, fptr->file_ctf_buf,
- fptr->file_ctf_size, *pgc->pgc_doff) !=
- fptr->file_ctf_size)
+ if (gc_pwrite64(pgc->pgc_fd, fptr->file_ctf_buf,
+ fptr->file_ctf_size, *pgc->pgc_doff) != 0)
return (-1);
if (write_shdr(pgc, STR_CTF, SHT_PROGBITS, 0,
@@ -887,10 +912,10 @@ dump_map(void *data, const prmap_t *pmp, const char *name)
* mapping would have been.
*/
if (Pread(P, pgc->pgc_chunk, csz, pmp->pr_vaddr + n) != csz ||
- pwrite64(pgc->pgc_fd, pgc->pgc_chunk, csz,
- *pgc->pgc_doff + n) != csz) {
+ gc_pwrite64(pgc->pgc_fd, pgc->pgc_chunk, csz,
+ *pgc->pgc_doff + n) != 0) {
int err = errno;
- (void) pwrite64(pgc->pgc_fd, &err, sizeof (err),
+ (void) gc_pwrite64(pgc->pgc_fd, &err, sizeof (err),
*pgc->pgc_doff);
*pgc->pgc_doff += roundup(sizeof (err), 8);
@@ -908,8 +933,8 @@ dump_map(void *data, const prmap_t *pmp, const char *name)
exclude:
if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
- if (pwrite64(pgc->pgc_fd, &phdr, sizeof (phdr),
- *pgc->pgc_poff) != sizeof (phdr))
+ if (gc_pwrite64(pgc->pgc_fd, &phdr, sizeof (phdr),
+ *pgc->pgc_poff) != 0)
return (1);
*pgc->pgc_poff += sizeof (phdr);
@@ -925,8 +950,8 @@ exclude:
phdr32.p_offset = (Elf32_Off)phdr.p_offset;
phdr32.p_filesz = (Elf32_Word)phdr.p_filesz;
- if (pwrite64(pgc->pgc_fd, &phdr32, sizeof (phdr32),
- *pgc->pgc_poff) != sizeof (phdr32))
+ if (gc_pwrite64(pgc->pgc_fd, &phdr32, sizeof (phdr32),
+ *pgc->pgc_poff) != 0)
return (1);
*pgc->pgc_poff += sizeof (phdr32);
@@ -961,7 +986,7 @@ write_shstrtab(struct ps_prochandle *P, pgcore_t *pgc)
if ((ndx = s->sst_ndx[i]) != 0 || i == STR_NONE) {
const char *str = shstrtab_data[i];
size_t len = strlen(str) + 1;
- if (pwrite64(pgc->pgc_fd, str, len, off + ndx) != len)
+ if (gc_pwrite64(pgc->pgc_fd, str, len, off + ndx) != 0)
return (1);
}
}
@@ -977,8 +1002,8 @@ write_shstrtab(struct ps_prochandle *P, pgcore_t *pgc)
shdr.sh_flags = SHF_STRINGS;
shdr.sh_type = SHT_STRTAB;
- if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
- *pgc->pgc_soff) != sizeof (shdr))
+ if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
+ *pgc->pgc_soff) != 0)
return (1);
*pgc->pgc_soff += sizeof (shdr);
@@ -994,8 +1019,8 @@ write_shstrtab(struct ps_prochandle *P, pgcore_t *pgc)
shdr.sh_flags = SHF_STRINGS;
shdr.sh_type = SHT_STRTAB;
- if (pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
- *pgc->pgc_soff) != sizeof (shdr))
+ if (gc_pwrite64(pgc->pgc_fd, &shdr, sizeof (shdr),
+ *pgc->pgc_soff) != 0)
return (1);
*pgc->pgc_soff += sizeof (shdr);
@@ -1120,7 +1145,7 @@ Pfgcore(struct ps_prochandle *P, int fd, core_content_t content)
ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs;
}
- if (pwrite64(fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
+ if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0)
goto err;
poff = ehdr.e_phoff;
@@ -1178,7 +1203,7 @@ Pfgcore(struct ps_prochandle *P, int fd, core_content_t content)
ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs;
}
- if (pwrite64(fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
+ if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0)
goto err;
poff = ehdr.e_phoff;
@@ -1260,7 +1285,7 @@ Pfgcore(struct ps_prochandle *P, int fd, core_content_t content)
phdr.p_filesz = doff - boff;
boff = doff;
- if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
+ if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
goto err;
poff += sizeof (phdr);
#ifdef _LP64
@@ -1274,7 +1299,7 @@ Pfgcore(struct ps_prochandle *P, int fd, core_content_t content)
phdr.p_filesz = doff - boff;
boff = doff;
- if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
+ if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
goto err;
poff += sizeof (phdr);
#endif /* _LP64 */
@@ -1432,7 +1457,7 @@ Pfgcore(struct ps_prochandle *P, int fd, core_content_t content)
phdr.p_filesz = doff - boff;
boff = doff;
- if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
+ if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
goto err;
poff += sizeof (phdr);
#ifdef _LP64
@@ -1446,7 +1471,7 @@ Pfgcore(struct ps_prochandle *P, int fd, core_content_t content)
phdr.p_filesz = doff - boff;
boff = doff;
- if (pwrite64(fd, &phdr, sizeof (phdr), poff) != sizeof (phdr))
+ if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0)
goto err;
poff += sizeof (phdr);
#endif /* _LP64 */