@@ -806,6 +806,7 @@ static void bpftuner_rollback(struct bpftuner *tuner, bool log_only)
806
806
char newvals [PATH_MAX ] = { };
807
807
bool changes = false;
808
808
char s [PATH_MAX ];
809
+ void * val ;
809
810
810
811
if (t -> desc .type != BPFTUNABLE_SYSCTL )
811
812
continue ;
@@ -823,13 +824,20 @@ static void bpftuner_rollback(struct bpftuner *tuner, bool log_only)
823
824
/* nothing to rollback? */
824
825
if (!changes )
825
826
continue ;
826
- for (j = 0 ; j < t -> desc .num_values ; j ++ ) {
827
- snprintf (s , sizeof (s ), "%ld " ,
828
- t -> initial_values [j ]);
829
- strcat (oldvals , s );
830
- snprintf (s , sizeof (s ), "%ld " ,
831
- t -> current_values [j ]);
832
- strcat (newvals , s );
827
+ if (t -> desc .flags & BPFTUNABLE_STRING ) {
828
+ strncpy (oldvals , t -> initial_str , sizeof (oldvals ));
829
+ strncpy (newvals , t -> current_str , sizeof (newvals ));
830
+ val = t -> initial_str ;
831
+ } else {
832
+ for (j = 0 ; j < t -> desc .num_values ; j ++ ) {
833
+ snprintf (s , sizeof (s ), "%ld " ,
834
+ t -> initial_values [j ]);
835
+ strcat (oldvals , s );
836
+ snprintf (s , sizeof (s ), "%ld " ,
837
+ t -> current_values [j ]);
838
+ strcat (newvals , s );
839
+ }
840
+ val = t -> initial_values ;
833
841
}
834
842
if (log_only ) {
835
843
bpftune_log (BPFTUNE_LOG_LEVEL , "# To roll back changes to '%s', run the following as a privileged user in a terminal:\n" ,
@@ -840,7 +848,7 @@ static void bpftuner_rollback(struct bpftuner *tuner, bool log_only)
840
848
bpftuner_tunable_sysctl_write (tuner , i , k ,
841
849
0 ,
842
850
t -> desc .num_values ,
843
- t -> initial_values ,
851
+ val ,
844
852
"Rolling back sysctl values for '%s' from (%s) to original values (%s)...\n" ,
845
853
t -> desc .name ,
846
854
newvals , oldvals );
@@ -1001,9 +1009,11 @@ void bpftune_sysctl_name_to_path(const char *name, char *path, size_t path_sz)
1001
1009
path [i ] = '/' ;
1002
1010
}
1003
1011
1004
- int bpftune_sysctl_read (int netns_fd , const char * name , long * values )
1012
+ static int __bpftune_sysctl_read (int netns_fd , const char * name , void * val ,
1013
+ bool isstr )
1005
1014
{
1006
1015
int i , orig_netns_fd = 0 , num_values = 0 ;
1016
+ long * values = val ;
1007
1017
char path [PATH_MAX ];
1008
1018
int err = 0 ;
1009
1019
FILE * fp ;
@@ -1025,25 +1035,33 @@ int bpftune_sysctl_read(int netns_fd, const char *name, long *values)
1025
1035
path , netns_fd , strerror (- err ));
1026
1036
goto out ;
1027
1037
}
1028
- num_values = fscanf (fp , "%ld %ld %ld" ,
1029
- & values [0 ], & values [1 ], & values [2 ]);
1030
- if (num_values == 0 )
1031
- err = - ENOENT ;
1032
- else if (num_values < 0 )
1033
- err = - errno ;
1038
+ if (isstr ) {
1039
+ num_values = fscanf (fp , "%[^\n]" , (char * )val );
1040
+ if (num_values != 1 )
1041
+ err = - ENOENT ;
1042
+ else
1043
+ bpftune_log (LOG_DEBUG , "Read %s = %s\n" , name , (char * )val );
1044
+ } else {
1045
+ num_values = fscanf (fp , "%ld %ld %ld" ,
1046
+ & values [0 ], & values [1 ], & values [2 ]);
1047
+ if (num_values == 0 ) {
1048
+ err = - ENOENT ;
1049
+ } else if (num_values < 0 ) {
1050
+ err = - errno ;
1051
+ } else {
1052
+ for (i = 0 ; i < num_values ; i ++ ) {
1053
+ bpftune_log (LOG_DEBUG , "Read %s[%d] = %ld\n" ,
1054
+ name , i , values [i ]);
1055
+ }
1056
+ }
1057
+ }
1034
1058
fclose (fp );
1035
1059
1036
1060
if (err ) {
1037
1061
bpftune_log (LOG_ERR , "could not read from %s: %s\n" , path ,
1038
1062
strerror (- err ));
1039
1063
goto out ;
1040
1064
}
1041
-
1042
- for (i = 0 ; i < num_values ; i ++ ) {
1043
- bpftune_log (LOG_DEBUG , "Read %s[%d] = %ld\n" ,
1044
- name , i , values [i ]);
1045
- }
1046
-
1047
1065
out :
1048
1066
bpftune_netns_set (orig_netns_fd , NULL , true);
1049
1067
out_unset :
@@ -1053,11 +1071,24 @@ int bpftune_sysctl_read(int netns_fd, const char *name, long *values)
1053
1071
return err ? err : num_values ;
1054
1072
}
1055
1073
1056
- int bpftune_sysctl_write (int netns_fd , const char * name , __u8 num_values , long * values )
1074
+ int bpftune_sysctl_read (int netns_fd , const char * name , long * values )
1075
+ {
1076
+ return __bpftune_sysctl_read (netns_fd , name , values , false);
1077
+ }
1078
+
1079
+ int bpftune_sysctl_read_string (int netns_fd , const char * name , char * val )
1080
+ {
1081
+ return __bpftune_sysctl_read (netns_fd , name , val , true);
1082
+ }
1083
+
1084
+ static int __bpftune_sysctl_write (int netns_fd , const char * name , __u8 num_values ,
1085
+ void * val , bool isstr )
1057
1086
{
1058
1087
long old_values [BPFTUNE_MAX_VALUES ] = {};
1088
+ char old_value_str [PATH_MAX ] = {};
1059
1089
int i , err = 0 , orig_netns_fd = 0 ;
1060
1090
int old_num_values ;
1091
+ long * values = val ;
1061
1092
char path [PATH_MAX ];
1062
1093
FILE * fp ;
1063
1094
@@ -1074,18 +1105,27 @@ int bpftune_sysctl_write(int netns_fd, const char *name, __u8 num_values, long *
1074
1105
goto out_unset ;
1075
1106
1076
1107
/* If value is already set to val, do nothing. */
1077
- old_num_values = bpftune_sysctl_read (0 , name , old_values );
1108
+ if (isstr ) {
1109
+ old_num_values = bpftune_sysctl_read_string (0 , name , old_value_str );
1110
+ } else {
1111
+ old_num_values = bpftune_sysctl_read (0 , name , old_values );
1112
+ }
1078
1113
if (old_num_values < 0 ) {
1079
1114
err = old_num_values ;
1080
1115
goto out ;
1081
1116
}
1082
1117
if (num_values == old_num_values ) {
1083
- for (i = 0 ; i < num_values ; i ++ ) {
1084
- if (old_values [i ] != values [i ])
1085
- break ;
1118
+ if (isstr ) {
1119
+ if (strcmp (old_value_str , val ) == 0 )
1120
+ goto out ;
1121
+ } else {
1122
+ for (i = 0 ; i < num_values ; i ++ ) {
1123
+ if (old_values [i ] != values [i ])
1124
+ break ;
1125
+ }
1126
+ if (i == num_values )
1127
+ goto out ;
1086
1128
}
1087
- if (i == num_values )
1088
- goto out ;
1089
1129
}
1090
1130
fp = fopen (path , "w" );
1091
1131
if (!fp ) {
@@ -1095,14 +1135,18 @@ int bpftune_sysctl_write(int netns_fd, const char *name, __u8 num_values, long *
1095
1135
goto out ;
1096
1136
}
1097
1137
1098
- for (i = 0 ; i < num_values ; i ++ )
1099
- fprintf (fp , "%ld " , values [i ]);
1138
+ if (isstr ) {
1139
+ fprintf (fp , "%s" , (char * )val );
1140
+ bpftune_log (LOG_DEBUG , "Wrote %s = %s\n" , name , val );
1141
+ } else {
1142
+ for (i = 0 ; i < num_values ; i ++ ) {
1143
+ fprintf (fp , "%ld " , values [i ]);
1144
+ bpftune_log (LOG_DEBUG , "Wrote %s[%d] = %ld\n" ,
1145
+ name , i , values [i ]);
1146
+ }
1147
+ }
1100
1148
fclose (fp );
1101
1149
1102
- for (i = 0 ; i < num_values ; i ++ ) {
1103
- bpftune_log (LOG_DEBUG , "Wrote %s[%d] = %ld\n" ,
1104
- name , i , values [i ]);
1105
- }
1106
1150
out :
1107
1151
bpftune_netns_set (orig_netns_fd , NULL , true);
1108
1152
out_unset :
@@ -1112,6 +1156,17 @@ int bpftune_sysctl_write(int netns_fd, const char *name, __u8 num_values, long *
1112
1156
return err ;
1113
1157
}
1114
1158
1159
+ int bpftune_sysctl_write (int netns_fd , const char * name , __u8 num_values , long * values )
1160
+ {
1161
+ return __bpftune_sysctl_write (netns_fd , name , num_values , values , false);
1162
+ }
1163
+
1164
+ int bpftune_sysctl_write_string (int netns_fd , const char * name , char * val )
1165
+ {
1166
+ return __bpftune_sysctl_write (netns_fd , name , 1 , val , true);
1167
+ }
1168
+
1169
+
1115
1170
long long bpftune_ksym_addr (char type , const char * name )
1116
1171
{
1117
1172
long long ret = - ENOENT ;
@@ -1302,8 +1357,12 @@ int bpftuner_tunables_init(struct bpftuner *tuner, unsigned int num_descs,
1302
1357
1303
1358
if (descs [i ].type != BPFTUNABLE_SYSCTL )
1304
1359
continue ;
1305
- num_values = bpftune_sysctl_read (0 , descs [i ].name ,
1306
- tuner -> tunables [i ].current_values );
1360
+ if (descs [i ].flags & BPFTUNABLE_STRING )
1361
+ num_values = bpftune_sysctl_read_string (0 , descs [i ].name ,
1362
+ tuner -> tunables [i ].current_str );
1363
+ else
1364
+ num_values = bpftune_sysctl_read (0 , descs [i ].name ,
1365
+ tuner -> tunables [i ].current_values );
1307
1366
if (num_values < 0 ) {
1308
1367
if (descs [i ].flags & BPFTUNABLE_OPTIONAL ) {
1309
1368
bpftune_log (LOG_DEBUG , "error reading optional tunable '%s': %s\n" ,
@@ -1319,9 +1378,15 @@ int bpftuner_tunables_init(struct bpftuner *tuner, unsigned int num_descs,
1319
1378
descs [i ].num_values , num_values );
1320
1379
return - EINVAL ;
1321
1380
}
1322
- memcpy (tuner -> tunables [i ].initial_values ,
1323
- tuner -> tunables [i ].current_values ,
1324
- sizeof (tuner -> tunables [i ].initial_values ));
1381
+ if (descs [i ].flags & BPFTUNABLE_STRING ) {
1382
+ strncpy (tuner -> tunables [i ].initial_str ,
1383
+ tuner -> tunables [i ].current_str ,
1384
+ sizeof (tuner -> tunables [i ].initial_str ));
1385
+ } else {
1386
+ memcpy (tuner -> tunables [i ].initial_values ,
1387
+ tuner -> tunables [i ].current_values ,
1388
+ sizeof (tuner -> tunables [i ].initial_values ));
1389
+ }
1325
1390
}
1326
1391
1327
1392
return 0 ;
@@ -1387,13 +1452,18 @@ static void __bpftuner_scenario_log(struct bpftuner *tuner, unsigned int tunable
1387
1452
char s [PATH_MAX ];
1388
1453
__u8 i ;
1389
1454
1390
- for (i = 0 ; i < t -> desc .num_values ; i ++ ) {
1391
- snprintf (s , sizeof (s ), "%ld " ,
1392
- t -> initial_values [i ]);
1393
- strcat (oldvals , s );
1394
- snprintf (s , sizeof (s ), "%ld " ,
1395
- t -> current_values [i ]);
1396
- strcat (newvals , s );
1455
+ if (t -> desc .flags & BPFTUNABLE_STRING ) {
1456
+ strncpy (oldvals , t -> initial_str , sizeof (oldvals ));
1457
+ strncpy (newvals , t -> current_str , sizeof (newvals ));
1458
+ } else {
1459
+ for (i = 0 ; i < t -> desc .num_values ; i ++ ) {
1460
+ snprintf (s , sizeof (s ), "%ld " ,
1461
+ t -> initial_values [i ]);
1462
+ strcat (oldvals , s );
1463
+ snprintf (s , sizeof (s ), "%ld " ,
1464
+ t -> current_values [i ]);
1465
+ strcat (newvals , s );
1466
+ }
1397
1467
}
1398
1468
bpftune_log (BPFTUNE_LOG_LEVEL , "# sysctl '%s' changed from (%s) -> (%s)\n" ,
1399
1469
t -> desc .name , oldvals , newvals );
@@ -1415,7 +1485,7 @@ static void __bpftuner_scenario_log(struct bpftuner *tuner, unsigned int tunable
1415
1485
1416
1486
int bpftuner_tunable_sysctl_write (struct bpftuner * tuner , unsigned int tunable ,
1417
1487
unsigned int scenario , unsigned long netns_cookie ,
1418
- __u8 num_values , long * values ,
1488
+ __u8 num_values , void * values ,
1419
1489
const char * fmt , ...)
1420
1490
{
1421
1491
struct bpftunable * t = bpftuner_tunable (tuner , tunable );
@@ -1450,16 +1520,23 @@ int bpftuner_tunable_sysctl_write(struct bpftuner *tuner, unsigned int tunable,
1450
1520
}
1451
1521
global_ns = fd == 0 ;
1452
1522
1453
- ret = bpftune_sysctl_write (fd , t -> desc .name , num_values , values );
1523
+ if (t -> desc .flags & BPFTUNABLE_STRING )
1524
+ ret = bpftune_sysctl_write_string (fd , t -> desc .name , values );
1525
+ else
1526
+ ret = bpftune_sysctl_write (fd , t -> desc .name , num_values , values );
1454
1527
if (!ret ) {
1455
1528
__u8 i ;
1456
1529
1457
1530
bpftuner_scenario_log_fmt (tuner , tunable , scenario , fd , false, fmt );
1458
1531
1459
1532
/* only cache values for rollback for global ns */
1460
1533
if (global_ns ) {
1461
- for (i = 0 ; i < t -> desc .num_values ; i ++ )
1462
- t -> current_values [i ] = values [i ];
1534
+ if (t -> desc .flags & BPFTUNABLE_STRING ) {
1535
+ strncpy (t -> current_str , values , sizeof (t -> current_str ));
1536
+ } else {
1537
+ for (i = 0 ; i < t -> desc .num_values ; i ++ )
1538
+ t -> current_values [i ] = ((long * )values )[i ];
1539
+ }
1463
1540
}
1464
1541
} else if (ret < 0 ) {
1465
1542
/* If sysctl update failed, mark non-global netns as gone to
0 commit comments