xmmap: inform Linux users of tuning knobs on ENOMEM
Linux users may benefit from additional information on how to avoid ENOMEM from mmap despite the system having enough RAM to accomodate them. We can't reliably unmap pack windows to work around the issue since malloc and other library routines may mmap without our knowledge. Signed-off-by: Eric Wong <e@80x24.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
670b81a890
commit
dc05929411
3
config.c
3
config.c
@ -3051,7 +3051,8 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
|
||||
if (contents == MAP_FAILED) {
|
||||
if (errno == ENODEV && S_ISDIR(st.st_mode))
|
||||
errno = EISDIR;
|
||||
error_errno(_("unable to mmap '%s'"), config_filename);
|
||||
error_errno(_("unable to mmap '%s'%s"),
|
||||
config_filename, mmap_os_err());
|
||||
ret = CONFIG_INVALID_FILE;
|
||||
contents = NULL;
|
||||
goto out_free;
|
||||
|
@ -876,6 +876,7 @@ char *xstrndup(const char *str, size_t len);
|
||||
void *xrealloc(void *ptr, size_t size);
|
||||
void *xcalloc(size_t nmemb, size_t size);
|
||||
void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
const char *mmap_os_err(void);
|
||||
void *xmmap_gently(void *start, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
int xopen(const char *path, int flags, ...);
|
||||
ssize_t xread(int fd, void *buf, size_t len);
|
||||
|
@ -1023,12 +1023,26 @@ void *xmmap_gently(void *start, size_t length,
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *mmap_os_err(void)
|
||||
{
|
||||
static const char blank[] = "";
|
||||
#if defined(__linux__)
|
||||
if (errno == ENOMEM) {
|
||||
/* this continues an existing error message: */
|
||||
static const char enomem[] =
|
||||
", check sys.vm.max_map_count and/or RLIMIT_DATA";
|
||||
return enomem;
|
||||
}
|
||||
#endif /* OS-specific bits */
|
||||
return blank;
|
||||
}
|
||||
|
||||
void *xmmap(void *start, size_t length,
|
||||
int prot, int flags, int fd, off_t offset)
|
||||
{
|
||||
void *ret = xmmap_gently(start, length, prot, flags, fd, offset);
|
||||
if (ret == MAP_FAILED)
|
||||
die_errno(_("mmap failed"));
|
||||
die_errno(_("mmap failed%s"), mmap_os_err());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -652,8 +652,8 @@ unsigned char *use_pack(struct packed_git *p,
|
||||
PROT_READ, MAP_PRIVATE,
|
||||
p->pack_fd, win->offset);
|
||||
if (win->base == MAP_FAILED)
|
||||
die_errno("packfile %s cannot be mapped",
|
||||
p->pack_name);
|
||||
die_errno(_("packfile %s cannot be mapped%s"),
|
||||
p->pack_name, mmap_os_err());
|
||||
if (!win->offset && win->len == p->pack_size
|
||||
&& !p->do_not_close)
|
||||
close_pack_fd(p);
|
||||
|
@ -2236,7 +2236,8 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
|
||||
|
||||
mmap = xmmap_gently(NULL, mmap_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (mmap == MAP_FAILED)
|
||||
die_errno(_("%s: unable to map index file"), path);
|
||||
die_errno(_("%s: unable to map index file%s"), path,
|
||||
mmap_os_err());
|
||||
close(fd);
|
||||
|
||||
hdr = (const struct cache_header *)mmap;
|
||||
|
Loading…
Reference in New Issue
Block a user