Exemplo n.º 1
0
void *read_sf_packet(int fd, int *len)
/* Effects: reads packet from serial forwarder on file descriptor fd
   Returns: the packet read (in newly allocated memory), and *len is
     set to the packet length, or NULL for failure
*/
{
  unsigned char l;
  void *packet;

  if (saferead(fd, &l, 1) != 1)
    return NULL;

  packet = malloc(l);
  if (!packet)
    return NULL;

  if (saferead(fd, packet, l) != l)
    {
      free(packet);
      return NULL;
    }
  *len = l;
  
  return packet;
}
Exemplo n.º 2
0
static int
SELinuxInitialize(void)
{
    char *ptr = NULL;
    int fd = 0;

    fd = open(selinux_virtual_domain_context_path(), O_RDONLY);
    if (fd < 0) {
        virReportSystemError(errno,
                             _("cannot open SELinux virtual domain context file '%s'"),
                             selinux_virtual_domain_context_path());
        return -1;
    }

    if (saferead(fd, default_domain_context, sizeof(default_domain_context)) < 0) {
        virReportSystemError(errno,
                             _("cannot read SELinux virtual domain context file %s"),
                             selinux_virtual_domain_context_path());
        VIR_FORCE_CLOSE(fd);
        return -1;
    }
    VIR_FORCE_CLOSE(fd);

    ptr = strchrnul(default_domain_context, '\n');
    *ptr = '\0';

    if ((fd = open(selinux_virtual_image_context_path(), O_RDONLY)) < 0) {
        virReportSystemError(errno,
                             _("cannot open SELinux virtual image context file %s"),
                             selinux_virtual_image_context_path());
        return -1;
    }

    if (saferead(fd, default_image_context, sizeof(default_image_context)) < 0) {
        virReportSystemError(errno,
                             _("cannot read SELinux virtual image context file %s"),
                             selinux_virtual_image_context_path());
        VIR_FORCE_CLOSE(fd);
        return -1;
    }
    VIR_FORCE_CLOSE(fd);

    ptr = strchrnul(default_image_context, '\n');
    if (*ptr == '\n') {
        *ptr = '\0';
        strcpy(default_content_context, ptr+1);
        ptr = strchrnul(default_content_context, '\n');
        if (*ptr == '\n')
            *ptr = '\0';
    }
    return 0;
}
Exemplo n.º 3
0
static uint32_t
virNetDevVPortProfileGetLldpadPid(void)
{
    int fd;
    uint32_t pid = 0;

    fd = open(LLDPAD_PID_FILE, O_RDONLY);
    if (fd >= 0) {
        char buffer[10];

        if (saferead(fd, buffer, sizeof(buffer)) <= sizeof(buffer)) {
            unsigned int res;
            char *endptr;

            if (virStrToLong_ui(buffer, &endptr, 10, &res) == 0
                && (*endptr == '\0' || c_isspace(*endptr))
                && res != 0) {
                pid = res;
            } else {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("error parsing pid of lldpad"));
            }
        }
    } else {
        virReportSystemError(errno,
                             _("Error opening file %s"), LLDPAD_PID_FILE);
    }

    VIR_FORCE_CLOSE(fd);

    return pid;
}
Exemplo n.º 4
0
/**
 * lxcFdForward:
 * @readFd: file descriptor to read
 * @writeFd: file desriptor to write
 *
 * Reads 1 byte of data from readFd and writes to writeFd.
 *
 * Returns 0 on success, EAGAIN if returned on read, or -1 in case of error
 */
