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"),
86 if (db_create_media_record(jcr, jcr->db, mr) &&
87 db_update_pool_record(jcr, jcr->db, &pr)) {
89 Jmsg(jcr, M_INFO, 0, _("Created new Volume \"%s\" in catalog.\n"), mr->VolumeName);
90 Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName);
93 Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
101 static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr)
103 char name[MAXSTRING];
106 /* See if volume already exists */
107 mr->VolumeName[0] = 0;
108 bstrncpy(name, pr->LabelFormat, sizeof(name));
109 for (int i=pr->NumVols+1; i<(int)pr->NumVols+11; i++) {
111 memset(&tmr, 0, sizeof(tmr));
112 sprintf(num, "%04d", i);
113 bstrncpy(tmr.VolumeName, name, sizeof(tmr.VolumeName));
114 bstrncat(tmr.VolumeName, num, sizeof(tmr.VolumeName));
115 if (db_get_media_record(jcr, jcr->db, &tmr)) {
116 Jmsg(jcr, M_WARNING, 0,
117 _("Wanted to create Volume \"%s\", but it already exists. Trying again.\n"),
121 bstrncpy(mr->VolumeName, name, sizeof(mr->VolumeName));
122 bstrncat(mr->VolumeName, num, sizeof(mr->VolumeName));
123 break; /* Got good name */
125 if (mr->VolumeName[0] == 0) {
126 Jmsg(jcr, M_ERROR, 0, _("Too many failures. Giving up creating Volume name.\n"));
133 * Perform full substitution on Label
135 static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr)
138 POOLMEM *label = get_pool_memory(PM_FNAME);
139 jcr->NumVols = pr->NumVols;
140 if (variable_expansion(jcr, pr->LabelFormat, &label)) {
141 bstrncpy(mr->VolumeName, label, sizeof(mr->VolumeName));
144 free_pool_memory(label);