From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29900 invoked by alias); 15 Jul 2008 15:39:08 -0000 Received: (qmail 29858 invoked by uid 9452); 15 Jul 2008 15:39:05 -0000 Date: Tue, 15 Jul 2008 15:39:00 -0000 Message-ID: <20080715153905.29843.qmail@sourceware.org> From: ccaulfield@sourceware.org To: cluster-cvs@sources.redhat.com, cluster-devel@redhat.com Subject: Cluster Project branch, master, updated. cluster-2.99.06-3-g470b806 X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 41e7b5a1db20a86d6f5306afeab89944f44bc7b2 X-Git-Newrev: 470b80623e73e310311272fd48a0f5cacfff2125 Mailing-List: contact cluster-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: cluster-cvs-owner@sourceware.org X-SW-Source: 2008-q3/txt/msg00066.txt.bz2 This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Cluster Project". http://sources.redhat.com/git/gitweb.cgi?p=cluster.git;a=commitdiff;h=470b80623e73e310311272fd48a0f5cacfff2125 The branch, master has been updated via 470b80623e73e310311272fd48a0f5cacfff2125 (commit) from 41e7b5a1db20a86d6f5306afeab89944f44bc7b2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 470b80623e73e310311272fd48a0f5cacfff2125 Author: Christine Caulfield Date: Tue Jul 15 16:38:50 2008 +0100 Revert "[CMAN] Don't use logsys in config modules." I'm not sure how those deletes got in there, sorry This reverts commit 41e7b5a1db20a86d6f5306afeab89944f44bc7b2. ----------------------------------------------------------------------- Summary of changes: ccs/ccs_tool/old_parser.c | 688 +++++++++++++++++++++++++++++++++++++++++++++ ccs/ccs_tool/old_parser.h | 64 +++++ ccs/ccs_tool/upgrade.c | 259 +++++++++++++++++ ccs/ccs_tool/upgrade.h | 6 + 4 files changed, 1017 insertions(+), 0 deletions(-) create mode 100644 ccs/ccs_tool/old_parser.c create mode 100644 ccs/ccs_tool/old_parser.h create mode 100644 ccs/ccs_tool/upgrade.c create mode 100644 ccs/ccs_tool/upgrade.h diff --git a/ccs/ccs_tool/old_parser.c b/ccs/ccs_tool/old_parser.c new file mode 100644 index 0000000..58ef18b --- /dev/null +++ b/ccs/ccs_tool/old_parser.c @@ -0,0 +1,688 @@ +#include +#include +#include +#include +#include +#include +#include +#include "old_parser.h" + +enum { + TOK_INT, + TOK_FLOAT, + TOK_STRING, + TOK_EQ, + TOK_SECTION_B, + TOK_SECTION_E, + TOK_ARRAY_B, + TOK_ARRAY_E, + TOK_IDENTIFIER, + TOK_COMMA, + TOK_EOF +}; + + +typedef struct parser { + const char *data; /* data and data limits */ + const char *db, *de; + + int t; /* token limits and type */ + const char *tb, *te; + + int line; /* line we're on */ +} parser_t; + + +static void _get_token(struct parser *p); +static void _eat_space(struct parser *p); +static ccs_node_t *_file(struct parser *p); +static ccs_node_t *_section(struct parser *p); +static ccs_value_t *_value(struct parser *p); +static ccs_value_t *_type(struct parser *p); +static int _match_aux(struct parser *p, int t); +static ccs_value_t *_create_value(void); +static ccs_node_t *_create_node(void); +static char *_dup_tok(struct parser *p); + + +#define match(t) do {\ + if (!_match_aux(p, (t))) {\ + fprintf(stderr, \ + "Parse error at line %d: unexpected token\n", p->line); \ + return 0;\ + } \ +} while(0); + + +static void free_ccs_value(ccs_value_t *cv){ + if(cv->next) + free_ccs_value(cv->next); + if(cv->type == CCS_STRING && cv->v.str) + free(cv->v.str); + free(cv); +} + +void free_ccs_node(ccs_node_t *cn){ + ccs_node_t *tmp, *sib_end; + + for(tmp = cn; tmp->sib; tmp = tmp->sib); + sib_end = tmp; + + for(tmp = cn; tmp; tmp = tmp->sib){ + if(tmp->child){ + sib_end->sib = tmp->child; + tmp->child = NULL; + while(sib_end->sib){ + sib_end = sib_end->sib; + } + } + } + + while(cn){ + tmp = cn; + cn = cn->sib; + if(tmp->v){ + free_ccs_value(tmp->v); + } + if(tmp->key){ + free(tmp->key); + } + free(tmp); + } +} + +static int isidchar(char c){ + if ( (c >= 'a' && c <= 'z') || /* [a-z] */ + (c >= 'A' && c <= 'Z') || /* [A-Z] */ + (c >= '0' && c <= '9') || /* [0-9] */ + (c == '_' ) || + (c == '$' ) || + (c == '-' ) || + (c == '.' ) ) + return 1; + else + return 0; +} + +static void _get_token(struct parser *p){ + int number_valid = 1; + + p->tb = p->te; + _eat_space(p); + if (p->tb == p->de){ + p->t = TOK_EOF; + return; + } + + p->t = TOK_INT; /* fudge so the fall through for + floats works */ + switch (*p->te) { + case '{': + p->t = TOK_SECTION_B; + p->te++; + break; + + case '}': + p->t = TOK_SECTION_E; + p->te++; + break; + + case '[': + p->t = TOK_ARRAY_B; + p->te++; + break; + + case ']': + p->t = TOK_ARRAY_E; + p->te++; + break; + + case ',': + p->t = TOK_COMMA; + p->te++; + break; + + case '=': + p->t = TOK_EQ; + p->te++; + break; + + case '"': + p->t = TOK_STRING; + p->te++; + while ((p->te != p->de) && (*p->te != '"')) { + /* $ is reserved */ + if (*p->te == '$') + { + /* set token to EOF due to parse error */ + p->t = TOK_EOF; + break; + } + + if ((*p->te == '\\') && (p->te + 1 != p->de)) + p->te++; + p->te++; + } + + if (p->te != p->de) + p->te++; + break; + + case '\'': + p->t = TOK_STRING; + p->te++; + while ((p->te != p->de) && (*p->te != '\'')) { + p->te++; + } + + if (p->te != p->de) + p->te++; + break; + + case '.': + p->t = TOK_FLOAT; + case '-': + case '+': + number_valid = 0; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + p->te++; + while (p->te != p->de) { + if (*p->te == '.') { + if (p->t == TOK_FLOAT) + break; + p->t = TOK_FLOAT; + } else if (!isdigit((int) *p->te)){ + break; + } + number_valid = 1; + p->te++; + } + if (!number_valid){ + p->t = TOK_EOF; + } else if(!isidchar(*p->te)){ + break; + } + default: + + + /* NOTE: at this point, [-.0-9] have already been checked. This means + * that valid identifiers can begin with [$_a-zA-Z] */ + if (isidchar(*p->te)) + { + p->t = TOK_IDENTIFIER; + while ((p->te != p->de) && !isspace(*p->te) && + (isidchar(*p->te)) && (*p->te != '#') && (*p->te != '=')) + p->te++; + }else + p->t = TOK_EOF; + + break; + } +} + + +static void _eat_space(struct parser *p){ + while (p->tb != p->de) { + if (*p->te == '#') { + while ((p->te != p->de) && (*p->te != '\n')) + p->te++; + /* p->line++; + since != \n, the \n will be picked up by else if */ + } + + else if (isspace(*p->te)) { + while ((p->te != p->de) && isspace(*p->te)) { + if (*p->te == '\n') + p->line++; + p->te++; + } + } + + else + return; + + p->tb = p->te; + } +} + + +static ccs_node_t *_file(struct parser *p){ + ccs_node_t *root = NULL, *n, *l = NULL; + + while (p->t != TOK_EOF) { + if (!(n = _section(p))) { + return 0; + } + + if (!root) + root = n; + else + l->sib = n; + l = n; + } + return root; +} + + +static ccs_node_t *_section(struct parser *p){ + /* IDENTIFIER '{' VALUE* '}' */ + ccs_node_t *root, *n, *l = NULL; + + if (!(root = _create_node())) { + return 0; + } + + if (!(root->key = _dup_tok(p))) { + free_ccs_node(root); + return 0; + } + + match(TOK_IDENTIFIER); + + if (p->t == TOK_SECTION_B) { + match(TOK_SECTION_B); + while (p->t != TOK_SECTION_E) { + if (!(n = _section(p))) { + free_ccs_node(root); + return 0; + } + + if (!root->child) + root->child = n; + else + l->sib = n; + l = n; + } + match(TOK_SECTION_E); + } else { + match(TOK_EQ); + if (!(root->v = _value(p))) { + free_ccs_node(root); + return 0; + } + } + + return root; +} + + +static ccs_value_t *_value(struct parser *p){ + /* '[' TYPE* ']' | TYPE */ + ccs_value_t *h = 0, *l, *ll = 0; + if (p->t == TOK_ARRAY_B) { + match(TOK_ARRAY_B); + while (p->t != TOK_ARRAY_E) { + if (!(l = _type(p))) { + return 0; + } + + if (!h) + h = l; + else + ll->next = l; + ll = l; + + if (p->t == TOK_COMMA) + match(TOK_COMMA); + } + match(TOK_ARRAY_E); + } else + h = _type(p); + + return h; +} + + +static ccs_value_t *_type(struct parser *p){ + /* [0-9]+ | [0-9]*\.[0-9]* | ".*" */ + ccs_value_t *v; + + if(!(v = _create_value())){ + return NULL; + } + + switch (p->t) { + case TOK_INT: + v->type = CCS_INT; + v->v.i = strtol(p->tb, 0, 0); /* FIXME: check error */ + match(TOK_INT); + break; + +#ifndef __KERNEL__ + case TOK_FLOAT: + v->type = CCS_FLOAT; + v->v.r = strtod(p->tb, 0); /* FIXME: check error */ + match(TOK_FLOAT); + break; +#endif + + case TOK_STRING: + v->type = CCS_STRING; + + p->tb++, p->te--; /* strip double-quotes */ + if (!(v->v.str = _dup_tok(p))) { + free_ccs_value(v); + return NULL; + } else { + char *tmp; + /* strip \'s */ + while((tmp = strstr(v->v.str, "\\"))){ + strcpy(tmp, tmp+1); + } + } + p->te++; + match(TOK_STRING); + break; + + default: + fprintf(stderr, "Error on line %d\n", p->line); + free_ccs_value(v); + return NULL; + } + return v; +} + + +static int _match_aux(struct parser *p, int t){ + if (p->t != t){ + return 0; + } + _get_token(p); + + return 1; +} + + +static ccs_value_t *_create_value(void){ + ccs_value_t *v = (ccs_value_t *)malloc(sizeof(ccs_value_t)); + if(v){ + memset(v, 0, sizeof(ccs_value_t)); + return v; + } + return NULL; +} + + +static ccs_node_t *_create_node(void){ + ccs_node_t *n = (ccs_node_t *)malloc(sizeof(ccs_node_t)); + if(n){ + memset(n, 0, sizeof(ccs_node_t)); + return n; + } + return NULL; +} + + +static char *_dup_tok(struct parser *p){ + int len = p->te - p->tb; + char *str = (char *)malloc(len + 1); + if (!str) { + return NULL; + } + strncpy(str, p->tb, len); + str[len] = '\0'; + return str; +} + + +static int get_ccs_file(int fd, char **file_data, char *filename){ + int error = 0; + int size; + char *data=NULL; + char *beginning, *end; + char search_str[128]; + + if((size = lseek(fd, 0, SEEK_END)) < 0){ + fprintf(stderr, "Unable to seek to end of archive: %s\n", strerror(errno)); + error = -errno; + goto fail; + } + + if(lseek(fd, 0, SEEK_SET) < 0){ + fprintf(stderr, "Bad lseek on archive: %s\n", strerror(errno)); + error = -errno; + goto fail; + } + + size++; + data = malloc(size); + memset(data, 0, size); + size--; + + if(read(fd, data, size) != size){ + fprintf(stderr, "Unable to read entire archive.\n"); + error = -EIO; + goto fail; + } + + sprintf(search_str, "#nigeb=%s mtime=", filename); + beginning = strstr(data, search_str); + if(!beginning){ + fprintf(stderr, "Unable to find %s in the archive.\n", filename); + error = -ENOENT; + goto fail; + } + beginning = strstr(beginning, "\n"); + if(!beginning){ + fprintf(stderr, "Unable to find %s in the archive.\n", filename); + error = -ENOENT; + goto fail; + } + beginning++; /* skip newline */ + + sprintf(search_str, "#dne=%s", filename); + end = strstr(beginning, search_str); + if(!end){ + fprintf(stderr, "Unable to find the end of %s in the archive.\n", filename); + error = -ENOENT; + goto fail; + } + + size = end - beginning; + + *file_data = malloc(size+1); + if(!file_data){ + fprintf(stderr, "Unable to allocate memory for CCS file.\n"); + error = -ENOMEM; + goto fail; + } + memset(*file_data, 0, size+1); + + memcpy(*file_data, beginning, size); + + fail: + if(data) free(data); + return error; +} + + +static int parse_filedata(ccs_node_t **cn, char *filedata){ + int error=0; + parser_t p; + + memset(&p, 0, sizeof(p)); + if(!filedata){ + error = -ENODATA; + goto fail; + } + p.db = p.data = filedata; + p.line =1; + p.de = (char *)(filedata + strlen(filedata)); + + p.tb = p.te = p.db; + _get_token(&p); + if(!(*cn = _file(&p))){ + error = -EPARSE; + } + + fail: + return error; +} + + +/* + * parse_ccs_file + * @cf: + * + * Returns: 0 on success, -EXXX on error + */ +int parse_ccs_file(int fd, ccs_node_t **cn, char *filename){ + int error; + char *file_data = NULL; + + error = get_ccs_file(fd, &file_data, filename); + if(error < 0){ + goto fail; + } + /* This is where the magic happens */ + error = parse_filedata(cn, file_data); + + fail: + if(file_data) free(file_data); + return error; +} + + +static int _tok_match(const char *str, const char *b, const char *e) +{ + while (*str && (b != e)) { + if (*str++ != *b++) + return 0; + } + + return !(*str || (b != e)); +} + + +ccs_node_t *find_ccs_node(ccs_node_t *cn, + const char *path, + char sep){ + const char *e; + while (cn) { + /* trim any leading slashes */ + while (*path && (*path == sep)) + path++; + + /* find the end of this segment */ + for (e = path; *e && (*e != sep); e++) ; + + /* hunt for the node */ + while (cn) { + if (_tok_match(cn->key, path, e)) + break; + + cn = cn->sib; + } + + if (cn && *e) + cn = cn->child; + else + break; /* don't move into the last node */ + + path = e; + } + + return cn; +} + + +const char *find_ccs_str(ccs_node_t *cn, + const char *path, + char sep, + const char *fail){ + ccs_node_t *n = find_ccs_node(cn, path, sep); + + if (n && n->v && n->v->type == CCS_STRING) { + return n->v->v.str; + } + + return fail; +} + + +int find_ccs_int(ccs_node_t *cn, + const char *path, + char sep, + int fail){ + ccs_node_t *n = find_ccs_node(cn, path, sep); + + if (n && n->v && n->v->type == CCS_INT) { + return n->v->v.i; + } + + return fail; +} + +#ifndef __KERNEL__ +float find_ccs_float(ccs_node_t *cn, + const char *path, + char sep, + float fail){ + ccs_node_t *n = find_ccs_node(cn, path, sep); + + if (n && n->v && n->v->type == CCS_FLOAT) { + return n->v->v.r; + } + + return fail; +} +#endif + +static int _str_in_array(const char *str, const char *values[]){ + int i; + + for (i = 0; values[i]; i++){ + if (!strcasecmp(str, values[i])) + return 1; + } + return 0; +} + + +static int _str_to_bool(const char *str, int fail){ + static const char *_true_values[] = { "y", "yes", "on", "true", NULL }; + static const char *_false_values[] = { "n", "no", "off", "false", NULL }; + + if (_str_in_array(str, _true_values)) + return 1; + + if (_str_in_array(str, _false_values)) + return 0; + + return fail; +} + +int find_ccs_bool(ccs_node_t *cn, + const char *path, + char sep, + int fail){ + ccs_node_t *n = find_ccs_node(cn, path, sep); + ccs_value_t *v; + + if (!n) + return fail; + + v = n->v; + + if(!v) + return fail; + + switch (v->type) { + case CCS_INT: + return v->v.i ? 1 : 0; + + case CCS_STRING: + return _str_to_bool(v->v.str, fail); + } + + return fail; +} diff --git a/ccs/ccs_tool/old_parser.h b/ccs/ccs_tool/old_parser.h new file mode 100644 index 0000000..275dcd7 --- /dev/null +++ b/ccs/ccs_tool/old_parser.h @@ -0,0 +1,64 @@ +#ifndef __OLD_PARSER_H__ +#define __OLD_PARSER_H__ + +/* A special error number for CCS. This error indicates that there was ** +** an error while parsing data. This number should not collide with ** +** other Linux error numbers, however, if someone has a better errno in ** +** mind, please let me know............................................ */ +#define EPARSE 2050 + +enum { + CCS_STRING, + CCS_FLOAT, + CCS_INT, +}; + + +typedef struct ccs_value { + int type; + union { + int i; + float r; + char *str; + } v; + struct ccs_value *next; /* for arrays */ +} ccs_value_t; + +typedef struct ccs_node_s{ + char *key; + struct ccs_node_s *sib, *child; + struct ccs_value *v; +} ccs_node_t; + + +void free_ccs_node(ccs_node_t *cn); + +int parse_ccs_file(int fd, ccs_node_t **cn, char *filename); + +ccs_node_t *find_ccs_node(ccs_node_t *cn, + const char *path, + char seperator); + +const char *find_ccs_str(ccs_node_t *cn, + const char *path, + char sep, + const char *fail); + +int find_ccs_int(ccs_node_t *cn, + const char *path, + char sep, + int fail); + +#ifndef __KERNEL__ +float find_ccs_float(ccs_node_t *cn, + const char *path, + char sep, + float fail); +#endif + +int find_ccs_bool(ccs_node_t *cn, + const char *path, + char sep, + int fail); + +#endif /* __OLD_PARSER_H__ */ diff --git a/ccs/ccs_tool/upgrade.c b/ccs/ccs_tool/upgrade.c new file mode 100644 index 0000000..a8a2314 --- /dev/null +++ b/ccs/ccs_tool/upgrade.c @@ -0,0 +1,259 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "old_parser.h" + +#define DEFAULT_BBS 16384 /* default basic block size */ + + +static int upgrade_file_archive(char *location); +static int upgrade_device_archive(char *location); + +int upgrade(char *location){ + struct stat stat_buf; + + if(stat(location, &stat_buf)){ + fprintf(stderr, "Unable to stat %s: %s\n", location, strerror(errno)); + return -errno; + } + + if(S_ISBLK(stat_buf.st_mode)){ + return upgrade_device_archive(location); + } else { + return upgrade_file_archive(location); + } +} + +static int _upgrade_file_archive(int fd){ + int error = 0; + ccs_node_t *cluster_cn = NULL; + ccs_node_t *fence_cn = NULL; + ccs_node_t *nodes_cn = NULL; + ccs_node_t *tmp_cn; + + if((error = parse_ccs_file(fd, &cluster_cn, "cluster.ccs"))){ + return error; + } + + if((error = parse_ccs_file(fd, &nodes_cn, "nodes.ccs"))){ + return error; + } + + if((error = parse_ccs_file(fd, &fence_cn, "fence.ccs"))){ + return error; + } + + tmp_cn = find_ccs_node(cluster_cn, "cluster/name", '/'); + if(!tmp_cn || !tmp_cn->v){ + fprintf(stderr, "Unable to find cluster name.\n"); + error = -EINVAL; + goto fail; + } + + printf("\n", tmp_cn->v->v.str); + + /* No cman on upgrade + printf("\n\n"); + printf("\n"); + */ + + tmp_cn = find_ccs_node(cluster_cn, "cluster/lock_gulm/servers", '/'); + printf("\n\n"); + if(tmp_cn && tmp_cn->v){ + ccs_value_t *server; + for(server = tmp_cn->v; server; server = server->next) + printf(" \n", server->v.str); + } + printf("\n"); + + printf("\n\n"); + + for(tmp_cn = nodes_cn->child; tmp_cn; tmp_cn = tmp_cn->sib){ + ccs_node_t *fence, *method, *device, *params; + + printf("\n \n", tmp_cn->key); + for(fence = tmp_cn->child; fence; fence = fence->sib){ + if(!strcmp(fence->key, "fence")){ + printf(" \n"); + for(method = fence->child; method; method = method->sib){ + printf(" \n", method->key); + for(device = method->child; device; device=device->sib){ + printf(" key); + for(params = device->child; params; params = params->sib){ + if (params->v->type == CCS_STRING) + printf(" %s=\"%s\"", params->key, params->v->v.str); + else if (params->v->type == CCS_INT) + printf(" %s=\"%d\"", params->key, params->v->v.i); + else if (params->v->type == CCS_FLOAT) + printf(" %s=[DECIMAL NOT CONVERTED]", params->key); + else + printf(" %s=[BAD TYPE CONVERSION]", params->key); + } + printf("/>\n"); + } + printf(" \n"); + } + printf(" \n"); + } + } + printf(" \n"); + } + + printf("\n\n"); + + printf("\n\n"); + for(tmp_cn = fence_cn->child; tmp_cn; tmp_cn = tmp_cn->sib){ + ccs_node_t *params; + + printf(" key); + for(params = tmp_cn->child; params; params = params->sib){ + printf(" %s=\"%s\"", params->key, params->v->v.str); + } + printf("/>\n"); + } + + printf("\n\n"); + + printf("\n"); + + fail: + if(cluster_cn) free_ccs_node(cluster_cn); + if(fence_cn) free_ccs_node(fence_cn); + if(nodes_cn) free_ccs_node(nodes_cn); + return error; +} + +static int upgrade_file_archive(char *location){ + int error = 0; + int fd=-1; + + if((fd = open(location, O_RDONLY)) < 0){ + fprintf(stderr, "Unable to open %s: %s\n", location, strerror(errno)); + error = -errno; + goto fail; + } + + error = _upgrade_file_archive(fd); + + fail: + if(fd >= 0) close(fd); + return error; +} + + +#define CCS_DH_MAGIC 0x122473 + +/* CCS Device Header */ +typedef struct ccs_dh_s { + u_int32_t dh_magic; + u_int32_t dh_format; + u_int32_t dh_generation; + u_int32_t dh_active; + u_int32_t dh_size; /* Size of archive on disk */ + u_int32_t dh_maxsize; + char dh_reserved[64]; +} ccs_dh_t; + +static void ccs_dh_in(ccs_dh_t *dh, char *buf){ + ccs_dh_t *tmp = (ccs_dh_t *)buf; + +#if __BYTE_ORDER == __BIG_ENDIAN + dh->dh_magic = tmp->dh_magic; + dh->dh_active = tmp->dh_active; + dh->dh_size = tmp->dh_size; + dh->dh_maxsize = tmp->dh_maxsize; +#else + dh->dh_magic = bswap_32(tmp->dh_magic); + dh->dh_active = bswap_32(tmp->dh_active); + dh->dh_size = bswap_32(tmp->dh_size); + dh->dh_maxsize = bswap_32(tmp->dh_maxsize); +#endif +} + +static int upgrade_device_archive(char *location){ + int error = 0; + int dev_fd=-1, tmp_fd=-1; + char tmp_file[64]; + void *buffer = NULL; + char *buffer_p; + ccs_dh_t dev_header; + + if(posix_memalign(&buffer, DEFAULT_BBS, DEFAULT_BBS)){ + fprintf(stderr, "Unable to allocate aligned memory.\n"); + return -ENOMEM; + } + buffer_p = (char *)buffer; + + if((dev_fd = open(location, O_RDONLY | O_DIRECT)) < 0){ + fprintf(stderr, "Unable to open %s: %s\n", location, strerror(errno)); + error = -errno; + goto fail; + } + + if(read(dev_fd, buffer_p, DEFAULT_BBS) < DEFAULT_BBS){ + fprintf(stderr, "Unable to read %s: %s\n", location, strerror(errno)); + error = -errno; + goto fail; + } + + ccs_dh_in(&dev_header, buffer_p); + if(dev_header.dh_magic == CCS_DH_MAGIC){ + if(!dev_header.dh_active){ + if(lseek(dev_fd, dev_header.dh_maxsize, SEEK_SET)< 0){ + fprintf(stderr, "Unable to lseek in %s: %s\n", location, strerror(errno)); + error = -errno; + goto fail; + } + } + } else { + fprintf(stderr, "The specified device does not contain a CCS archive.\n"); + error = -EINVAL; + goto fail; + } + + sprintf(tmp_file, "/tmp/tmp_%d", getpid()); + + tmp_fd = open(tmp_file, O_RDWR | O_CREAT |O_TRUNC, S_IRUSR|S_IWUSR); + if(tmp_fd < 0){ + fprintf(stderr, "Unable to create temporary archive: %s\n", strerror(errno)); + error = -errno; + goto fail; + } + unlink(tmp_file); + + while(dev_header.dh_size){ + int write_size; + if(read(dev_fd, buffer_p, DEFAULT_BBS) < DEFAULT_BBS){ + fprintf(stderr, "Bad read on %s: %s.\n", location, strerror(errno)); + error = -errno; + goto fail; + } + write_size = (dev_header.dh_size < DEFAULT_BBS) ? + dev_header.dh_size : DEFAULT_BBS; + if(write(tmp_fd, buffer_p, write_size) < write_size){ + fprintf(stderr, "Unable to write to temporary archive: %s.\n", strerror(errno)); + error = -errno; + goto fail; + } + dev_header.dh_size -= write_size; + } + lseek(tmp_fd, 0, SEEK_SET); + + error = _upgrade_file_archive(tmp_fd); + + fail: + if(buffer_p) free(buffer_p); + if(dev_fd >= 0) close(dev_fd); + if(tmp_fd >= 0) close(tmp_fd); + return error; +} + diff --git a/ccs/ccs_tool/upgrade.h b/ccs/ccs_tool/upgrade.h new file mode 100644 index 0000000..6f784c1 --- /dev/null +++ b/ccs/ccs_tool/upgrade.h @@ -0,0 +1,6 @@ +#ifndef __UPGRADE_DOT_H__ +#define __UPGRADE_DOT_H__ + +int upgrade(char *location); + +#endif /* __UPGRADE_DOT_H__ */ hooks/post-receive -- Cluster Project