@@ -102,7 +102,8 @@ __lxcfs_fuse_ops int proc_getattr(const char *path, struct stat *sb)
102
102
strcmp (path , "/proc/stat" ) == 0 ||
103
103
strcmp (path , "/proc/diskstats" ) == 0 ||
104
104
strcmp (path , "/proc/swaps" ) == 0 ||
105
- strcmp (path , "/proc/loadavg" ) == 0 ) {
105
+ strcmp (path , "/proc/loadavg" ) == 0 ||
106
+ strcmp (path , "/proc/slabinfo" ) == 0 ) {
106
107
sb -> st_size = 4096 ;
107
108
sb -> st_mode = S_IFREG | 00444 ;
108
109
sb -> st_nlink = 1 ;
@@ -124,7 +125,8 @@ __lxcfs_fuse_ops int proc_readdir(const char *path, void *buf,
124
125
DIR_FILLER (filler , buf , "uptime" , NULL , 0 ) != 0 ||
125
126
DIR_FILLER (filler , buf , "diskstats" , NULL , 0 ) != 0 ||
126
127
DIR_FILLER (filler , buf , "swaps" , NULL , 0 ) != 0 ||
127
- DIR_FILLER (filler , buf , "loadavg" , NULL , 0 ) != 0 )
128
+ DIR_FILLER (filler , buf , "loadavg" , NULL , 0 ) != 0 ||
129
+ DIR_FILLER (filler , buf , "slabinfo" , NULL , 0 ) != 0 )
128
130
return - EINVAL ;
129
131
130
132
return 0 ;
@@ -166,6 +168,8 @@ __lxcfs_fuse_ops int proc_open(const char *path, struct fuse_file_info *fi)
166
168
type = LXC_TYPE_PROC_SWAPS ;
167
169
else if (strcmp (path , "/proc/loadavg" ) == 0 )
168
170
type = LXC_TYPE_PROC_LOADAVG ;
171
+ else if (strcmp (path , "/proc/slabinfo" ) == 0 )
172
+ type = LXC_TYPE_PROC_SLABINFO ;
169
173
if (type == -1 )
170
174
return - ENOENT ;
171
175
@@ -1397,6 +1401,75 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
1397
1401
return total_len ;
1398
1402
}
1399
1403
1404
+ static int proc_slabinfo_read (char * buf , size_t size , off_t offset ,
1405
+ struct fuse_file_info * fi )
1406
+ {
1407
+ __do_free char * cgroup = NULL , * line = NULL ;
1408
+ __do_free void * fopen_cache = NULL ;
1409
+ __do_fclose FILE * f = NULL ;
1410
+ __do_close int fd = - EBADF ;
1411
+ struct fuse_context * fc = fuse_get_context ();
1412
+ struct file_info * d = INTTYPE_TO_PTR (fi -> fh );
1413
+ size_t linelen = 0 , total_len = 0 ;
1414
+ char * cache = d -> buf ;
1415
+ size_t cache_size = d -> buflen ;
1416
+ pid_t initpid ;
1417
+
1418
+ if (offset ) {
1419
+ int left ;
1420
+
1421
+ if (offset > d -> size )
1422
+ return - EINVAL ;
1423
+
1424
+ if (!d -> cached )
1425
+ return 0 ;
1426
+
1427
+ left = d -> size - offset ;
1428
+ total_len = left > size ? size : left ;
1429
+ memcpy (buf , cache + offset , total_len );
1430
+
1431
+ return total_len ;
1432
+ }
1433
+
1434
+ initpid = lookup_initpid_in_store (fc -> pid );
1435
+ if (initpid <= 1 || is_shared_pidns (initpid ))
1436
+ initpid = fc -> pid ;
1437
+
1438
+ cgroup = get_pid_cgroup (initpid , "memory" );
1439
+ if (!cgroup )
1440
+ return read_file_fuse ("/proc/slabinfo" , buf , size , d );
1441
+
1442
+ prune_init_slice (cgroup );
1443
+
1444
+ fd = cgroup_ops -> get_memory_slabinfo_fd (cgroup_ops , cgroup );
1445
+ if (fd < 0 )
1446
+ return read_file_fuse ("/proc/slabinfo" , buf , size , d );
1447
+
1448
+ f = fdopen_cached (fd , "re" , & fopen_cache );
1449
+ if (!f )
1450
+ return read_file_fuse ("/proc/slabinfo" , buf , size , d );
1451
+
1452
+ while (getline (& line , & linelen , f ) != -1 ) {
1453
+ ssize_t l = snprintf (cache , cache_size , "%s" , line );
1454
+ if (l < 0 )
1455
+ return log_error (0 , "Failed to write cache" );
1456
+ if (l >= cache_size )
1457
+ return log_error (0 , "Write to cache was truncated" );
1458
+
1459
+ cache += l ;
1460
+ cache_size -= l ;
1461
+ total_len += l ;
1462
+ }
1463
+
1464
+ d -> cached = 1 ;
1465
+ d -> size = total_len ;
1466
+ if (total_len > size )
1467
+ total_len = size ;
1468
+ memcpy (buf , d -> buf , total_len );
1469
+
1470
+ return total_len ;
1471
+ }
1472
+
1400
1473
__lxcfs_fuse_ops int proc_read (const char * path , char * buf , size_t size ,
1401
1474
off_t offset , struct fuse_file_info * fi )
1402
1475
{
@@ -1445,6 +1518,12 @@ __lxcfs_fuse_ops int proc_read(const char *path, char *buf, size_t size,
1445
1518
1446
1519
return read_file_fuse_with_offset (LXC_TYPE_PROC_LOADAVG_PATH ,
1447
1520
buf , size , offset , f );
1521
+ case LXC_TYPE_PROC_SLABINFO :
1522
+ if (liblxcfs_functional ())
1523
+ return proc_slabinfo_read (buf , size , offset , fi );
1524
+
1525
+ return read_file_fuse_with_offset (LXC_TYPE_PROC_SLABINFO_PATH ,
1526
+ buf , size , offset , f );
1448
1527
}
1449
1528
1450
1529
return - EINVAL ;
0 commit comments