static int lxcFdForward(int readFd, int writeFd)
{
    int rc = -1;
    char buf[2];

    if (1 != (saferead(readFd, buf, 1))) {
        if (EAGAIN == errno) {
            rc = EAGAIN;
            goto cleanup;
        }

        virReportSystemError(errno,
                             _("read of fd %d failed"),
                             readFd);
        goto cleanup;
    }

    if (1 != (safewrite(writeFd, buf, 1))) {
        virReportSystemError(errno,
                             _("write to fd %d failed"),
                             writeFd);
        goto cleanup;
    }

    rc = 0;

cleanup:
    return rc;
}
Exemplo n.º 5
0
static int
getDMISystemUUID(char *uuid, int len)
{
    unsigned int i = 0;
    const char *paths[] = {
        "/sys/devices/virtual/dmi/id/product_uuid",
        "/sys/class/dmi/id/product_uuid",
        NULL
    };

    while (paths[i]) {
        int fd = open(paths[i], O_RDONLY);
        if (fd >= 0) {
            if (saferead(fd, uuid, len - 1) == len - 1) {
                uuid[len - 1] = '\0';
                VIR_FORCE_CLOSE(fd);
                return 0;
            }
            VIR_FORCE_CLOSE(fd);
        }
        i++;
    }

    return -1;
}
Exemplo n.º 6
0
static int
cmdVolUploadSource(virStreamPtr st ATTRIBUTE_UNUSED,
                   char *bytes, size_t nbytes, void *opaque)
{
    int *fd = opaque;

    return saferead(*fd, bytes, nbytes);
}
Exemplo n.º 7
0
int init_sf_source(int fd)
/* Effects: Checks that fd is following the serial forwarder protocol
     Sends 'platform' for protocol version '!', and sets 'platform' to
     the received platform value.
   Modifies: platform
   Returns: 0 if it is, -1 otherwise
 */
{
  char check[2], us[2];
  int version;
  unsigned char nonce[4];
  /* Indicate version and check if serial forwarder on the other end */
  us[0] = 'T'; us[1] = '!';
  if (safewrite(fd, us, 2) != 2 ||
      saferead(fd, check, 2) != 2 ||
      check[0] != 'T' || check[1] < ' ')
    return -1;

  version = check[1];
  if (us[1] < version)
    version = us[1];

  switch (version)
    {
    case ' ': break;
    case '!': 
      nonce[0] = platform;
      nonce[1] = platform >>  8;
      nonce[2] = platform >> 16;
      nonce[3] = platform >> 24;
      if (safewrite(fd, nonce, 4) != 4)
	return -1;
      if (saferead(fd, nonce, 4) != 4)
	return -1;
      //Unlike the more general SFProtocol.java this piece of code always knows what platform it is connected to; just   drop the preferred platform from the client
//platform = nonce[0] | nonce[1] << 8 | nonce[2] << 16 | nonce[3] << 24;
      break;
    }

  return 0;
}
Exemplo n.º 8
0
static int
virFDStreamClose(virStreamPtr st)
{
    struct virFDStreamData *fdst = st->privateData;
    int ret;

    VIR_DEBUG("st=%p", st);

    if (!fdst)
        return 0;

    virMutexLock(&fdst->lock);

    ret = VIR_CLOSE(fdst->fd);
    if (fdst->cmd) {
        char buf[1024];
        ssize_t len;
        int status;
        if ((len = saferead(fdst->errfd, buf, sizeof(buf)-1)) < 0)
            buf[0] = '\0';
        else
            buf[len] = '\0';

        if (virCommandWait(fdst->cmd, &status) < 0) {
            ret = -1;
        } else if (status != 0) {
            if (buf[0] == '\0') {
                if (WIFEXITED(status)) {
                    streamsReportError(VIR_ERR_INTERNAL_ERROR,
                                       _("I/O helper exited with status %d"),
                                       WEXITSTATUS(status));
                } else {
                    streamsReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                       _("I/O helper exited abnormally"));
                }
            } else {
                streamsReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   buf);
            }
            ret = -1;
        }
        virCommandFree(fdst->cmd);
    }

    st->privateData = NULL;

    virMutexUnlock(&fdst->lock);
    virMutexDestroy(&fdst->lock);
    VIR_FREE(fdst);

    return ret;
}
Exemplo n.º 9
0
static int
virFDStreamCloseCommand(struct virFDStreamData *fdst, bool streamAbort)
{
    char buf[1024];
    ssize_t len;
    int status;
    int ret = -1;

    if (!fdst->cmd)
        return 0;

    if ((len = saferead(fdst->errfd, buf, sizeof(buf)-1)) < 0)
        buf[0] = '\0';
    else
        buf[len] = '\0';

    virCommandRawStatus(fdst->cmd);
    if (virCommandWait(fdst->cmd, &status) < 0)
        goto cleanup;

    if (status != 0) {
        if (buf[0] != '\0') {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s", buf);
        } else if (WIFSIGNALED(status) && WTERMSIG(status) == SIGPIPE) {
            if (streamAbort) {
                /* Explicit abort request means the caller doesn't care
                   if there's data left over, so skip the error */
                goto out;
            }

            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("I/O helper exited "
                             "before all data was processed"));
        } else {
            char *str = virProcessTranslateStatus(status);
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("I/O helper exited with %s"),
                           NULLSTR(str));
            VIR_FREE(str);
        }
        goto cleanup;
    }

 out:
    ret = 0;
 cleanup:
    virCommandFree(fdst->cmd);
    fdst->cmd = NULL;
    return ret;
}
Exemplo n.º 10
0
void l_eval_path(const char *filename, LClosure *closure) {
  FILE *fp = fopen(filename, "r");
  if(fp == NULL) {
    printf("An error occurred while opening the file %s.\n", filename);
    exit(1);
  }

  LValue* f = l_value_new(L_STR_TYPE, closure);
  f->core.str = make_stringbuf((char*)filename);
  l_closure_set(closure, "-filename", f, true);

  stringbuf *source = make_stringbuf("");
  source->str = saferead(fp);

  l_eval(source->str, filename, closure);
}
Exemplo n.º 11
0
static int
pciRead(pciDevice *dev, unsigned pos, uint8_t *buf, unsigned buflen)
{
    memset(buf, 0, buflen);

    if (pciOpenConfig(dev) < 0)
        return -1;

    if (lseek(dev->fd, pos, SEEK_SET) != pos ||
        saferead(dev->fd, buf, buflen) != buflen) {
        char ebuf[1024];
        VIR_WARN("Failed to read from '%s' : %s", dev->path,
                 virStrerror(errno, ebuf, sizeof(ebuf)));
        return -1;
    }
    return 0;
}
Exemplo n.º 12
0
/**
 * lxcContainerWaitForContinue:
 * @control: Control FD from parent
 *
 * This function will wait for the container continue message from the
 * parent process.  It will send this message on the socket pair stored in
 * the vm structure once it has completed the post clone container setup.
 *
 * Returns 0 on success or -1 in case of error
 */
