2009-11-12 95 views
0

我正在修改操作系統,我們在Linux Red Hat 8.0中工作 作爲一項任務的一部分,我必須更改sys close和sys open。對sys關閉的更改沒有發生事件,但是當我將引導sys更改突然關閉時,操作系統在引導過程中遇到錯誤,聲稱它無法掛載根fs並引發恐慌。據報道,在發生這種情況時,EIP處於系統關閉狀態。sys_close發生變化後發生內核崩潰

下面是我所做的更改(尋找「HW1補充」的評論):

asmlinkage long sys_open(const char * filename, int flags, int mode) 
{ 
    char * tmp; 
    int fd, error; 
    event_t* new_event; 

#if BITS_PER_LONG != 32 
    flags |= O_LARGEFILE; 
#endif 
    tmp = getname(filename); 
    fd = PTR_ERR(tmp); 
    if (!IS_ERR(tmp)) { 
     fd = get_unused_fd(); 
     if (fd >= 0) { 
      struct file *f = filp_open(tmp, flags, mode); 
      error = PTR_ERR(f); 
      if (IS_ERR(f)) 
       goto out_error; 
      fd_install(fd, f); 
     } 
     /* HW1 additions */ 
     if (current->record_flag==1){ 
      new_event=(event_t*)kmalloc(sizeof(event_t), GFP_KERNEL); 
      if (!new_event){ 
       new_event->type=Open; 
       strcpy(new_event->filename, tmp); 
       file_queue_add(*new_event, current->queue); 
      } 
     } 
     /* End HW1 additions */ 
out: 
     putname(tmp); 
    } 
    return fd; 

out_error: 
    put_unused_fd(fd); 
    fd = error; 
    goto out; 
} 

asmlinkage long sys_close(unsigned int fd) 
{ 
    struct file * filp; 
    struct files_struct *files = current->files; 
    event_t* new_event; 
    char* tmp = files->fd[fd]->f_dentry->d_name.name; 

    write_lock(&files->file_lock); 
    if (fd >= files->max_fds) 
     goto out_unlock; 
    filp = files->fd[fd]; 
    if (!filp) 
     goto out_unlock; 
    files->fd[fd] = NULL; 
    FD_CLR(fd, files->close_on_exec); 
    __put_unused_fd(files, fd); 
    write_unlock(&files->file_lock); 
    /* HW1 additions */  
    if(current->record_flag == 1){ 
     new_event=(event_t*)kmalloc(sizeof(event_t), GFP_KERNEL); 
     if (!new_event){ 
      new_event->type=Close; 
      strcpy(new_event->filename, tmp); 
      file_queue_add(*new_event, current->queue); 
     } 
    } 
    /* End HW1 additions */ 
    return filp_close(filp, files); 

out_unlock: 
    write_unlock(&files->file_lock); 
    return -EBADF; 
} 

在schedule.h定義的是task_struct在年底改爲包括: 在FS/open.c :

unsigned int record_flag; /* when zero: do not record. when one: record. */ 
file_queue* queue; 

和文件隊列以及事件噸都在一個單獨的文件中定義如下:

typedef enum {Open, Close} EventType; 

typedef struct event_t{ 
    EventType type; 
    char filename[256]; 
}event_t; 

typedef struct file_quque_t{ 
    event_t queue[101]; 
    int head, tail; 
}file_queue; 

文件隊列添加工作原理是這樣:

void file_queue_add(event_t event, file_queue* queue){ 
    queue->queue[queue->head]=event; 
    queue->head = (queue->head+1) % 101; 
    if (queue->head==queue->tail){ 
     queue->tail=(queue->tail+1) % 101; 
    } 
} 
+0

你可以把系統恐慌時得到的堆棧轉儲? – 2009-11-13 11:35:59

回答

2
if (!new_event) { 
    new_event->type = … 

這相當於if (new_event == NULL)。我想你的意思是if (new_event != NULL),內核人員通常寫爲if (new_event)

+0

你是對的,但這並不能解決問題。令我困惑的是,由於所有進程的創建都將record_flag設置爲0,所以此代碼部分甚至不應該有效果,但問題只發生在我引入這些更改之後。 – 2009-11-12 21:11:58

0

你可以請張貼錯誤的stackdump。我沒有看到queue_info結構被分配內存的地方。還有一件事是你不能確定,如果在內核中未分配內存,進程record_flag將始終爲零,因爲內核是一個長時間運行的程序,內存包含垃圾。

它也可以通過查看堆棧跟蹤來檢查函數中的確切位置。