This is an archive of the discontinued Mercurial Phabricator instance.

cdatapack: do not keep fd open
ClosedPublic

Authored by quark on Oct 18 2017, 7:19 PM.
Tags
None
Subscribers

Details

Reviewers
singhsrb
Group Reviewers
Restricted Project
Commits
rFBHGX6a9de6c27e3a: cdatapack: do not keep fd open
Summary

Once mmap succeeded, it's no longer necessary to keep the underlying fd
open. Therefore just close them as an attempt to reduce file descriptors
opened by the process.

Thanks for spectral from Google for pointing out that fd could be closed.

Test Plan
make clean local
rt test-cstore.t test-*pack*.t

Diff Detail

Repository
rFBHGX Facebook Mercurial Extensions
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

quark created this revision.Oct 18 2017, 7:19 PM
Herald added a reviewer: Restricted Project. · View Herald TranscriptOct 18 2017, 7:19 PM
durham added a subscriber: durham.Oct 18 2017, 7:22 PM

If the FD are closed, does the mmap still work if the file is deleted? Does that count against the open file limit?

quark edited the summary of this revision. (Show Details)Oct 18 2017, 7:22 PM
quark added a comment.EditedOct 18 2017, 7:26 PM
In D1185#19960, @durham wrote:

If the FD are closed, does the mmap still work if the file is deleted?

Yes. I think the only problematic case is truncating the file, which also breaks the old code.

Does that count against the open file limit?

I think so. Let me do an experiment.

quark added a comment.Oct 18 2017, 7:43 PM

I tried the following and it works without hitting fd limit.

#include <string>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

using namespace std;

char *dommap(const char *path) {
  int fd = open(path, O_RDONLY);
  char *p = (char *)mmap(NULL, 4096, PROT_READ, MAP_SHARED, fd, 0);
  close(fd);
  return p;
}

int main(int argc, char const *argv[]) {
  for (int i = 0; i < 40960; ++i) {
    printf("%d\n", i);
    auto dest = string("/tmp/true-") + to_string(i);
    system((string("cp /bin/true ") + dest).c_str());
    char *p = dommap(dest.c_str());
    if (strncmp(p + 1, "ELF", 3) != 0) {
      printf("p is not 'ELF' !\n");
      abort();
    }
  }
  return 0;
}
singhsrb accepted this revision.Oct 18 2017, 7:50 PM
singhsrb added a subscriber: singhsrb.

Cool!

This revision is now accepted and ready to land.Oct 18 2017, 7:50 PM
This revision was automatically updated to reflect the committed changes.