static int listener_init (ctx_t *ctx, char *sockpath) { struct sockaddr_un addr; int fd; fd = socket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); if (fd < 0) { flux_log (ctx->h, LOG_ERR, "socket: %s", strerror (errno)); goto done; } if (remove (sockpath) < 0 && errno != ENOENT) { flux_log (ctx->h, LOG_ERR, "remove %s: %s", sockpath, strerror (errno)); goto error_close; } memset (&addr, 0, sizeof (struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy (addr.sun_path, sockpath, sizeof (addr.sun_path) - 1); if (bind (fd, (struct sockaddr *)&addr, sizeof (struct sockaddr_un)) < 0) { flux_log (ctx->h, LOG_ERR, "bind: %s", strerror (errno)); goto error_close; } if (listen (fd, LISTEN_BACKLOG) < 0) { flux_log (ctx->h, LOG_ERR, "listen: %s", strerror (errno)); goto error_close; } done: cleanup_push_string(cleanup_file, sockpath); return fd; error_close: close (fd); return -1; }
static sqlite_ctx_t *getctx (flux_t *h) { sqlite_ctx_t *ctx = (sqlite_ctx_t *)flux_aux_get (h, "flux::content-sqlite"); const char *dir; const char *tmp; bool cleanup = false; if (!ctx) { if (!(ctx = calloc (1, sizeof (*ctx)))) goto error; if (!(ctx->lzo_buf = calloc (1, lzo_buf_chunksize))) goto error; ctx->lzo_bufsize = lzo_buf_chunksize; ctx->h = h; if (!(ctx->hashfun = flux_attr_get (h, "content.hash"))) { flux_log_error (h, "content.hash"); goto error; } if (!(tmp = flux_attr_get (h, "content.blob-size-limit"))) { flux_log_error (h, "content.blob-size-limit"); goto error; } ctx->blob_size_limit = strtoul (tmp, NULL, 10); if (!(dir = flux_attr_get (h, "persist-directory"))) { if (!(dir = flux_attr_get (h, "broker.rundir"))) { flux_log_error (h, "broker.rundir"); goto error; } cleanup = true; } if (asprintf (&ctx->dbdir, "%s/content", dir) < 0) goto error; if (mkdir (ctx->dbdir, 0755) < 0 && errno != EEXIST) { flux_log_error (h, "mkdir %s", ctx->dbdir); goto error; } if (cleanup) cleanup_push_string (cleanup_directory_recursive, ctx->dbdir); if (asprintf (&ctx->dbfile, "%s/sqlite", ctx->dbdir) < 0) goto error; if (sqlite3_open (ctx->dbfile, &ctx->db) != SQLITE_OK) { flux_log_error (h, "sqlite3_open %s", ctx->dbfile); goto error; } if (sqlite3_exec (ctx->db, "PRAGMA journal_mode=OFF", NULL, NULL, NULL) != SQLITE_OK || sqlite3_exec (ctx->db, "PRAGMA synchronous=OFF", NULL, NULL, NULL) != SQLITE_OK || sqlite3_exec (ctx->db, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, NULL) != SQLITE_OK) { log_sqlite_error (ctx, "setting sqlite pragmas"); goto error_sqlite; } if (sqlite3_exec (ctx->db, sql_create_table, NULL, NULL, NULL) != SQLITE_OK) { log_sqlite_error (ctx, "creating table"); goto error_sqlite; } if (sqlite3_prepare_v2 (ctx->db, sql_load, -1, &ctx->load_stmt, NULL) != SQLITE_OK) { log_sqlite_error (ctx, "preparing load stmt"); goto error_sqlite; } if (sqlite3_prepare_v2 (ctx->db, sql_store, -1, &ctx->store_stmt, NULL) != SQLITE_OK) { log_sqlite_error (ctx, "preparing store stmt"); goto error_sqlite; } if (sqlite3_prepare_v2 (ctx->db, sql_dump, -1, &ctx->dump_stmt, NULL) != SQLITE_OK) { log_sqlite_error (ctx, "preparing dump stmt"); goto error_sqlite; } if (flux_aux_set (h, "flux::content-sqlite", ctx, freectx) < 0) goto error; } return ctx; error_sqlite: set_errno_from_sqlite_error (ctx); error: freectx (ctx); return NULL; }
int main(int argc, char** argv) { const char *tmp = getenv ("TMPDIR"); char file[PATH_MAX]; char dir[PATH_MAX]; char dir2[PATH_MAX]; struct stat sb; int fd, len; plan (NO_PLAN); /* Independent file and dir */ len = snprintf (file, sizeof (file), "%s/cleanup_test.XXXXXX", tmp ? tmp : "/tmp"); if ((len < 0) || (len >= sizeof (file))) BAIL_OUT ("snprintf failed creating tmp file path"); if (!(fd = mkstemp (file))) BAIL_OUT ("could not create tmp file"); close (fd); len = snprintf (dir, sizeof (dir), "%s/cleanup_test.XXXXXX", tmp ? tmp : "/tmp"); if ((len < 0) || (len >= sizeof (dir))) BAIL_OUT ("snprintf failed creating tmp directory"); if (!mkdtemp (dir)) BAIL_OUT ("could not create tmp directory"); cleanup_push_string (cleanup_file, file); cleanup_push_string (cleanup_directory, dir); cleanup_run (); ok (stat (file, &sb) < 0 && errno == ENOENT, "cleanup removed independent file"); ok (stat (dir, &sb) < 0 && errno == ENOENT, "cleanup removed independent dir"); /* This time put file inside directory */ len = snprintf (dir, sizeof (dir), "%s/cleanup_test.XXXXXX", tmp ? tmp : "/tmp"); if ((len < 0) || (len >= sizeof (dir))) BAIL_OUT ("snprintf failed creating tmp directory"); if (!mkdtemp (dir)) BAIL_OUT ("could not create tmp directory"); len = snprintf (file, sizeof (file), "%s/file", dir); if ((len < 0) || (len >= sizeof (file))) BAIL_OUT ("snprintf failed creating tmp file path"); if (!(fd = open (file, O_CREAT, 0644))) BAIL_OUT ("could not create tmp file"); close (fd); cleanup_push_string (cleanup_directory, dir); cleanup_push_string (cleanup_file, file); cleanup_run (); ok (stat (file, &sb) < 0 && errno == ENOENT, "cleanup removed file pushed second"); ok (stat (dir, &sb) < 0 && errno == ENOENT, "cleanup removed dir pushed first"); /* Same but reverse push order */ len = snprintf (dir, sizeof (dir), "%s/cleanup_test.XXXXXX", tmp ? tmp : "/tmp"); if ((len < 0) || (len >= sizeof (dir))) BAIL_OUT ("snprintf failed creating tmp directory"); if (!mkdtemp (dir)) BAIL_OUT ("could not create tmp directory"); len = snprintf (file, sizeof (file), "%s/file", dir); if ((len < 0) || (len >= sizeof (file))) BAIL_OUT ("snprintf failed creating tmp file path"); if (!(fd = open (file, O_CREAT, 0644))) BAIL_OUT ("could not create tmp file"); close (fd); cleanup_push_string (cleanup_file, file); cleanup_push_string (cleanup_directory, dir); cleanup_run (); ok (stat (dir, &sb) == 0, "cleanup failed to remove dir pushed first"); ok (stat (file, &sb) < 0 && errno == ENOENT, "cleanup removed file pushed second (1 deep)"); if (rmdir (dir) < 0) BAIL_OUT ("rmdir %s failed", dir); /* Same but recursive removal */ len = snprintf (dir, sizeof (dir), "%s/cleanup_test.XXXXXX", tmp ? tmp : "/tmp"); if ((len < 0) || (len >= sizeof (dir))) BAIL_OUT ("snprintf failed creating tmp directory"); if (!mkdtemp (dir)) BAIL_OUT ("could not create tmp directory"); len = snprintf (file, sizeof (file), "%s/file", dir); if ((len < 0) || (len >= sizeof (file))) BAIL_OUT ("snprintf failed creating tmp file path"); if (!(fd = open (file, O_CREAT, 0644))) BAIL_OUT ("could not create tmp file"); close (fd); cleanup_push_string (cleanup_directory_recursive, dir); cleanup_run (); ok (stat (file, &sb) < 0 && errno == ENOENT, "cleanup removed file not pushed (1 deep)"); ok (stat (dir, &sb) < 0 && errno == ENOENT, "cleanup removed pushed dir recursively"); /* Try couple levels deep */ len = snprintf (dir, sizeof (dir), "%s/cleanup_test.XXXXXX", tmp ? tmp : "/tmp"); if ((len < 0) || (len >= sizeof (dir))) BAIL_OUT ("snprintf failed creating tmp dir path"); if (!mkdtemp (dir)) BAIL_OUT ("could not create tmp directory"); len = snprintf (dir2, sizeof (dir2), "%s/dir", dir); if ((len < 0) || (len >= sizeof (dir2))) BAIL_OUT ("snprintf failed creating tmp dir path"); if (mkdir (dir2, 0755) < 0) BAIL_OUT ("mkdir failed"); len = snprintf (file, sizeof (file), "%s/file", dir2); if ((len < 0) || (len >= sizeof (file))) BAIL_OUT ("snprintf failed creating tmp file path"); if (!(fd = open (file, O_CREAT, 0644))) BAIL_OUT ("could not create tmp file"); close (fd); cleanup_push_string (cleanup_directory_recursive, dir); cleanup_run (); ok (stat (file, &sb) < 0 && errno == ENOENT, "cleanup removed file not pushed (2 deep)"); ok (stat (dir2, &sb) < 0 && errno == ENOENT, "cleanup removed dir not pushed (1 deep)"); ok (stat (dir, &sb) < 0 && errno == ENOENT, "cleanup removed pushed dir recursively"); done_testing(); }