/*
Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
This file is licensed to you under your choice of the GNU Lesser
General Public License, version 3 or any later version (LGPLv3 or
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
*/
#ifndef __BIT_ROT_COMMON_H__
#define __BIT_ROT_COMMON_H__
#include <glusterfs/glusterfs.h>
#include "bit-rot-object-version.h"
#define BR_VXATTR_VERSION (1 << 0)
#define BR_VXATTR_SIGNATURE (1 << 1)
#define BR_VXATTR_SIGN_MISSING (BR_VXATTR_SIGNATURE)
#define BR_VXATTR_ALL_MISSING (BR_VXATTR_VERSION | BR_VXATTR_SIGNATURE)
#define BR_BAD_OBJ_CONTAINER \
(uuid_t) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 }
typedef enum br_vxattr_state {
BR_VXATTR_STATUS_FULL = 0,
BR_VXATTR_STATUS_MISSING = 1,
BR_VXATTR_STATUS_UNSIGNED = 2,
BR_VXATTR_STATUS_INVALID = 3,
} br_vxattr_status_t;
typedef enum br_sign_state {
BR_SIGN_INVALID = -1,
BR_SIGN_NORMAL = 0,
BR_SIGN_REOPEN_WAIT = 1,
BR_SIGN_QUICK = 2,
} br_sign_state_t;
static inline br_vxattr_status_t
br_version_xattr_state(dict_t *xattr, br_version_t **obuf,
br_signature_t **sbuf, gf_boolean_t *objbad)
{
int32_t ret = 0;
int32_t vxattr = 0;
br_vxattr_status_t status;
void *data = NULL;
/**
* The key being present in the dict indicates the xattr was set on
* disk. The presence of xattr itself as of now is suffecient to say
* the the object is bad.
*/
*objbad = _gf_false;
ret = dict_get_bin(xattr, BITROT_OBJECT_BAD_KEY, (void **)&data);
if (!ret)
*objbad = _gf_true;
ret = dict_get_bin(xattr, BITROT_CURRENT_VERSION_KEY, (void **)obuf);
if (ret)
vxattr |= BR_VXATTR_VERSION;
ret = dict_get_bin(xattr, BITROT_SIGNING_VERSION_KEY, (void **)sbuf);
if (ret)
vxattr |= BR_VXATTR_SIGNATURE;
switch (vxattr) {
case 0:
status = BR_VXATTR_STATUS_FULL;
break;
case BR_VXATTR_SIGN_MISSING:
status = BR_VXATTR_STATUS_UNSIGNED;
break;
case BR_VXATTR_ALL_MISSING:
status = BR_VXATTR_STATUS_MISSING;
break;
default:
status = BR_VXATTR_STATUS_INVALID;
}
return status;
}
/**
* in-memory representation of signature used by signer for object
* signing.
*/
typedef struct br_isignature_in {
int8_t signaturetype; /* signature type */
unsigned long signedversion; /* version against which the
object was signed */
size_t signaturelen; /* signature length */
char signature[0]; /* object signature */
} br_isignature_t;
/**
* in-memory representation of signature used by scrubber for object
* verification.
*/
typedef struct br_isignature_out {
char stale; /* stale signature? */
unsigned long version; /* current signed version */
uint32_t time[2]; /* time when the object
got dirtied */
int8_t signaturetype; /* hash type */
size_t signaturelen; /* signature length */
char signature[0]; /* signature (hash) */
} br_isignature_out_t;
typedef struct br_stub_init {
uint32_t timebuf[2];
char export[PATH_MAX];
} br_stub_init_t;
typedef enum {
BR_SIGNATURE_TYPE_VOID = -1, /* object is not signed */
BR_SIGNATURE_TYPE_ZERO = 0, /* min boundary */
BR_SIGNATURE_TYPE_SHA256 = 1, /* signed with SHA256 */
BR_SIGNATURE_TYPE_MAX = 2, /* max boundary */
} br_signature_type;
/* BitRot stub start time (virtual xattr) */
#define GLUSTERFS_GET_BR_STUB_INIT_TIME "trusted.glusterfs.bit-rot.stub-init"
/* signing/reopen hint */
#define BR_OBJECT_RESIGN 0
#define BR_OBJECT_REOPEN 1
#define BR_REOPEN_SIGN_HINT_KEY "trusted.glusterfs.bit-rot.reopen-hint"
static inline int
br_is_signature_type_valid(int8_t signaturetype)
{
return ((signaturetype > BR_SIGNATURE_TYPE_ZERO) &&
(signaturetype < BR_SIGNATURE_TYPE_MAX));
}
static inline void
br_set_default_ongoingversion(br_version_t *buf, uint32_t *tv)
{
buf->ongoingversion = BITROT_DEFAULT_CURRENT_VERSION;
buf->timebuf[0] = tv[0];
buf->timebuf[1] = tv[1];
}
static inline void
br_set_default_signature(br_signature_t *buf, size_t *size)
{
buf->signaturetype = (int8_t)BR_SIGNATURE_TYPE_VOID;
buf->signedversion = BITROT_DEFAULT_SIGNING_VERSION;
*size = sizeof(br_signature_t); /* no signature */
}
static inline void
br_set_ongoingversion(br_version_t *buf, unsigned long version, uint32_t *tv)
{
buf->ongoingversion = version;
buf->timebuf[0] = tv[0];
buf->timebuf[1] = tv[1];
}
static inline void
br_set_signature(br_signature_t *buf, br_isignature_t *sign,
size_t signaturelen, size_t *size)
{
buf->signaturetype = sign->signaturetype;
buf->signedversion = ntohl(sign->signedversion);
memcpy(buf->signature, sign->signature, signaturelen);
*size = sizeof(br_signature_t) + signaturelen;
}
#endif /* __BIT_ROT_COMMON_H__ */