diff options
| author | Nicolas Williams <nico@cryptonector.com> | 2012-08-17 18:19:31 -0500 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2012-10-05 13:54:20 -0400 |
| commit | 4fd4144b3222b060f3e9928a9cb4587df9979539 (patch) | |
| tree | d0260c405fd3dc1e41976dc4e9cc7d5193d011ba /src/kadmin/server | |
| parent | 0d4f7d520f269c034c639f5b382b9f009848f482 (diff) | |
Use a single global dump for iprop full syncs
Use a global dump (the default dump file) for full syncs for iprop.
When a slave asks for a fullsync we kprop the existing global dump to it
if that is good enough, else we dump the DB and send the new global
dump.
Before this change kadmind would run kdb5_util dump -i... each time a
slave asked for a full dump. This was done in a sub-process,
thankfully, but it was still a waste of time and storage (e.g., if one
has a huge KDB).
Also, long dump times might cause a slave to give up (the timeout for
this is now configurable). But since iprop dumps bear a serial number
and timestamp and since slaves will resync from that point forward, it
doesn't matter if the dump we send a slave is fresh as long as it is
fresh enough (i.e., that its sno and timestamp are in the ulog).
Also:
- Rename dumps into place instead of unlink, create, write (but we
still keep the dump ok files as lock files and as a method of
signaling to kprop that the dump is complete).
ticket: 7371
Diffstat (limited to 'src/kadmin/server')
| -rw-r--r-- | src/kadmin/server/ipropd_svc.c | 68 |
1 files changed, 34 insertions, 34 deletions
diff --git a/src/kadmin/server/ipropd_svc.c b/src/kadmin/server/ipropd_svc.c index 0e45f6a17..19c1bac95 100644 --- a/src/kadmin/server/ipropd_svc.c +++ b/src/kadmin/server/ipropd_svc.c @@ -246,10 +246,10 @@ static kdb_fullresync_result_t * ipropx_resync(uint32_t vers, struct svc_req *rqstp) { static kdb_fullresync_result_t ret; - char *tmpf = 0; char *ubuf = 0; char clhost[MAXHOSTNAMELEN] = {0}; int pret, fret; + FILE *p; kadm5_server_handle_t handle = global_server_handle; OM_uint32 min_stat; gss_name_t name = NULL; @@ -320,23 +320,21 @@ ipropx_resync(uint32_t vers, struct svc_req *rqstp) } /* - * construct db dump file name; kprop style name + clnt fqdn - */ - if (asprintf(&tmpf, "%s_%s", KPROP_DEFAULT_FILE, clhost) < 0) { - krb5_klog_syslog(LOG_ERR, - _("%s: unable to construct db dump file name; out of memory"), - whoami); - goto out; - } - - /* - * note the -i; modified version of kdb5_util dump format + * Note the -i; modified version of kdb5_util dump format * to include sno (serial number). This argument is now * versioned (-i0 for legacy dump format, -i1 for ipropx - * version 1 format, etc) + * version 1 format, etc). + * + * The -c option ("conditional") causes the dump to dump only if no + * dump already exists or that dump is not in ipropx format, or the + * sno and timestamp in the header of that dump are outside the + * ulog. This allows us to share a single global dump with all + * slaves, since it's OK to share an older dump, as long as its sno + * and timestamp are in the ulog (then the slaves can get the + * subsequent updates very iprop). */ - if (asprintf(&ubuf, "%s dump -i%d %s </dev/null 2>&1", - KPROPD_DEFAULT_KDB5_UTIL, vers, tmpf) < 0) { + if (asprintf(&ubuf, "%s dump -i%d -c %s", + KPROPD_DEFAULT_KDB5_UTIL, vers, KPROP_DEFAULT_FILE) < 0) { krb5_klog_syslog(LOG_ERR, _("%s: cannot construct kdb5 util dump string too long; out of memory"), whoami); @@ -366,8 +364,14 @@ ipropx_resync(uint32_t vers, struct svc_req *rqstp) DPRINT(("%s: run `%s' ...\n", whoami, ubuf)); (void) signal(SIGCHLD, SIG_DFL); /* run kdb5_util(1M) dump for IProp */ - /* XXX popen can return NULL; is pclose(NULL) okay? */ - pret = pclose(popen(ubuf, "w")); + p = popen(ubuf, "w"); + if (p == NULL) { + krb5_klog_syslog(LOG_ERR, + _("%s: popen failed: %s"), + whoami, error_message(errno)); + _exit(1); + } + pret = pclose(p); DPRINT(("%s: pclose=%d\n", whoami, pret)); if (pret != 0) { /* XXX popen/pclose may not set errno @@ -384,25 +388,22 @@ ipropx_resync(uint32_t vers, struct svc_req *rqstp) } DPRINT(("%s: exec `kprop -f %s %s' ...\n", - whoami, tmpf, clhost)); + whoami, KPROP_DEFAULT_FILE, clhost)); /* XXX Yuck! */ - if (getenv("KPROP_PORT")) - pret = execl(KPROPD_DEFAULT_KPROP, "kprop", "-f", tmpf, - "-P", getenv("KPROP_PORT"), - clhost, NULL); - else - pret = execl(KPROPD_DEFAULT_KPROP, "kprop", "-f", tmpf, + if (getenv("KPROP_PORT")) { + pret = execl(KPROP_DEFAULT_FILE, "kprop", "-f", + KPROP_DEFAULT_FILE, "-P", getenv("KPROP_PORT"), clhost, NULL); - if (pret == -1) { - if (nofork) { - perror(whoami); - } - krb5_klog_syslog(LOG_ERR, - _("%s: exec failed: %s"), - whoami, - error_message(errno)); - _exit(1); + } else { + pret = execl(KPROP_DEFAULT_FILE, "kprop", "-f", + KPROP_DEFAULT_FILE, clhost, NULL); } + perror(whoami); + krb5_klog_syslog(LOG_ERR, + _("%s: exec failed: %s"), + whoami, + error_message(errno)); + _exit(1); default: /* parent */ ret.ret = UPDATE_OK; @@ -427,7 +428,6 @@ out: free(service_name); if (name) gss_release_name(&min_stat, &name); - free(tmpf); free(ubuf); return (&ret); } |
