3 * Bacula Director -- newvol.c -- creates new Volumes in
4 * catalog Media table from the LabelFormat specification.
6 * Kern Sibbald, May MMI
8 * This routine runs as a thread and must be thread reentrant.
10 * Basic tasks done here:
11 * If possible create a new Media entry
16 Copyright (C) 2000-2006 Kern Sibbald
18 This program is free software; you can redistribute it and/or
19 modify it under the terms of the GNU General Public License
20 version 2 as amended with additional clauses defined in the
21 file LICENSE in the main source directory.
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 the file LICENSE for additional details.
33 /* Forward referenced functions */
34 static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr);
35 static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr);
39 * Automatic Volume name creation using the LabelFormat
41 * The media record must have the PoolId filled in when
42 * calling this routine.
44 bool newVolume(JCR *jcr, MEDIA_DBR *mr)
48 memset(&pr, 0, sizeof(pr));
50 /* See if we can create a new Volume */
52 pr.PoolId = mr->PoolId;
53 if (!db_get_pool_record(jcr, jcr->db, &pr)) {
56 if (pr.MaxVols == 0 || pr.NumVols < pr.MaxVols) {
57 memset(mr, 0, sizeof(MEDIA_DBR));
58 set_pool_dbr_defaults_in_media_dbr(mr, &pr);
59 jcr->VolumeName[0] = 0;
60 bstrncpy(mr->MediaType, jcr->store->media_type, sizeof(mr->MediaType));
61 if (generate_job_event(jcr, "NewVolume") == 1 && jcr->VolumeName[0] &&
62 is_volume_name_legal(NULL, jcr->VolumeName)) {
63 bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName));
64 /* Check for special characters */
65 } else if (pr.LabelFormat[0] && pr.LabelFormat[0] != '*') {
66 if (is_volume_name_legal(NULL, pr.LabelFormat)) {
67 /* No special characters, so apply simple algorithm */
68 if (!create_simple_name(jcr, mr, &pr)) {
71 } else { /* try full substitution */
72 /* Found special characters, so try substitution */
73 if (!perform_full_name_substitution(jcr, mr, &pr)) {
76 if (!is_volume_name_legal(NULL, mr->VolumeName)) {
77 Jmsg(jcr, M_ERROR, 0, _("Illegal character in Volume name \"%s\"\n"),
87 if (db_create_media_record(jcr, jcr->db, mr) &&
88 db_update_pool_record(jcr, jcr->db, &pr)) {
90 Jmsg(jcr, M_INFO, 0, _("Created new Volume \"%s\" in catalog.\n"), mr->VolumeName);
91 Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName);
94 Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
102 static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr)
104 char name[MAXSTRING];
107 /* See if volume already exists */
108 mr->VolumeName[0] = 0;
109 bstrncpy(name, pr->LabelFormat, sizeof(name));
110 for (int i=pr->NumVols+1; i<(int)pr->NumVols+11; i++) {
112 memset(&tmr, 0, sizeof(tmr));
113 sprintf(num, "%04d", i);
114 bstrncpy(tmr.VolumeName, name, sizeof(tmr.VolumeName));
115 bstrncat(tmr.VolumeName, num, sizeof(tmr.VolumeName));
116 if (db_get_media_record(jcr, jcr->db, &tmr)) {
117 Jmsg(jcr, M_WARNING, 0,
118 _("Wanted to create Volume \"%s\", but it already exists. Trying again.\n"),
122 bstrncpy(mr->VolumeName, name, sizeof(mr->VolumeName));
123 bstrncat(mr->VolumeName, num, sizeof(mr->VolumeName));
124 break; /* Got good name */
126 if (mr->VolumeName[0] == 0) {
127 Jmsg(jcr, M_ERROR, 0, _("Too many failures. Giving up creating Volume name.\n"));
134 * Perform full substitution on Label
136 static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr)
139 POOLMEM *label = get_pool_memory(PM_FNAME);
140 jcr->NumVols = pr->NumVols;
141 if (variable_expansion(jcr, pr->LabelFormat, &label)) {
142 bstrncpy(mr->VolumeName, label, sizeof(mr->VolumeName));
145 free_pool_memory(label);