Заранее прошу прощения за назойливость ;)
Вообщем имеется модуль, в нём создаётся устройство, которое далее создаётся
mknod /dev/netfw c 252 0
В модуле есть такой код:
/*******************************************************************************
********************************/
//................. for IO at dev ....................//
int step, n_par, n_arg, n, par_accept;
char **par, **arg;
char *to_table;
int id, it, num, act;
//..........................................................//
int netfw_add_rule(char *table_name, int id, int it, char **par, char **arg, int num)
{
int i;
for(i = 0; i < num; i++){
if(par[i]) kfree(par[i]);
if(arg[i]) kfree(arg[i]);
}
printk( KERN_DEBUG "NetFW: Rule was add successfull\n");
return 1;
}
//функция записи
ssize_t netfw_write (struct file *f, const char *ch, size_t size, loff_t *loff)
{
if(num > 0)if(n < num*2)
{
if(par_accept)
{
par[n_par] = kmalloc((sizeof(char) * strlen(ch)) + 1,GFP_ATOMIC);
if(!par[n_par]) return 0;
par[n_par] = strcpy(par[n_par],ch);
printk("par[%d] = %s, ch = %s\n",n_par,par[n_par],ch); //Тестовый вывод тут
par_accept = 0;
n_par++;
}
else
{
arg[n_arg] = kmalloc((sizeof(char) * strlen(ch)) + 1,GFP_ATOMIC);
if(!arg[n_arg]) return 0;
arg[n_arg] = strcpy(arg[n_arg],ch);
printk("arg[%d] = %s, ch = %s\n",n_arg,arg[n_arg],ch); //И тут тоже вывод
par_accept = 1;
n_arg++;
}
n++;
}
if(!strcmp(ch,"$"))
{
step = -1;
n = n_par = n_arg = 0;
if(act > 0)
{
switch(act)
{
case NETFW_ADD_RULE:
/*if(*/netfw_add_rule(to_table,0,it,par,arg,num)/*)*/;
break;
...
}
}
if(par) kfree(par);
if(arg) kfree(arg);
if(to_table) kfree(to_table);
to_table = 0;
num = 0;
}
step++;
switch(step)
{
//Action
case 1:
if(!strcmp(ch,"add"))
{
act = NETFW_ADD_RULE;
}
if(!strcmp(ch,"del"))
{
act = NETFW_DEL_RULE;
}
if(!strcmp(ch,"policy"))
{
act = NETFW_SET_POL;
}
if(!strcmp(ch,"show"))
{
act = NETFW_SHOW_RULE;
}
break;
//Table name
case 2:
to_table = kmalloc(sizeof(char[strlen(ch)]),GFP_ATOMIC);
if(!to_table) return 0;
to_table = strcpy(to_table,ch);
break;
//What to do ( aka "it" )
case 3:
if(!strcmp(ch,"accept"))
{
it = NETFW_ACCEPT;
}
if(!strcmp(ch,"drop"))
{
it = NETFW_DROP;
}
break;
//Num of elements
case 4:
num = netfw_char_to_int((char*)ch); //эта функция конвертит char* в int
//работает одназначно и правильно :)
par = kmalloc((sizeof(char *) * num),GFP_ATOMIC);
if(!par) return 0;
arg = kmalloc((sizeof(char *) * num),GFP_ATOMIC);
if(!arg) return 0;
par_accept = 1;
break;
}
return 0;
}
/*******************************************************************************
********************************/
Используется это из приложения-интерфейса.
/************************************** user-space-app.c **************************************************/
char *num;
int main(int argc, char *argv[])
{
int fd;
char *end = "$";
//this is dev for netfw control
fd = open("/dev/netfw", O_RDWR);
if(fd == -1){
printf("open failed\n");
return -1;
}
printf("Device netfw open\nTry to write\n");
//calc num of parametrs like: from, to, fport, tport
int ap = argc - 1 - 3;
printf("ap = %d\n",ap); //check it
int i;
//write control element like: add/del, pass/drop and name of table
printf("argc = %d\n",argc); //check it
if(!argv[1]){
printf("write 1$\n");
write(fd,end,sizeof(end));
return 0;
}
else write(fd, argv[1], sizeof(argv[1]));
if(!argv[2]){
printf("wrte 2$\n");
write(fd,end,sizeof(end));
return 0;
}
else write(fd, argv[2], sizeof(argv[2]));
if(!argv[3]){
printf("write 3$\n");
write(fd,end,sizeof(end));
return 0;
}
else write(fd, argv[3], sizeof(argv[3]));
if(ap > 0){
//write num of parametrs
int_to_char(ap/2); //эта функция конвертит int в char*
//так же работает одназначно и без ошибок
//устанавливает глобальную переменную char *num
write(fd, num, sizeof(num));
//write parametrs
for(i = argc - ap; i < argc; i++)
{
printf(argv[i]);
printf("\n");
write(fd, argv[i], sizeof(argv[i]));
}
}
//write symbol to finish transacton, in this case it's "$"
printf("write 4$\n");
write(fd,end,sizeof(end));
//close file
close(fd);
printf("Device netfw close\n");
return 0;
}
/*******************************************************************************
*********************************/
Вообщем запись работает по принципу конвеера и заканчивается с записью символа "$".
А суть проблеммы такая, при попытке в третий раз записать блок данных, в массивах
char **par и char **arg начинает появлятся мусор
(выглядит примерно так)
//первая запись
par[0] = from, ch = from
arg[0] = 127.0.0.1, ch = 127.0.0.1
NetFW: Rule was add successfull
//вторая запись
//Дальше идёт мусор
par[0] = , ch = from
arg[0] = -0.0.1, ch = 127.0.0.1
NetFW: Rule was add successfull
//третья запись
par[0] = J=, ch = from
arg[0] = .50.0.1, ch = 127.0.0.1
NetFW: Rule was add successfull
и при последующих действиях,
таких как выгрузка модуля или если попытаться что то cat'нуть /var/log/messages, а
иногда и просто так.. вообщем всё виснет. Как я понимаю проблемма в том что
где то не очищается память или что то похожее.
Может помочь опознать ошибку в функции записи ssize_t netfw_write () в модуле,
как полагаю это именно там.
Заранее спасибо!!!