int lxcContainerWaitForContinue(int control)
{
    lxc_message_t msg;
    int readLen;

    readLen = saferead(control, &msg, sizeof(msg));
    if (readLen != sizeof(msg)) {
        if (readLen >= 0)
            errno = EIO;
        return -1;
    }
    if (msg != LXC_CONTINUE_MSG) {
        errno = EINVAL;
        return -1;
    }

    return 0;
}
Exemplo n.º 13
0
/**
 * lxcContainerWaitForContinue:
 * @control: Control FD from parent
 *
 * This function will wait for the container continue message from the
 * parent process.  It will send this message on the socket pair stored in
 * the vm structure once it has completed the post clone container setup.
 *
 * Returns 0 on success or -1 in case of error
 */
static int lxcContainerWaitForContinue(int control)
{
    lxc_message_t msg;
    int readLen;

    readLen = saferead(control, &msg, sizeof(msg));
    if (readLen != sizeof(msg) ||
        msg != LXC_CONTINUE_MSG) {
        virReportSystemError(errno, "%s",
                             _("Failed to read the container continue message"));
        return -1;
    }
    close(control);

    DEBUG0("Received container continue message");

    return 0;
}
Exemplo n.º 14
0
int read_wwn_linux(int host, const char *file, char **wwn)
{
    char *p = NULL;
    int fd = -1, retval = 0;
    char buf[64];

    if (open_wwn_file(LINUX_SYSFS_FC_HOST_PREFIX, host, file, &fd) < 0) {
        goto out;
    }

    memset(buf, 0, sizeof(buf));
    if (saferead(fd, buf, sizeof(buf)) < 0) {
        retval = -1;
        VIR_DEBUG("Failed to read WWN for host%d '%s'",
                  host, file);
        goto out;
    }

    p = strstr(buf, "0x");
    if (p != NULL) {
        p += strlen("0x");
    } else {
        p = buf;
    }

    *wwn = strndup(p, sizeof(buf));
    if (*wwn == NULL) {
        virReportOOMError();
        retval = -1;
        goto out;
    }

    p = strchr(*wwn, '\n');
    if (p != NULL) {
        *p = '\0';
    }

out:
    if (fd != -1) {
        close(fd);
    }
    return retval;
}
Exemplo n.º 15
0
int
virPerfReadEvent(virPerfPtr perf,
                 virPerfEventType type,
                 uint64_t *value)
{
    virPerfEventPtr event = virPerfGetEvent(perf, type);
    if (event == NULL || !event->enabled)
        return -1;

    if (saferead(event->fd, value, sizeof(uint64_t)) < 0) {
        virReportSystemError(errno, "%s",
                             _("Unable to read cache data"));
        return -1;
    }

    if (type == VIR_PERF_EVENT_CMT)
        *value *= event->efields.cmt.scale;

    return 0;
}
Exemplo n.º 16
0
int virPidFileReadPath(const char *path,
                       pid_t *pid)
{
    int fd;
    int rc;
    ssize_t bytes;
    long long pid_value = 0;
    char pidstr[INT_BUFSIZE_BOUND(pid_value)];
    char *endptr = NULL;

    *pid = 0;

    if ((fd = open(path, O_RDONLY)) < 0) {
        rc = -errno;
        goto cleanup;
    }

    bytes = saferead(fd, pidstr, sizeof(pidstr));
    if (bytes < 0) {
        rc = -errno;
        VIR_FORCE_CLOSE(fd);
        goto cleanup;
    }
    pidstr[bytes] = '\0';

    if (virStrToLong_ll(pidstr, &endptr, 10, &pid_value) < 0 ||
        !(*endptr == '\0' || c_isspace(*endptr)) ||
        (pid_t) pid_value != pid_value) {
        rc = -1;
        goto cleanup;
    }

    *pid = pid_value;
    rc = 0;

cleanup:
    if (VIR_CLOSE(fd) < 0)
        rc = -errno;

    return rc;
}
Exemplo n.º 17
0
/**
 * virRotatingFileReaderConsume:
 * @file: the file context
 * @buf: the buffer to fill with data
 * @len: the size of @buf
 *
 * Reads data from the file starting at the current offset.
 * The returned data may be pulled from multiple files.
 *
 * Returns: the number of bytes read or -1 on error
 */
