From: Serge Hallyn Date: Fri, 12 Jul 2013 19:07:23 +0000 (-0500) Subject: lxc_create: prepend pretty header to config file (v2) X-Git-Tag: lxc-1.0.0.alpha1~1^2~122 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3ce746862b2a2b33f3de65aeecda0bad1a5dd27c;p=thirdparty%2Flxc.git lxc_create: prepend pretty header to config file (v2) Define a sha1sum_file() function in utils.c. Use that in lxcapi_create to write out the sha1sum of the template being used. If libgnutls is not found, then the template sha1sum simply won't be printed into the container config. This patch also trivially fixes some cases where SYSERROR is used after a fclose (masking errno) and missing consts in mkdir_p. Signed-off-by: Serge Hallyn --- diff --git a/configure.ac b/configure.ac index 456700185..56638d4ee 100644 --- a/configure.ac +++ b/configure.ac @@ -105,6 +105,8 @@ if test "$enable_apparmor" = "check" ; then fi AM_CONDITIONAL([ENABLE_APPARMOR], [test "x$enable_apparmor" = "xyes"]) +AC_CHECK_LIB([gnutls], [gnutls_hash_fast]) + AM_COND_IF([ENABLE_APPARMOR], [AC_CHECK_HEADER([sys/apparmor.h],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])]) AC_CHECK_LIB([apparmor], [aa_change_profile],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])]) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 446827c0a..0c13e0682 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -870,6 +870,107 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet return true; } +bool prepend_lxc_header(char *path, const char *t, char *const argv[]) +{ + size_t flen; + char *contents, *tpath; + int i, ret; + FILE *f; + unsigned char md_value[SHA_DIGEST_LENGTH]; + bool have_tpath = false; + + if ((f = fopen(path, "r")) == NULL) { + SYSERROR("Opening old config"); + return false; + } + if (fseek(f, 0, SEEK_END) < 0) { + SYSERROR("Seeking to end of old config file"); + fclose(f); + return false; + } + if ((flen = ftell(f)) < 0) { + SYSERROR("telling size of old config"); + fclose(f); + return false; + } + if (fseek(f, 0, SEEK_SET) < 0) { + SYSERROR("rewinding old config"); + fclose(f); + return false; + } + if ((contents = malloc(flen + 1)) == NULL) { + SYSERROR("out of memory"); + fclose(f); + return false; + } + if (fread(contents, 1, flen, f) != flen) { + SYSERROR("Reading old config"); + free(contents); + fclose(f); + return false; + } + contents[flen] = '\0'; + if (fclose(f) < 0) { + SYSERROR("closing old config"); + free(contents); + return false; + } + + if ((tpath = get_template_path(t)) < 0) { + ERROR("bad template: %s\n", t); + free(contents); + return false; + } + +#if HAVE_LIBGNUTLS + if (tpath) { + have_tpath = true; + ret = sha1sum_file(tpath, md_value); + if (ret < 0) { + ERROR("Error getting sha1sum of %s", tpath); + free(contents); + return false; + } + free(tpath); + } +#endif + + if ((f = fopen(path, "w")) == NULL) { + SYSERROR("reopening config for writing"); + free(contents); + return false; + } + fprintf(f, "# Template used to create this container: %s\n", t); + if (argv) { + fprintf(f, "# Parameters passed to the template:"); + while (*argv) { + fprintf(f, " %s", *argv); + argv++; + } + fprintf(f, "\n"); + } +#if HAVE_LIBGNUTLS + if (have_tpath) { + fprintf(f, "# Template script checksum (SHA-1): "); + for (i=0; ilxc_conf) lxc_conf_free(c->lxc_conf); c->lxc_conf = NULL; + + if (!prepend_lxc_header(c->configfile, tpath, argv)) { + ERROR("Error prepending header to configuration file"); + goto out_unlock; + } bret = load_config_locked(c, c->configfile); out_unlock: @@ -1623,13 +1729,13 @@ static int update_name_and_paths(const char *path, struct lxc_container *oldc, } flen = ftell(f); if (flen < 0) { - fclose(f); SYSERROR("telling size of old config"); + fclose(f); return -1; } if (fseek(f, 0, SEEK_SET) < 0) { - fclose(f); SYSERROR("rewinding old config"); + fclose(f); return -1; } contents = malloc(flen+1); @@ -1639,15 +1745,15 @@ static int update_name_and_paths(const char *path, struct lxc_container *oldc, return -1; } if (fread(contents, 1, flen, f) != flen) { + SYSERROR("reading old config"); free(contents); fclose(f); - SYSERROR("reading old config"); return -1; } contents[flen] = '\0'; if (fclose(f) < 0) { - free(contents); SYSERROR("closing old config"); + free(contents); return -1; } diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 136f943a1..c3f734b05 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -37,6 +37,7 @@ #include #include +#include "utils.h" #include "log.h" lxc_log_define(lxc_utils, lxc); @@ -173,10 +174,10 @@ extern int get_u16(unsigned short *val, const char *arg, int base) return 0; } -extern int mkdir_p(char *dir, mode_t mode) +extern int mkdir_p(const char *dir, mode_t mode) { - char *tmp = dir; - char *orig = dir; + const char *tmp = dir; + const char *orig = dir; char *makeme; do { @@ -392,3 +393,57 @@ int lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expected } return ret; } + +#if HAVE_LIBGNUTLS +#include +#include +int sha1sum_file(char *fnam, unsigned char *digest) +{ + char *buf; + int ret; + FILE *f; + long flen; + + if (!fnam) + return -1; + if ((f = fopen(fnam, "r")) < 0) { + SYSERROR("Error opening template"); + return -1; + } + if (fseek(f, 0, SEEK_END) < 0) { + SYSERROR("Error seeking to end of template"); + fclose(f); + return -1; + } + if ((flen = ftell(f)) < 0) { + SYSERROR("Error telling size of template"); + fclose(f); + return -1; + } + if (fseek(f, 0, SEEK_SET) < 0) { + SYSERROR("Error seeking to start of template"); + fclose(f); + return -1; + } + if ((buf = malloc(flen+1)) == NULL) { + SYSERROR("Out of memory"); + fclose(f); + return -1; + } + if (fread(buf, 1, flen, f) != flen) { + SYSERROR("Failure reading template"); + free(buf); + fclose(f); + return -1; + } + if (fclose(f) < 0) { + SYSERROR("Failre closing template"); + free(buf); + return -1; + } + buf[flen] = '\0'; + ret = gnutls_hash_fast(GNUTLS_DIG_SHA1, buf, flen, (void *)digest); + free(buf); + return ret; +} +#endif diff --git a/src/lxc/utils.h b/src/lxc/utils.h index 063f76cce..14b8439d4 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -176,5 +176,9 @@ extern int lxc_wait_for_pid_status(pid_t pid); extern int lxc_write_nointr(int fd, const void* buf, size_t count); extern int lxc_read_nointr(int fd, void* buf, size_t count); extern int lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expected_buf); +#if HAVE_LIBGNUTLS +#define SHA_DIGEST_LENGTH 20 +extern int sha1sum_file(char *fnam, unsigned char *md_value); +#endif #endif