3 use proxmox
::tools
::Uuid
;
5 use pbs_tape
::{TapeWrite, MediaContentHeader}
;
7 /// Writes data streams using multiple volumes
9 /// Note: We do not use this feature currently.
10 pub struct MultiVolumeWriter
<'a
> {
11 writer
: Option
<Box
<dyn TapeWrite
+ 'a
>>,
12 next_writer_fn
: Box
<dyn 'a
+ FnMut() -> Result
<Box
<dyn TapeWrite
+'a
>, Error
>>,
16 header
: MediaContentHeader
,
18 bytes_written
: usize, // does not include bytes from current writer
21 impl <'a
> MultiVolumeWriter
<'a
> {
23 /// Creates a new instance
25 writer
: Box
<dyn TapeWrite
+'a
>,
26 content_magic
: [u8; 8],
28 next_writer_fn
: Box
<dyn 'a
+ FnMut() -> Result
<Box
<dyn TapeWrite
+ 'a
>, Error
>>,
31 let header
= MediaContentHeader
::new(content_magic
, header_data
.len() as u32);
45 /// Returns the cuntent Uuid with the current part number
46 pub fn uuid_and_part_number(&self) -> (Uuid
, usize) {
47 (self.header
.uuid
.into(), self.header
.part_number
as usize)
51 impl <'a
> TapeWrite
for MultiVolumeWriter
<'a
> {
53 fn write_all(&mut self, buf
: &[u8]) -> Result
<bool
, std
::io
::Error
> {
56 proxmox
::io_bail
!("multi-volume writer already finished: internal error");
60 if !self.wrote_header
{
61 proxmox
::io_bail
!("multi-volume writer: got LEOM before writing anything - internal error");
63 let mut writer
= match self.writer
.take() {
64 Some(writer
) => writer
,
65 None
=> proxmox
::io_bail
!("multi-volume writer: no writer -internal error"),
67 self.bytes_written
= writer
.bytes_written();
71 if self.writer
.is_none() {
72 if self.header
.part_number
>= 255 {
73 proxmox
::io_bail
!("multi-volume writer: too many parts");
76 (self.next_writer_fn
)()
77 .map_err(|err
| proxmox
::io_format_err
!("multi-volume get next volume failed: {}", err
))?
79 self.got_leom
= false;
80 self.wrote_header
= false;
81 self.header
.part_number
+= 1;
84 let leom
= match self.writer
{
85 None
=> unreachable
!(),
86 Some(ref mut writer
) => {
87 if !self.wrote_header
{
88 writer
.write_header(&self.header
, &self.header_data
)?
;
89 self.wrote_header
= true;
91 writer
.write_all(buf
)?
95 if leom { self.got_leom = true; }
100 fn bytes_written(&self) -> usize {
101 let mut bytes_written
= self.bytes_written
;
102 if let Some(ref writer
) = self.writer
{
103 bytes_written
+= writer
.bytes_written();
108 fn finish(&mut self, incomplete
: bool
) -> Result
<bool
, std
::io
::Error
> {
111 "incomplete flag makes no sense for multi-volume stream: internal error");
114 match self.writer
.take() {
115 None
if self.finished
=> proxmox
::io_bail
!(
116 "multi-volume writer already finished: internal error"),
118 Some(ref mut writer
) => {
119 self.finished
= true;
120 if !self.wrote_header
{
121 writer
.write_header(&self.header
, &self.header_data
)?
;
122 self.wrote_header
= true;
129 fn logical_end_of_media(&self) -> bool
{