pxar: implement feature flag support for device nodes, fifos and sockets
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
		
				
					committed by
					
						
						Dietmar Maurer
					
				
			
			
				
	
			
			
			
						parent
						
							8abc95a145
						
					
				
				
					commit
					81a9905e0a
				
			@ -94,6 +94,9 @@ fn extract_archive(
 | 
				
			|||||||
    let no_xattrs = param["no-xattrs"].as_bool().unwrap_or(false);
 | 
					    let no_xattrs = param["no-xattrs"].as_bool().unwrap_or(false);
 | 
				
			||||||
    let no_fcaps = param["no-fcaps"].as_bool().unwrap_or(false);
 | 
					    let no_fcaps = param["no-fcaps"].as_bool().unwrap_or(false);
 | 
				
			||||||
    let no_acls = param["no-acls"].as_bool().unwrap_or(false);
 | 
					    let no_acls = param["no-acls"].as_bool().unwrap_or(false);
 | 
				
			||||||
 | 
					    let no_device_nodes = param["no-device-nodes"].as_bool().unwrap_or(false);
 | 
				
			||||||
 | 
					    let no_fifos = param["no-fifos"].as_bool().unwrap_or(false);
 | 
				
			||||||
 | 
					    let no_sockets = param["no-sockets"].as_bool().unwrap_or(false);
 | 
				
			||||||
    let allow_existing_dirs = param["allow-existing-dirs"].as_bool().unwrap_or(false);
 | 
					    let allow_existing_dirs = param["allow-existing-dirs"].as_bool().unwrap_or(false);
 | 
				
			||||||
    let files_from = param["files-from"].as_str();
 | 
					    let files_from = param["files-from"].as_str();
 | 
				
			||||||
    let empty = Vec::new();
 | 
					    let empty = Vec::new();
 | 
				
			||||||
@ -109,6 +112,15 @@ fn extract_archive(
 | 
				
			|||||||
    if no_acls {
 | 
					    if no_acls {
 | 
				
			||||||
        feature_flags ^= pxar::CA_FORMAT_WITH_ACL;
 | 
					        feature_flags ^= pxar::CA_FORMAT_WITH_ACL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if no_device_nodes {
 | 
				
			||||||
 | 
					        feature_flags ^= pxar::CA_FORMAT_WITH_DEVICE_NODES;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if no_fifos {
 | 
				
			||||||
 | 
					        feature_flags ^= pxar::CA_FORMAT_WITH_FIFOS;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if no_sockets {
 | 
				
			||||||
 | 
					        feature_flags ^= pxar::CA_FORMAT_WITH_SOCKETS;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut pattern_list = Vec::new();
 | 
					    let mut pattern_list = Vec::new();
 | 
				
			||||||
    if let Some(filename) = files_from {
 | 
					    if let Some(filename) = files_from {
 | 
				
			||||||
@ -158,6 +170,9 @@ fn create_archive(
 | 
				
			|||||||
    let no_xattrs = param["no-xattrs"].as_bool().unwrap_or(false);
 | 
					    let no_xattrs = param["no-xattrs"].as_bool().unwrap_or(false);
 | 
				
			||||||
    let no_fcaps = param["no-fcaps"].as_bool().unwrap_or(false);
 | 
					    let no_fcaps = param["no-fcaps"].as_bool().unwrap_or(false);
 | 
				
			||||||
    let no_acls = param["no-acls"].as_bool().unwrap_or(false);
 | 
					    let no_acls = param["no-acls"].as_bool().unwrap_or(false);
 | 
				
			||||||
 | 
					    let no_device_nodes = param["no-device-nodes"].as_bool().unwrap_or(false);
 | 
				
			||||||
 | 
					    let no_fifos = param["no-fifos"].as_bool().unwrap_or(false);
 | 
				
			||||||
 | 
					    let no_sockets = param["no-sockets"].as_bool().unwrap_or(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let devices = if all_file_systems { None } else { Some(HashSet::new()) };
 | 
					    let devices = if all_file_systems { None } else { Some(HashSet::new()) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -183,6 +198,15 @@ fn create_archive(
 | 
				
			|||||||
    if no_acls {
 | 
					    if no_acls {
 | 
				
			||||||
        feature_flags ^= pxar::CA_FORMAT_WITH_ACL;
 | 
					        feature_flags ^= pxar::CA_FORMAT_WITH_ACL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if no_device_nodes {
 | 
				
			||||||
 | 
					        feature_flags ^= pxar::CA_FORMAT_WITH_DEVICE_NODES;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if no_fifos {
 | 
				
			||||||
 | 
					        feature_flags ^= pxar::CA_FORMAT_WITH_FIFOS;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if no_sockets {
 | 
				
			||||||
 | 
					        feature_flags ^= pxar::CA_FORMAT_WITH_SOCKETS;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pxar::Encoder::encode(source, &mut dir, &mut writer, devices, verbose, false, feature_flags)?;
 | 
					    pxar::Encoder::encode(source, &mut dir, &mut writer, devices, verbose, false, feature_flags)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -205,6 +229,9 @@ fn main() {
 | 
				
			|||||||
                    .optional("no-fcaps", BooleanSchema::new("Ignore file capabilities.").default(false))
 | 
					                    .optional("no-fcaps", BooleanSchema::new("Ignore file capabilities.").default(false))
 | 
				
			||||||
                    .optional("no-acls", BooleanSchema::new("Ignore access control list entries.").default(false))
 | 
					                    .optional("no-acls", BooleanSchema::new("Ignore access control list entries.").default(false))
 | 
				
			||||||
                    .optional("all-file-systems", BooleanSchema::new("Include mounted sudirs.").default(false))
 | 
					                    .optional("all-file-systems", BooleanSchema::new("Include mounted sudirs.").default(false))
 | 
				
			||||||
 | 
					                    .optional("no-device-nodes", BooleanSchema::new("Ignore device nodes.").default(false))
 | 
				
			||||||
 | 
					                    .optional("no-fifos", BooleanSchema::new("Ignore fifos.").default(false))
 | 
				
			||||||
 | 
					                    .optional("no-sockets", BooleanSchema::new("Ignore sockets.").default(false))
 | 
				
			||||||
            ))
 | 
					            ))
 | 
				
			||||||
            .arg_param(vec!["archive", "source"])
 | 
					            .arg_param(vec!["archive", "source"])
 | 
				
			||||||
            .completion_cb("archive", tools::complete_file_name)
 | 
					            .completion_cb("archive", tools::complete_file_name)
 | 
				
			||||||
@ -229,6 +256,9 @@ fn main() {
 | 
				
			|||||||
                    .optional("no-acls", BooleanSchema::new("Ignore access control list entries.").default(false))
 | 
					                    .optional("no-acls", BooleanSchema::new("Ignore access control list entries.").default(false))
 | 
				
			||||||
                    .optional("allow-existing-dirs", BooleanSchema::new("Allows directories to already exist on restore.").default(false))
 | 
					                    .optional("allow-existing-dirs", BooleanSchema::new("Allows directories to already exist on restore.").default(false))
 | 
				
			||||||
                    .optional("files-from", StringSchema::new("Match pattern for files to restore."))
 | 
					                    .optional("files-from", StringSchema::new("Match pattern for files to restore."))
 | 
				
			||||||
 | 
					                    .optional("no-device-nodes", BooleanSchema::new("Ignore device nodes.").default(false))
 | 
				
			||||||
 | 
					                    .optional("no-fifos", BooleanSchema::new("Ignore fifos.").default(false))
 | 
				
			||||||
 | 
					                    .optional("no-sockets", BooleanSchema::new("Ignore sockets.").default(false))
 | 
				
			||||||
            ))
 | 
					            ))
 | 
				
			||||||
            .arg_param(vec!["archive", "pattern"])
 | 
					            .arg_param(vec!["archive", "pattern"])
 | 
				
			||||||
            .completion_cb("archive", tools::complete_file_name)
 | 
					            .completion_cb("archive", tools::complete_file_name)
 | 
				
			||||||
 | 
				
			|||||||
@ -809,11 +809,26 @@ impl <'a, W: Write> Encoder<'a, W> {
 | 
				
			|||||||
                    Err(err) => bail!("readlink {:?} failed - {}", self.full_path(), err),
 | 
					                    Err(err) => bail!("readlink {:?} failed - {}", self.full_path(), err),
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else if is_block_dev(&stat) || is_char_dev(&stat) {
 | 
					            } else if is_block_dev(&stat) || is_char_dev(&stat) {
 | 
				
			||||||
                self.write_filename(&filename)?;
 | 
					                if self.has_features(CA_FORMAT_WITH_DEVICE_NODES) {
 | 
				
			||||||
                self.encode_device(&stat)?;
 | 
					                    self.write_filename(&filename)?;
 | 
				
			||||||
            } else if is_fifo(&stat) || is_socket(&stat) {
 | 
					                    self.encode_device(&stat)?;
 | 
				
			||||||
                self.write_filename(&filename)?;
 | 
					                } else {
 | 
				
			||||||
                self.encode_special(&stat)?;
 | 
					                    eprintln!("skip device node: {:?}", self.full_path());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else if is_fifo(&stat) {
 | 
				
			||||||
 | 
					                if self.has_features(CA_FORMAT_WITH_FIFOS) {
 | 
				
			||||||
 | 
					                    self.write_filename(&filename)?;
 | 
				
			||||||
 | 
					                    self.encode_special(&stat)?;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    eprintln!("skip fifo: {:?}", self.full_path());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else if is_socket(&stat) {
 | 
				
			||||||
 | 
					                if self.has_features(CA_FORMAT_WITH_SOCKETS) {
 | 
				
			||||||
 | 
					                    self.write_filename(&filename)?;
 | 
				
			||||||
 | 
					                    self.encode_special(&stat)?;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    eprintln!("skip socket: {:?}", self.full_path());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                bail!("unsupported file type (mode {:o} {:?})", stat.st_mode, self.full_path());
 | 
					                bail!("unsupported file type (mode {:o} {:?})", stat.st_mode, self.full_path());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -508,6 +508,9 @@ impl <'a, R: Read, F: Fn(&Path) -> Result<(), Error>> SequentialDecoder<'a, R, F
 | 
				
			|||||||
        entry: &CaFormatEntry,
 | 
					        entry: &CaFormatEntry,
 | 
				
			||||||
        filename: &OsStr
 | 
					        filename: &OsStr
 | 
				
			||||||
    ) -> Result<(), Error> {
 | 
					    ) -> Result<(), Error> {
 | 
				
			||||||
 | 
					        if !self.has_features(CA_FORMAT_WITH_SOCKETS) {
 | 
				
			||||||
 | 
					            return Ok(());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if let Some(fd) = parent_fd {
 | 
					        if let Some(fd) = parent_fd {
 | 
				
			||||||
            self.restore_socket_at(fd, filename)?;
 | 
					            self.restore_socket_at(fd, filename)?;
 | 
				
			||||||
            self.restore_mode_at(&entry, fd, filename)?;
 | 
					            self.restore_mode_at(&entry, fd, filename)?;
 | 
				
			||||||
@ -524,6 +527,9 @@ impl <'a, R: Read, F: Fn(&Path) -> Result<(), Error>> SequentialDecoder<'a, R, F
 | 
				
			|||||||
        entry: &CaFormatEntry,
 | 
					        entry: &CaFormatEntry,
 | 
				
			||||||
        filename: &OsStr
 | 
					        filename: &OsStr
 | 
				
			||||||
    ) -> Result<(), Error> {
 | 
					    ) -> Result<(), Error> {
 | 
				
			||||||
 | 
					        if !self.has_features(CA_FORMAT_WITH_FIFOS) {
 | 
				
			||||||
 | 
					            return Ok(());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if let Some(fd) = parent_fd {
 | 
					        if let Some(fd) = parent_fd {
 | 
				
			||||||
            self.restore_fifo_at(fd, filename)?;
 | 
					            self.restore_fifo_at(fd, filename)?;
 | 
				
			||||||
            self.restore_mode_at(&entry, fd, filename)?;
 | 
					            self.restore_mode_at(&entry, fd, filename)?;
 | 
				
			||||||
@ -545,6 +551,9 @@ impl <'a, R: Read, F: Fn(&Path) -> Result<(), Error>> SequentialDecoder<'a, R, F
 | 
				
			|||||||
            bail!("got unknown header type inside device entry {:016x}", head.htype);
 | 
					            bail!("got unknown header type inside device entry {:016x}", head.htype);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        let device: CaFormatDevice = self.read_item()?;
 | 
					        let device: CaFormatDevice = self.read_item()?;
 | 
				
			||||||
 | 
					        if !self.has_features(CA_FORMAT_WITH_DEVICE_NODES) {
 | 
				
			||||||
 | 
					            return Ok(());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if let Some(fd) = parent_fd {
 | 
					        if let Some(fd) = parent_fd {
 | 
				
			||||||
            self.restore_device_at(&entry, fd, filename, &device)?;
 | 
					            self.restore_device_at(&entry, fd, filename, &device)?;
 | 
				
			||||||
            self.restore_mode_at(&entry, fd, filename)?;
 | 
					            self.restore_mode_at(&entry, fd, filename)?;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user