Skip to content

Commit dc05929

Browse files
Eric Wonggitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 670b81a commit dc05929

File tree

5 files changed

+22
-5
lines changed

5 files changed

+22
-5
lines changed

config.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3051,7 +3051,8 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
30513051
if (contents == MAP_FAILED) {
30523052
if (errno == ENODEV && S_ISDIR(st.st_mode))
30533053
errno = EISDIR;
3054-
error_errno(_("unable to mmap '%s'"), config_filename);
3054+
error_errno(_("unable to mmap '%s'%s"),
3055+
config_filename, mmap_os_err());
30553056
ret = CONFIG_INVALID_FILE;
30563057
contents = NULL;
30573058
goto out_free;

git-compat-util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,7 @@ char *xstrndup(const char *str, size_t len);
876876
void *xrealloc(void *ptr, size_t size);
877877
void *xcalloc(size_t nmemb, size_t size);
878878
void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
879+
const char *mmap_os_err(void);
879880
void *xmmap_gently(void *start, size_t length, int prot, int flags, int fd, off_t offset);
880881
int xopen(const char *path, int flags, ...);
881882
ssize_t xread(int fd, void *buf, size_t len);

object-file.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1023,12 +1023,26 @@ void *xmmap_gently(void *start, size_t length,
10231023
return ret;
10241024
}
10251025

1026+
const char *mmap_os_err(void)
1027+
{
1028+
static const char blank[] = "";
1029+
#if defined(__linux__)
1030+
if (errno == ENOMEM) {
1031+
/* this continues an existing error message: */
1032+
static const char enomem[] =
1033+
", check sys.vm.max_map_count and/or RLIMIT_DATA";
1034+
return enomem;
1035+
}
1036+
#endif /* OS-specific bits */
1037+
return blank;
1038+
}
1039+
10261040
void *xmmap(void *start, size_t length,
10271041
int prot, int flags, int fd, off_t offset)
10281042
{
10291043
void *ret = xmmap_gently(start, length, prot, flags, fd, offset);
10301044
if (ret == MAP_FAILED)
1031-
die_errno(_("mmap failed"));
1045+
die_errno(_("mmap failed%s"), mmap_os_err());
10321046
return ret;
10331047
}
10341048

packfile.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -652,8 +652,8 @@ unsigned char *use_pack(struct packed_git *p,
652652
PROT_READ, MAP_PRIVATE,
653653
p->pack_fd, win->offset);
654654
if (win->base == MAP_FAILED)
655-
die_errno("packfile %s cannot be mapped",
656-
p->pack_name);
655+
die_errno(_("packfile %s cannot be mapped%s"),
656+
p->pack_name, mmap_os_err());
657657
if (!win->offset && win->len == p->pack_size
658658
&& !p->do_not_close)
659659
close_pack_fd(p);

read-cache.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2236,7 +2236,8 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
22362236

22372237
mmap = xmmap_gently(NULL, mmap_size, PROT_READ, MAP_PRIVATE, fd, 0);
22382238
if (mmap == MAP_FAILED)
2239-
die_errno(_("%s: unable to map index file"), path);
2239+
die_errno(_("%s: unable to map index file%s"), path,
2240+
mmap_os_err());
22402241
close(fd);
22412242

22422243
hdr = (const struct cache_header *)mmap;

0 commit comments

Comments
 (0)