ssize_t
virRotatingFileReaderConsume(virRotatingFileReaderPtr file,
                             char *buf,
                             size_t len)
{
    ssize_t ret = 0;

    VIR_DEBUG("Consume %p %zu\n", buf, len);
    while (len) {
        virRotatingFileReaderEntryPtr entry;
        ssize_t got;

        if (file->current >= file->nentries)
            break;

        entry = file->entries[file->current];
        if (entry->fd == -1) {
            file->current++;
            continue;
        }

        got = saferead(entry->fd, buf + ret, len);
        if (got < 0) {
            virReportSystemError(errno,
                                 _("Unable to read from file %s"),
                                 entry->path);
            return -1;
        }

        if (got == 0) {
            file->current++;
            continue;
        }

        ret += got;
        len -= got;
    }

    return ret;
}
Exemplo n.º 18
0
int main(int argc, char *argv[ ])
{
    FILE *infile, *outfile;
    char prefix[4];
    char fileFormat[4];
    char ckID[4];
    uint32_t nChunkSize;
    short wFormatTag;
    short nChannels;
    uint32_t nSamplesPerSecond;
    uint32_t nBytesPerSecond;
    uint32_t nOutputSamplesPerSecond;
    short nBlockAlign;
    short nBitsPerSample;
    int i, j;

    if (argc < 3)
    {
        printf("WavToRaw %s - Stephane Dallongeville - copyright 2014\n", version);
        printf("\n");
        printf("Usage: wav2raw sourceFile destFile <outRate>\n");
        printf("Output rate is given in Hz.\n");
        printf("Success returns errorlevel 0. Error return greater than zero.\n");
        printf("\n");
        printf("Ex: wav2raw input.wav output.raw 11025\n");
        exit(1);
    }

    /* Open source for binary read (will fail if file does not exist) */
    if ((infile = fopen( argv[1], "rb" )) == NULL)
    {
        printf("The source file %s was not opened\n", argv[1]);
        exit(2);
    }

    if (argc > 3)
        nOutputSamplesPerSecond = atoi(argv[3]);
    else
        nOutputSamplesPerSecond = 0;

    /* Read the header bytes. */
    #define saferead(x, y, z) if (fscanf(x, y, z) != 1) puts("Failed to read " #z)

    saferead( infile, "%4s", prefix );
    saferead( infile, "%4c", &nChunkSize );
    saferead( infile, "%4c", fileFormat );
    saferead( infile, "%4c", ckID );
    saferead( infile, "%4c", &nChunkSize );
    saferead( infile, "%2c", &wFormatTag );
    saferead( infile, "%2c", &nChannels );
    saferead( infile, "%4c", &nSamplesPerSecond );
    saferead( infile, "%4c", &nBytesPerSecond );
    saferead( infile, "%2c", &nBlockAlign );
    saferead( infile, "%2c", &nBitsPerSample );

    // pass extra bytes in bloc
    for(i = 0; i < nChunkSize - 0x10; i++)
        saferead( infile, "%1c", &j);

    saferead( infile, "%4c", ckID );
    saferead( infile, "%4c", &nChunkSize );

    #undef saferead

    if (nOutputSamplesPerSecond == 0)
        nOutputSamplesPerSecond = nSamplesPerSecond;

    /* Open output for write */
    if( (outfile = fopen( argv[2], "wb" )) == NULL )
    {
        printf("The output file %s was not opened\n", argv[2]);
        exit(3);
    }

    int nBytesPerSample = nBitsPerSample / 8;
    int size = nChunkSize / (nChannels * nBytesPerSample);
    const double *data = readSample(infile, nChunkSize, nBytesPerSample, nChannels);
    int iOffset;
    double offset;
    double step;
    double value;
    double lastSample;

    step = nSamplesPerSecond;
    step /= nOutputSamplesPerSecond;
    value = 0;
    lastSample = 0;
    iOffset = 0;

    for(offset = 0; offset < size; offset += step)
    {
        char byte;
        double sample = 0;

        // extrapolation
        if (step > 1.0)
        {
            if (value < 0) sample += lastSample * -value;

            value += step;

            while(value > 0)
            {
                lastSample = data[iOffset++];

                if (value >= 1)
                    sample += lastSample;
                else
                    sample += lastSample * value;

                value--;
            }

            sample /= step;
        }
        // interpolation
        else
        {
//            if (floor(offset) == offset)
                sample = data[(int) offset];
//            else
//            {
//                double sample0 = data[(int) floor(offset)];
//                double sample1 = data[(int) ceil(offset)];
//
//                sample += sample0 * (ceil(offset) - offset);
//                sample += sample1 * (offset - floor(offset));
//            }
        }

        byte = round(sample);
        fwrite(&byte, 1, 1, outfile);
    }

    fclose(infile);
    fclose(outfile);

    return 0;
}
static int
virFDStreamCloseInt(virStreamPtr st, bool streamAbort)
{
    struct virFDStreamData *fdst;
    virStreamEventCallback cb;
    void *opaque;
    int ret;

    VIR_DEBUG("st=%p", st);

    if (!st || !(fdst = st->privateData) || fdst->abortCallbackDispatching)
        return 0;

    virMutexLock(&fdst->lock);

    /* aborting the stream, ensure the callback is called if it's
     * registered for stream error event */
    if (streamAbort &&
        fdst->cb &&
        (fdst->events & (VIR_STREAM_EVENT_READABLE |
                         VIR_STREAM_EVENT_WRITABLE))) {
        /* don't enter this function accidentally from the callback again */
        if (fdst->abortCallbackCalled) {
            virMutexUnlock(&fdst->lock);
            return 0;
        }

        fdst->abortCallbackCalled = true;
        fdst->abortCallbackDispatching = true;

        /* cache the pointers */
        cb = fdst->cb;
        opaque = fdst->opaque;
        virMutexUnlock(&fdst->lock);

        /* call failure callback, poll reports nothing on closed fd */
        (cb)(st, VIR_STREAM_EVENT_ERROR, opaque);

        virMutexLock(&fdst->lock);
        fdst->abortCallbackDispatching = false;
    }

    /* mutex locked */
    ret = VIR_CLOSE(fdst->fd);
    if (fdst->cmd) {
        char buf[1024];
        ssize_t len;
        int status;
        if ((len = saferead(fdst->errfd, buf, sizeof(buf)-1)) < 0)
            buf[0] = '\0';
        else
            buf[len] = '\0';

        virCommandRawStatus(fdst->cmd);
        if (virCommandWait(fdst->cmd, &status) < 0) {
            ret = -1;
        } else if (status != 0) {
            if (buf[0] == '\0') {
                if (WIFEXITED(status)) {
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("I/O helper exited with status %d"),
                                   WEXITSTATUS(status));
                } else {
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("I/O helper exited abnormally"));
                }
            } else {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               buf);
            }
            ret = -1;
        }
        virCommandFree(fdst->cmd);
        fdst->cmd = NULL;
    }

    if (VIR_CLOSE(fdst->errfd) < 0)
        VIR_DEBUG("ignoring failed close on fd %d", fdst->errfd);

    st->privateData = NULL;

    /* call the internal stream closing callback */
    if (fdst->icbCb) {
        /* the mutex is not accessible anymore, as private data is null */
        (fdst->icbCb)(st, fdst->icbOpaque);
        if (fdst->icbFreeOpaque)
            (fdst->icbFreeOpaque)(fdst->icbOpaque);
    }

    if (fdst->dispatching) {
        fdst->closed = true;
        virMutexUnlock(&fdst->lock);
    } else {
        virMutexUnlock(&fdst->lock);
        virMutexDestroy(&fdst->lock);
        VIR_FREE(fdst);
    }

    return ret;
}
Exemplo n.º 20
0
error:
    virMutexUnlock(&eventLoop.lock);
