使用clonezilla恢复系统到大小不一致的磁盘上

Clonezilla是个很好用的磁盘和分区克隆工具,中文名字再生龙。

支持多种分区格式,所以备份windows备份linux不再话下,直接整个磁盘或者整个分区克隆备份与恢复,支持备份到磁盘、samba网络共享、ssh server等多种目标上。对于小规模的系统发行也是很好的选择。甚至还有诸如把物理机系统迁移到虚拟机的应用等。

如果是简单的磁盘大小完全相同的备份恢复,很简单使用Beginner模式即可。但是如果你恢复到的磁盘小于映像来源磁盘大小,或者想恢复时想重新划分分区等,就需要使用Expert专家模式,激活-icds和紧下一步的k2选项,k2选项会让你在恢复时手动分区,要保证各分区大小不小于镜像中的分区哦。
目标盘比原盘小,但是原盘使用的所有分区大小并没有超出目标盘(即原盘中存在未分区部分),可以使用icds选项屏蔽磁盘检查。但是各个分区的大小仍然必须遵从目标分区大小必须大于等于原分区的要求,否则底层使用的partclone还是会失败【查partclone文档其实有Use option -C to disable size checking(Dangerous), 但没在clonezilla中找到该控制选项】。
如果想调整分区大小。只能这么做:第一步,镜像恢复到对应磁盘大小的磁盘上(若是原磁盘就略过);第二步,使用gparted工具调整分区;第三步,clonezilla就可以备份和恢复经过分区调整的磁盘镜像了。
所以创建image时尽量不要使用太大的主分区,这样之后有回旋余地。

Extracting files from CloneZilla images – Server Fault

1) Prepare a large disk in Linux
2) Say if your image is /home/partimag/YOURIMAGE/, and the image is /home/partimag/YOURIMAGE/hda1.ntfs-img.aa, hda1.ntfs-img.ab … run
file /home/partimag/YOURIMAGE/hda1.ntfs-img.aa
to see it’s gzip, bzip or lzop image. Say it’s gzip, then you can run
cat /home/partimag/YOURIMAGE/hda1.ntfs-img.* | gzip -d -c | ntfsclone --restore-image -o hda1.img -
Then you will have a “hda1.img” which you can mount it by
mount -o loop -t ntfs hda1.img /mnt
Then all the files are in /mnt/

Clonezilla上的账户密码

In Clonezilla live, two accounts are available: (1) account user with sudo privilege, password is live, (2) administration account root, no password. Therefore you can not login as root, the only way to get root privilege is to login as user, and run sudo -i or sudo su - to become root.

fdisk 常用的文件系统编号

  1 EFI System   C12A7328-F81F-11D2-BA4B-00A0C93EC93B
14 Linux swap   0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
15 Linux filesystem   0FC63DAF-8483-4772-8E79-3D69D8477DE4

ubuntu自动登录和直接无桌面启动到某图形界面程序

弄一个直接至图形界面的X桌面session
/usr/share/xsessions/MYPROGRAM.desktop

[Desktop Entry]
Name=myprogram
Comment=Auto start of myprogram with 'username' user without password
Exec=/home/username/myprogram.sh
TryExec=/home/username/myprogram.sh
Type=Application
Terminal=true

把lightdm登录配置/etc/lightdm/lightdm.conf改成自动登录我们定义的session。

[Seat:*]
autologin-user=username
autologin-session=myprogram
xserver-command=X -s 0 -dpms 

还有注意用户的~/.dmrc配置,把里面的session改成我们的,或者直接删除。如果有这个文件且其session还不是我们想要的,也不会自动登录,但登陆时可以选择登录哪个session。

另外,把用户添加到autologinnopasswdlogin组这个操作在ubuntu上不是必须的。如果别的桌面版需要,使用这些命令LightDM#Enabling_autologin

groupadd -r autologin
gpasswd -a username autologin
groupadd -r nopasswdlogin
gpasswd -a username nopasswdlogin

参考
Disable screen blanking in X-Windows on Raspbian [duplicate]
How do I disable the screensaver/lock?
Autostarting XBMC with a LightDM session

ubuntu挂载smb网络共享文件夹

手工挂载或者挂载脚本,

#!/bin/bash
# 需要安装cifs-utils
# sudo apt-get install cifs-utils

SERVER_IP="192.168.1.2"
SHARE_NAME="share"
USERNAME="samba user name"
PASSWD="samba password"
DOMAIN="domain"

