Esempio n. 1
0
static int ubi_attach_fastmap(struct ubi_scan_info *ubi,
			      struct ubi_attach_info *ai,
			      struct ubi_fastmap_layout *fm)
{
	struct ubi_fm_hdr *fmhdr;
	struct ubi_fm_scan_pool *fmpl1, *fmpl2;
	struct ubi_fm_ec *fmec;
	struct ubi_fm_volhdr *fmvhdr;
	struct ubi_fm_eba *fm_eba;
	int ret, i, j, pool_size, wl_pool_size;
	size_t fm_pos = 0, fm_size = ubi->fm_size;
	void *fm_raw = ubi->fm_buf;

	memset(ubi->fm_used, 0, sizeof(ubi->fm_used));

	fm_pos += sizeof(struct ubi_fm_sb);
	if (fm_pos >= fm_size)
		goto fail_bad;

	fmhdr = (struct ubi_fm_hdr *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmhdr);
	if (fm_pos >= fm_size)
		goto fail_bad;

	if (be32_to_cpu(fmhdr->magic) != UBI_FM_HDR_MAGIC) {
		ubi_err("bad fastmap header magic: 0x%x, expected: 0x%x",
			be32_to_cpu(fmhdr->magic), UBI_FM_HDR_MAGIC);
		goto fail_bad;
	}

	fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl1);
	if (fm_pos >= fm_size)
		goto fail_bad;
	if (be32_to_cpu(fmpl1->magic) != UBI_FM_POOL_MAGIC) {
		ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x",
			be32_to_cpu(fmpl1->magic), UBI_FM_POOL_MAGIC);
		goto fail_bad;
	}

	fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl2);
	if (fm_pos >= fm_size)
		goto fail_bad;
	if (be32_to_cpu(fmpl2->magic) != UBI_FM_POOL_MAGIC) {
		ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x",
			be32_to_cpu(fmpl2->magic), UBI_FM_POOL_MAGIC);
		goto fail_bad;
	}

	pool_size = be16_to_cpu(fmpl1->size);
	wl_pool_size = be16_to_cpu(fmpl2->size);
	fm->max_pool_size = be16_to_cpu(fmpl1->max_size);
	fm->max_wl_pool_size = be16_to_cpu(fmpl2->max_size);

	if (pool_size > UBI_FM_MAX_POOL_SIZE || pool_size < 0) {
		ubi_err("bad pool size: %i", pool_size);
		goto fail_bad;
	}

	if (wl_pool_size > UBI_FM_MAX_POOL_SIZE || wl_pool_size < 0) {
		ubi_err("bad WL pool size: %i", wl_pool_size);
		goto fail_bad;
	}

	if (fm->max_pool_size > UBI_FM_MAX_POOL_SIZE ||
	    fm->max_pool_size < 0) {
		ubi_err("bad maximal pool size: %i", fm->max_pool_size);
		goto fail_bad;
	}

	if (fm->max_wl_pool_size > UBI_FM_MAX_POOL_SIZE ||
	    fm->max_wl_pool_size < 0) {
		ubi_err("bad maximal WL pool size: %i", fm->max_wl_pool_size);
		goto fail_bad;
	}

	/* read EC values from free list */
	for (i = 0; i < be32_to_cpu(fmhdr->free_peb_count); i++) {
		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fmec);
		if (fm_pos >= fm_size)
			goto fail_bad;
	}

	/* read EC values from used list */
	for (i = 0; i < be32_to_cpu(fmhdr->used_peb_count); i++) {
		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fmec);
		if (fm_pos >= fm_size)
			goto fail_bad;

		generic_set_bit(be32_to_cpu(fmec->pnum), ubi->fm_used);
	}

	/* read EC values from scrub list */
	for (i = 0; i < be32_to_cpu(fmhdr->scrub_peb_count); i++) {
		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fmec);
		if (fm_pos >= fm_size)
			goto fail_bad;
	}

	/* read EC values from erase list */
	for (i = 0; i < be32_to_cpu(fmhdr->erase_peb_count); i++) {
		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fmec);
		if (fm_pos >= fm_size)
			goto fail_bad;
	}

	/* Iterate over all volumes and read their EBA table */
	for (i = 0; i < be32_to_cpu(fmhdr->vol_count); i++) {
		u32 vol_id, vol_type, used, reserved;

		fmvhdr = (struct ubi_fm_volhdr *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fmvhdr);
		if (fm_pos >= fm_size)
			goto fail_bad;

		if (be32_to_cpu(fmvhdr->magic) != UBI_FM_VHDR_MAGIC) {
			ubi_err("bad fastmap vol header magic: 0x%x, " \
				"expected: 0x%x",
				be32_to_cpu(fmvhdr->magic), UBI_FM_VHDR_MAGIC);
			goto fail_bad;
		}

		vol_id = be32_to_cpu(fmvhdr->vol_id);
		vol_type = fmvhdr->vol_type;
		used = be32_to_cpu(fmvhdr->used_ebs);

		fm_eba = (struct ubi_fm_eba *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fm_eba);
		fm_pos += (sizeof(__be32) * be32_to_cpu(fm_eba->reserved_pebs));
		if (fm_pos >= fm_size)
			goto fail_bad;

		if (be32_to_cpu(fm_eba->magic) != UBI_FM_EBA_MAGIC) {
			ubi_err("bad fastmap EBA header magic: 0x%x, " \
				"expected: 0x%x",
				be32_to_cpu(fm_eba->magic), UBI_FM_EBA_MAGIC);
			goto fail_bad;
		}

		reserved = be32_to_cpu(fm_eba->reserved_pebs);
		ubi_dbg("FA: vol %u used %u res: %u", vol_id, used, reserved);
		for (j = 0; j < reserved; j++) {
			int pnum = be32_to_cpu(fm_eba->pnum[j]);

			if ((int)be32_to_cpu(fm_eba->pnum[j]) < 0)
				continue;

			if (!__test_and_clear_bit(pnum, ubi->fm_used))
				continue;

			/*
			 * We only handle static volumes so used_ebs
			 * needs to be handed in. And we do not assign
			 * the reserved blocks
			 */
			if (j >= used)
				continue;

			ret = assign_aeb_to_av(ubi, pnum, j, vol_id,
					       vol_type, used);
			if (!ret)
				continue;

			/*
			 * Nasty: The fastmap claims that the volume
			 * has one block more than it, but that block
			 * is always empty and the other blocks have
			 * the correct number of total LEBs in the
			 * headers. Deal with it.
			 */
			if (ret != UBI_IO_FF && j != used - 1)
				goto fail_bad;
			ubi_dbg("FA: Vol: %u Ignoring empty LEB %d of %d",
				vol_id, j, used);
		}
	}

	ret = scan_pool(ubi, fmpl1->pebs, pool_size);
	if (ret)
		goto fail;

	ret = scan_pool(ubi, fmpl2->pebs, wl_pool_size);
	if (ret)
		goto fail;

