File:  [Coherent Logic Development] / freem / src / tp_check.c
Revision 1.4: download - view: text, annotated - select for diffs
Sat Mar 22 18:43:54 2025 UTC (10 days, 5 hours ago) by snw
Branches: MAIN
CVS tags: v0-62-3, v0-62-2, HEAD
Make STRLEN 255 chars and add BIGSTR macro for larger buffers

/*
 *   $Id: tp_check.c,v 1.4 2025/03/22 18:43:54 snw Exp $
 *    TP global checkpointing code
 *
 *  
 *   Author: Serena Willis <snw@coherent-logic.com>
 *    Copyright (C) 1998 MUG Deutschland
 *    Copyright (C) 2022, 2025 Coherent Logic Development LLC
 *
 *
 *   This file is part of FreeM.
 *
 *   FreeM is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   FreeM is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero Public License for more details.
 *
 *   You should have received a copy of the GNU Affero Public License
 *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
 *
 *   $Log: tp_check.c,v $
 *   Revision 1.4  2025/03/22 18:43:54  snw
 *   Make STRLEN 255 chars and add BIGSTR macro for larger buffers
 *
 *   Revision 1.3  2025/03/09 19:50:47  snw
 *   Second phase of REUSE compliance and header reformat
 *
 *
 * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
 * SPDX-License-Identifier: AGPL-3.0-or-later
 **/

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tp_check.h"
#include "mpsdef.h"
#include "transact.h"
#include "journal.h"
#include "fs.h"

short frm_global_exists(char *, char *, char *);

cptab *cptab_head[TP_MAX_NEST];

cptab *cptab_insert(int tlevel, char *global)
{
    cptab *t;
    char mode;

    short g_exists;
    
    char *gc_ns;
    char *gc_pth;
    
    gc_ns = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(gc_ns,"cptab_insert");

    gc_pth = (char *) malloc (PATHLEN * sizeof (char));
    NULLPTRCHK(gc_pth,"cptab_insert");

    for (t = cptab_head[tlevel]; t != NULL; t = t->next) {

        if ((strcmp (t->global, global) == 0) && (t->mode > CP_UNUSED)) {
            /* found match */
            return t;
        }

    }

    /* insert */
    t = (cptab *) malloc (sizeof (cptab));
    NULLPTRCHK(t,"cptab_insert");

    t->global = (char *) malloc (sizeof (char) * (strlen (global) + 1));
    NULLPTRCHK(t->global,"cptab_insert");

    strcpy (t->global, global);

    g_exists = frm_global_exists (gc_ns, gc_pth, global);
    
    t->file = (char *) malloc (sizeof (char) * (strlen (gc_pth)));
    NULLPTRCHK(t->file,"cptab_insert");

    t->cp_file = (char *) malloc (sizeof (char) * PATHLEN);
    NULLPTRCHK(t->cp_file,"cptab_insert");
    
    strcpy (t->file, gc_pth);
    stcnv_m2c (t->file);
    
    snprintf (t->cp_file, PATHLEN, "%s.%d.%d.chk", t->file, pid, tp_level);

    free (gc_ns);
    free (gc_pth);
    
    if (!g_exists) {
        t->mode = CP_REMOVE;
    }
    else {
        t->mode = CP_RESTORE;
    }

    t->next = cptab_head[tlevel];
    cptab_head[tlevel] = t;

    return t;
}

short cptab_precommit(int tlevel)
{
    cptab *t;
    /*char *cmd;*/
    char *pctmp;
    int rc;

    /*
    cmd = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(cmd,"cptab_precommit");
    */
    
    pctmp = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(pctmp,"cptab_precommit");
    
    for (t = cptab_head[tlevel]; t != NULL; t = t->next) {
        
        if (t->mode == CP_RESTORE) {

            /*
            snprintf (cmd, STRLEN - 1, "/bin/cp %s %s", t->file, t->cp_file);
            rc = system (cmd);
            */
            
            rc = cp (t->cp_file, t->file);
            
            if (rc != 0) {

                strcpy (pctmp, t->file);
                stcnv_c2m (pctmp);
                
                jnl_ent_write (JNLA_CHECKPOINT_FAIL, " \201", pctmp);
                
                /*free (cmd);*/
                free (pctmp);

                return FALSE;
                
            }
            else {

                strcpy (pctmp, t->file);
                stcnv_c2m (pctmp);
                
                jnl_ent_write (JNLA_CHECKPOINT_OK, " \201", pctmp);

            }

        }
        
    }
    
    /*free (cmd);*/
    free (pctmp);
    
    return TRUE;    
}

void cptab_postcommit(int tlevel)
{
    cptab *t;
    /*char *cmd;*/
    int rc;

    /*
    cmd = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(cmd,"cptab_postcommit");
    */

    for (t = cptab_head[tlevel]; t != NULL; t = t->next) {

        if (t->mode == CP_RESTORE) {
            /*
            snprintf (cmd, STRLEN - 1, "/bin/rm -f '%s'", t->cp_file);
            rc = system (cmd);
            */
            unlink (t->cp_file);
        }
        
    }

    cptab_head[tlevel] = NULL;
}

short cptab_rollback(int tlevel)
{
    cptab *t;
    /*char *cmd;*/
    int rc;

    /*
    cmd = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(cmd,"cptab_rollback");
    */
    
    for (t = cptab_head[tlevel]; t != NULL; t = t->next) {
        
        switch (t->mode) {

            case CP_REMOVE:
                unlink (t->file);
                /*
                snprintf (cmd, STRLEN - 1, "/bin/rm -f '%s'", t->file);
                rc = system (cmd);
                */
                break;

            case CP_RESTORE:
                /*
                snprintf (cmd, STRLEN - 1, "/bin/cp '%s' '%s'", t->cp_file, t->file);
                rc = system (cmd);
                */
                rc = cp (t->file, t->cp_file);
                
                if (rc != 0) {
                    cptab_head[tlevel] = NULL;
                    /*free (cmd);*/
                    return FALSE;
                }

                /*
                snprintf (cmd, STRLEN - 1, "/bin/rm -f %s", t->cp_file);
                rc = system (cmd);
                */

                unlink (t->cp_file);
                if (rc != 0) {
                    cptab_head[tlevel] = NULL;
                    /*free (cmd);*/
                    return FALSE;
                }

                break;

                
        }

    }

    cptab_head[tlevel] = NULL;
    
    return TRUE;

}

void cptab_dump(int tlevel)
{
    cptab *gt;
    char cp_mode[15];
    
    printf ("\n  Global database checkpoints:\n");

    printf ("\n   %-30s%-20s%s\n", "GLOBAL", "MODE", "FILES");
    printf ("   %-30s%-20s%s\n", "------", "----", "-----");

    for (gt = cptab_head[tlevel]; gt != NULL; gt = gt->next) {

        switch (gt->mode) {

            case CP_UNUSED:
                strcpy (cp_mode, "CP_UNUSED");
                break;

            case CP_REMOVE:
                strcpy (cp_mode, "CP_REMOVE");
                break;

            case CP_RESTORE:
                strcpy (cp_mode, "CP_RESTORE");
                break;

        }

        if (gt->mode > CP_UNUSED) {
            printf ("   %-30s%-20sIN:   %s\n", gt->global, cp_mode, gt->file); 
        }
        else {
            printf ("   N/A\n");
        }
        
        if (gt->mode == CP_RESTORE) {
            printf ("   %-30s%-20sOUT:  %s\n", "", "", gt->cp_file);
        }
        
    }
}


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>