#mount.cifs //$SERVER_IP/$SHARE_NAME -o username=$USERNAME,password=$PASSWD,dom=$DOMAIN /media/user/smbshare
mount.cifs //$SERVER_IP/$SHARE_NAME -o username=$USERNAME,password=$PASSWD /media/user/smbshare
# mount -t cifs //$SERVER_IP/$SHARE_NAME -o username=$USERNAME,password=$PASSWD /media/user/smbshare

放在/etc/fstab中自动挂载

//192.168.1.2/share /media/user/smbshare cifs users,suid,uid=1000,gid=1000,_netdev,file_mode=0777,dir_mode=0777,username=USERNAME,password=PASSWD 0 0

如何更容易的开发和共享caffe新层

caffe项目中早已有不少人在尝试解决这个问题:
Allow self-contained development of Caffe layers · Issue #1896 · BVLC/caffe
Layer modules by hgaiser · Pull Request #5294 · BVLC/caffe
还有动态加载的讨论:
Decentralize development with layer parameter registration mechanism · Issue #3408 · BVLC/caffe

为什么要讨论这个问题,虽然Making a Caffe Layer Development等链接已给出了指导,但是因为caffe版本或者这样那样的原因,别人开发的新层要插入到你自己的caffe代码里也并不是容易的事情,开发新层要在不同的目录添加文件和修改文件,扒起来不易。较好的方法就是直接将新层的代码git clone下来与caffe一起编译最好了。
我们有交流model的 Model Zoo,但caffe的这个缺陷导致迟迟产生不了 Layer Zoo。各位在开发过程中添加的风格也很不统一,甚至部分人对caffe原有代码还有改动,这些代码合并起来颇为麻烦。

我的设想是在在caffe的src目录中再放一个plugins子目录,这个plugins目录中新加层就新加个子目录,一个新层一个子目录,绝不与caffe原有代码混淆。
但这里有个问题就是proto文件,虽然protobuf支持Extension特性,但是caffe网络初始化就要知道参数信息,无法基于 protobuf Extension 开发。
PR #5294 的方法是像python层一样使用一个param_str的通用参数,新层的特性参数就编码到这个字符串中。
我自己的方案就是新层也提供一个 .proto 文件,然后我编译前把所有层的 .proto 文件全部插入到 caffe.proto 文件中再编译。这个方案里,新层所有参数的使用完全和原有层一样,而不需要去解析param_str字符串拿参数。

ubuntu从源下载软件以及制作本地源的部分命令

1、备份已安装软件包列表

sudo dpkg --get-selections > ~/package.selections

2、下载这份软件包列表中的软件

但是不安装,比如制作部分apt mirror时使用

for req in $(cat ~/package.selections | cut -f 1 | cut -f 1 -d  ":" ); do apt-get download $req; done

3、dpkg-scanpackages 制作软件包文件

dpkg-scanpackages ~/ubuntu-local/xenial /dev/null 2>>~/mkpackage.error |gzip > ~/ubuntu-local/xenial/Packages.gz -r

这之后就可以利用apache服务器对外提供服务了。

4、删除过时的软件版本

不断更新本地Mirror,会保留统一软件的的多个版本,删除过时版本。

egrep  "\(filename .*\) is repeat" ~/mkpackage.error | awk '{print $6}' | sed 's/)//' | while read filename
do
  # mv ~/ubuntu-local/xenial/$filename ~/.local/share/Trash/files
  gvfs-trash somefile
done

5、添加本地源的方法

# 使用网络服务形式提供的本地mirror
echo 'deb http://192.168.0.2/ubuntu-local/xenial /' | sudo tee /etc/apt/source.list.d/local.list

6、其他一些有关命令

# 直接根据第1步导出的软件列表 重新下载安装之前系统中的软件
# 如果你安装的软件数量比较多,可能会花费较长时间。
sudo dpkg --set-selections <~/package.selections && sudo apt-get dselect-upgrade

