/***************************************************************************** 函 数 名 : acl_rfc_process 功能描述 : 生成RFC表 输入参数 : 无 输出参数 : cnt ---- 规则数 返 回 值 : ERROR_SUCCESS ---- 成功 ERR_ACL_RFC_ERR ---- 失败 ----------------------------------------------------------------------------- 最近一次修改记录: 修改作者 : Fuzhiqing 修改目的 : 新增函数 修改日期 : 2011年05月18日 *****************************************************************************/ s32 acl_rfc_process(void) { if (ERROR_SUCCESS != acl_rfc_process_phase0()) { DEBUG_F ("Error.\n"); return ERR_ACL_RFC_ERR; } if (ERROR_SUCCESS != acl_rfc_process_phase1()) { DEBUG_F ("Error.\n"); return ERR_ACL_RFC_ERR; } if (ERROR_SUCCESS != acl_rfc_process_phase2()) { DEBUG_F ("Error.\n"); return ERR_ACL_RFC_ERR; } if (ERROR_SUCCESS != acl_rfc_process_phase3()) { DEBUG_F ("Error.\n"); return ERR_ACL_RFC_ERR; } return ERROR_SUCCESS; }
static int read_disk_block(struct boot_file_t *file, u64 block, int start, int length, void *buf) { u64 pos = block * 512; pos += partition_offset + start; DEBUG_F("Reading %d bytes, starting at block %Lu, disk offset %Lu\n", length, block, pos); if (!prom_seek(file->of_device, pos)) { DEBUG_F("prom_seek failed\n"); return 0; } return prom_read(file->of_device, buf, length); }
/***************************************************************************** 函 数 名 : ws__delMonitorLink 功能描述 : 删除一条smartlink信息 输入参数 : uplinkPort ---- 上行端口字符串 输出参数 : 返 回 值 : WS_OK ---- 执行成功 else ---- 执行失败 ----------------------------------------------------------------------------- 最近一次修改记录: 修改作者: wuyang 修改目的: 生成新函数 修改日期: 2011年09月19日 *****************************************************************************/ int ws__delMonitorLink(WS_ENV* soap, xsd__string uplinkPort, xsd__int* ret) { u32 sys_error_code; u32 ul_str_len; s32 i; s32 ul_count = 0; s8* solo_str; s8* saveptr; s32* port_list; sys_error_code = smart_link_dba_del_monitor_link(uplinkPort); DEBUG_F("db del, ret:%d.\n",sys_error_code); if (ERROR_SUCCESS != sys_error_code) { return ws_send_soap_error(soap, smart_link_error_str(sys_error_code)); } ul_str_len = strlen(uplinkPort); for (solo_str = strtok_r(uplinkPort, ",", &saveptr); NULL != solo_str; solo_str = strtok_r(NULL, ",", &saveptr)) { ul_count++; } port_list = (s32*)ws_malloc(soap, sizeof(s32)*(ul_count)); if (NULL == port_list) { return ws_send_soap_error(soap, smart_link_error_str(ERR_SMART_LINK_FAIL_MALLOC)); } for (i = 0; i < ul_str_len; i++) { if (uplinkPort[i] == '\0') { uplinkPort[i] = ','; } } for (solo_str = strtok_r(uplinkPort, ",", &saveptr), i = 0; NULL != solo_str; solo_str = strtok_r(NULL, ",", &saveptr), i++) { port_list[i] = atoi(solo_str); } sys_error_code = smart_link_del_monitor_link(port_list, ul_count); DEBUG_F("kernel del, ret:%d.\n",sys_error_code); if (ERROR_SUCCESS != sys_error_code) { return ws_send_soap_error(soap, smart_link_error_str(sys_error_code)); } return WS_OK; }
static int read_disk_block( struct boot_file_t *file, __u32 block, __u32 start, __u32 length, void *buf ) { __u16 fs_blocksize = INFO->blocksize == 0 ? REISERFS_OLD_BLOCKSIZE : INFO->blocksize; unsigned long long pos = (unsigned long long)block * (unsigned long long)fs_blocksize; pos += (unsigned long long)INFO->partition_offset + (unsigned long long)start; DEBUG_F( "Reading %u bytes, starting at block %u, disk offset %Lu\n", length, block, pos ); if (!prom_lseek( file->of_device, pos )) { DEBUG_F("prom_lseek failed\n"); return 0; } return prom_read( file->of_device, buf, length ); }
/***************************************************************************** 函 数 名 : acl_rfc_handle 功能描述 : 生成RFC表 输入参数 : num ---- 表示第几套表 输出参数 : cnt ---- 规则数 返 回 值 : ERROR_SUCCESS ---- 成功 ERR_ACL_RFC_STEP_OK ---- 本套执行成功 ERR_ACL_RFC_ERR ---- 失败 ----------------------------------------------------------------------------- 最近一次修改记录: 修改作者 : Fuzhiqing 修改目的 : 新增函数 修改日期 : 2011年05月17日 *****************************************************************************/ s32 acl_rfc_handle(void) { s32 i; s32 ret; pid_t pid; pid = fork(); if (-1 == pid) { return ERR_ACL_RFC_ERR; } else if (pid > 0) { return ERROR_SUCCESS; } /* 子进程继续进行 */ /* 内核准备规则 */ ret = acl_rfc_syscall_notify_kernel_prepare_rule(); if (ERROR_SUCCESS != ret) { DEBUG_F ("ret: %d.\n", ret); return ret; } /* 10K条规则拆成5套,每套2K,各套独立生成查找表并下发 */ for (i = 0; i < MAX_ACL_GROUP_CNT; i++) { ret = _rfc_acl_handle(i); DEBUG_F ("ret %d, i: %d.\n", ret, i); if (ERROR_SUCCESS == ret || ERR_ACL_RFC_NO_RULE == ret) { return ERROR_SUCCESS; } else if (ERR_ACL_RFC_STEP_OK == ret) { continue; } else { return ERR_ACL_RFC_ERR; } } return ERROR_SUCCESS; }
static int xfs_close(struct boot_file_t *file) { if (file->of_device) { prom_close(file->of_device); file->of_device = 0; DEBUG_F("xfs_close called\n"); } return FILE_ERR_OK; }
static int xfs_open(struct boot_file_t *file, const char *dev_name, struct partition_t *part, const char *file_name) { char buffer[1024]; DEBUG_ENTER; DEBUG_OPEN; DEBUG_F("Determining offset for partition %d\n", part->part_number); partition_offset = ((u64) part->part_start) * part->blocksize; DEBUG_F("%Lu = %lu * %hu\n", partition_offset, part->part_start, part->blocksize); sprintf(buffer, "%s:0", dev_name); /* 0 is full disk in OF */ DEBUG_F("Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n", buffer, file_name, partition_offset); file->of_device = prom_open(buffer); if (file->of_device == PROM_INVALID_HANDLE || file->of_device == NULL) { DEBUG_F("Can't open device %p\n", file->of_device); DEBUG_LEAVE(FILE_ERR_BADDEV); return FILE_ERR_BADDEV; } DEBUG_F("%p was successfully opened\n", file->of_device); xfs_file = file; if (xfs_mount() != 1) { DEBUG_F("Couldn't open XFS @ %s/%Lu\n", buffer, partition_offset); prom_close(file->of_device); DEBUG_LEAVE(FILE_ERR_BAD_FSYS); DEBUG_SLEEP; return FILE_ERR_BAD_FSYS; } DEBUG_F("Attempting to open %s\n", file_name); strcpy(buffer, file_name); /* xfs_dir modifies argument */ if (!xfs_dir(buffer)) { DEBUG_F("xfs_dir() failed. errnum = %d\n", errnum); prom_close(file->of_device); DEBUG_LEAVE_F(errnum); DEBUG_SLEEP; return errnum; } DEBUG_F("Successfully opened %s\n", file_name); DEBUG_LEAVE(FILE_ERR_OK); return FILE_ERR_OK; }
/* Read in the node at the current path and depth into the node cache. * You must set INFO->blocks[depth] before. */ static char * read_tree_node( __u32 blockNr, __u16 depth ) { char *cache = CACHE(depth); int num_cached = INFO->cached_slots; errnum = 0; if ( depth < num_cached ) { /* This is the cached part of the path. Check if same block is needed. */ if ( blockNr == INFO->blocks[depth] ) return cache; } else cache = CACHE(num_cached); DEBUG_F( " next read_in: block=%u (depth=%u)\n", blockNr, depth ); if ( !block_read( blockNr, 0, INFO->blocksize, cache ) ) { DEBUG_F( "block_read failed\n" ); return 0; } DEBUG_F( "FOUND: blk_level=%u, blk_nr_item=%u, blk_free_space=%u\n", blkh_level(BLOCKHEAD(cache)), blkh_nr_item(BLOCKHEAD(cache)), le16_to_cpu(BLOCKHEAD(cache)->blk_free_space) ); /* Make sure it has the right node level */ if ( blkh_level(BLOCKHEAD(cache)) != depth ) { DEBUG_F( "depth = %u != %u\n", blkh_level(BLOCKHEAD(cache)), depth ); DEBUG_LEAVE(FILE_ERR_BAD_FSYS); errnum = FILE_ERR_BAD_FSYS; return 0; } INFO->blocks[depth] = blockNr; return cache; }
/***************************************************************************** 函 数 名 : rfc_printf_map_u 功能描述 : 打印位图 输入参数 : 无 输出参数 : cnt ---- 规则数 返 回 值 : ERROR_SUCCESS ---- 成功 ERR_ACL_RFC_ERR ---- 失败 ----------------------------------------------------------------------------- 最近一次修改记录: 修改作者 : Fuzhiqing 修改目的 : 新增函数 修改日期 : 2011年05月20日 *****************************************************************************/ static inline void rfc_printf_map_u (u32 *map) { s32 j, k; for(j=0; j<RFC_ACL_MAP_SIZE; j++) { if (map[j]) { for(k = 0; k < 32; k++ ) { if (map[j] & (1 << k)) { DEBUG_F ("%8d", j*32 + k); } } } } DEBUG_F ("\n"); }
/***************************************************************************** 函 数 名 : acl_rfc_node_in_range 功能描述 : 检查指定规则是否匹配指定chunk的指定cell 输入参数 : 无 输出参数 : cnt ---- 规则数 返 回 值 : ERROR_SUCCESS ---- 成功 ERR_ACL_RFC_ERR ---- 失败 ----------------------------------------------------------------------------- 最近一次修改记录: 修改作者 : Fuzhiqing 修改目的 : 新增函数 修改日期 : 2011年05月18日 *****************************************************************************/ static s32 acl_rfc_node_in_range (s32 chunk_id, s32 cell, s32 rule_index) { struct acl_rfc_rule* rule = &(g_acl_rfc_rule_u.rule_arr[rule_index]); switch(chunk_id) { case RFC_ACL_SIP_H: return ((cell & rule->sip_high_mask) == (rule->sip_high & rule->sip_high_mask)); case RFC_ACL_SIP_L: return ((cell & rule->sip_low_mask) == (rule->sip_low & rule->sip_low_mask)); case RFC_ACL_DIP_H: return ((cell & rule->dip_high_mask) == (rule->dip_high & rule->dip_high_mask)); case RFC_ACL_DIP_L: return ((cell & rule->dip_low_mask) == (rule->dip_low & rule->dip_low_mask)); case RFC_ACL_SPORT: return ((cell >= rule->sport_min) && (cell <= rule->sport_max)); case RFC_ACL_DPORT: return ((cell >= rule->dport_min) && (cell <= rule->dport_max)); case RFC_ACL_PROTO: return ((cell >= rule->proto_min) && (cell <= rule->proto_max)); case RFC_ACL_INPORT: if (PORT_ID_ALL == rule->in_port) { return 1; } else { return cell == rule->in_port; } default: DEBUG_F ("ERROR chunk_id: %d.\n", chunk_id); return 0; } return 0; }
/***************************************************************************** 函 数 名 : acl_rfc_flush_data 功能描述 : 向内核刷RFC表项 输入参数 : 无 输出参数 : cnt ---- 规则数 返 回 值 : ERROR_SUCCESS ---- 成功 ERR_ACL_RFC_ERR ---- 失败 ----------------------------------------------------------------------------- 最近一次修改记录: 修改作者 : Fuzhiqing 修改目的 : 新增函数 修改日期 : 2011年05月18日 *****************************************************************************/ s32 acl_rfc_flush_data(s32 num) { s32 chunk_id; s32 offset; s32 data_size; struct acl_rfc_flush_data_s* data; data = (struct acl_rfc_flush_data_s*)malloc(sizeof(struct acl_rfc_flush_data_s)); RFC_ASSERT_NOT_NULL_U (data); for (chunk_id = 0; chunk_id < RFC_ACL_PHASE0_CHUNK_CNT; chunk_id++) { data_size = ACL_RFC_CHUNK_SIZE; offset = 0; while(1) { memset (data, 0, sizeof(struct acl_rfc_flush_data_s)); data->num = num; /* 第几套表 */ data->type = RFC_ACL_PHASE0; data->p_id = chunk_id; /* 第几个chunk */ data->size = data_size-offset > ACL_RFC_MAX_FLUSH_DATA?ACL_RFC_MAX_FLUSH_DATA:data_size-offset; data->offset = offset; memcpy(data->data, (void*)g_acl_rfc_result_u.rfc_phase0[chunk_id] + offset, data->size); //DEBUG_F("data_size: %d, offset: %d, size: %d, chunk: %d.\n", data_size, offset, data->size, chunk_id); acl_rfc_syscall_flush_data_to_kernel(data); offset += data->size; /* 数据已全部下刷 */ if (offset == data_size) { break; } } } DEBUG_F("phase 0 over.\n"); for (chunk_id = 0; chunk_id < RFC_ACL_PHASE1_CHUNK_CNT; chunk_id++) { data_size = acl_rfc_u_size.p1_row[chunk_id] * acl_rfc_u_size.p1_line[chunk_id] * sizeof(u16); offset = 0; while(1) { memset (data, 0, sizeof(struct acl_rfc_flush_data_s)); data->num = num; data->type = RFC_ACL_PHASE1; data->p_id = chunk_id; data->size = data_size-offset > ACL_RFC_MAX_FLUSH_DATA?ACL_RFC_MAX_FLUSH_DATA:data_size-offset; data->offset = offset; memcpy(data->data, (void*)g_acl_rfc_result_u.rfc_phase1[chunk_id] + offset, data->size); //DEBUG_F("data_size: %d, offset: %d, size: %d, chunk: %d.\n", data_size, offset, data->size, chunk_id); acl_rfc_syscall_flush_data_to_kernel(data); offset += data->size; /* 数据已全部下刷 */ if (offset == data_size) { break; } } } DEBUG_F("phase 1 over.\n"); for (chunk_id = 0; chunk_id < RFC_ACL_PHASE2_CHUNK_CNT; chunk_id++) { data_size = acl_rfc_u_size.p2_row[chunk_id] * acl_rfc_u_size.p2_line[chunk_id] * sizeof(u16); offset = 0; while (1) { memset (data, 0, sizeof(struct acl_rfc_flush_data_s)); data->num = num; data->type = RFC_ACL_PHASE2; data->p_id = chunk_id; data->size = data_size-offset > ACL_RFC_MAX_FLUSH_DATA?ACL_RFC_MAX_FLUSH_DATA:data_size-offset; data->offset = offset; memcpy(data->data, (void*)g_acl_rfc_result_u.rfc_phase2[chunk_id] + offset, data->size); //DEBUG_F("data_size: %d, offset: %d, size: %d, chunk: %d.\n", data_size, offset, data->size, chunk_id); acl_rfc_syscall_flush_data_to_kernel(data); offset += data->size; /* 数据已全部下刷 */ if (offset == data_size) { break; } } } DEBUG_F("phase 2 over.\n"); for (chunk_id = 0; chunk_id < RFC_ACL_PHASE3_CHUNK_CNT; chunk_id++) { data_size = acl_rfc_u_size.p3_row[chunk_id] * acl_rfc_u_size.p3_line[chunk_id] * sizeof(unsigned long); offset = 0; while (1) { memset (data, 0, sizeof(struct acl_rfc_flush_data_s)); data->num = num; data->type = RFC_ACL_PHASE3; data->p_id = chunk_id; data->size = data_size-offset > ACL_RFC_MAX_FLUSH_DATA?ACL_RFC_MAX_FLUSH_DATA:data_size-offset; data->offset = offset; memcpy(data->data, (void*)g_acl_rfc_result_u.rfc_phase3[chunk_id] + offset, data->size); //DEBUG_F("data_size: %d, offset: %d, size: %d, chunk: %d.\n", data_size, offset, data->size, chunk_id); acl_rfc_syscall_flush_data_to_kernel(data); offset += data->size; /* 数据已全部下刷 */ if (offset == data_size) { break; } } } DEBUG_F("phase 3 over.\n"); acl_rfc_free(data); return ERROR_SUCCESS; }
/* Read a block from ReiserFS file system, taking the journal into * account. If the block nr is in the journal, the block from the * journal taken. */ static int block_read( __u32 blockNr, __u32 start, __u32 len, char *buffer ) { __u32 transactions = INFO->journal_transactions; __u32 desc_block = INFO->journal_first_desc; __u32 journal_mask = INFO->journal_block_count - 1; __u32 translatedNr = blockNr; __u32 *journal_table = JOURNAL_START; // DEBUG_F( "block_read( %u, %u, %u, ..)\n", blockNr, start, len ); while ( transactions-- > 0 ) { int i = 0; int j_len; if ( *journal_table != 0xffffffff ) { /* Search for the blockNr in cached journal */ j_len = le32_to_cpu(*journal_table++); while ( i++ < j_len ) { if ( le32_to_cpu(*journal_table++) == blockNr ) { journal_table += j_len - i; goto found; } } } else { /* This is the end of cached journal marker. The remaining * transactions are still on disk. */ struct reiserfs_journal_desc desc; struct reiserfs_journal_commit commit; if ( !journal_read( desc_block, sizeof(desc), (char *) &desc ) ) return 0; j_len = le32_to_cpu(desc.j_len); while ( i < j_len && i < JOURNAL_TRANS_HALF ) if ( le32_to_cpu(desc.j_realblock[i++]) == blockNr ) goto found; if ( j_len >= JOURNAL_TRANS_HALF ) { int commit_block = ( desc_block + 1 + j_len ) & journal_mask; if ( !journal_read( commit_block, sizeof(commit), (char *) &commit ) ) return 0; while ( i < j_len ) if ( le32_to_cpu(commit.j_realblock[i++ - JOURNAL_TRANS_HALF]) == blockNr ) goto found; } } goto not_found; found: translatedNr = INFO->journal_block + ( ( desc_block + i ) & journal_mask ); DEBUG_F( "block_read: block %u is mapped to journal block %u.\n", blockNr, translatedNr - INFO->journal_block ); /* We must continue the search, as this block may be overwritten in * later transactions. */ not_found: desc_block = (desc_block + 2 + j_len) & journal_mask; } return read_disk_block( INFO->file, translatedNr, start, len, buffer ); }
/***************************************************************************** 函 数 名 : acl_rfc_process_phase3 功能描述 : 处理phase3的表。即最终的表,此表中不存eqid,而存规则地址(控制面处理成u32整数)。 输入参数 : 无 输出参数 : 无 返 回 值 : ERROR_SUCCESS ---- 成功 ERR_ACL_RFC_ERR ---- 失败 ----------------------------------------------------------------------------- 最近一次修改记录: 修改作者 : Fuzhiqing 修改目的 : 新增函数 修改日期 : 2011年05月18日 *****************************************************************************/ s32 acl_rfc_process_phase3(void) { s32 chunk_id; struct acl_rule_map_head *p1, *p2; s32 i, j, k, l; u32 chunk_size; u32 intersected_bmp[RFC_ACL_MAP_SIZE]; s32 rule_index = -1; struct acl_eqid_table *a, *b; for (chunk_id = 0; chunk_id < RFC_ACL_PHASE3_CHUNK_CNT; chunk_id++) { DEBUG_F ("proc 3 %d start\n", chunk_id); acl_rfc_get_phase3_source(chunk_id, &p1, &p2); /* 为维度赋值, 匹配时使用*/ g_acl_rfc_result_u.rfc_phase3_dim[chunk_id] = p2->max_eqid + 1; /* 保存全局大小, 下发内核使用*/ acl_rfc_u_size.p3_row[chunk_id] = p1->max_eqid + 1; acl_rfc_u_size.p3_line[chunk_id] = p2->max_eqid + 1; //DEBUG_F("acl_rfc_u_size[%d] p3_row: %d, p3_line: %d.\n", chunk_id, acl_rfc_u_size.p3_row[chunk_id], acl_rfc_u_size.p3_line[chunk_id]); chunk_size = sizeof(u32) * acl_rfc_u_size.p3_row[chunk_id] * acl_rfc_u_size.p3_line[chunk_id]; g_acl_rfc_result_u.rfc_phase3[chunk_id] = (u32*)malloc(chunk_size); RFC_ASSERT_NOT_NULL_U(g_acl_rfc_result_u.rfc_phase3[chunk_id]); memset (g_acl_rfc_result_u.rfc_phase3[chunk_id], 0, chunk_size); for (a = p1->head, i = 1; NULL != a; a = a->next, i++) { for (b = p2->head, j = 1; NULL != b; b = b->next, j++) { for (k = 0; k < RFC_ACL_MAP_SIZE; k++) { intersected_bmp[k] = (a->cbm[k] & b->cbm[k]); if (intersected_bmp[k]) { /* 找到匹配的规则,将其对应的规则的地址置于查找表中 */ for(l = 0; l < 32; l++) { if (intersected_bmp[k] & (1 << l)) { rule_index = k*32 + l; break; } } #ifdef acl_rfc_debug_flag_u DEBUG_F ("chunk_id %d \n", chunk_id); DEBUG_F ("[%d , %d]==>", i, j); //rfc_printf_map_u (intersected_bmp); DEBUG_F ("rule_index %d\n", rule_index); if (rule_index < MAX_ACL_RULE_PER_STEP) { DEBUG_F ("node %x\n", g_acl_rfc_rule_u.rule_arr[rule_index].node_address); } #endif /* 为查找表赋值 */ g_acl_rfc_result_u.rfc_phase3[chunk_id][i * g_acl_rfc_result_u.rfc_phase3_dim[chunk_id] + j] = g_acl_rfc_rule_u.rule_arr[rule_index].node_address; break; } } } } } return ERROR_SUCCESS; }
/***************************************************************************** 函 数 名 : acl_rfc_process_phase2 功能描述 : 处理phase2的表 输入参数 : 无 输出参数 : 无 返 回 值 : ERROR_SUCCESS ---- 成功 ERR_ACL_RFC_ERR ---- 失败 ----------------------------------------------------------------------------- 最近一次修改记录: 修改作者 : Fuzhiqing 修改目的 : 新增函数 修改日期 : 2011年05月18日 *****************************************************************************/ s32 acl_rfc_process_phase2(void) { s32 chunk_id; struct acl_rule_map_head *p1 = NULL, *p2 = NULL; s32 i, j, k; s32 temp_eqid; s32 rule_on_cell; u32 chunk_size; u32 intersected_bmp[RFC_ACL_MAP_SIZE]; struct acl_eqid_table *a, *b; struct acl_eqid_table *rule_map; for (chunk_id = 0; chunk_id < RFC_ACL_PHASE2_CHUNK_CNT; chunk_id++) { DEBUG_F ("proc 2 %d start.\n", chunk_id); acl_rfc_get_phase2_source (chunk_id, &p1, &p2); /* 为维度赋值, 匹配时使用*/ g_acl_rfc_result_u.rfc_phase2_dim[chunk_id] = p2->max_eqid + 1; /* 保存全局大小, 下发内核使用*/ acl_rfc_u_size.p2_row[chunk_id] = p1->max_eqid + 1; acl_rfc_u_size.p2_line[chunk_id] = p2->max_eqid + 1; chunk_size = sizeof(u16) * acl_rfc_u_size.p2_row[chunk_id] * acl_rfc_u_size.p2_line[chunk_id]; g_acl_rfc_result_u.rfc_phase2[chunk_id] = (u16*)malloc(chunk_size); RFC_ASSERT_NOT_NULL_U(g_acl_rfc_result_u.rfc_phase2[chunk_id]); //memset(g_acl_rfc_result_u.rfc_phase2[chunk_id], 0, chunk_size); for (a = p1->head, i = 1; NULL != a; a = a->next, i++) { for (b = p2->head, j = 1; NULL != b; b = b->next, j++) { for (rule_on_cell = 0, k = 0; k < RFC_ACL_MAP_SIZE; k++) { intersected_bmp[k] = (a->cbm[k] & b->cbm[k]); if (0 == rule_on_cell && intersected_bmp[k]) { rule_on_cell = 1; } } if (rule_on_cell) { /* 查找此位图是否已存在于eqid表中 */ for (temp_eqid = -1, rule_map = acl_phase2[chunk_id].head; NULL != rule_map; rule_map = rule_map->next) { if (0 == memcmp(rule_map->cbm, intersected_bmp, sizeof(intersected_bmp))) { temp_eqid = rule_map->eqID; break; } } /* 如果新分配了eqid, 添加到链表中*/ if (NULL == rule_map) { temp_eqid = acl_rfc_add_bmp(&acl_phase2[chunk_id],intersected_bmp); } #ifdef acl_rfc_debug_flag_u DEBUG_F ("chunk_id %d \n", chunk_id); DEBUG_F ("eqid %d [%d , %d]==>", temp_eqid, i, j); //rfc_printf_map_u (intersected_bmp); #endif /* 为查找表赋值 */ g_acl_rfc_result_u.rfc_phase2[chunk_id][i * g_acl_rfc_result_u.rfc_phase2_dim[chunk_id] + j] = temp_eqid; } else { g_acl_rfc_result_u.rfc_phase2[chunk_id][i * g_acl_rfc_result_u.rfc_phase2_dim[chunk_id] + j] = 0; } } } } return ERROR_SUCCESS; }
/***************************************************************************** 函 数 名 : acl_rfc_process_phase0 功能描述 : 处理phase0的表 输入参数 : 无 输出参数 : 无 返 回 值 : ERROR_SUCCESS ---- 成功 ERR_ACL_RFC_ERR ---- 失败 ----------------------------------------------------------------------------- 最近一次修改记录: 修改作者 : Fuzhiqing 修改目的 : 新增函数 修改日期 : 2011年05月18日 *****************************************************************************/ s32 acl_rfc_process_phase0(void) { s32 chunk_id; s32 cell; s32 temp_eqid; s32 rule_index; s32 rule_on_cell; u32 bmp[RFC_ACL_MAP_SIZE]; //s32 max_cell; #ifdef acl_rfc_debug_flag_u time_t start_time,end_time; #endif struct acl_eqid_table *rule_map; /* 遍历phase0的8个chunk(即匹配条件) */ for (chunk_id = 0; chunk_id < RFC_ACL_PHASE0_CHUNK_CNT; chunk_id++) { #ifdef acl_rfc_debug_flag_u start_time = time(0); DEBUG_F ("proc 0 %d start.\n", chunk_id); #endif g_acl_rfc_result_u.rfc_phase0[chunk_id] = (u16*)malloc(ACL_RFC_CHUNK_SIZE); RFC_ASSERT_NOT_NULL_U(g_acl_rfc_result_u.rfc_phase0[chunk_id]); //memset(g_acl_rfc_result_u.rfc_phase0[chunk_id], 0, ACL_RFC_CHUNK_SIZE); for (cell = 0; cell < ACL_RFC_CHUNK_LEN; cell++) { rule_on_cell = 0; /* 处理每个chunk之前都需要清空map*/ memset (bmp, 0, sizeof(bmp)); for (rule_index = 0; rule_index < g_acl_rfc_rule_u.copy_number; rule_index++) { if (acl_rfc_node_in_range (chunk_id, cell, rule_index)) { rule_on_cell = 1; bmp[rule_index/32] |= (1<<(rule_index%32)); } } if (rule_on_cell) { /* 查找此位图是否已存在于eqid表中 */ for (temp_eqid = -1, rule_map = acl_phase0[chunk_id].head; NULL != rule_map; rule_map = rule_map->next) { if (0 == memcmp(rule_map->cbm, bmp, sizeof(bmp))) { temp_eqid = rule_map->eqID; break; } } /* 如果新分配了eqid, 添加到链表中*/ if (NULL == rule_map) { //DEBUG_F("Not get a map. bmp[0]: %x.\n", bmp[0]); temp_eqid = acl_rfc_add_bmp(&acl_phase0[chunk_id], bmp); } /* 为查找表(chunk)赋值 */ g_acl_rfc_result_u.rfc_phase0[chunk_id][cell] = temp_eqid; } else { g_acl_rfc_result_u.rfc_phase0[chunk_id][cell] = 0; } } #ifdef acl_rfc_debug_flag_u end_time = time(0); DEBUG_F ("proc 0 %d end, use time %ld\n", chunk_id, end_time - start_time); #endif } return ERROR_SUCCESS; }
/* check filesystem types and read superblock into memory buffer */ static int reiserfs_read_super( void ) { struct reiserfs_super_block super; __u64 superblock = REISERFS_SUPERBLOCK_BLOCK; if (read_disk_block(INFO->file, superblock, 0, sizeof(super), &super) != sizeof(super)) { DEBUG_F("read_disk_block failed!\n"); return 0; } DEBUG_F( "Found super->magic: \"%s\"\n", super.s_magic ); if( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 && strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 ) { /* Try old super block position */ superblock = REISERFS_OLD_SUPERBLOCK_BLOCK; if (read_disk_block( INFO->file, superblock, 0, sizeof (super), &super ) != sizeof(super)) { DEBUG_F("read_disk_block failed!\n"); return 0; } if ( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 && strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 ) { /* pre journaling super block - untested */ if ( strcmp( REISERFS_SUPER_MAGIC_STRING, (char *) ((__u32) &super + 20 ) ) != 0 ) return 0; super.s_blocksize = cpu_to_le16(REISERFS_OLD_BLOCKSIZE); super.s_journal_block = 0; super.s_version = 0; } } DEBUG_F( "ReiserFS superblock data:\n" ); DEBUG_F( "Block count: %u\n", le32_to_cpu(super.s_block_count) ) DEBUG_F( "Free blocks: %u\n", le32_to_cpu(super.s_free_blocks) ); DEBUG_F( "Journal block: %u\n", le32_to_cpu(super.s_journal_block) ); DEBUG_F( "Journal size (in blocks): %u\n", le32_to_cpu(super.s_orig_journal_size) ); DEBUG_F( "Root block: %u\n\n", le32_to_cpu(super.s_root_block) ); INFO->version = le16_to_cpu(super.s_version); INFO->blocksize = le16_to_cpu(super.s_blocksize); INFO->blocksize_shift = log2( INFO->blocksize ); INFO->journal_block = le32_to_cpu(super.s_journal_block); INFO->journal_block_count = le32_to_cpu(super.s_orig_journal_size); INFO->cached_slots = (FSYSREISER_CACHE_SIZE >> INFO->blocksize_shift) - 1; /* At this point, we've found a valid superblock. If we run into problems * mounting the FS, the user should probably know. */ /* A few sanity checks ... */ if ( INFO->version > REISERFS_MAX_SUPPORTED_VERSION ) { prom_printf( "ReiserFS: Unsupported version field: %u\n", INFO->version ); return 0; } if ( INFO->blocksize < FSYSREISER_MIN_BLOCKSIZE || INFO->blocksize > FSYSREISER_MAX_BLOCKSIZE ) { prom_printf( "ReiserFS: Unsupported block size: %u\n", INFO->blocksize ); return 0; } /* Setup the journal.. */ if ( INFO->journal_block != 0 ) { if ( !is_power_of_two( INFO->journal_block_count ) ) { prom_printf( "ReiserFS: Unsupported journal size, " "not a power of 2: %u\n", INFO->journal_block_count ); return 0; } journal_init(); /* Read in super block again, maybe it is in the journal */ block_read( superblock, 0, sizeof (struct reiserfs_super_block), (char *) &super ); } /* Read in the root block */ if ( !block_read( le32_to_cpu(super.s_root_block), 0, INFO->blocksize, ROOT ) ) { prom_printf( "ReiserFS: Failed to read in root block\n" ); return 0; } /* The root node is always the "deepest", so we can determine the hieght of the tree using it. */ INFO->tree_depth = blkh_level(BLOCKHEAD(ROOT)); DEBUG_F( "root read_in: block=%u, depth=%u\n", le32_to_cpu(super.s_root_block), INFO->tree_depth ); if ( INFO->tree_depth >= REISERFS_MAX_TREE_HEIGHT ) { prom_printf( "ReiserFS: Unsupported tree depth (too deep): %u\n", INFO->tree_depth ); return 0; } if ( INFO->tree_depth == BLKH_LEVEL_LEAF ) { /* There is only one node in the whole filesystem, which is simultanously leaf and root */ memcpy( LEAF, ROOT, INFO->blocksize ); } return 1; }
/* Get the next key, i.e. the key following the last retrieved key in * tree order. INFO->current_ih and * INFO->current_info are adapted accordingly. */ static int next_key( void ) { __u16 depth; struct item_head *ih = INFO->current_ih + 1; char *cache; DEBUG_F( "next_key:\n old ih: key %u:%u:%u:%u version:%u\n", le32_to_cpu(INFO->current_ih->ih_key.k_dir_id), le32_to_cpu(INFO->current_ih->ih_key.k_objectid), le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset), le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness), ih_version(INFO->current_ih) ); if ( ih == &ITEMHEAD[blkh_nr_item(BLOCKHEAD( LEAF ))] ) { depth = BLKH_LEVEL_LEAF; /* The last item, was the last in the leaf node. * Read in the next * * block */ do { if ( depth == INFO->tree_depth ) { /* There are no more keys at all. * Return a dummy item with * * MAX_KEY */ ih = ( struct item_head * ) &BLOCKHEAD( LEAF )->blk_right_delim_key; goto found; } depth++; DEBUG_F( " depth=%u, i=%u\n", depth, INFO->next_key_nr[depth] ); } while ( INFO->next_key_nr[depth] == 0 ); if ( depth == INFO->tree_depth ) cache = ROOT; else if ( depth <= INFO->cached_slots ) cache = CACHE( depth ); else { cache = read_tree_node( INFO->blocks[depth], --depth ); if ( !cache ) return 0; } do { __u16 nr_item = blkh_nr_item(BLOCKHEAD( cache )); int key_nr = INFO->next_key_nr[depth]++; DEBUG_F( " depth=%u, i=%u/%u\n", depth, key_nr, nr_item ); if ( key_nr == nr_item ) /* This is the last item in this block, set the next_key_nr * * to 0 */ INFO->next_key_nr[depth] = 0; cache = read_tree_node( dc_block_number( &(DC( cache )[key_nr])), --depth ); if ( !cache ) return 0; } while ( depth > BLKH_LEVEL_LEAF ); ih = ITEMHEAD; } found: INFO->current_ih = ih; INFO->current_item = &LEAF[ih_location(ih)]; DEBUG_F( " new ih: key %u:%u:%u:%u version:%u\n", le32_to_cpu(INFO->current_ih->ih_key.k_dir_id), le32_to_cpu(INFO->current_ih->ih_key.k_objectid), le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset), le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness), ih_version(INFO->current_ih) ); return 1; }
/* preconditions: reiserfs_read_super already executed, therefore * INFO block is valid * returns: 0 if error, nonzero iff we were able to find the file successfully * postconditions: on a nonzero return, INFO->fileinfo contains the info * of the file we were trying to look up, filepos is 0 and filemax is * the size of the file. */ static int reiserfs_open_file( char *dirname ) { struct reiserfs_de_head *de_head; char *rest, ch; __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0; char linkbuf[PATH_MAX]; /* buffer for following symbolic links */ int link_count = 0; int mode; errnum = 0; dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID); objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID); while ( 1 ) { DEBUG_F( "dirname=%s\n", dirname ); /* Search for the stat info first. */ if ( !search_stat( dir_id, objectid ) ) return 0; DEBUG_F( "sd_mode=0%o sd_size=%Lu\n", sd_mode((struct stat_data *) INFO->current_item ), sd_size(INFO->current_ih, INFO->current_item )); mode = sd_mode((struct stat_data *)INFO->current_item); /* If we've got a symbolic link, then chase it. */ if ( S_ISLNK( mode ) ) { int len = 0; DEBUG_F("link count = %d\n", link_count); DEBUG_SLEEP; if ( ++link_count > MAX_LINK_COUNT ) { DEBUG_F("Symlink loop\n"); errnum = FILE_ERR_SYMLINK_LOOP; return 0; } /* Get the symlink size. */ INFO->file->len = sd_size(INFO->current_ih, INFO->current_item); /* Find out how long our remaining name is. */ while ( dirname[len] && !isspace( dirname[len] ) ) len++; if ( INFO->file->len + len > sizeof ( linkbuf ) - 1 ) { errnum = FILE_ERR_LENGTH; return 0; } /* Copy the remaining name to the end of the symlink data. Note * * that DIRNAME and LINKBUF may overlap! */ memmove( linkbuf + INFO->file->len, dirname, len + 1 ); INFO->fileinfo.k_dir_id = dir_id; INFO->fileinfo.k_objectid = objectid; INFO->file->pos = 0; if ( !next_key() || reiserfs_read_data( linkbuf, INFO->file->len ) != INFO->file->len ) { DEBUG_F("reiserfs_open_file - if !next_key || reiserfs_read_data\n"); DEBUG_SLEEP; errnum = FILE_IOERR; return 0; } DEBUG_F( "symlink=%s\n", linkbuf ); DEBUG_SLEEP; dirname = linkbuf; if ( *dirname == '/' ) { /* It's an absolute link, so look it up in root. */ dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID); objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID); } else { /* Relative, so look it up in our parent directory. */ dir_id = parent_dir_id; objectid = parent_objectid; } /* Now lookup the new name. */ continue; } /* if we have a real file (and we're not just printing * * possibilities), then this is where we want to exit */ if ( !*dirname || isspace( *dirname ) ) { if ( !S_ISREG( mode ) ) { errnum = FILE_ERR_BAD_TYPE; return 0; } INFO->file->pos = 0; INFO->file->len = sd_size(INFO->current_ih, INFO->current_item); INFO->fileinfo.k_dir_id = dir_id; INFO->fileinfo.k_objectid = objectid; return next_key(); } /* continue with the file/directory name interpretation */ while ( *dirname == '/' ) dirname++; if ( !S_ISDIR( mode ) ) { errnum = FILE_ERR_NOTDIR; return 0; } for ( rest = dirname; ( ch = *rest ) && !isspace( ch ) && ch != '/'; rest++ ) ; *rest = 0; while ( 1 ) { char *name_end; int num_entries; if ( !next_key() ) return 0; if ( INFO->current_ih->ih_key.k_objectid != objectid ) break; name_end = INFO->current_item + ih_item_len(INFO->current_ih); de_head = ( struct reiserfs_de_head * ) INFO->current_item; num_entries = ih_entry_count(INFO->current_ih); while ( num_entries > 0 ) { char *filename = INFO->current_item + deh_location(de_head); char tmp = *name_end; if( deh_state(de_head) & (1 << DEH_Visible)) { int cmp; /* Directory names in ReiserFS are not null * terminated. * We write a temporary 0 behind it. * NOTE: that this * may overwrite the first block in * the tree cache. * That doesn't hurt as long as we * don't call next_key * () in between. */ *name_end = 0; cmp = strcmp( dirname, filename ); *name_end = tmp; if ( cmp == 0 ) goto found; } /* The beginning of this name marks the end of the next name. */ name_end = filename; de_head++; num_entries--; } } errnum = FILE_ERR_NOTFOUND; *rest = ch; return 0; found: *rest = ch; dirname = rest; parent_dir_id = dir_id; parent_objectid = objectid; dir_id = de_head->deh_dir_id; /* LE */ objectid = de_head->deh_objectid; /* LE */ } }
static int reiserfs_read_data( char *buf, __u32 len ) { __u32 blocksize; __u32 offset; __u32 to_read; char *prev_buf = buf; errnum = 0; DEBUG_F( "reiserfs_read_data: INFO->file->pos=%Lu len=%u, offset=%Lu\n", INFO->file->pos, len, (__u64) IH_KEY_OFFSET(INFO->current_ih) - 1 ); if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid || IH_KEY_OFFSET( INFO->current_ih ) > INFO->file->pos + 1 ) { search_stat( INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid ); goto get_next_key; } while ( errnum == 0 ) { if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid ) break; offset = INFO->file->pos - IH_KEY_OFFSET( INFO->current_ih ) + 1; blocksize = ih_item_len(INFO->current_ih); DEBUG_F( " loop: INFO->file->pos=%Lu len=%u, offset=%u blocksize=%u\n", INFO->file->pos, len, offset, blocksize ); if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_DIRECT ) && offset < blocksize ) { to_read = blocksize - offset; if ( to_read > len ) to_read = len; memcpy( buf, INFO->current_item + offset, to_read ); goto update_buf_len; } else if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_INDIRECT ) ) { blocksize = ( blocksize >> 2 ) << INFO->blocksize_shift; while ( offset < blocksize ) { __u32 blocknr = le32_to_cpu(((__u32 *) INFO->current_item)[offset >> INFO->blocksize_shift]); int blk_offset = offset & (INFO->blocksize - 1); to_read = INFO->blocksize - blk_offset; if ( to_read > len ) to_read = len; /* Journal is only for meta data. Data blocks can be read directly without using block_read */ read_disk_block( INFO->file, blocknr, blk_offset, to_read, buf ); update_buf_len: len -= to_read; buf += to_read; offset += to_read; INFO->file->pos += to_read; if ( len == 0 ) goto done; } } get_next_key: next_key(); }
/* preconditions: reiserfs_read_super already executed, therefore * INFO block is valid * returns: 0 if error (errnum is set), * nonzero iff we were able to find the key successfully. * postconditions: on a nonzero return, the current_ih and * current_item fields describe the key that equals the * searched key. INFO->next_key contains the next key after * the searched key. * side effects: messes around with the cache. */ static int search_stat( __u32 dir_id, __u32 objectid ) { char *cache; int depth; int nr_item; int i; struct item_head *ih; errnum = 0; DEBUG_F( "search_stat:\n key %u:%u:0:0\n", le32_to_cpu(dir_id), le32_to_cpu(objectid) ); depth = INFO->tree_depth; cache = ROOT; DEBUG_F( "depth = %d\n", depth ); while ( depth > BLKH_LEVEL_LEAF ) { struct key *key; nr_item = blkh_nr_item(BLOCKHEAD( cache )); key = KEY( cache ); for ( i = 0; i < nr_item; i++ ) { if (le32_to_cpu(key->k_dir_id) > le32_to_cpu(dir_id) || (key->k_dir_id == dir_id && (le32_to_cpu(key->k_objectid) > le32_to_cpu(objectid) || (key->k_objectid == objectid && (key->u.k_offset_v1.k_offset | key->u.k_offset_v1.k_uniqueness) > 0)))) break; key++; } DEBUG_F( " depth=%d, i=%d/%d\n", depth, i, nr_item ); INFO->next_key_nr[depth] = ( i == nr_item ) ? 0 : i + 1; cache = read_tree_node( dc_block_number(&(DC(cache)[i])), --depth ); if ( !cache ) return 0; } /* cache == LEAF */ nr_item = blkh_nr_item(BLOCKHEAD(LEAF)); ih = ITEMHEAD; DEBUG_F( "nr_item = %d\n", nr_item ); for ( i = 0; i < nr_item; i++ ) { if ( ih->ih_key.k_dir_id == dir_id && ih->ih_key.k_objectid == objectid && ih->ih_key.u.k_offset_v1.k_offset == 0 && ih->ih_key.u.k_offset_v1.k_uniqueness == 0 ) { DEBUG_F( " depth=%d, i=%d/%d\n", depth, i, nr_item ); INFO->current_ih = ih; INFO->current_item = &LEAF[ih_location(ih)]; return 1; } ih++; } DEBUG_LEAVE(FILE_ERR_BAD_FSYS); errnum = FILE_ERR_BAD_FSYS; return 0; }
static int reiserfs_open( struct boot_file_t *file, const char *dev_name, struct partition_t *part, const char *file_name ) { static char buffer[1024]; DEBUG_ENTER; DEBUG_OPEN; memset( INFO, 0, sizeof(struct reiserfs_state) ); INFO->file = file; if (part) { DEBUG_F( "Determining offset for partition %d\n", part->part_number ); INFO->partition_offset = ((uint64_t)part->part_start) * part->blocksize; DEBUG_F( "%Lu = %lu * %hu\n", INFO->partition_offset, part->part_start, part->blocksize ); } else INFO->partition_offset = 0; strncpy(buffer, dev_name, 1020); if (_machine != _MACH_bplan) strcat(buffer, ":0"); /* 0 is full disk in (non-buggy) OF */ file->of_device = prom_open( buffer ); DEBUG_F( "Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n", buffer, file_name, INFO->partition_offset ); if ( file->of_device == PROM_INVALID_HANDLE || file->of_device == NULL ) { DEBUG_F( "Can't open device %p\n", file->of_device ); DEBUG_LEAVE(FILE_ERR_BADDEV); return FILE_ERR_BADDEV; } DEBUG_F("%p was successfully opened\n", file->of_device); if ( reiserfs_read_super() != 1 ) { DEBUG_F( "Couldn't open ReiserFS @ %s/%Lu\n", buffer, INFO->partition_offset ); prom_close( file->of_device ); DEBUG_LEAVE(FILE_ERR_BAD_FSYS); return FILE_ERR_BAD_FSYS; } DEBUG_F( "Attempting to open %s\n", file_name ); strcpy(buffer, file_name); /* reiserfs_open_file modifies argument */ if (reiserfs_open_file(buffer) == 0) { DEBUG_F( "reiserfs_open_file failed. errnum = %d\n", errnum ); prom_close( file->of_device ); DEBUG_LEAVE_F(errnum); return errnum; } DEBUG_F( "Successfully opened %s\n", file_name ); DEBUG_LEAVE(FILE_ERR_OK); DEBUG_SLEEP; return FILE_ERR_OK; }
/***************************************************************************** 函 数 名 : _rfc_acl_handle 功能描述 : 生成RFC表,编译流程: 0 sip_h--8-| |---16 phase1_0---| 1 sip_l--9-| | |---20 phase2_0---| 2 dip_h--10| | | |---17 phase1_1---| | 3 dip_l--11| | |---22 phase3_0(final) 4 sport--12| | |---18 phase1_2---| | 5 dport--13| | | |---21 phase2_1---| 6 proto--14| | |---19 phase1_3---| 7 inport-15| 输入参数 : num ---- 表示第几套表 输出参数 : cnt ---- 规则数 返 回 值 : ERROR_SUCCESS ---- 成功 ERR_ACL_RFC_STEP_OK ---- 本套执行成功 ERR_ACL_RFC_ERR ---- 失败 ----------------------------------------------------------------------------- 最近一次修改记录: 修改作者 : Fuzhiqing 修改目的 : 新增函数 修改日期 : 2011年05月18日 *****************************************************************************/ s32 _rfc_acl_handle(s32 num) { s32 ret = ERROR_SUCCESS; #ifdef acl_rfc_debug_flag_u time_t start_time,end_time; #endif #ifdef acl_rfc_debug_flag_u start_time = time(0); DEBUG_F ("num %d start_time %ld \n", num, start_time); #endif /* 从内核获取规则条数及相应条数的规则 */ if (ERROR_SUCCESS != acl_rfc_syscall_get_rule(&g_acl_rfc_rule_u)) { DEBUG_F ("ret: %d.\n", ret); ret = ERR_ACL_RFC_ERR; goto out; } DEBUG_F ("acl_rfc_get_rule over , copy_number %d, will process rule\n", g_acl_rfc_rule_u.copy_number); if (0 == g_acl_rfc_rule_u.copy_number) { DEBUG_F ("there is no rule \n"); ret = ERR_ACL_RFC_NO_RULE; goto out; } ret = acl_rfc_prepare_data_base(); if (ERROR_SUCCESS != ret) { DEBUG_F ("ret: %d.\n", ret); ret = ERR_ACL_RFC_ERR; goto out; } ret = acl_rfc_process(); if (ERROR_SUCCESS != ret) { DEBUG_F ("ret: %d.\n", ret); ret = ERR_ACL_RFC_ERR; goto out; } acl_rfc_u_size.num = num; ret = acl_rfc_syscall_notify_kernel_prepare_data(&acl_rfc_u_size); if (ERROR_SUCCESS != ret) { DEBUG_F ("ret: %d.\n", ret); ret = ERR_ACL_RFC_ERR; goto out; } ret = acl_rfc_flush_data(num); if (ERROR_SUCCESS != ret) { DEBUG_F ("ret: %d.\n", ret); ret = ERR_ACL_RFC_ERR; goto out; } if (g_acl_rfc_rule_u.copy_number < MAX_ACL_RULE_PER_STEP) /* 说明规则已取尽 */ { goto out; } if (MAX_ACL_GROUP_CNT != num + 1) { ret = ERR_ACL_RFC_STEP_OK; } out: if (ERR_ACL_RFC_ERR == ret) { acl_rfc_syscall_err(); } else if (ERR_ACL_RFC_STEP_OK == ret || ERROR_SUCCESS == ret) { acl_rfc_syscall_over(num); DEBUG_F("ret: %d.\n", ret); } acl_rfc_free_data_base(); #ifdef acl_rfc_debug_flag_u end_time = time(0); DEBUG_F (" out num %d end_time %ld use %ld\n", num, end_time, end_time-start_time); #endif return ret; }
/* Init the journal data structure. We try to cache as much as * possible in the JOURNAL_START-JOURNAL_END space, but if it is full * we can still read the rest from the disk on demand. * * The first number of valid transactions and the descriptor block of the * first valid transaction are held in INFO. The transactions are all * adjacent, but we must take care of the journal wrap around. */ static int journal_init( void ) { struct reiserfs_journal_header header; struct reiserfs_journal_desc desc; struct reiserfs_journal_commit commit; __u32 block_count = INFO->journal_block_count; __u32 desc_block; __u32 commit_block; __u32 next_trans_id; __u32 *journal_table = JOURNAL_START; journal_read( block_count, sizeof ( header ), ( char * ) &header ); desc_block = le32_to_cpu(header.j_first_unflushed_offset); if ( desc_block >= block_count ) return 0; INFO->journal_transactions = 0; INFO->journal_first_desc = desc_block; next_trans_id = le32_to_cpu(header.j_last_flush_trans_id) + 1; DEBUG_F( "journal_init: last flushed %u\n", le32_to_cpu(header.j_last_flush_trans_id) ); while ( 1 ) { journal_read( desc_block, sizeof(desc), (char *) &desc ); if ( strcmp( JOURNAL_DESC_MAGIC, desc.j_magic ) != 0 || desc.j_trans_id != next_trans_id || desc.j_mount_id != header.j_mount_id ) /* no more valid transactions */ break; commit_block = ( desc_block + le32_to_cpu(desc.j_len) + 1 ) & ( block_count - 1 ); journal_read( commit_block, sizeof(commit), (char *) &commit ); if ( desc.j_trans_id != commit.j_trans_id || desc.j_len != commit.j_len ) /* no more valid transactions */ break; DEBUG_F( "Found valid transaction %u/%u at %u.\n", le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id), desc_block ); next_trans_id++; if ( journal_table < JOURNAL_END ) { if ( ( journal_table + 1 + le32_to_cpu(desc.j_len) ) >= JOURNAL_END ) { /* The table is almost full; mark the end of the cached * * * journal. */ *journal_table = 0xffffffff; journal_table = JOURNAL_END; } else { int i; /* Cache the length and the realblock numbers in the table. * * The block number of descriptor can easily be computed. * * and need not to be stored here. */ *journal_table++ = desc.j_len; for ( i = 0; i < le32_to_cpu(desc.j_len) && i < JOURNAL_TRANS_HALF; i++ ) { *journal_table++ = desc.j_realblock[i]; DEBUG_F( "block %u is in journal %u.\n", le32_to_cpu(desc.j_realblock[i]), desc_block ); } for ( ; i < le32_to_cpu(desc.j_len); i++ ) { *journal_table++ = commit.j_realblock[i - JOURNAL_TRANS_HALF]; DEBUG_F( "block %u is in journal %u.\n", le32_to_cpu(commit.j_realblock[i - JOURNAL_TRANS_HALF]), desc_block ); } } } desc_block = (commit_block + 1) & (block_count - 1); } DEBUG_F( "Transaction %u/%u at %u isn't valid.\n", le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id), desc_block ); INFO->journal_transactions = next_trans_id - le32_to_cpu(header.j_last_flush_trans_id) - 1; return (errnum == 0); }
//由于修改接收控制vlan列表时页面下发两个接收接口, //所以拆开两个函数分别添加和修改 int ws__addAcceptCtrlVlan(WS_ENV* soap, xsd__int addAcceptPort, xsd__string acceptCtrlVlan, xsd__int* ret) { DEBUG_F("add ac, addAcceptPort:%x, acceptCtrlVlan:%s.\n",addAcceptPort, acceptCtrlVlan); return ws__setAcceptCtrlVlan(soap, addAcceptPort, acceptCtrlVlan, ret); }
int ws__modAcceptCtrlVlan(WS_ENV* soap, xsd__int modAcceptPort, xsd__int modAcceptPort2, xsd__string acceptCtrlVlan, xsd__int* ret) { DEBUG_F("mod ac, modAcceptPort:%x, modAcceptPort2: %x,acceptCtrlVlan:%s.\n",modAcceptPort, modAcceptPort2, acceptCtrlVlan); return ws__setAcceptCtrlVlan(soap, modAcceptPort, acceptCtrlVlan, ret); }
// // Copied largely unchanged from Marlin // void Device_Heater::DoPidAutotune(uint8_t device_number, float temp, int ncycles) { float input = 0.0; int cycles = 0; bool heating = true; unsigned long temp_millis = millis(); unsigned long t1=temp_millis; unsigned long t2=temp_millis; long t_high = 0; long t_low = 0; long bias, d; float Ku, Tu; float Kp, Ki, Kd; float max = 0; float min = 10000; uint8_t p; uint8_t i; extern volatile bool temp_meas_ready; DEBUGLNPGM("PID Autotune start"); // switch off all heaters during auto-tune for (i=0; i<Device_Heater::GetNumDevices(); i++) { if (Device_Heater::IsInUse(i)) Device_Heater::SetHeaterPower(&heater_info_array[device_number], 0); } HeaterInfo *heater_info = &heater_info_array[device_number]; bias = d = p = heater_info->power_on_level; SetHeaterPower(heater_info, p); for(;;) { if(temp_meas_ready == true) { // temp sample ready Device_TemperatureSensor::UpdateTemperatureSensors(); input = Device_Heater::ReadCurrentTemperature(device_number); max=max(max,input); min=min(min,input); if(heating == true && input > temp) { if(millis() - t2 > 5000) { heating=false; p = bias - d; SetHeaterPower(heater_info, p); t1=millis(); t_high=t1 - t2; max=temp; } } if(heating == false && input < temp) { if(millis() - t1 > 5000) { heating=true; t2=millis(); t_low=t2 - t1; if(cycles > 0) { bias += (d*(t_high - t_low))/(t_low + t_high); bias = constrain(bias, 20 ,heater_info->power_on_level-20); if (bias > heater_info->power_on_level/2) d = heater_info->power_on_level - 1 - bias; else d = bias; DEBUGPGM(" bias: "); DEBUG_F(bias, DEC); DEBUGPGM(" d: "); DEBUG_F(d, DEC); DEBUGPGM(" min: "); DEBUG(min); DEBUGPGM(" max: "); DEBUGLN(max); if(cycles > 2) { Ku = (4.0*d)/(3.14159*(max-min)/2.0); Tu = ((float)(t_low + t_high)/1000.0); DEBUGPGM(" Ku: "); DEBUG(Ku); DEBUGPGM(" Tu: "); DEBUGLN(Tu); Kp = 0.6*Ku; Ki = 2*Kp/Tu; Kd = Kp*Tu/8; DEBUGLNPGM(" Clasic PID "); DEBUGPGM(" Kp: "); DEBUGLN(Kp); DEBUGPGM(" Ki: "); DEBUGLN(Ki); DEBUGPGM(" Kd: "); DEBUGLN(Kd); /* Kp = 0.33*Ku; Ki = Kp/Tu; Kd = Kp*Tu/3; DEBUGLNPGM(" Some overshoot ") DEBUGPGM(" Kp: "); DEBUGLN(Kp); DEBUGPGM(" Ki: "); DEBUGLN(Ki); DEBUGPGM(" Kd: "); DEBUGLN(Kd); Kp = 0.2*Ku; Ki = 2*Kp/Tu; Kd = Kp*Tu/3; DEBUGLNPGM(" No overshoot ") DEBUGPGM(" Kp: "); DEBUGLN(Kp); DEBUGPGM(" Ki: "); DEBUGLN(Ki); DEBUGPGM(" Kd: "); DEBUGLN(Kd); */ } } p = bias + d; SetHeaterPower(heater_info, p); cycles++; min=temp; } } } if(input > (temp + 20)) { ERRORLNPGM("PID Autotune failed! Temperature too high"); return; } if(millis() - temp_millis > 2000) { DEBUGLNPGM("ok T:"); DEBUG(input); DEBUGPGM(" @:"); DEBUGLN(p); temp_millis = millis(); } if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) { ERRORLNPGM("PID Autotune failed! timeout"); return; } if(cycles > ncycles) { DEBUGLNPGM("PID Autotune finished! Record the last Kp, Ki and Kd constants"); return; } } }
void loop() { // quickly scan through baudrates until we receive a valid packet within timeout period #if 0 // the baud rate change still isn't working for some reason. if (autodetect_baudrates_index != 0xFF) { if (millis() - first_rcvd_time > MAX_FRAME_COMPLETION_DELAY_MS * 1.5) // make sure its not a multiple of 100ms { PSERIAL.end(); PSERIAL.flush(); autodetect_baudrates_index += 1; if (autodetect_baudrates_index >= NUM_ARRAY_ELEMENTS(autodetect_baudrates)) autodetect_baudrates_index = 0; PSERIAL.begin(pgm_read_dword(&autodetect_baudrates[autodetect_baudrates_index])); recv_buf_len = 0; first_rcvd_time = millis(); } } #endif if (get_command()) { autodetect_baudrates_index = 0xFF; last_order_time = millis(); is_host_active = true; order_code = recv_buf[PM_ORDER_BYTE_OFFSET]; control_byte = recv_buf[PM_CONTROL_BYTE_OFFSET]; parameter_length = recv_buf[PM_LENGTH_BYTE_OFFSET]-2; #if TRACE_ORDER DEBUGPGM("\nOrder("); DEBUG_F(order_code, HEX); DEBUGPGM(", plen="); DEBUG_F(parameter_length, DEC); DEBUGPGM(", cb="); DEBUG_F(control_byte, HEX); DEBUGPGM("):"); for (uint8_t i = 0; i < parameter_length; i++) { DEBUG_CH(' '); DEBUG_F(recv_buf[i], HEX); } DEBUG_EOL(); #endif // does this match the sequence number of the last reply if ((control_byte & CONTROL_BYTE_SEQUENCE_NUMBER_MASK) == (reply_control_byte & CONTROL_BYTE_SEQUENCE_NUMBER_MASK) && (control_byte & CONTROL_BYTE_ORDER_HOST_RESET_BIT) == 0 && reply_control_byte != 0xFF) { if (!reply_started) { // resend last response reply_started = true; generate_response_send(); } else { // this is an unexpected error case (matching sequence number but nothing to send) generate_response_transport_error_start(PARAM_FRAME_RECEIPT_ERROR_TYPE_UNABLE_TO_ACCEPT, control_byte); generate_response_msg_addPGM(PMSG(MSG_ERR_NO_RESPONSE_TO_SEND)); generate_response_send(); } } else { reply_sent = false; process_command(); if (!reply_sent) { send_app_error_response(PARAM_APP_ERROR_TYPE_FIRMWARE_ERROR, PMSG(MSG_ERR_NO_RESPONSE_GENERATED)); } } recv_buf_len = 0; } // Idle loop activities // Check if heaters need to be updated? if (temp_meas_ready) { Device_TemperatureSensor::UpdateTemperatureSensors(); Device_Heater::UpdateHeaters(); } // Now check low-priority stuff uint32_t now = millis(); if (now - last_idle_check > 1000) // checked every second { #if !DEBUG_DISABLE_HOST_TIMEOUT // have we heard from the host within the timeout? if (now - last_order_time > (HOST_TIMEOUT_SECS * 1000) && is_host_active) { is_host_active = false; if (!is_stopped) { emergency_stop(PARAM_STOPPED_CAUSE_HOST_TIMEOUT); } } #endif #if TRACE_MOVEMENT print_movement_ISR_state(); #endif last_idle_check = now; } }