aboutsummaryrefslogblamecommitdiffstats
path: root/main.c
blob: 169f61f6a91bf1e947e20f634d4fdd9cfbddab92 (plain) (tree)









































                                                                                
                       
                                   

                




                                                                          






                             














                                                                               
                                                                               





                                    
                                              

                    
                 


















                                                                  
                                                                              

















                                                                                

                                                          
                                                                                    









                                                                                 
                                                                                 






                                           

                                                                       


                                                                
                                           


                                              


                                                            

            

// The MIT License (MIT)

// Copyright (c) 2017 Yun-Chih Chen
// Copyright (c) 2013 Florian Richter (nflogtable)

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "commit.h"
#include "main.h"
#include "nflog.h"
#include <fcntl.h>
#include <getopt.h>
#include <pthread.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

sem_t nfl_commit_queue;
uint16_t nfl_group_id;
char *storage_dir = NULL;
const char *storage_prefix = "nflog_storage";

const char *help_text =
    "Usage: " PACKAGE " [OPTION]\n"
    "\n"
    "Options:\n"
    "  -d --storage_dir=<dirname>   log files storage directory\n"
    "  -h --help                    print this help\n"
    "  -g --nflog-group=<id>        the group id to collect\n"
    "  -s --storage_size=<dirsize>  log files maximum total size in MiB\n"
    "  -v --version                 print version information\n"
    "\n";

void sig_handler(int signo) {
    if (signo == SIGHUP) {
        /* TODO */
    }
}

int main(int argc, char *argv[]) {

    uint32_t i, max_commit_worker = 0, storage_size = 0;
    int nflog_group_id;

    struct option longopts[] = {/* name, has_args, flag, val */
                                {"nflog-group", required_argument, NULL, 'g'},
                                {"storage_dir", required_argument, NULL, 'd'},
                                {"storage_size", required_argument, NULL, 's'},
                                {"help", no_argument, NULL, 'h'},
                                {"version", no_argument, NULL, 'v'},
                                {0, 0, 0, 0}};

    int opt;
    while ((opt = getopt_long(argc, argv, "g:d:s:hv", longopts, NULL)) != -1) {
        switch (opt) {
        case 'h':
            printf("%s", help_text);
            exit(0);
            break;
        case 'v':
            printf("%s %s", PACKAGE, VERSION);
            exit(0);
            break;
        case 'd':
            storage_dir = optarg;
            break;
        case 'g':
            nflog_group_id = atoi(optarg);
            break;
        case 's':
            storage_size = atoi(optarg);
            break;
        case '?':
            fprintf(stderr, "Unknown argument, see --help\n");
            exit(1);
        }
    }

    // verify arguments
    ASSERT(nflog_group_id != -1,
           "You must provide a nflog group (see --help)!\n");
    ASSERT(storage_dir != NULL,
           "You must provide a storage directory (see --help)\n");
    ASSERT(storage_size != 0, "You must provide the desired size of log file "
                              "(in MiB) (see --help)\n");
    struct stat _d;
    if(stat(storage_dir, &_d) != 0 || !S_ISDIR(_d.st_mode)){
        fprintf(stderr, "storage directory '%s' not exist", storage_dir);
    }

    // max number of commit worker defaults to #processor - 1
    if (max_commit_worker == 0) {
        max_commit_worker = sysconf(_SC_NPROCESSORS_ONLN) - 1;
        max_commit_worker = max_commit_worker > 0 ? max_commit_worker : 1;
    }

    nfl_group_id = nflog_group_id;

    // register signal handler
    ERR(signal(SIGHUP, sig_handler) == SIG_ERR, "Could not set SIGHUP handler");

    uint32_t pgsize = getpagesize();
    storage_size *= 1024 * 1024; // MiB
    uint32_t trunk_size_byte = storage_size / TRUNK_SIZE ;
    trunk_size_byte = (trunk_size_byte < TRUNK_SIZE) ? TRUNK_SIZE : trunk_size_byte;
    trunk_size_byte = (trunk_size_byte / pgsize) * pgsize; // align with pagesize

    uint32_t trunk_cnt = CEILING(storage_size, trunk_size_byte);
    uint32_t entries_max = (trunk_size_byte - sizeof(nflog_header_t)) /
                           sizeof(nflog_entry_t);

    // Set up commit worker
    sem_init(&nfl_commit_queue, 0, max_commit_worker);

    // Set up nflog receiver worker
    nflog_state_t **trunks = (nflog_state_t **)malloc(sizeof(void*) * trunk_cnt);
    for (i = 0; i < trunk_cnt; ++i) {
        trunks[i] = NULL;
    }
    
    nfl_commit_init(trunk_cnt);

    for (i = 0;; i = (i + 1) % trunk_cnt) {
        nfl_state_update_or_create(&(trunks[i]), i, entries_max);
        // will be unlocked when #i has finished receiving & committing
        pthread_mutex_lock(&(trunks[i]->lock));
        pthread_create(&(trunks[i]->thread), NULL, nflog_worker,
                       (void *)trunks[i]);
        // wait for current receiver worker
        pthread_join(trunks[i]->thread, NULL);
    }
    
    // Won't reach here
    // We don't actually free trunks or the semaphore at all
    // sem_destroy(&nfl_commit_queue);
    exit(0);
}