Message ID | 152339792009.39156.13688341802570458197.stgit@djiang5-desk3.ch.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Apr 10, 2018 at 3:06 PM, Dave Jiang <dave.jiang@intel.com> wrote: > Providing an API call in libndctl to support accessing the region deep_flush > in sysfs. > > Signed-off-by: Dave Jiang <dave.jiang@intel.com> > --- > > v2: Cover case where deep_flush doesn't exist, i.e. memmap=nn!ss. (Dan) > > ndctl/lib/libndctl.c | 35 +++++++++++++++++++++++++++++++++++ > ndctl/lib/libndctl.sym | 1 + > ndctl/libndctl.h | 1 + > 3 files changed, 37 insertions(+) > > diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c > index 580a450e..c34f1e09 100644 > --- a/ndctl/lib/libndctl.c > +++ b/ndctl/lib/libndctl.c > @@ -181,6 +181,8 @@ struct ndctl_region { > FILE *badblocks; > struct badblock bb; > enum ndctl_persistence_domain persistence_domain; > + /* file descriptor for deep flush sysfs entry */ > + int flush_fd; > }; > > /** > @@ -511,6 +513,8 @@ static void free_region(struct ndctl_region *region) > free(region->region_path); > if (region->badblocks) > fclose(region->badblocks); > + if (region->flush_fd > 0) > + close(region->flush_fd); > free(region); > } > > @@ -1049,6 +1053,14 @@ NDCTL_EXPORT unsigned long long ndctl_region_get_resource(struct ndctl_region *r > return strtoull(buf, NULL, 0); > } > > +NDCTL_EXPORT int ndctl_region_deep_flush(struct ndctl_region *region) > +{ > + int rc = pwrite(region->flush_fd, "1", 1, 0); Make this write "1\n" to match standard sysfs manipulation done by "echo" that includes a newline. > + > + return (rc == -1) ? -errno : 0; > +} > + > + > NDCTL_EXPORT const char *ndctl_bus_get_cmd_name(struct ndctl_bus *bus, int cmd) > { > return nvdimm_bus_cmd_name(cmd); > @@ -1791,6 +1803,7 @@ static void *add_region(void *parent, int id, const char *region_base) > struct ndctl_bus *bus = parent; > struct ndctl_ctx *ctx = bus->ctx; > char *path = calloc(1, strlen(region_base) + 100); > + int perm; > > if (!path) > return NULL; > @@ -1866,6 +1879,28 @@ static void *add_region(void *parent, int id, const char *region_base) > else > region->persistence_domain = region_get_pd_type(buf); > > + sprintf(path, "%s/deep_flush", region_base); > + region->flush_fd = open(path, O_RDWR); Make this O_CLOEXEC, so we don't leak fds on exec.
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c index 580a450e..c34f1e09 100644 --- a/ndctl/lib/libndctl.c +++ b/ndctl/lib/libndctl.c @@ -181,6 +181,8 @@ struct ndctl_region { FILE *badblocks; struct badblock bb; enum ndctl_persistence_domain persistence_domain; + /* file descriptor for deep flush sysfs entry */ + int flush_fd; }; /** @@ -511,6 +513,8 @@ static void free_region(struct ndctl_region *region) free(region->region_path); if (region->badblocks) fclose(region->badblocks); + if (region->flush_fd > 0) + close(region->flush_fd); free(region); } @@ -1049,6 +1053,14 @@ NDCTL_EXPORT unsigned long long ndctl_region_get_resource(struct ndctl_region *r return strtoull(buf, NULL, 0); } +NDCTL_EXPORT int ndctl_region_deep_flush(struct ndctl_region *region) +{ + int rc = pwrite(region->flush_fd, "1", 1, 0); + + return (rc == -1) ? -errno : 0; +} + + NDCTL_EXPORT const char *ndctl_bus_get_cmd_name(struct ndctl_bus *bus, int cmd) { return nvdimm_bus_cmd_name(cmd); @@ -1791,6 +1803,7 @@ static void *add_region(void *parent, int id, const char *region_base) struct ndctl_bus *bus = parent; struct ndctl_ctx *ctx = bus->ctx; char *path = calloc(1, strlen(region_base) + 100); + int perm; if (!path) return NULL; @@ -1866,6 +1879,28 @@ static void *add_region(void *parent, int id, const char *region_base) else region->persistence_domain = region_get_pd_type(buf); + sprintf(path, "%s/deep_flush", region_base); + region->flush_fd = open(path, O_RDWR); + if (region->flush_fd == -1) { + /* for those that do not export deep_flush sysfs file */ + if (errno == ENOENT) + goto out; + else + goto err_read; + } + + if (pread(region->flush_fd, buf, 1, 0) == -1) { + close(region->flush_fd); + goto err_read; + } + + perm = strtol(buf, NULL, 0); + if (perm == 0) { + region->flush_fd = -1; + close(region->flush_fd); + } + + out: free(path); return region; diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym index 3209aefe..38cc3b9a 100644 --- a/ndctl/lib/libndctl.sym +++ b/ndctl/lib/libndctl.sym @@ -352,4 +352,5 @@ global: ndctl_dimm_fw_update_supported; ndctl_region_get_persistence_domain; ndctl_bus_get_persistence_domain; + ndctl_region_deep_flush; } LIBNDCTL_14; diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h index cf6a77fd..1a622ae5 100644 --- a/ndctl/libndctl.h +++ b/ndctl/libndctl.h @@ -365,6 +365,7 @@ int ndctl_region_enable(struct ndctl_region *region); int ndctl_region_disable_invalidate(struct ndctl_region *region); int ndctl_region_disable_preserve(struct ndctl_region *region); void ndctl_region_cleanup(struct ndctl_region *region); +int ndctl_region_deep_flush(struct ndctl_region *region); struct ndctl_interleave_set; struct ndctl_interleave_set *ndctl_region_get_interleave_set(
Providing an API call in libndctl to support accessing the region deep_flush in sysfs. Signed-off-by: Dave Jiang <dave.jiang@intel.com> --- v2: Cover case where deep_flush doesn't exist, i.e. memmap=nn!ss. (Dan) ndctl/lib/libndctl.c | 35 +++++++++++++++++++++++++++++++++++ ndctl/lib/libndctl.sym | 1 + ndctl/libndctl.h | 1 + 3 files changed, 37 insertions(+)