Esempio n. 1
0
int main(int argc, char **argv)
{
	struct rlimit lim;
	struct map_list *list, *entry;
	size_t page_size, i;
	void *map = NULL;
	unsigned long mem_free = 0;
	unsigned long hugepage_size = 0;
	unsigned long mem_fragmentable = 0;

	if (prereq() != 0) {
		printf("Either the sysctl compact_unevictable_allowed is not\n"
		       "set to 1 or couldn't read the proc file.\n"
		       "Skipping the test\n");
		return 0;
	}

	lim.rlim_cur = RLIM_INFINITY;
	lim.rlim_max = RLIM_INFINITY;
	if (setrlimit(RLIMIT_MEMLOCK, &lim)) {
		perror("Failed to set rlimit:\n");
		return -1;
	}

	page_size = getpagesize();

	list = NULL;

	if (read_memory_info(&mem_free, &hugepage_size) != 0) {
		printf("ERROR: Cannot read meminfo\n");
		return -1;
	}

	mem_fragmentable = mem_free * 0.8 / 1024;

	while (mem_fragmentable > 0) {
		map = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
			   MAP_ANONYMOUS | MAP_PRIVATE | MAP_LOCKED, -1, 0);
		if (map == MAP_FAILED)
			break;

		entry = malloc(sizeof(struct map_list));
		if (!entry) {
			munmap(map, MAP_SIZE);
			break;
		}
		entry->map = map;
		entry->next = list;
		list = entry;

		/* Write something (in this case the address of the map) to
		 * ensure that KSM can't merge the mapped pages
		 */
		for (i = 0; i < MAP_SIZE; i += page_size)
			*(unsigned long *)(map + i) = (unsigned long)map + i;

		mem_fragmentable--;
	}

	for (entry = list; entry != NULL; entry = entry->next) {
		munmap(entry->map, MAP_SIZE);
		if (!entry->next)
			break;
		entry = entry->next;
	}

	if (check_compaction(mem_free, hugepage_size) == 0)
		return 0;

	return -1;
}
Esempio n. 2
0
static status_t read_sys_info( struct SYSInfo * sysinfo )
{
    char buff[BUFFLEN], buff1[BUFFLEN], str[BUFFLEN];
    char *new_line, *find_str;
    int i, j, k, net_num, rval, fd;
    int kernel_26 = 0;

    /*************************** Initialization ****************************/

    bzero(buff, BUFFLEN);
    bzero(buff1, BUFFLEN);
    bzero(str, BUFFLEN);

    init_sysinfo_data(sysinfo);

    /* Copy the network interface names from predefined CONSTNETNAME in 
     * util.h if user has not specified a nic name
     */

    if ( ! Defined_Nic_Name )
	for ( i = 0; i < NETTYPE; i++ )
	    strcpy(NETNAME[i], CONSTNETNAME[i]);

    /************** Fill in loopback "interface" as the first NIC **********/
    /* Loopback "interface" has no records in /proc/interrupts. We are still
     * interested in some statistics about this "interface", whose info be
     * found in /proc/net/dev.
     */
	
    for ( i = 0; i < NETTYPE; i++ ) {
	if ( strncmp(NETNAME[i], "loop", strlen(NETNAME[i])) == 0 ) {
	    sysinfo->net_num = 1;
	    strcpy(sysinfo->net[0].name, "loop");
	}
    }

    /*** Interrupt information is stored in /proc/interrupts in Linux ******/

    if ( (fd = open("/proc/interrupts", O_RDONLY)) < 0 || 
	 (rval=read(fd, buff, BUFFLEN-1)) <= 0) {
        perror("Fail to get interrupt information from /proc/interrupts");
	return NOTOK;
    }
    close(fd); 

    /**** Frist line of /proc/interrupts indicates the number of CPUs ******/

    for ( i = 0; buff[i] != '\n' && i < BUFFLEN-1; i++) // copy the first line to buff1
           buff1[i] = buff[i];
    if ( strlen(buff) == 0 || ( sysinfo->cpu_num = sscanf(buff1, 
	 "%s %s %s %s %s %s %s %s", str, str, str, str, str, str, str, str)) < 1 ) {
 	perror("Failed to parse /proc/interrupts");
	return NOTOK;
    }
    if ( sysinfo->cpu_num > 8 ) {
	fprintf(stderr, "Exceed the maximum CPU number: %d.\n",sysinfo->cpu_num);
	return NOTOK;
    }
 
    /********** Parse the interrupt information line by line ***************/

    new_line = buff;
    net_num = sysinfo->net_num;
    while ( net_num < MAXNETWORK ) {
	
	/******************* Copy next line to buff1 for parsing ***********/
	
        if ( (new_line = strstr(new_line, "\n")) == NULL )
	    break;
	new_line++;
	if ( strlen(new_line) == 0 )
	    break;
	strncpy(buff1, new_line, BUFFLEN-1);
	for ( i = 0; buff1[i] != '\n' && i < BUFFLEN-1; i++ );
	buff1[i] = '\0';
	
	/****************** Search the network interface entry *************/

	for ( i = 0; i < NETTYPE; i++ ) {
	    if ( (find_str = strstr(buff1, NETNAME[i])) != NULL ) { // got one
		
		/******************* First number is IRQ *******************/
		
		sysinfo->net[net_num].irq = atoi(strtok(buff1, " :\t().,"));  

		/******** Following are interrupts for each CPU ************/
	
		for ( j = 0; j < sysinfo->cpu_num; j++ ) {
		    sysinfo->cpu[j].net_int[net_num] = atol(strtok(NULL, " :\t()."));
		    sysinfo->net[net_num].interrupt += sysinfo->cpu[j].net_int[net_num];
		}

		/** The last part is device name such as keyboard and eth0 */
 
		while ( (find_str = (char *)strtok(NULL, " :\t().,")) != NULL ) {
		    if ( (find_str = strstr(find_str, NETNAME[i])) != NULL ) { 
			strncpy(sysinfo->net[net_num].name, find_str, NETNAMELEN-1);
			break;
		    }
		}
		net_num++;
		break;

	    } // end of if find_str
	} // end of for loop 
    } // end of while loop 

    sysinfo->net_num = net_num;

#ifdef DEBUG
    fprintf(stderr, " DEBUG: Parse /proc/interrupts (%d bytes read). CPU: %d  Network-card: %d (%s %s %s)\n",
	   rval, sysinfo->cpu_num, net_num, sysinfo->net[0].name, sysinfo->net[1].name, sysinfo->net[2].name);
#endif        

    /*
    FILE  *fd1;
    if ( (fd1 = open("/proc/stat", "r")) == NULLf || 
	 fscanf(fp1, "%s %d %d %d %d", &str, &sysinfo->cpu_user, &sysinfo->cpu_nice, 
		    &sysinfo->cpu_system, &sysinfo->cpu_idle) != 5 ) {
        perror("Failed to get cpu information from /proc/stat.");
	return NOTOK;
    }
    fclose(fp1); 
    */

    /************************* Read CPU usage ******************************/

    /* CPU information is stored in /proc/stat in Linux. Format:
     * cpu-name user-jiffies nice-jiffies system-jiffies idle-jiffies. For example,
     * cpu  123456 123 12345 1234567
     * The number of jiffies that the system spent in user/nice/system/idle mode are
     * 123456, 123, 12345, and 1234567, respectively. Jiffy is defined by kernel (HZ).
     */ 

    bzero(buff, BUFFLEN);
    if ( (fd = open("/proc/stat", O_RDONLY)) < 0 || 
	 (rval=read(fd, buff, BUFFLEN-1)) <= 0) {
        perror("Failed to get cpu information from /proc/stat.");
	return NOTOK;
    }
    close(fd);

    /************* First line shows the summary of CPU statistics **********/

    if ( strlen(buff) == 0 || sscanf(buff, "%s %lld %lld %lld %lld", str, &sysinfo->cpu_user, 
		&sysinfo->cpu_nice, &sysinfo->cpu_system, &sysinfo->cpu_idle) != 5 ) {
	perror("Failed to get cpu information from /proc/stat.");
	return NOTOK;
    }
   
#ifdef DEBUG
    fprintf(stderr, " DEBUG: Parse /proc/stat (%d byt read): %lld[user] %lld[nice] %lld[system] %lld[idle]\n", rval, 
	   sysinfo->cpu_user, sysinfo->cpu_nice, sysinfo->cpu_system, sysinfo->cpu_idle);
#endif        

    /************************ Get each CPU's usage *************************/
    
    new_line = buff;
    for( i = 0; i < sysinfo->cpu_num; i++){
        if ( (new_line = strstr(new_line, "\n")) == NULL )
	    break;
	new_line++;
	if ( strlen(new_line) == 0 || sscanf(new_line, "%s %lld %lld %lld %lld", 
	     str, &sysinfo->cpu[i].user_mode, &sysinfo->cpu[i].nice_mode, 
             &sysinfo->cpu[i].system_mode, &sysinfo->cpu[i].idle_mode) != 5 ) {
	    perror("Failed to get cpu information from /proc/stat.");
	    return NOTOK;
	}
    }

    if ( (new_line = strstr(buff, "page")) == NULL ) {
      kernel_26 = 1;	    
    } else {
      if ( sscanf(new_line, "%s %lld %lld", str, &sysinfo->page_in, &sysinfo->page_out) != 3 ) {
	    perror("Fail to parse page info from /proc/stat.");
	    return NOTOK;
      }

      if ( (new_line = strstr(buff, "swap")) == NULL || sscanf(new_line, 
	    "%s %lld %lld", str, &sysinfo->swap_in, &sysinfo->swap_out) != 3 ) {
	    perror("Fail to parse swap info.");
	    return NOTOK;
      }
    }

    if ( (new_line = strstr(buff, "intr")) == NULL || sscanf(new_line, 
	  "%s %lld", str, &sysinfo->interrupts) != 2 ) {
	    perror("Fail to parse interrupt info from /proc/stat.");
	    return NOTOK;
    }

    if ( (new_line = strstr(buff, "ctxt")) == NULL || sscanf(new_line, 
	  "%s %lld", str, &sysinfo->context_switch) != 2 ) {
	    perror("Fail to parse context switch info from /proc/stat.");
	    return NOTOK;
    }

    if ( kernel_26 ) {
      read_from_vmstat(sysinfo);
      read_memory_info(sysinfo);
    } else {

      /*************** Read memory information  Kernel 2.4 ****************/

      bzero(buff, BUFFLEN);
      if ( (fd = open("/proc/meminfo", O_RDONLY)) < 0 || 
	   (rval=read(fd, buff, BUFFLEN-1)) <= 0) {
        perror("Failed to open /proc/meminfo.");
	return NOTOK;
      }
      close(fd);

      /********* Ignore the first comment line of /proc/meminfo ************/
      if ( (new_line = strstr(buff, "\n")) == NULL ) {
	perror("Fail to parse /proc/meminfo (No newline?).");
	return NOTOK;
      }
      new_line++;
      
      /************* Parse the second line of /proc/meminfo ****************/
      
      if ( strlen(new_line) == 0 || sscanf(new_line, "%s %lld %lld", str, 
					   &sysinfo->mem_total, &sysinfo->mem_used) != 3 ) {
	perror("Fail to parse /proc/meminfo (Wrong format).");
	return NOTOK;
      }
    }
   
#ifdef DEBUG
    fprintf(stderr, " DEBUG: Parse /proc/meminfo (%d byt read): %lld[mem-total] %lld[mem-used]\n", 
	   rval, sysinfo->mem_total, sysinfo->mem_used);
#endif        

    /*************** Read network device information ***********************/

    bzero(buff, BUFFLEN);
    if ( (fd = open("/proc/net/dev", O_RDONLY)) < 0 || 
	 (rval=read(fd, buff, BUFFLEN-1)) <= 0) {
        perror("Failed to open /proc/net/dev.");
	return NOTOK;
    }
    close(fd);

    /******* Ignore the first two comment lines of /proc/net/dev ***********/
    
    if ( (new_line = strstr(buff, "\n")) == NULL ) {
	perror("Fail to parse /proc/net/dev (No newline?).");
	return NOTOK;
    }
    new_line++;

    for ( i = 0; i < MAXNETWORK;  ) {
	
	/******************* Copy next line to buff1 for parsing ***********/

        if ( (new_line = strstr(new_line, "\n")) == NULL )
	    break;
	new_line++;
	if ( strlen(new_line) == 0 ) 
	    break;
	strncpy(buff1, new_line, BUFFLEN-1);
	for ( j = 0; buff1[j] != '\n' && j < BUFFLEN-1; j++);
	buff1[j] = '\0';

	strcpy(str, strtok(buff1, " :\t()."));
	for ( j = 0; j < sysinfo->net_num; j++ ) {
	    if ( strncmp(str, sysinfo->net[j].name, strlen(str)) == 0 ) {
		sysinfo->net[j].recv_byte = parse_size( strtok(NULL, " :\t()."));
		sysinfo->net[j].recv_packet = parse_size(strtok(NULL, " :\t()."));
		for ( k = 0; k < 6; k++) // We don't use those middle six fields
		    strtok(NULL, " :\t().");
		sysinfo->net[j].send_byte = parse_size(strtok(NULL, " :\t()."));
		sysinfo->net[j].send_packet = parse_size(strtok(NULL, " :\t()."));
#ifdef DEBUG
		fprintf(stderr, " DEBUG: %s: recv-bytes: %lld recv-packets: %lld send-bytes: %lld send-packets: %lld\n",
		   sysinfo->net[j].name, sysinfo->net[j].recv_byte, sysinfo->net[j].recv_packet, 
		   sysinfo->net[j].send_byte, sysinfo->net[j].send_packet);
#endif
		i++; 
		break;

	    } // end of if strncmp
	} // end of for loop of j
    } // end of for loop of i
 
    return OK;
}