* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amcleanupdisk.c,v 1.16 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amcleanupdisk.c 7238 2007-07-06 20:03:37Z dustin $
*/
#include "amanda.h"
#include "infofile.h"
#include "server_util.h"
-sl_t *holding_list;
-char *datestamp;
+/* Utility funcitons */
-/* local functions */
-int main P((int argc, char **argv));
-void check_holdingdisk P((char *diskdir, char *datestamp));
-void check_disks P((void));
-
-int main(main_argc, main_argv)
-int main_argc;
-char **main_argv;
+/* Call open_infofile() with the infofile from the configuration
+ */
+static void
+init_infofile(void)
{
- struct passwd *pw;
- char *dumpuser;
- disklist_t diskq;
- char *conffile;
- char *conf_diskfile;
- char *conf_infofile;
-
- safe_fd(-1, 0);
- safe_cd();
-
- set_pname("amcleanupdisk");
-
- /* Don't die when child closes pipe */
- signal(SIGPIPE, SIG_IGN);
-
- if(main_argc != 2)
- error("Usage: amcleanupdisk%s <confdir>", versionsuffix());
-
- config_name = main_argv[1];
-
- config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
-
- conffile = stralloc2(config_dir, CONFFILE_NAME);
- if(read_conffile(conffile))
- error("errors processing config file \"%s\"", conffile);
- amfree(conffile);
-
- conf_diskfile = getconf_str(CNF_DISKFILE);
- if (*conf_diskfile == '/') {
- conf_diskfile = stralloc(conf_diskfile);
- } else {
- conf_diskfile = stralloc2(config_dir, conf_diskfile);
+ char *conf_infofile = config_dir_relative(getconf_str(CNF_INFOFILE));
+ if (open_infofile(conf_infofile) < 0) {
+ error(_("could not open info db \"%s\""), conf_infofile);
+ /*NOTREACHED*/
}
- if (read_diskfile(conf_diskfile, &diskq) < 0)
- error("could not load disklist %s", conf_diskfile);
- amfree(conf_diskfile);
-
- conf_infofile = getconf_str(CNF_INFOFILE);
- if (*conf_infofile == '/') {
- conf_infofile = stralloc(conf_infofile);
- } else {
- conf_infofile = stralloc2(config_dir, conf_infofile);
- }
- if (open_infofile(conf_infofile) < 0)
- error("could not open info db \"%s\"", conf_infofile);
amfree(conf_infofile);
-
- datestamp = construct_datestamp(NULL);
-
- dumpuser = getconf_str(CNF_DUMPUSER);
- if((pw = getpwnam(dumpuser)) == NULL)
- error("dumpuser %s not found in password file", dumpuser);
- if(pw->pw_uid != getuid())
- error("must run amcleanupdisk as user %s", dumpuser);
-
- holding_list = pick_all_datestamp(1);
-
- check_disks();
-
- close_infofile();
-
- free_sl(holding_list);
- holding_list = NULL;
- amfree(config_dir);
- return 0;
}
-
-void check_holdingdisk(diskdir, datestamp)
-char *diskdir, *datestamp;
+/* A callback for holding_cleanup to mark corrupt DLEs with force_no_bump
+ * for their next run.
+ *
+ * @param hostname: hostname of DLE
+ * @param disk: disk of DLE
+ */
+static void
+corrupt_dle(
+ char *hostname,
+ char *disk)
{
- DIR *workdir;
- struct dirent *entry;
- char *dirname = NULL;
- char *tmpname = NULL;
- char *destname = NULL;
- char *hostname = NULL;
- char *diskname = NULL;
- disk_t *dp;
- filetype_t filetype;
info_t info;
- int level;
- int dl, l;
- dirname = vstralloc(diskdir, "/", datestamp, NULL);
- dl = strlen(dirname);
+ dbprintf(_("Corrupted dump of DLE %s:%s found; setting force-no-bump.\n"),
+ hostname, disk);
- if((workdir = opendir(dirname)) == NULL) {
- amfree(dirname);
- return;
+ get_info(hostname, disk, &info);
+ info.command &= ~FORCE_BUMP;
+ info.command |= FORCE_NO_BUMP;
+ if(put_info(hostname, disk, &info)) {
+ dbprintf(_("could not put info record for %s:%s: %s"),
+ hostname, disk, strerror(errno));
}
+}
- while((entry = readdir(workdir)) != NULL) {
- if(is_dot_or_dotdot(entry->d_name)) {
- continue;
- }
+int
+main(
+ int argc,
+ char ** argv)
+{
+ FILE *verbose_output = NULL;
+ char *cfg_opt = NULL;
+ char *conf_diskfile;
+ disklist_t diskq;
- if((l = strlen(entry->d_name)) < 7 ) {
- continue;
- }
+ /*
+ * Configure program for internationalization:
+ * 1) Only set the message locale for now.
+ * 2) Set textdomain for all amanda related programs to "amanda"
+ * We don't want to be forced to support dozens of message catalogs.
+ */
+ setlocale(LC_MESSAGES, "C");
+ textdomain("amanda");
- if(strncmp(&entry->d_name[l-4],".tmp",4) != 0) {
- continue;
- }
+ safe_fd(-1, 0);
+ safe_cd();
- tmpname = newvstralloc(tmpname,
- dirname, "/", entry->d_name,
- NULL);
+ set_pname("amcleanupdisk");
- destname = newstralloc(destname, tmpname);
- destname[dl + 1 + l - 4] = '\0';
+ dbopen(DBG_SUBDIR_SERVER);
- amfree(hostname);
- amfree(diskname);
- filetype = get_amanda_names(tmpname, &hostname, &diskname, &level);
- if(filetype != F_DUMPFILE) {
- continue;
- }
+ if(argc < 2) {
+ error(_("Usage: amcleanupdisk%s <config>"), versionsuffix());
+ /*NOTREACHED*/
+ }
- dp = lookup_disk(hostname, diskname);
+ /* parse options */
+ if (argc >= 2 && strcmp(argv[1], "-v") == 0) {
+ verbose_output = stderr;
+ cfg_opt = argv[2];
+ } else {
+ cfg_opt = argv[1];
+ }
- if (dp == NULL) {
- continue;
- }
+ config_init(CONFIG_INIT_EXPLICIT_NAME,
+ cfg_opt);
- if(level < 0 || level > 9) {
- continue;
- }
+ conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
+ read_diskfile(conf_diskfile, &diskq);
+ /* diskq also ends up in a global, used by holding_cleanup */
+ amfree(conf_diskfile);
- if(rename_tmp_holding(destname, 0)) {
- get_info(dp->host->hostname, dp->name, &info);
- info.command &= ~FORCE_BUMP;
- info.command |= FORCE_NO_BUMP;
- if(put_info(dp->host->hostname, dp->name, &info)) {
- error("could not put info record for %s:%s: %s",
- dp->host->hostname, dp->name, strerror(errno));
- }
- } else {
- fprintf(stderr,"rename_tmp_holding(%s) failed\n", destname);
+ if (config_errors(NULL) >= CFGERR_WARNINGS) {
+ config_print_errors();
+ if (config_errors(NULL) >= CFGERR_ERRORS) {
+ g_critical(_("errors processing config file"));
}
}
- closedir(workdir);
- /* try to zap the potentially empty working dir */
- /* ignore any errors -- it either works or it doesn't */
- (void) rmdir(dirname);
+ check_running_as(RUNNING_AS_DUMPUSER);
- amfree(diskname);
- amfree(hostname);
- amfree(destname);
- amfree(dirname);
-}
+ dbrename(get_config_name(), DBG_SUBDIR_SERVER);
+ init_infofile();
-void check_disks()
-{
- holdingdisk_t *hdisk;
- sle_t *dir;
+ /* actually perform the cleanup */
+ holding_cleanup(corrupt_dle, verbose_output);
- for(dir = holding_list->first; dir !=NULL; dir = dir->next) {
- for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next)
- check_holdingdisk(hdisk->diskdir, dir->name);
- }
+ close_infofile();
+ return 0;
}
+