Esempio n. 1
0
int gtcm_cn_acpt(omi_conn_ll *cll, int now)		/* now --> current time in seconds */
{
	int		i;
	omi_conn	*cptr;
	omi_fd		fd;
	int		rc;
	char 		*tmp_time;

#ifdef BSD_TCP
	GTM_SOCKLEN_TYPE	sln;
	struct sockaddr_storage	sas;
	int			optsize;
	const boolean_t		keepalive = TRUE;

	/*  Accept the connection from the network layer */
	sln = SIZEOF(sas);
	if ((fd = accept(cll->nve, (struct sockaddr *)&sas, (GTM_SOCKLEN_TYPE *)&sln)) < 0)
		return -1;
#endif				/* defined(BSD_TCP) */

	/*  Build the client data structure */
	if (!(cptr = (omi_conn *)malloc(SIZEOF(omi_conn))) || !(cptr->buff = (char *)malloc(OMI_BUFSIZ)))
	{
		if (cptr)
			free(cptr);
		CLOSEFILE_RESET(fd, rc);	/* resets "fd" to FD_INVALID */
		return -1;
	}
	/*  Initialize the connection structure */
	cptr->next  = (omi_conn *)0;
	cptr->fd    = fd;
	cptr->ping_cnt = 0;
	cptr->timeout = now + conn_timeout;
	cptr->bsiz  = OMI_BUFSIZ;
	cptr->bptr  = cptr->buff;
	cptr->xptr  = (char *)0;
	cptr->blen  = 0;
	cptr->exts  = 0;
	cptr->state = OMI_ST_DISC;
	cptr->ga    = (ga_struct *)0; /* struct gd_addr_struct */
	cptr->of = (oof_struct *) malloc(SIZEOF(struct rc_oflow));
	memset(cptr->of, 0, SIZEOF(struct rc_oflow));
	cptr->pklog = FD_INVALID;
	/*  Initialize the statistics */
	memcpy(&cptr->stats.sas, &sas, sln);
	cptr->stats.ai.ai_addr = (struct sockaddr *)&cptr->stats.sas;
	cptr->stats.ai.ai_addrlen = sln;
	cptr->stats.bytes_recv = 0;
	cptr->stats.bytes_send = 0;
	cptr->stats.start      = time((time_t *)0);
	for (i = 0; i < OMI_OP_MAX; i++)
		cptr->stats.xact[i] = 0;
	for (i = 0; i < OMI_ER_MAX; i++)
		cptr->stats.errs[i] = 0;

	/* if we only allowing one connection per internet address, close any existing ones with the same addr. */
	if (one_conn_per_inaddr)
	{
		omi_conn	*this, *prev;

		for (prev = NULL, this = cll->head; this; prev = this, this = this->next)
		{
			if (0 == memcmp((sockaddr_ptr)(&this->stats.sas), (sockaddr_ptr)&sas, sln))
			{
				if (cll->tail == this)
				    cll->tail = cptr;
				if (prev)
				    prev->next = cptr;
				else
				    cll->head = cptr;
				cptr->next = this->next;
				OMI_DBG_STMP;
				OMI_DBG((omi_debug, "%s: dropping old connection to %s\n",
					SRVR_NAME, gtcm_hname(&cptr->stats.ai)));
				gtcm_cn_disc(this, cll);
				break;
			}
		}
		/* not found - add to the end of the list */
		if (!this)
		{
			if (cll->tail)
			{
				cll->tail->next = cptr;
				cll->tail       = cptr;
			} else
				cll->head = cll->tail = cptr;
		}
	} else
	{
		/*  Insert the client into the list of connections */
		if (cll->tail)
		{
			cll->tail->next = cptr;
			cll->tail       = cptr;
		} else
			cll->head = cll->tail = cptr;
	}
	cptr->stats.id = ++cll->stats.conn;

	DEBUG_ONLY(
		if (omi_pklog)
		{
			int		errno_save;
			char		pklog[1024];

			(void)SPRINTF(pklog, "%s.%04d", omi_pklog, cptr->stats.id);
			if (INV_FD_P((cptr->pklog = OPEN3(pklog, O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, 0644))))
			{
				errno_save = errno;
				OMI_DBG_STMP;
				OMI_DBG((omi_debug, "%s: unable to open packet log \"%s\"\n\t%s\n",
					SRVR_NAME, pklog, STRERROR(errno_save)));
			}
		}
	)
Esempio n. 2
0
void iob_read(BFILE *bf, char *buf, int nbytes)
{
	int4	nread, nreread;
	int	rc;

	error_def(ERR_IOEOF);

	if (bf->write_mode)
	{
		iob_flush(bf);
		bf->write_mode = FALSE;
	}

#ifdef DEBUG_IOB
	PRINTF("iob_read:\tiob_read(%x, %x, %d), bf->remaining = %d\n",
	       bf, buf, nbytes, bf->remaining);
#endif

	while (nbytes > bf->remaining)
	{
		/* copy bytes remaining in buffer */
		memcpy(buf, bf->bptr, bf->remaining);
		nbytes -= bf->remaining;
		buf += bf->remaining;

		/* refill */
		DOREADRL(bf->fd, bf->buf, bf->bufsiz, nread);
#ifdef DEBUG_IOB
		PRINTF("iob_read:\t\tread(%d, %x, %d) = %d\n", bf->fd, bf->buf,
		       bf->bufsiz, nread);
#endif
		bf->bptr = bf->buf;
		bf->remaining = nread;

		if (nread == -1)
		{
			rts_error(VARLSTCNT(1) errno);
			return;
		}
		else if (nread == 0 || nread % bf->blksiz)
		{
			CLOSEFILE_RESET(bf->fd, rc);	/* resets "bf->fd" to FD_INVALID */
			rts_error(VARLSTCNT(1) ERR_IOEOF);

			/* if we continued from here, assume that this is a magnetic
			   tape and we have loaded the next volume. Re-open and
			   finish the read operation.
			   */
			while (FD_INVALID == (bf->fd = OPEN3(bf->path,bf->oflag,bf->mode)))
				rts_error(VARLSTCNT(1) errno);

			DOREADRL(bf->fd, bf->buf + nread, bf->bufsiz - nread, nreread);
#ifdef DEBUG_IOB
			PRINTF("iob_read:\t\tread(%d, %x, %d) = %d\n", bf->fd, bf->buf,
			       bf->bufsiz, nread);
#endif
			if (nreread < bf->bufsiz - nread)
			{
				rts_error(VARLSTCNT(1) errno);
				return;
			}
			bf->remaining = nread;
		}
	}

	memcpy(buf, bf->bptr, nbytes);
	bf->bptr += nbytes;
	bf->remaining -= nbytes;
}
Esempio n. 3
0
unsigned char mu_cre_file(void)
{
	char		*cc = NULL, path[MAX_FBUFF + 1], errbuff[512];
	unsigned char	buff[DISK_BLOCK_SIZE];
	int		fd = -1, i, lower, upper, status, padded_len, padded_vbn, norm_vbn;
	uint4		raw_dev_size;		/* size of a raw device, in bytes */
	int4		blocks_for_create, blocks_for_extension, save_errno;
	GTM_BAVAIL_TYPE	avail_blocks;
	file_control	fc;
	mstr		file;
	parse_blk	pblk;
	unix_db_info	udi_struct, *udi;
	char		*fgets_res;
	gd_segment	*seg;

	error_def(ERR_NOSPACECRE);
	error_def(ERR_LOWSPACECRE);

	assert((-(sizeof(uint4) * 2) & sizeof(sgmnt_data)) == sizeof(sgmnt_data));
	cs_addrs = &udi_struct.s_addrs;
	cs_data = (sgmnt_data_ptr_t)NULL;	/* for CLEANUP */
	memset(&pblk, 0, sizeof(pblk));
	pblk.fop = (F_SYNTAXO | F_PARNODE);
	pblk.buffer = path;
	pblk.buff_size = MAX_FBUFF;
	file.addr = (char*)gv_cur_region->dyn.addr->fname;
	file.len = gv_cur_region->dyn.addr->fname_len;
	strncpy(path,file.addr,file.len);
	*(path+file.len) = '\0';
	if (is_raw_dev(path))
	{	/* do not use a default extension for raw device files */
		pblk.def1_buf = DEF_NODBEXT;
		pblk.def1_size = sizeof(DEF_NODBEXT) - 1;
	} else
	{
		pblk.def1_buf = DEF_DBEXT;
		pblk.def1_size = sizeof(DEF_DBEXT) - 1;
	}
	if (1 != (parse_file(&file, &pblk) & 1))
	{
		PRINTF("Error translating filename %s.\n", gv_cur_region->dyn.addr->fname);
		return EXIT_ERR;
	}
	path[pblk.b_esl] = 0;
	if (pblk.fnb & F_HAS_NODE)
	{	/* Remote node specification given */
		assert(pblk.b_node);
		PRINTF("Database file for region %s not created; cannot create across network.\n", path);
		return EXIT_WRN;
	}
	udi = &udi_struct;
	udi->raw = is_raw_dev(pblk.l_dir);
	if (udi->raw)
	{
		fd = OPEN(pblk.l_dir,O_EXCL | O_RDWR);
		if (-1 == fd)
		{
			SPRINTF_AND_PERROR("Error opening file %s\n");
			return EXIT_ERR;
		}
		if (-1 != (status = (ssize_t)lseek(fd, 0, SEEK_SET)))
		{
			DOREADRC(fd, buff, sizeof(buff), status);
		} else
			status = errno;
		if (0 != status)
		{
			SPRINTF_AND_PERROR("Error reading header for file %s\n");
			return EXIT_ERR;
		}
		if (!memcmp(buff, GDS_LABEL, STR_LIT_LEN(GDS_LABEL)))
		{
			char rsp[80];
			PRINTF("Database already exists on device %s\n", path);
			PRINTF("Do you wish to re-initialize (all current data will be lost) [y/n] ? ");
			FGETS(rsp, 79, stdin, fgets_res);
			if ('y' != *rsp)
				return EXIT_NRM;
		}
		PRINTF("Determining size of raw device...\n");
		for(i = 1; read(fd, buff, sizeof(buff)) == sizeof(buff);)
		{
			i *= 2;
			lseek(fd, (off_t)i * BUFSIZ, SEEK_SET);
		}

		lower = i / 2;
		upper = i;
		while ((lower + upper) / 2 != lower)
		{
			i = (lower + upper) / 2;
			lseek(fd, (off_t)i * BUFSIZ, SEEK_SET);
 			if (read(fd, buff, sizeof(buff)) == sizeof(buff))
				lower = i;
			else
				upper = i;
		}
		raw_dev_size = i * BUFSIZ;
	} else
	{
		fd = OPEN3(pblk.l_dir, O_CREAT | O_EXCL | O_RDWR, 0600);
		if (-1 == fd)
		{
			SPRINTF_AND_PERROR("Error opening file %s\n");
			return EXIT_ERR;
		}
		if (0 != (save_errno = disk_block_available(fd, &avail_blocks, FALSE)))
		{
			errno = save_errno;
			SPRINTF_AND_PERROR("Error checking available disk space for %s\n");
			CLEANUP(EXIT_ERR);
			return EXIT_ERR;
		}
		seg = gv_cur_region->dyn.addr;

		/* blocks_for_create is in the unit of DISK_BLOCK_SIZE */
		blocks_for_create = DIVIDE_ROUND_UP(sizeof(sgmnt_data), DISK_BLOCK_SIZE) + 1 +
					(seg->blk_size / DISK_BLOCK_SIZE *
					 ((DIVIDE_ROUND_UP(seg->allocation, BLKS_PER_LMAP - 1)) + seg->allocation));
		if ((uint4)avail_blocks < blocks_for_create)
		{
			gtm_putmsg(VARLSTCNT(6) ERR_NOSPACECRE, 4, LEN_AND_STR(path), blocks_for_create, (uint4)avail_blocks);
			send_msg(VARLSTCNT(6) ERR_NOSPACECRE, 4, LEN_AND_STR(path), blocks_for_create, (uint4)avail_blocks);
			CLEANUP(EXIT_ERR);
			return EXIT_ERR;
		}
		blocks_for_extension = (seg->blk_size / DISK_BLOCK_SIZE *
					((DIVIDE_ROUND_UP(EXTEND_WARNING_FACTOR * seg->ext_blk_count, BLKS_PER_LMAP - 1))
				 	  + EXTEND_WARNING_FACTOR * seg->ext_blk_count));
		if ((uint4)(avail_blocks - blocks_for_create) < blocks_for_extension)
		{
			gtm_putmsg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, LEN_AND_STR(path), EXTEND_WARNING_FACTOR, blocks_for_extension,
					DISK_BLOCK_SIZE, (uint4)(avail_blocks - blocks_for_create));
			send_msg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, LEN_AND_STR(path), EXTEND_WARNING_FACTOR, blocks_for_extension,
					DISK_BLOCK_SIZE, (uint4)(avail_blocks - blocks_for_create));
		}
	}
	gv_cur_region->dyn.addr->file_cntl = &fc;
	fc.file_info = (void*)&udi_struct;
	udi->fd = fd;
	cs_data = (sgmnt_data_ptr_t)malloc(sizeof(sgmnt_data));
	memset(cs_data, 0, sizeof(*cs_data));
	cs_data->createinprogress = TRUE;
	cs_data->semid = INVALID_SEMID;
	cs_data->shmid = INVALID_SHMID;
	/* We want our datablocks to start on what would be a block boundary within the file so pad the fileheader
	   if necessary to make this happen.
	*/
	padded_len = ROUND_UP(sizeof(sgmnt_data), BLK_SIZE);
	padded_vbn = DIVIDE_ROUND_UP(padded_len, DISK_BLOCK_SIZE) + 1;
	norm_vbn = DIVIDE_ROUND_UP(sizeof(sgmnt_data), DISK_BLOCK_SIZE) + 1;
	cs_data->start_vbn = padded_vbn;
	cs_data->free_space += (padded_vbn - norm_vbn) * DISK_BLOCK_SIZE;
	cs_data->acc_meth = gv_cur_region->dyn.addr->acc_meth;
	if (udi->raw)
	{
		/* calculate total blocks, reduce to make room for the
		 * database header (size rounded up to a block), then
		 * make into a multiple of BLKS_PER_LMAP to have a complete bitmap
		 * for each set of blocks.
		 */
		cs_data->trans_hist.total_blks = raw_dev_size - ROUND_UP(sizeof(sgmnt_data), DISK_BLOCK_SIZE);
		cs_data->trans_hist.total_blks /= (uint4)(((gd_segment *)gv_cur_region->dyn.addr)->blk_size);
		if (0 == (cs_data->trans_hist.total_blks - DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, BLKS_PER_LMAP - 1)
			  % (BLKS_PER_LMAP - 1)))
			cs_data->trans_hist.total_blks -= 1;	/* don't create a bitmap with no data blocks */
		cs_data->extension_size = 0;
		PRINTF("Raw device size is %dK, %d GDS blocks\n",
		raw_dev_size / 1000,
		cs_data->trans_hist.total_blks);
	} else
	{
		cs_data->trans_hist.total_blks = gv_cur_region->dyn.addr->allocation;
		/* There are (bplmap - 1) non-bitmap blocks per bitmap, so add (bplmap - 2) to number of non-bitmap blocks
		 * and divide by (bplmap - 1) to get total number of bitmaps for expanded database. (must round up in this
		 * manner as every non-bitmap block must have an associated bitmap)
		 */
		cs_data->trans_hist.total_blks += DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, BLKS_PER_LMAP - 1);
		cs_data->extension_size = gv_cur_region->dyn.addr->ext_blk_count;
	}
	mucregini(cs_data->trans_hist.total_blks);
	cs_data->createinprogress = FALSE;
	LSEEKWRITE(udi->fd, 0, cs_data, sizeof(sgmnt_data), status);
	if (0 != status)
	{
		SPRINTF_AND_PERROR("Error writing out header for file %s\n");
		CLEANUP(EXIT_ERR);
		return EXIT_ERR;
	}
	cc = (char*)malloc(DISK_BLOCK_SIZE);
	memset(cc, 0, DISK_BLOCK_SIZE);
	LSEEKWRITE(udi->fd,
		   (cs_data->start_vbn - 1) * DISK_BLOCK_SIZE + ((off_t)(cs_data->trans_hist.total_blks) * cs_data->blk_size),
		   cc,
		   DISK_BLOCK_SIZE,
		   status);
	if (0 != status)
	{
		SPRINTF_AND_PERROR("Error writing out end of file %s\n");
		CLEANUP(EXIT_ERR);
		return EXIT_ERR;
	}
	if ((!udi->raw) && (-1 == CHMOD(pblk.l_dir, 0666)))
	{
		SPRINTF_AND_PERROR("Error changing file mode on file %s\n");
		CLEANUP(EXIT_WRN);
		return EXIT_WRN;
	}
	CLEANUP(EXIT_NRM);
	PRINTF("Created file %s\n", path);
	return EXIT_NRM;
}