error_unlocked:
    VIR_FREE(fds);
    return -1;
}


static void virEventPollHandleWakeup(int watch ATTRIBUTE_UNUSED,
                                     int fd,
                                     int events ATTRIBUTE_UNUSED,
                                     void *opaque ATTRIBUTE_UNUSED)
{
    char c;
    virMutexLock(&eventLoop.lock);
    ignore_value(saferead(fd, &c, sizeof(c)));
    virMutexUnlock(&eventLoop.lock);
}

int virEventPollInit(void)
{
    if (virMutexInit(&eventLoop.lock) < 0) {
        virReportSystemError(errno, "%s",
                             _("Unable to initialize mutex"));
        return -1;
    }

    if (pipe2(eventLoop.wakeupfd, O_CLOEXEC | O_NONBLOCK) < 0) {
        virReportSystemError(errno, "%s",
                             _("Unable to setup wakeup pipe"));
        return -1;
Exemplo n.º 21
0
static int
virLXCProcessReadLogOutput(virDomainObjPtr vm,
                           char *logfile,
                           off_t pos,
                           char *buf,
                           size_t buflen)
{
    int fd;
    off_t off;
    int whence;
    int got = 0, ret = -1;
    int retries = 10;

    if ((fd = open(logfile, O_RDONLY)) < 0) {
        virReportSystemError(errno, _("failed to open logfile %s"),
                             logfile);
        goto cleanup;
    }

    if (pos < 0) {
        off = 0;
        whence = SEEK_END;
    } else {
        off = pos;
        whence = SEEK_SET;
    }

    if (lseek(fd, off, whence) < 0) {
        if (whence == SEEK_END)
            virReportSystemError(errno,
                                 _("unable to seek to end of log for %s"),
                                 logfile);
        else
            virReportSystemError(errno,
                                 _("unable to seek to %lld from start for %s"),
                                 (long long)off, logfile);
        goto cleanup;
    }

    while (retries) {
        ssize_t bytes;
        int isdead = 0;

        if (kill(vm->pid, 0) == -1 && errno == ESRCH)
            isdead = 1;

        /* Any failures should be detected before we read the log, so we
         * always have something useful to report on failure. */
        bytes = saferead(fd, buf+got, buflen-got-1);
        if (bytes < 0) {
            virReportSystemError(errno, "%s",
                                 _("Failure while reading guest log output"));
            goto cleanup;
        }

        got += bytes;
        buf[got] = '\0';

        if ((got == buflen-1) || isdead) {
            break;
        }

        usleep(100*1000);
        retries--;
    }


    ret = got;
cleanup:
    VIR_FORCE_CLOSE(fd);
    return ret;
}
Exemplo n.º 22
0
/*
 * Process all calls pending dispatch/receive until we
 * get a reply to our own call. Then quit and pass the buck
 * to someone else.
 */
static int virNetClientIOEventLoop(virNetClientPtr client,
                                   virNetClientCallPtr thiscall)
{
    struct pollfd fds[2];
    int ret;

    fds[0].fd = virNetSocketGetFD(client->sock);
    fds[1].fd = client->wakeupReadFD;

    for (;;) {
        virNetClientCallPtr tmp = client->waitDispatch;
        virNetClientCallPtr prev;
        char ignore;
        sigset_t oldmask, blockedsigs;
        int timeout = -1;

        /* If we have existing SASL decoded data we
         * don't want to sleep in the poll(), just
         * check if any other FDs are also ready
         */
        if (virNetSocketHasCachedData(client->sock))
            timeout = 0;

        fds[0].events = fds[0].revents = 0;
        fds[1].events = fds[1].revents = 0;

        fds[1].events = POLLIN;
        while (tmp) {
            if (tmp->mode == VIR_NET_CLIENT_MODE_WAIT_RX)
                fds[0].events |= POLLIN;
            if (tmp->mode == VIR_NET_CLIENT_MODE_WAIT_TX)
                fds[0].events |= POLLOUT;

            tmp = tmp->next;
        }

        /* We have to be prepared to receive stream data
         * regardless of whether any of the calls waiting
         * for dispatch are for streams.
         */
        if (client->nstreams)
            fds[0].events |= POLLIN;

        /* Release lock while poll'ing so other threads
         * can stuff themselves on the queue */
        virNetClientUnlock(client);

        /* Block SIGWINCH from interrupting poll in curses programs,
         * then restore the original signal mask again immediately
         * after the call (RHBZ#567931).  Same for SIGCHLD and SIGPIPE
         * at the suggestion of Paolo Bonzini and Daniel Berrange.
         */
        sigemptyset (&blockedsigs);
#ifdef SIGWINCH
        sigaddset (&blockedsigs, SIGWINCH);
#endif
#ifdef SIGCHLD
        sigaddset (&blockedsigs, SIGCHLD);
#endif
        sigaddset (&blockedsigs, SIGPIPE);
        ignore_value(pthread_sigmask(SIG_BLOCK, &blockedsigs, &oldmask));

    repoll:
        ret = poll(fds, ARRAY_CARDINALITY(fds), timeout);
        if (ret < 0 && errno == EAGAIN)
            goto repoll;

        ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));

        virNetClientLock(client);

        /* If we have existing SASL decoded data, pretend
         * the socket became readable so we consume it
         */
        if (virNetSocketHasCachedData(client->sock))
            fds[0].revents |= POLLIN;

        if (fds[1].revents) {
            VIR_DEBUG("Woken up from poll by other thread");
            if (saferead(client->wakeupReadFD, &ignore, sizeof(ignore)) != sizeof(ignore)) {
                virReportSystemError(errno, "%s",
                                     _("read on wakeup fd failed"));
                goto error;
            }
        }

        if (ret < 0) {
            if (errno == EWOULDBLOCK)
                continue;
            virReportSystemError(errno,
                                 "%s", _("poll on socket failed"));
            goto error;
        }

        if (fds[0].revents & POLLOUT) {
            if (virNetClientIOHandleOutput(client) < 0)
                goto error;
        }

        if (fds[0].revents & POLLIN) {
            if (virNetClientIOHandleInput(client) < 0)
                goto error;
        }

        /* Iterate through waiting threads and if
         * any are complete then tell 'em to wakeup
         */
        tmp = client->waitDispatch;
        prev = NULL;
        while (tmp) {
            if (tmp != thiscall &&
                tmp->mode == VIR_NET_CLIENT_MODE_COMPLETE) {
                /* Take them out of the list */
                if (prev)
                    prev->next = tmp->next;
                else
                    client->waitDispatch = tmp->next;

                /* And wake them up....
                 * ...they won't actually wakeup until
                 * we release our mutex a short while
                 * later...
                 */
                VIR_DEBUG("Waking up sleep %p %p", tmp, client->waitDispatch);
                virCondSignal(&tmp->cond);
            } else {
                prev = tmp;
            }
            tmp = tmp->next;
        }

        /* Now see if *we* are done */
        if (thiscall->mode == VIR_NET_CLIENT_MODE_COMPLETE) {
            /* We're at head of the list already, so
             * remove us
             */
            client->waitDispatch = thiscall->next;
            VIR_DEBUG("Giving up the buck %p %p", thiscall, client->waitDispatch);
            /* See if someone else is still waiting
             * and if so, then pass the buck ! */
            if (client->waitDispatch) {
                VIR_DEBUG("Passing the buck to %p", client->waitDispatch);
                virCondSignal(&client->waitDispatch->cond);
            }
            return 0;
        }


        if (fds[0].revents & (POLLHUP | POLLERR)) {
            virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("received hangup / error event on socket"));
            goto error;
        }
    }


