- pr.PoolId = jcr->PoolId;
- if (db_get_pool_record(jcr->db, &pr) && pr.LabelFormat[0] &&
- pr.LabelFormat[0] != '*') {
- if (pr.MaxVols == 0 || pr.NumVols < pr.MaxVols) {
- set_pool_dbr_defaults_in_media_dbr(mr, &pr);
- mr->LabelDate = 0;
- strcpy(mr->MediaType, jcr->store->media_type);
- strcpy(name, pr.LabelFormat);
- if (strchr(name, (int)'%') != NULL) {
- Jmsg(jcr, M_ERROR, 0, _("Illegal character in Label Format\n"));
- return 0;
- }
- strcat(name, "%04d");
- sprintf(mr->VolumeName, name, ++pr.NumVols);
- if (db_create_media_record(jcr->db, mr) &&
- db_update_pool_record(jcr->db, &pr) == 1) {
- Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName);
- return 1;
- } else {
- Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
- }
+ db_lock(jcr->db);
+ pr.PoolId = mr->PoolId;
+ if (!db_get_pool_record(jcr, jcr->db, &pr)) {
+ goto bail_out;
+ }
+ if (pr.MaxVols == 0 || pr.NumVols < pr.MaxVols) {
+ memset(mr, 0, sizeof(MEDIA_DBR));
+ set_pool_dbr_defaults_in_media_dbr(mr, &pr);
+ jcr->VolumeName[0] = 0;
+ bstrncpy(mr->MediaType, jcr->wstore->media_type, sizeof(mr->MediaType));
+ generate_job_event(jcr, "NewVolume"); /* return bool */
+ generate_plugin_event(jcr, bEventNewVolume); /* return void... */
+ if (jcr->VolumeName[0] && is_volume_name_legal(NULL, jcr->VolumeName)) {
+ bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName));
+ /* Check for special characters */
+ } else if (pr.LabelFormat[0] && pr.LabelFormat[0] != '*') {
+ if (is_volume_name_legal(NULL, pr.LabelFormat)) {
+ /* No special characters, so apply simple algorithm */
+ if (!create_simple_name(jcr, mr, &pr)) {
+ goto bail_out;
+ }
+ } else { /* try full substitution */
+ /* Found special characters, so try substitution */
+ if (!perform_full_name_substitution(jcr, mr, &pr)) {
+ goto bail_out;
+ }
+ if (!is_volume_name_legal(NULL, mr->VolumeName)) {
+ Jmsg(jcr, M_ERROR, 0, _("Illegal character in Volume name \"%s\"\n"),
+ mr->VolumeName);
+ goto bail_out;
+ }
+ }
+ } else {
+ goto bail_out;
+ }
+ pr.NumVols++;
+ mr->Enabled = 1;
+ if (db_create_media_record(jcr, jcr->db, mr) &&
+ db_update_pool_record(jcr, jcr->db, &pr)) {
+ db_unlock(jcr->db);
+ Jmsg(jcr, M_INFO, 0, _("Created new Volume \"%s\" in catalog.\n"), mr->VolumeName);
+ Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName);
+ return true;
+ } else {
+ Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
+ }
+ }
+bail_out:
+ db_unlock(jcr->db);
+ return false;
+}
+
+static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr)
+{
+ char name[MAXSTRING];
+ char num[20];
+ db_int64_ctx ctx;
+ POOL_MEM query(PM_MESSAGE);
+ char ed1[50];
+
+ /* See if volume already exists */
+ mr->VolumeName[0] = 0;
+ bstrncpy(name, pr->LabelFormat, sizeof(name));
+ ctx.value = 0;
+ Mmsg(query, "SELECT MAX(MediaId) FROM Media,Pool WHERE Pool.PoolId=%s",
+ edit_int64(pr->PoolId, ed1));
+ if (!db_sql_query(jcr->db, query.c_str(), db_int64_handler, (void *)&ctx)) {
+ Jmsg(jcr, M_WARNING, 0, _("SQL failed, but ignored. ERR=%s\n"), db_strerror(jcr->db));
+ ctx.value = pr->NumVols+1;
+ }
+ for (int i=(int)ctx.value+1; i<(int)ctx.value+100; i++) {
+ MEDIA_DBR tmr;
+ memset(&tmr, 0, sizeof(tmr));
+ sprintf(num, "%04d", i);
+ bstrncpy(tmr.VolumeName, name, sizeof(tmr.VolumeName));
+ bstrncat(tmr.VolumeName, num, sizeof(tmr.VolumeName));
+ if (db_get_media_record(jcr, jcr->db, &tmr)) {
+ Jmsg(jcr, M_WARNING, 0,
+ _("Wanted to create Volume \"%s\", but it already exists. Trying again.\n"),
+ tmr.VolumeName);
+ continue;