/*
* Copyright 2014-2017, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* addlog -- given a log file, append a log entry
*
* Usage:
* fallocate -l 1G /path/to/pm-aware/file
* addlog /path/to/pm-aware/file "first line of entry" "second line"
*/
#include <ex_common.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <libpmemlog.h>
#include "logentry.h"
int
main(int argc, char *argv[])
{
PMEMlogpool *plp;
struct logentry header;
struct iovec *iovp;
struct iovec *next_iovp;
int iovcnt;
if (argc < 3) {
fprintf(stderr, "usage: %s filename lines...\n", argv[0]);
exit(1);
}
const char *path = argv[1];
/* create the log in the given file, or open it if already created */
plp = pmemlog_create(path, 0, CREATE_MODE_RW);
if (plp == NULL &&
(plp = pmemlog_open(path)) == NULL) {
perror(path);
exit(1);
}
/* fill in the header */
time(&header.timestamp);
header.pid = getpid();
/*
* Create an iov for pmemlog_appendv(). For each argument given,
* allocate two entries (one for the string, one for the newline
* appended to the string). Allocate 1 additional entry for the
* header that gets prepended to the entry.
*/
iovcnt = (argc - 2) * 2 + 2;
if ((iovp = malloc(sizeof(*iovp) * iovcnt)) == NULL) {
perror("malloc");
exit(1);
}
next_iovp = iovp;
/* put the header into iov first */
next_iovp->iov_base = &header;
next_iovp->iov_len = sizeof(header);
next_iovp++;
/*
* Now put each arg in, following it with the string "\n".
* Calculate a total character count in header.len along the way.
*/
header.len = 0;
for (int arg = 2; arg < argc; arg++) {
/* add the string given */
next_iovp->iov_base = argv[arg];
next_iovp->iov_len = strlen(argv[arg]);
header.len += next_iovp->iov_len;
next_iovp++;
/* add the newline */
next_iovp->iov_base = "\n";
next_iovp->iov_len = 1;
header.len += 1;
next_iovp++;
}
/*
* pad with NULs (at least one) to align next entry to sizeof(long long)
* bytes
*/
int a = sizeof(long long);
int len_to_round = 1 + (a - (header.len + 1) % a) % a;
char *buf[sizeof(long long)] = {0};
next_iovp->iov_base = buf;
next_iovp->iov_len = len_to_round;
header.len += len_to_round;
next_iovp++;
/* atomically add it all to the log */
if (pmemlog_appendv(plp, iovp, iovcnt) < 0) {
perror("pmemlog_appendv");
free(iovp);
exit(1);
}
free(iovp);
pmemlog_close(plp);
}