1
1
/*
2
2
* Copyright © 2009 CNRS
3
- * Copyright © 2009-2015 Inria. All rights reserved.
3
+ * Copyright © 2009-2016 Inria. All rights reserved.
4
4
* Copyright © 2009-2013, 2015 Université Bordeaux
5
5
* Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved.
6
6
* Copyright © 2015 Intel, Inc. All rights reserved.
36
36
#include <pthread.h>
37
37
#include <sys/mman.h>
38
38
#include <sys/syscall.h>
39
+ #include <mntent.h>
39
40
#if defined HWLOC_HAVE_SET_MEMPOLICY || defined HWLOC_HAVE_MBIND
40
41
#define migratepages migrate_pages /* workaround broken migratepages prototype in numaif.h before libnuma 2.0.2 */
41
42
#include <numaif.h>
42
43
#endif
43
44
44
45
struct hwloc_linux_backend_data_s {
46
+ char * root_path ; /* NULL if unused */
45
47
int root_fd ; /* The file descriptor for the file system root, used when browsing, e.g., Linux' sysfs and procfs. */
46
48
int is_real_fsroot ; /* Boolean saying whether root_fd points to the real filesystem root of the system */
47
49
#ifdef HAVE_LIBUDEV_H
@@ -1652,96 +1654,40 @@ hwloc_parse_cpumap(const char *mappath, int fsroot_fd)
1652
1654
return set ;
1653
1655
}
1654
1656
1655
- static char *
1656
- hwloc_strdup_mntpath (const char * escapedpath , size_t length )
1657
- {
1658
- char * path = malloc (length + 1 );
1659
- const char * src = escapedpath , * tmp ;
1660
- char * dst = path ;
1661
-
1662
- while ((tmp = strchr (src , '\\' )) != NULL ) {
1663
- strncpy (dst , src , tmp - src );
1664
- dst += tmp - src ;
1665
- if (!strncmp (tmp + 1 , "040" , 3 ))
1666
- * dst = ' ' ;
1667
- else if (!strncmp (tmp + 1 , "011" , 3 ))
1668
- * dst = ' ' ;
1669
- else if (!strncmp (tmp + 1 , "012" , 3 ))
1670
- * dst = '\n' ;
1671
- else
1672
- * dst = '\\' ;
1673
- dst ++ ;
1674
- src = tmp + 4 ;
1675
- }
1676
-
1677
- strcpy (dst , src );
1678
-
1679
- return path ;
1680
- }
1681
-
1682
1657
static void
1683
- hwloc_find_linux_cpuset_mntpnt (char * * cgroup_mntpnt , char * * cpuset_mntpnt , int fsroot_fd )
1658
+ hwloc_find_linux_cpuset_mntpnt (char * * cgroup_mntpnt , char * * cpuset_mntpnt , const char * root_path )
1684
1659
{
1685
- #define PROC_MOUNT_LINE_LEN 512
1686
- char line [ PROC_MOUNT_LINE_LEN ] ;
1660
+ char * mount_path ;
1661
+ struct mntent * mntent ;
1687
1662
FILE * fd ;
1663
+ int err ;
1688
1664
1689
1665
* cgroup_mntpnt = NULL ;
1690
1666
* cpuset_mntpnt = NULL ;
1691
1667
1692
- /* ideally we should use setmntent, getmntent, hasmntopt and endmntent,
1693
- * but they do not support fsroot_fd.
1694
- */
1695
-
1696
- fd = hwloc_fopen ("/proc/mounts" , "r" , fsroot_fd );
1668
+ if (root_path ) {
1669
+ /* setmntent() doesn't support openat(), so use the root_path directly */
1670
+ err = asprintf (& mount_path , "%s/proc/mounts" , root_path );
1671
+ if (err < 0 )
1672
+ return ;
1673
+ fd = setmntent (mount_path , "r" );
1674
+ free (mount_path );
1675
+ } else {
1676
+ fd = setmntent ("/proc/mounts" , "r" );
1677
+ }
1697
1678
if (!fd )
1698
1679
return ;
1699
1680
1700
- while (fgets (line , sizeof (line ), fd )) {
1701
- char * path ;
1702
- char * type ;
1703
- char * tmp ;
1704
-
1705
- /* remove the ending " 0 0\n" that the kernel always adds */
1706
- tmp = line + strlen (line ) - 5 ;
1707
- if (tmp < line || strcmp (tmp , " 0 0\n" ))
1708
- fprintf (stderr , "Unexpected end of /proc/mounts line `%s'\n" , line );
1709
- else
1710
- * tmp = '\0' ;
1711
-
1712
- /* path is after first field and a space */
1713
- tmp = strchr (line , ' ' );
1714
- if (!tmp )
1715
- continue ;
1716
- path = tmp + 1 ;
1717
-
1718
- /* type is after path, which may not contain spaces since the kernel escaped them to \040
1719
- * (see the manpage of getmntent) */
1720
- tmp = strchr (path , ' ' );
1721
- if (!tmp )
1722
- continue ;
1723
- type = tmp + 1 ;
1724
- /* mark the end of path to ease upcoming strdup */
1725
- * tmp = '\0' ;
1726
-
1727
- if (!strncmp (type , "cpuset " , 7 )) {
1728
- /* found a cpuset mntpnt */
1729
- hwloc_debug ("Found cpuset mount point on %s\n" , path );
1730
- * cpuset_mntpnt = hwloc_strdup_mntpath (path , type - path );
1681
+ while ((mntent = getmntent (fd )) != NULL ) {
1682
+ if (!strcmp (mntent -> mnt_type , "cpuset" )) {
1683
+ hwloc_debug ("Found cpuset mount point on %s\n" , mntent -> mnt_dir );
1684
+ * cpuset_mntpnt = strdup (mntent -> mnt_dir );
1731
1685
break ;
1732
-
1733
- } else if (!strncmp (type , "cgroup " , 7 )) {
1686
+ } else if (!strcmp (mntent -> mnt_type , "cgroup" )) {
1734
1687
/* found a cgroup mntpnt */
1735
- char * opt , * opts ;
1688
+ char * opt , * opts = mntent -> mnt_opts ;
1736
1689
int cpuset_opt = 0 ;
1737
1690
int noprefix_opt = 0 ;
1738
-
1739
- /* find options */
1740
- tmp = strchr (type , ' ' );
1741
- if (!tmp )
1742
- continue ;
1743
- opts = tmp + 1 ;
1744
-
1745
1691
/* look at options */
1746
1692
while ((opt = strsep (& opts , "," )) != NULL ) {
1747
1693
if (!strcmp (opt , "cpuset" ))
@@ -1751,19 +1697,18 @@ hwloc_find_linux_cpuset_mntpnt(char **cgroup_mntpnt, char **cpuset_mntpnt, int f
1751
1697
}
1752
1698
if (!cpuset_opt )
1753
1699
continue ;
1754
-
1755
1700
if (noprefix_opt ) {
1756
- hwloc_debug ("Found cgroup emulating a cpuset mount point on %s\n" , path );
1757
- * cpuset_mntpnt = hwloc_strdup_mntpath ( path , type - path );
1701
+ hwloc_debug ("Found cgroup emulating a cpuset mount point on %s\n" , mntent -> mnt_dir );
1702
+ * cpuset_mntpnt = strdup ( mntent -> mnt_dir );
1758
1703
} else {
1759
- hwloc_debug ("Found cgroup/cpuset mount point on %s\n" , path );
1760
- * cgroup_mntpnt = hwloc_strdup_mntpath ( path , type - path );
1704
+ hwloc_debug ("Found cgroup/cpuset mount point on %s\n" , mntent -> mnt_dir );
1705
+ * cgroup_mntpnt = strdup ( mntent -> mnt_dir );
1761
1706
}
1762
1707
break ;
1763
1708
}
1764
1709
}
1765
1710
1766
- fclose (fd );
1711
+ endmntent (fd );
1767
1712
}
1768
1713
1769
1714
/*
@@ -4130,7 +4075,7 @@ hwloc_look_linuxfs(struct hwloc_backend *backend)
4130
4075
/**********************
4131
4076
* Gather the list of admin-disabled cpus and mems
4132
4077
*/
4133
- hwloc_find_linux_cpuset_mntpnt (& cgroup_mntpnt , & cpuset_mntpnt , data -> root_fd );
4078
+ hwloc_find_linux_cpuset_mntpnt (& cgroup_mntpnt , & cpuset_mntpnt , data -> root_path );
4134
4079
if (cgroup_mntpnt || cpuset_mntpnt ) {
4135
4080
cpuset_name = hwloc_read_linux_cpuset_name (data -> root_fd , topology -> pid );
4136
4081
if (cpuset_name ) {
@@ -5157,6 +5102,8 @@ hwloc_linux_backend_disable(struct hwloc_backend *backend)
5157
5102
{
5158
5103
struct hwloc_linux_backend_data_s * data = backend -> private_data ;
5159
5104
#ifdef HAVE_OPENAT
5105
+ if (data -> root_path )
5106
+ free (data -> root_path );
5160
5107
close (data -> root_fd );
5161
5108
#endif
5162
5109
#ifdef HAVE_LIBUDEV_H
@@ -5197,6 +5144,7 @@ hwloc_linux_component_instantiate(struct hwloc_disc_component *component,
5197
5144
/* default values */
5198
5145
data -> is_knl = 0 ;
5199
5146
data -> is_real_fsroot = 1 ;
5147
+ data -> root_path = NULL ;
5200
5148
if (!fsroot_path )
5201
5149
fsroot_path = "/" ;
5202
5150
@@ -5208,6 +5156,7 @@ hwloc_linux_component_instantiate(struct hwloc_disc_component *component,
5208
5156
if (strcmp (fsroot_path , "/" )) {
5209
5157
backend -> is_thissystem = 0 ;
5210
5158
data -> is_real_fsroot = 0 ;
5159
+ data -> root_path = strdup (fsroot_path );
5211
5160
}
5212
5161
5213
5162
/* Since this fd stays open after hwloc returns, mark it as
@@ -5246,6 +5195,10 @@ hwloc_linux_component_instantiate(struct hwloc_disc_component *component,
5246
5195
return backend ;
5247
5196
5248
5197
out_with_data :
5198
+ #ifdef HAVE_OPENAT
5199
+ if (data -> root_path )
5200
+ free (data -> root_path );
5201
+ #endif
5249
5202
free (data );
5250
5203
out_with_backend :
5251
5204
free (backend );
0 commit comments