# 每次安装软件后,即时地把新安装的软件包拷贝到Mirror中,后续还需要dpkg-scanpackages
cp /var/cache/apt/*.deb ~/ubuntu-local/xenial/

# sudo chown -R user:pswd ~/ubuntu-local/
# sudo chmod ug+rw,o+r *

修改caffemodel文件

1 修改某层名称

先把prototxt新修改出一份,然后分别用新旧prototxt去加载caffemodel文件,再把旧参数付给新网络的相应层。

#! python
#coding=utf-8
import sys
from caffe import Net
n_orig = Net('test_o.prototxt', 'orig.caffemodel', 0)
n_new = Net('test_n.prototxt', 'orig.caffemodel', 0)
n_new.params['newlayername'] = n_orig.params['origlayername']
n_new.save('new.caffemodel')

2 修改层shape

如添加一个新类,直接修改classification全连接层,修改后继续训练就可以了。

#! python
#coding=utf-8
import sys,caffe
import numpy as np

n = caffe.Net('train.prototxt','orig.caffemodel',0)

# 这里直接用原有数值的均值初始化新数据空间。
cls_score0=n.params['cls_score'][0].data.copy()
cls_score0_n = np.append(cls_score0, np.mean(cls_score0)*np.ones((1,4096), dtype=cls_score0.dtype),axis=0)

cls_score1 = n.params['cls_score'][1].data.copy()
cls_score1_n = np.append(cls_score1, np.mean(cls_score1))

n.params['cls_score'][0].reshape(22,4096)
n.params['cls_score'][0].data[...] = cls_score0_n
n.params['cls_score'][1].reshape (*cls_score1_n.shape)
n.params['cls_score'][1].data[...] = cls_score1_n
 
n.save('newclass22.caffemodel')

3 从caffemodel中恢复出prototxt结构

可以从caffemodel反推出网络结构,但不会完全一致,主要是原来隐含层会被显式表达出来。

#! python
#coding=utf-8
 
from caffe.proto import caffe_pb2
 
def Caffemodel2Prototxt(modelName,deployName):
  with open(modelName, 'rb') as f:
    caffemodel = caffe_pb2.NetParameter()
    caffemodel.ParseFromString(f.read())
  for item in caffemodel.layers:
    item.ClearField('blobs')
  for item in caffemodel.layer:
    item.ClearField('blobs')
 
  with open(deployName, 'w') as f:
    f.write(str(caffemodel))
 
if __name__ == '__main__':
  modelName = 'VGG16_iter_28000.caffemodel'
  deployName = 'VGG16_deploy.prototxt'
  Caffemodel2Prototxt(modelName,deployName)

caffe 支持 CUDA Dynamic Parallelism

CUDA从3.5开始就支持了动态并行,就是支持GPU线程再直接启动一组子计算线程,而在这个之前GPU计算线程都是由CPU线程启动的。
为了支持这个动态并行特性,需要链接 cudadevrt 库。

不过,caffe 始终没有应用这个CUDA特性。 我自己fork了一个分支启用了该特性 支持动态并行的caffe实现
为了启用该特性,还更改了cuda代码的编译链接过程,原来都是每个cu文件直出可链接的目标文件。这个分支时每个cu文件都先 device-c 到一个目标文件,再把所有的cu的目标文件 dlink 到一个可链接的目标文件。
启用这个特性的所有修改都在 Makefile 中,我定义了一个 CUDA_DYNAMIC_PARALLEL 标识控制是否启用, 在 Makefile.config 中定义 CUDA_DYNAMIC_PARALLEL := 1 即可启用。启用后也传递了一个 CUDA_DYNAMIC_PARALLEL 预定义变量到编译器以方便代码中据此控制区分下代码。

启用后即可在cuda代码中享用动态并行特性了。

至于能不能显著提高计算速度?对原有的层没有影响,这是要修改代码的啊,可能原有的部分层会受益于此功能,我没检查。对于新增层的话,如果层计算逻辑可以包含用GPU计算线程新起计算线程的话,就可受益,毕竟不必在绕回到CPU线程由CPU线程来启动下一轮GPU线程。

ubuntu获取网卡IP和MAC地址

ip addr | grep link/ether | awk '{print $2}'
ip=`ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'`
mac=`ifconfig | grep HWaddr | awk -F" " '{print $5}'`
/sys/class/net/eth0/address
# lshw可以获取很多硬件信息哦
lshw -class network
# 获取网卡名称
ip -o -4 route show to default | awk '{print $5}'

问题1,环回lo和虚拟网卡要不要
docker或者别的虚拟网卡存在,看您需要不需要避免获取到虚拟网卡的。

问题2,网卡命名的问题
之前一般被系统命名为eth0,现在改别的命名规则了。看要不要把网卡名称写死了,还是要求自动获取网卡名。

问题3,多网卡
这个问题一般不重要,一般也就不用指定特定网卡,只要是真实网络接口即可。若只需要一个,awk里打印完一个立即 exit 即可。

那这段代码有什么用呢?
比如自动设置机器名称为与MAC地址有关的名字避免克隆系统名称冲突,就可以写个服务启动后立即修改下机器名 hostname,更改机器名称为MAC有关