GError* meta1_backend_services_poll(struct meta1_backend_s *m1, struct oio_url_s *url, const char *srvtype, gboolean dryrun, gboolean autocreate, gchar ***result) { EXTRA_ASSERT(srvtype != NULL); EXTRA_ASSERT(result != NULL); gboolean renewed = FALSE; struct sqlx_sqlite3_s *sq3 = NULL; GError *err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERONLY, &sq3); if (err) return err; struct sqlx_repctx_s *repctx = NULL; if (!(err = sqlx_transaction_begin(sq3, &repctx))) { if (!(err = __info_user(sq3, url, autocreate, NULL))) { enum m1v2_getsrv_e mode = dryrun ? M1V2_GETSRV_DRYRUN : M1V2_GETSRV_RENEW; err = __get_container_service(sq3, url, srvtype, m1, mode, result, &renewed); if (NULL != err) g_prefix_error(&err, "Query error: "); } if (!(err = sqlx_transaction_end(repctx, err)) && renewed) { if (renewed) __notify_services_by_cid(m1, sq3, url); } } sqlx_repository_unlock_and_close_noerror(sq3); return err; }
GError* meta1_backend_services_set(struct meta1_backend_s *m1, struct oio_url_s *url, const char *packedurl, gboolean autocreate, gboolean force) { struct meta1_service_url_s *m1url; if (!(m1url = meta1_unpack_url(packedurl))) return NEWERROR(CODE_BAD_REQUEST, "Invalid URL"); struct sqlx_sqlite3_s *sq3 = NULL; GError *err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERONLY, &sq3); if (err) { g_free(m1url); return err; } struct sqlx_repctx_s *repctx = NULL; if (!(err = sqlx_transaction_begin(sq3, &repctx))) { if (!(err = __info_user(sq3, url, autocreate, NULL))) err = __save_service(sq3, url, m1url, force); if (!(err = sqlx_transaction_end(repctx, err))) __notify_services_by_cid(m1, sq3, url); } sqlx_repository_unlock_and_close_noerror(sq3); g_free(m1url); /* XXX JFS: ugly quirk until we find a pretty way to distinguish the * commit errors (e.g. it can fail because of a replication error or * a constraint violation) */ if (err && NULL != strstr(err->message, "UNIQUE")) err->code = CODE_SRV_ALREADY; return err; }
GError* meta1_backend_services_config(struct meta1_backend_s *m1, struct oio_url_s *url, const char *packedurl) { struct meta1_service_url_s *m1url; if (!(m1url = meta1_unpack_url(packedurl))) return NEWERROR(CODE_BAD_REQUEST, "Invalid URL"); GRID_DEBUG("About to reconfigure [%s] [%"G_GINT64_FORMAT"] [%s] [%s]", m1url->srvtype, m1url->seq, m1url->host, m1url->args); struct sqlx_sqlite3_s *sq3 = NULL; GError *err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERONLY, &sq3); if (err) { g_free(m1url); return err; } struct sqlx_repctx_s *repctx = NULL; if (!(err = sqlx_transaction_begin(sq3, &repctx))) { if (!(err = __info_user(sq3, url, FALSE, NULL))) err = __configure_service(sq3, url, m1url); if (!(err = sqlx_transaction_end(repctx, err))) __notify_services_by_cid(m1, sq3, url); } sqlx_repository_unlock_and_close_noerror(sq3); g_free(m1url); return err; }
GError* meta1_backend_services_unlink(struct meta1_backend_s *m1, struct oio_url_s *url, const char *srvtype, gchar **urlv) { GError *err = __check_backend_events (m1); if (err) return err; EXTRA_ASSERT(srvtype != NULL); struct sqlx_sqlite3_s *sq3 = NULL; err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERONLY, &sq3); if (err) return err; struct sqlx_repctx_s *repctx = NULL; if (!(err = sqlx_transaction_begin(sq3, &repctx))) { if (!(err = __info_user(sq3, url, FALSE, NULL))) { err = __del_container_services(sq3, url, srvtype, urlv); if (NULL != err) g_prefix_error(&err, "Query error: "); } if (!(err = sqlx_transaction_end(repctx, err))) __notify_services_by_cid(m1, sq3, url); } sqlx_repository_unlock_and_close_noerror(sq3); return err; }
GError * meta1_backend_notify_services(struct meta1_backend_s *m1, struct oio_url_s *url) { struct sqlx_sqlite3_s *sq3 = NULL; GError *err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERSLAVE, &sq3); if (!err) { __notify_services_by_cid(m1, sq3, url); sqlx_repository_unlock_and_close_noerror(sq3); } return err; }
GError* meta1_backend_services_relink(struct meta1_backend_s *m1, struct oio_url_s *url, const char *kept, const char *replaced, gboolean dryrun, gchar ***out) { GError *err = NULL; struct meta1_service_url_s **ukept = NULL, **urepl = NULL; /* fields to be prefetched */ struct grid_lb_iterator_s *iterator = NULL; struct compound_type_s ct; memset (&ct, 0, sizeof(ct)); ukept = __parse_and_expand (kept); urepl = __parse_and_expand (replaced); /* Sanity checks: we must receive at least one service */ if ((!ukept || !*ukept) && (!urepl || !*urepl)) { err = NEWERROR (CODE_BAD_REQUEST, "Missing URL set"); goto out; } /* Sanity check : all the services must have the same <seq,type> */ struct meta1_service_url_s *ref = ukept && *ukept ? *ukept : *urepl; for (struct meta1_service_url_s **p = ukept; p && *p ; ++p) { if (0 != _sorter(p, &ref)) { err = NEWERROR(CODE_BAD_REQUEST, "Mismatch in URL set (%s)", "kept"); goto out; } } for (struct meta1_service_url_s **p = urepl; p && *p ; ++p) { if (0 != _sorter(p, &ref)) { err = NEWERROR(CODE_BAD_REQUEST, "Mismatch in URL set (%s)", "kept"); goto out; } } /* prefetch some fields from the backend: the compound type (so it is * parsed only once), the iterator (so we can already poll services, out * of the sqlite3 transaction) */ if (NULL != (err = compound_type_parse(&ct, ref->srvtype))) { err = NEWERROR(CODE_BAD_REQUEST, "Invalid service type"); goto out; } if (NULL != (err = _get_iterator (m1, &ct, &iterator))) { err = NEWERROR(CODE_BAD_REQUEST, "Service type not managed"); goto out; } /* Call the backend logic now */ struct sqlx_sqlite3_s *sq3 = NULL; struct sqlx_repctx_s *repctx = NULL; if (!(err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERONLY, &sq3))) { if (!(err = sqlx_transaction_begin(sq3, &repctx))) { if (!(err = __info_user(sq3, url, FALSE, NULL))) { struct m1v2_relink_input_s in = { .m1 = m1, .sq3 = sq3, .url = url, .iterator = iterator, .ct = &ct, .kept = ukept, .replaced = urepl, .dryrun = dryrun }; err = __relink_container_services(&in, out); } if (!(err = sqlx_transaction_end(repctx, err))) { if (!dryrun) __notify_services_by_cid(m1, sq3, url); } } sqlx_repository_unlock_and_close_noerror(sq3); } out: meta1_service_url_cleanv (ukept); meta1_service_url_cleanv (urepl); grid_lb_iterator_clean (iterator); compound_type_clean (&ct); return err; }