Пример #1
0
int startup()
{
  unsigned char c;
  int i,ack,ret;

  dsyslog(LOG_INFO,"startup...\n");
  c = X10_PL_START;
  for (i = 0; i < retries; i++) {
    dsyslog(LOG_INFO,"sending 0x%x\n",X10_PL_START);
    ret = write(serial,&c,1);
    ack = waitforack(timeout);
    if (ack == 1)
      break;
    else if (ack != -1)
      return -1;
  }
  if (i > retries){
    dsyslog(LOG_INFO,"Error:  timeout exceeded for startup\n");
    return -1;
  }
  return 0;
}
Пример #2
0
/* 
 * -- _csmap
 * 
 * this function provides an interface similar to mmap. 
 * it maps in memory a region of the file. before doing so, informs 
 * the server of this intentions and makes sure that it can do it. 
 *  
 * the acknowledgement from the server carries two pieces of information: 
 *   . offset, that is set to the start offset of the file that 
 *     contains the block.
 *   . size, that indicates the size of the region that can be memory mapped. 
 *     (different only if the region overlaps multiple files). 
 * 
 * this function returns a pointer to the memory mapped region and the size
 * of the region. 
 *
 * _csmap is the back-end for csmap, csreadp, csseek. 
 * 
 */
static void * 
_csmap(int fd, off_t ofs, ssize_t * sz, int method) 
{
    csfile_t * cf;
    csmsg_t out, in;
    int flags;
    int diff;

    cf = files[fd];

    /* Package the request and send it to the server */
    out.id = cf->id;
    if (method == S_REGION) {
	out.arg = 0; 
	out.type = method;
	out.size = *sz;
	out.ofs = ofs; /* the map offset */
    } else {	/* all the seek variants */
	out.type = S_SEEK;
	out.arg = CS_SEEK_FILE_NEXT;
	out.size = 0; 
	out.ofs = 0; 
    }

    /* send the request out */
    if (write(cf->sd, &out, sizeof(out)) < 0) {
	logmsg(LOGWARN, "message to storage: %s\n", strerror(errno)); 
	*sz = -1;
	return NULL;
    }

    /* block waiting for the acknowledgment */
    waitforack(cf->sd, &in);

    switch (in.type) { 
    case S_ERROR: 
	logmsg(LOGWARN, "csmap error in %s: %s\n", cf->name, strerror(in.arg));
	errno = in.arg;
	*sz = -1;
	return NULL;

    case S_ACK: 
	/* 
	 * The server acknowledged our request,
	 * unmap the current block (both for csmap and csseek)
	 */
	if (cf->addr)
	    munmap(cf->addr, cf->size);

	if (method == S_REGION) {
	    /* 
	     * A zero sized block indicates end-of-bytestream. If so, close
	     * the current file and return an EOF as well.
	     */
	    if (in.size == 0) { 
		close(cf->fd);
		*sz = 0;
		return NULL;
	    }
	} else {	/* seek variants */
	    /* the current file is not valid anymore */
	    close(cf->fd);
	    cf->off_file = in.ofs;
	    cf->fd = -1;
	    *sz = (size_t)in.ofs;	/* return value */
	    return NULL;		/* we are done */
	}
	break;

    default: 
	panic("unknown msg type %d from storage\n", in.type);
	break;
    }

    if ((ssize_t)in.size == -1)
	panic("unexpected return from storage process");

    /*
     * now check if the requested block is in the same file (i.e., 
     * the server replied with an offset that is the first offset of 
     * the currently open file. if not, close the current file and 
     * open a new one. 
     */
    if (cf->fd < 0 || in.ofs != cf->off_file) {
	char * nm;

	if (cf->fd >= 0)
	    close(cf->fd);

#ifdef linux
	flags = (cf->mode == CS_READER)? O_RDWR : O_RDWR|O_APPEND; 
#else
	flags = (cf->mode == CS_READER)? O_RDONLY : O_WRONLY|O_APPEND; 
#endif
	asprintf(&nm, "%s/%016llx", cf->name, in.ofs); 
	cf->fd = open(nm, flags, 0666);
	if (cf->fd < 0)
	    panic("opening file %s acked! (%s)\n", nm, strerror(errno));
	cf->off_file = in.ofs;
	free(nm);
    } 
	   
    /*
     * mmap the new block 
     */
    flags = (cf->mode == CS_READER)? PROT_READ : PROT_WRITE; 
    cf->offset = ofs; 
    cf->size = *sz = in.size;

    /* 
     * align the mmap to the memory pagesize 
     */
    diff = (cf->offset - cf->off_file) % getpagesize();
    cf->offset -= diff; 
    cf->size += diff; 

    cf->addr = mmap(0, cf->size, flags, MAP_NOSYNC|MAP_SHARED, 
	cf->fd, cf->offset - cf->off_file);
    if (cf->addr == MAP_FAILED || cf->addr == NULL)
        panic("mmap got NULL (%s)\n", strerror(errno)); 

    assert(cf->addr + diff != NULL);

    return (cf->addr + diff);
}
Пример #3
0
/* 
 * -- csopen
 * 
 * csopen() opens a file managed by the storage process. It 
 * uses the unix socket to communicate its intentions. The function 
 * returns an integer used as file descriptor, or -1 on error.
 * Obviously the descriptor is not select()-able.
 */ 
int
csopen(const char * name, int mode, off_t size, int sd) 
{ 
    csfile_t * cf;
    csmsg_t m;
    int fd; 

    if (mode != CS_READER && mode != CS_WRITER) {
	logmsg(LOGWARN, "csopen: [%s] bad mode %d\n", name, mode);
	return -1;
    }

    logmsg(LOGSTORAGE, "csopen: [%s] %s\n", name,
	mode == CS_READER ? "CS_READER" : "CS_WRITER" );

    /* look for an empty file descriptor */
    for (fd = 0; fd < CS_MAXCLIENTS && files[fd] != NULL; fd++)
	;

    if (fd == CS_MAXCLIENTS) {
	logmsg(LOGWARN, "Too many open files, cannot open %s\n", name); 
	return -1;
    } 

    /* 
     * file descriptor found, prepare and send the request 
     * message to the storage process
     */
    bzero(&m, sizeof(m));
    m.type = S_OPEN;
    m.id = 0;
    m.arg = mode;
    m.size = size;
    strncpy(m.name, name, FILENAME_MAX); 

    if (write(sd, (char *) &m, sizeof(m)) < 0) 
	panic("sending message to storage: %s\n", strerror(errno)); 

    /* wait for the acknowledgment */
    waitforack(sd, &m);

    if (m.type == S_ERROR) {
	logmsg(LOGWARN, "error opening file %s: %s\n", name, strerror(m.arg));
	return -1;
    }

    /* 
     * allocate a new file descriptor and initialize it with 
     * the information in the message. 
     */
    cf = safe_calloc(1, sizeof(csfile_t)); 
    cf->fd = -1; 
    cf->sd = sd;
    cf->name = strdup(name);
    cf->mode = mode;
    cf->id = m.id;
    cf->off_file = m.ofs;  

    /* store current offset. m.size is set to 0 by the server if this client
     * is a reader. otherwise it is equal to the size of the bytestream so 
     * that writes are append only. 
     */
    cf->offset = m.ofs + m.size; 

    files[fd] = cf;
    return fd; 
}