error:
    client->waitDispatch = thiscall->next;
    VIR_DEBUG("Giving up the buck due to I/O error %p %p", thiscall, client->waitDispatch);
    /* See if someone else is still waiting
     * and if so, then pass the buck ! */
    if (client->waitDispatch) {
        VIR_DEBUG("Passing the buck to %p", client->waitDispatch);
        virCondSignal(&client->waitDispatch->cond);
    }
    return -1;
}
Exemplo n.º 23
0
int
main(int argc, char **argv)
{
	int encrypt = 0;  /* 0=decrypt, 1=encrypt */
	int n, nkey, pass_stdin = 0, pass_nvram = 0;
	char *pass;
	unsigned char key[AESmaxkey], key2[SHA1dlen];
	unsigned char buf[BUF+SHA1dlen];    /* assumption: CHK <= SHA1dlen */
	AESstate aes;
	DigestState *dstate;
	Nvrsafe nvr;

	ARGBEGIN{
	case 'e':
		encrypt = 1;
		break;
	case 'i':
		pass_stdin = 1;
		break;
	case 'n':
		pass_nvram = 1;
		break;
	}ARGEND;
	if(argc!=0){
		fprint(2,"usage: %s -d < cipher.aes > clear.txt\n", argv0);
		fprint(2,"   or: %s -e < clear.txt > cipher.aes\n", argv0);
		exits("usage");
	}
	Binit(&bin, 0, OREAD);
	Binit(&bout, 1, OWRITE);

	if(pass_stdin){
		n = readn(3, buf, (sizeof buf)-1);
		if(n < 1)
			exits("usage: echo password |[3=1] auth/aescbc -i ...");
		buf[n] = 0;
		while(buf[n-1] == '\n')
			buf[--n] = 0;
	}else if(pass_nvram){
		if(readnvram(&nvr, 0) < 0)
			exits("readnvram: %r");
		strecpy((char*)buf, (char*)buf+sizeof buf, (char*)nvr.config);
		n = strlen((char*)buf);
	}else{
		pass = getpassm("aescbc key:");
		n = strlen(pass);
		if(n >= BUF)
			exits("key too long");
		strcpy((char*)buf, pass);
		memset(pass, 0, n);
		free(pass);
	}
	if(n <= 0)
		sysfatal("no key");
	dstate = sha1((unsigned char*)"aescbc file", 11, nil, nil);
	sha1(buf, n, key2, dstate);
	memcpy(key, key2, 16);
	nkey = 16;
	md5(key, nkey, key2, 0);  /* so even if HMAC_SHA1 is broken, encryption key is protected */

	if(encrypt){
		safewrite(v2hdr, AESbsize);
		genrandom(buf,2*AESbsize); /* CBC is semantically secure if IV is unpredictable. */
		setupAESstate(&aes, key, nkey, buf);  /* use first AESbsize bytes as IV */
		aesCBCencrypt(buf+AESbsize, AESbsize, &aes);  /* use second AESbsize bytes as initial plaintext */
		safewrite(buf, 2*AESbsize);
		dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
		for(;;){
			n = Bread(&bin, buf, BUF);
			if(n < 0)
				sysfatal("read error");
			aesCBCencrypt(buf, n, &aes);
			safewrite(buf, n);
			dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
			if(n < BUF)
				break; /* EOF */
		}
		hmac_sha1(0, 0, key2, MD5dlen, buf, dstate);
		safewrite(buf, SHA1dlen);
	}else{ /* decrypt */
		saferead(buf, AESbsize);
		if(memcmp(buf, v2hdr, AESbsize) == 0){
			saferead(buf, 2*AESbsize);  /* read IV and random initial plaintext */
			setupAESstate(&aes, key, nkey, buf);
			dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
			aesCBCdecrypt(buf+AESbsize, AESbsize, &aes);
			saferead(buf, SHA1dlen);
			while((n = Bread(&bin, buf+SHA1dlen, BUF)) > 0){
				dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
				aesCBCdecrypt(buf, n, &aes);
				safewrite(buf, n);
				memmove(buf, buf+n, SHA1dlen);  /* these bytes are not yet decrypted */
			}
			hmac_sha1(0, 0, key2, MD5dlen, buf+SHA1dlen, dstate);
			if(memcmp(buf, buf+SHA1dlen, SHA1dlen) != 0)
				sysfatal("decrypted file failed to authenticate");
		}else{ /* compatibility with past mistake */
			// if file was encrypted with bad aescbc use this:
			//         memset(key, 0, AESmaxkey);
			//    else assume we're decrypting secstore files
			setupAESstate(&aes, key, AESbsize, buf);
			saferead(buf, CHK);
			aesCBCdecrypt(buf, CHK, &aes);
			while((n = Bread(&bin, buf+CHK, BUF)) > 0){
				aesCBCdecrypt(buf+CHK, n, &aes);
				safewrite(buf, n);
				memmove(buf, buf+n, CHK);
			}
			if(memcmp(buf, "XXXXXXXXXXXXXXXX", CHK) != 0)
				sysfatal("decrypted file failed to authenticate");
		}
	}
	exits("");
	return 1;  /* keep  other compilers happy */
}
Exemplo n.º 24
0
static int
virLXCProcessReadLogOutputData(virDomainObjPtr vm,
                               int fd,
                               char *buf,
                               size_t buflen)
{
    int retries = 10;
    int got = 0;
    int ret = -1;
    char *filter_next = buf;

    buf[0] = '\0';

    while (retries) {
        ssize_t bytes;
        bool isdead = false;
        char *eol;

        if (vm->pid <= 0 ||
            (kill(vm->pid, 0) == -1 && errno == ESRCH))
            isdead = true;

        /* Any failures should be detected before we read the log, so we
         * always have something useful to report on failure. */
        bytes = saferead(fd, buf+got, buflen-got-1);
        if (bytes < 0) {
            virReportSystemError(errno, "%s",
                                 _("Failure while reading log output"));
            goto cleanup;
        }

        got += bytes;
        buf[got] = '\0';

        /* Filter out debug messages from intermediate libvirt process */
        while ((eol = strchr(filter_next, '\n'))) {
            *eol = '\0';
            if (virLXCProcessIgnorableLogLine(filter_next)) {
                memmove(filter_next, eol + 1, got - (eol - buf));
                got -= eol + 1 - filter_next;
            } else {
                filter_next = eol + 1;
                *eol = '\n';
            }
        }

        if (got == buflen-1) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Out of space while reading log output: %s"),
                           buf);
            goto cleanup;
        }

        if (isdead) {
            ret = got;
            goto cleanup;
        }

        usleep(100*1000);
        retries--;
    }

    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("Timed out while reading log output: %s"),
                   buf);

 cleanup:
    return ret;
}
Exemplo n.º 25
0
static int testFDStreamWriteCommon(const char *scratchdir, bool blocking)
{
    int fd = -1;
    char *file = NULL;
    int ret = -1;
    char *pattern = NULL;
    char *buf = NULL;
    virStreamPtr st = NULL;
    size_t i;
    virConnectPtr conn = NULL;
    int flags = 0;

    if (!blocking)
        flags |= VIR_STREAM_NONBLOCK;

    if (!(conn = virConnectOpen("test:///default")))
        goto cleanup;

    if (VIR_ALLOC_N(pattern, PATTERN_LEN) < 0 ||
        VIR_ALLOC_N(buf, PATTERN_LEN) < 0)
        goto cleanup;

    for (i = 0; i < PATTERN_LEN; i++)
        pattern[i] = i;

    if (virAsprintf(&file, "%s/input.data", scratchdir) < 0)
        goto cleanup;

    if (!(st = virStreamNew(conn, flags)))
        goto cleanup;

    /* Start writing 1/2 way through first pattern
     * and end 1/2 way through last pattern
     */
    if (virFDStreamCreateFile(st, file,
                              PATTERN_LEN / 2, PATTERN_LEN * 9,
                              O_WRONLY, 0600) < 0)
        goto cleanup;

    for (i = 0; i < 10; i++) {
        size_t offset = 0;
        size_t want;
        if (i == 0)
            want = PATTERN_LEN / 2;
        else
            want = PATTERN_LEN;

        while (want > 0) {
            int got;
        rewrite:
            got = st->driver->streamSend(st, pattern + offset, want);
            if (got < 0) {
                if (got == -2 && !blocking) {
                    usleep(20 * 1000);
                    goto rewrite;
                }
                if (i == 9 &&
                    want == (PATTERN_LEN / 2))
                    break;
                virFilePrintf(stderr, "Failed to write stream: %s\n",
                              virGetLastErrorMessage());
                goto cleanup;
            }
            offset += got;
            want -= got;
        }
    }

    if (st->driver->streamFinish(st) != 0) {
        virFilePrintf(stderr, "Failed to finish stream: %s\n",
                      virGetLastErrorMessage());
        goto cleanup;
   }

    if ((fd = open(file, O_RDONLY)) < 0)
        goto cleanup;

    for (i = 0; i < 10; i++) {
        size_t want;
        if (i == 9)
            want = PATTERN_LEN / 2;
        else
            want = PATTERN_LEN;

        if (saferead(fd, buf, want) != want) {
            virFilePrintf(stderr, "Short read from data\n");
            goto cleanup;
        }

        if (i == 0) {
            size_t j;
            for (j = 0; j < (PATTERN_LEN / 2); j++) {
                if (buf[j] != 0) {
                    virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i);
                    goto cleanup;
                }
            }
            if (memcmp(buf + (PATTERN_LEN / 2), pattern, PATTERN_LEN / 2) != 0) {
                virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i);
                goto cleanup;
            }
        } else if (i == 9) {
            if (memcmp(buf, pattern, PATTERN_LEN / 2) != 0) {
                virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i);
                goto cleanup;
            }
        } else {
            if (memcmp(buf, pattern, PATTERN_LEN) != 0) {
                virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i);
                goto cleanup;
            }
        }
    }

    if (VIR_CLOSE(fd) < 0)
        goto cleanup;

    ret = 0;
cleanup:
    if (st)
        virStreamFree(st);
    VIR_FORCE_CLOSE(fd);
    if (file != NULL)
        unlink(file);
    if (conn)
        virConnectClose(conn);
    VIR_FREE(file);
    VIR_FREE(pattern);
    VIR_FREE(buf);
    return ret;
}