#ifdef CHECKME
	/*
	 * If fastmap is leaking PEBs (must not happen), raise a
	 * fat warning and fall back to scanning mode.
	 * We do this here because in ubi_wl_init() it's too late
	 * and we cannot fall back to scanning.
	 */
	if (WARN_ON(count_fastmap_pebs(ai) != ubi->peb_count -
		    ai->bad_peb_count - fm->used_blocks))
		goto fail_bad;
#endif

	return 0;

fail_bad:
	ret = UBI_BAD_FASTMAP;
fail:
	return ret;
}
Esempio n. 2
0
int main()
{
	int i;
	char ipstr[STRSIZE];
	struct sockaddr_in laddr;
	struct sigaction sa,osa1,osa2;
	sigset_t set,oset;

	/* signal */

	sa.sa_handler = usr2_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sigaction(SIG_NOTIFY,&sa,&osa1);
	/*if error*/

	sa.sa_handler = SIG_IGN;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_NOCLDWAIT;
	sigaction(SIGCHLD,&sa,&osa2);
	/*if error*/

	sigemptyset(&set);
	sigaddset(&set,SIG_NOTIFY);
	sigprocmask(SIG_BLOCK,&set,&oset);


	/* init */

	serverpool = mmap(NULL,sizeof(struct server_st)*MAXCLIENT,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
	if(serverpool == MAP_FAILED)
	{
		perror("mmap()");
		exit(1);
	}

	for(i = 0 ; i < MAXCLIENT; i++)
		serverpool[i].pid = -1;


	/* socket */

	sd = socket(AF_INET,SOCK_STREAM,0/*IPPROTO_TCP,IPPROTO_SCTP*/);
	if(sd < 0)
	{
		perror("socket()");
		exit(1);
	}

	int val = 1;
	if(setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val)) < 0)
	{
		perror("setsockopt()");
		exit(1);
	}

	laddr.sin_family = AF_INET;
	laddr.sin_port = htons(atoi(SERVERPORT));
	inet_pton(AF_INET,"0.0.0.0",&laddr.sin_addr);	
	if(bind(sd,(void *)&laddr,sizeof(laddr)) < 0)
	{
		perror("bind()");
		exit(1);
	}

	if(listen(sd,200) < 0)
	{
		perror("listen()");
		exit(1);
	}


	for(i = 0 ; i < MINSPARESERVER; i++)
		add_1_server();

	while(1)
	{
		sigsuspend(&oset);

		scan_pool();

		if(idle_count > MAXSPARESERVER)
		{
			for(i = 0 ; i < idle_count-MAXSPARESERVER; i++)
				del_1_server();
		}
		else if(idle_count < MINSPARESERVER)
		{
			for(i = 0 ; i < MINSPARESERVER-idle_count; i++)
				add_1_server();
		}

		for(i = 0 ; i < MAXCLIENT; i++)
		{
			if(serverpool[i].pid == -1)
				putchar('n');
			else 
			{
				if(serverpool[i].state == STATE_IDLE)
					putchar('.');
				else
					putchar('x');
			}
		}
		printf("\n");
	}


	/*free  destroy*/
	sigprocmask(SIG_SETMASK,&oset,NULL);
	exit(0);

}