[GUIDE] How to Make Persistent System Changes (crontab, etc)


#1

Many people have had trouble making persistent changes (crontab, etc) to their NAS. Various methods have been tried, with varying degrees of success, but the changes usually revert after some time has passed and/or the NAS is rebooted. This guide will show you how to access certain NAS system areas so that persistent changes can be made.

The config.xml file is used in many examples shown below. Changing other system files is beyond the scope of this guide.

WARNING: THE FOLLOWING PROCEDURES CAN VOID YOUR WARRANTY AND BRICK YOUR NAS - USE EXTREME CAUTION AT ALL TIMES

NOTE: BASIC LINUX SKILLS AND ROOT ACCESS VIA SSH ARE REQUIRED

Each of the Linux command examples shown below is preceeded with "# " (no quotes). This indicates a command prompt with root access. If copying/pasting a command, do not copy/paste the "# " portion of the example.

The following instructions are based on the WD My Cloud PR4100 NAS firmware, but they should be applicable to many other WD My Cloud models, possibly with minor variations applied as needed.

Most NAS options are stored in a file called config.xml and this file is stored in several locations. The contents of the file can be viewed by executing either of the following commands.

# cat /usr/local/modules/default/config.xml
# cat /etc/NAS_CFG/config.xml

Note the differences between the two files, where /usr/local/modules/default/config.xml appears to be a default basic configuration, possibly used as a fallback.

The config.xml file is also stored in a RAM database controlled by a Linux program called xmldbc.

# xmldbc -h

Usage: xmldbc version 2 [OPTIONS]
  -h                     show this help message.
  -H                     show version number.
  -v                     verbose mode.
  -i                     ignore external function (like runtime).
  -g {node path}         get value from {node path}.
  -s {node path} {value} set  {value} in {node path}.
  -d {node path}         delete {node path}.
  -l {XML file}          reload XML file to database.
  -D {XML file}          dump database to XML file.
  -S {unix socket}       specify unix socket name, default is /var/run/xmldb_sock
  -A {ephp file}         embeded php parse.
  -V {name=value}        variable for ephp.
  -x {command}           set extended get/set command.
  -t {tag:sec:command}   schedule a timer.
  -k {tag}               kill timers by tag.
  -X {node field}        sorting.
  -I {node field}        insert row.
  -p {node path} {file}  print node to file.
  -r {XML file}          read file and insert to XMLDB.

The contents of the xmldbc database can be dumped to an XML file by executing the following command. Any destination path and filename may be used, as long as they do not conflict with existing system files.

# xmldbc -D /tmp/xmldbc_test.xml

At first, I thought xmldbc may have been the actual source that was used to revert system changes, but a detailed examination of the source code revealed that it was not.

Further investigation revealed a number of “hidden” system partitions which are stored in eMMC flash memory. The partitions aren’t actually “hidden” per-se, but they are not easy to find unless you know what to look for. All things considered, I think this is a good thing because it prevents inexperienced users from accidentally bricking their NAS. A list of all active partitions can be viewed by executing the following command.

# cat /proc/partitions

Pay particular attention to the partitions with a mmcblk name prefix. These are eMMC flash partitions, and they are read/write, so USE EXTREME CAUTION at all times. A more detailed and meaningful list can be seen by executing the following command.

# blkid -o list

device                                   fs_type         label            mount point            UUID
-------------------------------------------------------------------------------------------------------------------------------------
/dev/loop0                               squashfs                         (in use)
/dev/loop1                               ext4                             (in use)               94c1bc4e-98f8-4aa6-b699-9d02c4c8f43d
/dev/loop3                               squashfs                         /usr/local/modules
/dev/sda1                                linux_raid_member                (in use)               1bd71974-bf36-f39b-bb4b-d7932c0a2b97
/dev/sda2                                ext4                             /mnt/HD/HD_a2          27bd93dd-a6b4-49d7-af45-9cfc6a1eef61
/dev/sda4                                ext4                             /mnt/HD_a4             da63156e-198b-43bb-8b37-beac6d94f44b
/dev/sdb1                                linux_raid_member                (in use)               1bd71974-bf36-f39b-bb4b-d7932c0a2b97
/dev/sdb2                                ext4                             /mnt/HD/HD_b2          d23c5cac-b202-465a-ba32-325e99672a1f
/dev/sdb4                                ext4                             /mnt/HD_b4             9fad9dd3-ddff-4e4d-9149-fe61787cdb50
/dev/sdc1                                linux_raid_member                (in use)               1bd71974-bf36-f39b-bb4b-d7932c0a2b97
/dev/sdc2                                ext4                             /mnt/HD/HD_c2          c4669438-f2df-4a99-a29b-17e772e7ceaa
/dev/sdc4                                ext4                             /mnt/HD_c4             ed1be8c5-d51f-4c35-b115-53676f2def74
/dev/mmcblk0                                                              (not mounted)
/dev/mmcblk0p1                           vfat            wdnas_efi        (not mounted)          9FE2-0840
/dev/mmcblk0p2                           ext4            wdnas_kernel     (not mounted)          c5d6e030-df55-4731-99e4-cbb2e5b771e2
/dev/mmcblk0p3                           ext4            wdnas_initramfs  (not mounted)          6bab9bea-2650-4944-84ea-a6fc4ba3fdd0
/dev/mmcblk0p4                           ext4            wdnas_image.cfs  (not mounted)          00035529-6b69-4fca-a0fd-cde0cd805a00
/dev/mmcblk0p5                           ext4            wdnas_rescue_fw  (not mounted)          8c54a8c2-9055-407c-bab1-5985d107fb3a
/dev/mmcblk0p6                           ext4            wdnas_config     (not mounted)          43eafe4c-2503-401e-b288-6cba67952ac9
/dev/mmcblk0p9                           ext4            wdnas_backup     (not mounted)          46330f66-5c9f-4862-9053-6ba3461685be
/dev/md0                                 swap                             <swap>                 b66719fa-c34d-44c1-9f1d-98e48a95ce05
/dev/mapper/docker-8:2-81788934-pool     ext4                             (not mounted)          94c1bc4e-98f8-4aa6-b699-9d02c4c8f43d

The following is a list of named system (mmcblk) eMMC flash partitions, preceded by descriptions.

GRUB Bootloader           wdnas_efi
Linux Kernel              wdnas_kernel
Initial RAM Filesystem    wdnas_initramfs
Squashfs Filesystem       wdnas_image.cfs
Rescue Firmware           wdnas_rescue_fw
Configuration Files       wdnas_config
Backup Files              wdnas_backup

Note that the mount point for each of the mmcblk partitions indicates if they are mounted. A list of mounted partitions can be viewed by executing the following command.

# cat /proc/mounts

Before one can interact with a partition, it must be mounted. If a partition is already mounted, one simply needs to change to the directory it’s mounted to. To mount one of the mmcblk partitions, execute the following sequence of commands, one at a time. Note that a temporary directory named /tmp/eMMC_flash is used to prevent conflicts with existing system directories. In the following example the /dev/mmcblk0p9 eMMC flash partition is mounted, where the path corresponding to any partition of interest can be used instead.

# cd /
# mkdir /tmp/eMMC_flash
# mount /dev/mmcblk0p9 /tmp/eMMC_flash
# cd /tmp/eMMC_flash
# ls -l

Too make persistent changes (adding cron jobs, etc) to the config.xml file, first mount the appropriate partitions (if required), then make two copies of the file. One copy (config_backup.xml) is simply a backup in case changes need to be reverted, and the second copy (config_edit.xml) will be used for making changes. Note: On my WD PR4100 NAS /usr/local/tmp_wdnas_config is mounted to the /dev/mmcblk0p6 device on system startup, and the system configuration files are stored in a subfolder named config. Mount points and paths may vary, depending on the NAS model and firmware version.

# cp -f /usr/local/tmp_wdnas_config/config/config.xml /shares/Public/config_backup.xml
# cp -f /usr/local/tmp_wdnas_config/config/config.xml /shares/Public/config_edit.xml

In the example shown below, note that I’ve added a new cron job named cron_test. Within the config.xml file is a <crond></crond> section, which contains all cron jobs which are added to the crontab at system startup.

<crond>
	<list>
		<count>9</count>
		<name id="1">stime</name>
		<name id="2">wd_crontab</name>
		<name id="3">app_get_info</name>
		<name id="4">recycle_bin_clear</name>
		<name id="5">chk_wfs_download</name>
		<name id="6">random_check</name>
		<name id="7">user_expire_chk</name>
		<name id="8">fw_available</name>
		<name id="9">cron_test</name>
	</list>
	<stime>
		<count>1</count>
		<item id="1">
			<method>3</method>
			<1>30</1>
			<2>2</2>
			<3>*</3>
			<4>*</4>
			<5>*</5>
			<run>/usr/sbin/stime&amp;</run>
		</item>
	</stime>
	<wd_crontab>
		<count>1</count>
		<item id="1">
			<method>3</method>
			<1>0</1>
			<2>3</2>
			<3>*</3>
			<4>*</4>
			<5>*</5>
			<run>wd_crontab.sh&amp;</run>
		</item>
	</wd_crontab>
	<app_get_info>
		<count>1</count>
		<item id="1">
			<method>3</method>
			<1>0</1>
			<2>4</2>
			<3>*</3>
			<4>*</4>
			<5>*</5>
			<run>auto_fw -a -c&amp;</run>
		</item>
	</app_get_info>
	<recycle_bin_clear>
		<count>1</count>
		<item id="1">
			<method>3</method>
			<1>0</1>
			<2>0</2>
			<3>*</3>
			<4>*</4>
			<5>*</5>
			<run>auto_clear_recycle_bin.sh &amp;</run>
		</item>
	</recycle_bin_clear>
	<chk_wfs_download>
		<count>1</count>
		<item id="1">
			<method>3</method>
			<1>30</1>
			<2>3</2>
			<3>*</3>
			<4>*</4>
			<5>*</5>
			<run>/usr/sbin/chk_wfs_download&amp;</run>
		</item>
	</chk_wfs_download>
	<random_check>
		<item id="1">
			<method>3</method>
			<1>0</1>
			<2>0</2>
			<3>*</3>
			<4>*</4>
			<5>*</5>
			<run>random_check -s &amp;</run>
		</item>
	</random_check>
	<user_expire_chk>
		<item id="1">
			<method>3</method>
			<1>0</1>
			<2>0</2>
			<3>*</3>
			<4>*</4>
			<5>*</5>
			<run>expire.sh</run>
		</item>
	</user_expire_chk>
	<fw_available>
		<item id="1">
			<method>3</method>
			<1>52</1>
			<2>18</2>
			<3>*</3>
			<4>*</4>
			<5>*</5>
			<run>auto_fw -c 1 &amp;</run>
		</item>
	</fw_available>
	<cron_test>
		<item id="1">
			<method>3</method>
			<1>*</1>
			<2>*</2>
			<3>*</3>
			<4>*</4>
			<5>*</5>
			<run>date >> /shares/Public/test.txt &amp;</run>
		</item>
	</cron_test>
</crond>

To add a new cron job, first edit the <list></list> section as follows, using any name you want for the new cron job, as long as it’s unique. Note that the id="" attributes can only contain numbers, and each number must be unique. Also, the number within the <count></count> element should be changed to reflect the number of cron jobs contained in the <list></list> section. In this case, there are 9 cron jobs, so the count is 9.

<list>
	<count>9</count>
	<name id="1">stime</name>
	<name id="2">wd_crontab</name>
	<name id="3">app_get_info</name>
	<name id="4">recycle_bin_clear</name>
	<name id="5">chk_wfs_download</name>
	<name id="6">random_check</name>
	<name id="7">user_expire_chk</name>
	<name id="8">fw_available</name>
	<name id="9">cron_test</name>
</list>

Next, add a new section to the end of the <crond></crond> section as follows. Note that the outer element name must EXACTLY match the name element value used in the <list></list> section. In this case, the outer element name is <cron_test></cron_test>.

<cron_test>
	<item id="1">
		<method>3</method>
		<1>*</1>
		<2>*</2>
		<3>*</3>
		<4>*</4>
		<5>*</5>
		<run>date >> /shares/Public/test.txt &amp;</run>
	</item>
</cron_test>

The exact purpose of the <method></method> element is currently unknown. The numbered elements (<1></1>, <2></2>. etc) represent the 5 fields used by crontab for specifying time intervals. For more information about crontab time intervals, see: [GUIDE] Crontab Demystified

In the examples shown above, the text within the <run></run> element is the command or script to be executed. The & (ampersand) character at the end of a shell command is known as job control. The & (ampersand) character informs the shell to put the command in the background, allowing parallel commands to be run. The & (ampersand) character is reserved as a special character in XML files, so it must be represented by &amp; at all times.

For example, the following command will append the current date to a text file in the “Public” share folder. The & (ampersand) character at the end of the line isn’t strictly necessary, but I’ve included it so I could explain it’s purpose and how to use it within XML files.

# date >> /shares/Public/test.txt &

Shell scripts contained in text files, or even binary programs can also be executed by a cron job. However, they must be saved in a location which is not periodically refreshed along with the root filesystem. eMMC flash partitions can be used for this purpose, but one must be EXTREMELY CAREFUL to not overwrite any existing files.

For example, if the shell command in the examples shown above were contained in a text file, the resulting <cron_test></cron_test> XML <run></run> command line might resemble the following.

<run>/usr/local/tmp_wdnas_config/config/cron_test.sh &amp;</run>

When finished making changes, simply save the config.xml file, then copy it to the appropriate location, replacing the existing config.xml file.

# cp -f /shares/Public/config_flash.xml /usr/local/tmp_wdnas_config/config/config.xml

One should be ABSOLUTELY CERTAIN that the config.xml file does not contain any typos or errors BEFORE replacing the existing config.xml file. Note that standard XML parsers or validation services may report the config.xml XML file as being malformed because the developers chose to use element names (<1></1>, <2></2>. etc) which violate the XML syntax rules. The NAS must be rebooted from the dashboard for changes to take effect.

After the NAS is finished rebooting, verify that the new cron job has been added to the crontab by executing the following command.

# crontab -l

When finished, ALWAYS UNMOUNT eMMC FLASH PARTITIONS, as shown in the following example. Either the partition or the mount point may be used to unmount a partition. Note: Partitions mounted by the system should NOT be unmounted.

# umount /tmp/eMMC_flash

Again, USE EXTREME CAUTION because making changes to any of the system files stored in the eMMC flash partitions can very easily BRICK YOUR NAS. You have been warned… multiple times.


[GUIDE] Crontab Demystified
Add scripts to the startup
Upgrade My Cloud to Twonky 8
File path for logging cronjobs
My Cloud PR4100 Firmware Analysis
"No crontab for root" on WD My Cloud
Boot script to set ssh keyfile and disable clear password login
How to disable reset hole (PR2100 & EX2 Ultra) [design flaw, security]
how to create a cron job on the EX4100
Automate a Batch File
Shares permissions
EX4100 becomes unresponsive, loses network
#2

We appreciate you taking the time to provide this guide.


#3

Hi,

When making changes as you mention, this will be override with a future firmware upgrade?

If for instance the changed config.xml is invalid (some mistake while closing a tag) what is the side effect, it is possible to recover without losing the precious disk content?

Changing this config.xml void the warranty, but after a software update it is possible to detect those changes?

Sorry for many questions but it seems that you have good knowledge not this :grin:

Thanks


#4

This guide is only intended to show where the system files are located and how to access them. Unfortunately, I haven’t have time to examine all the complex processes involved, so I would advise not making any changes unless you know the precise impact they might have.

In the case of an invalid config.xml file, I would strongly advise that any changes be validated prior to being applied. I’ve read about cases where an invalid config.xml file caused the dashboard to become inaccessible, but I have not tested it.


#5

So using your method are you able to save the modified config.xml back to the NAND flash - BECAUSE THAT IS how you can make changes persistent. And after reading this I am unsure if your method accomplishes that.


#6

There is no method per-se, the guide merely shows how to mount the NAND flash partitions and gives an example of copying a file from a mounted partition to a share.

It’s assumed that one will automatically know they can copy a file back to any mounted partition with read/write access. If one does not know this basic Linux fact, then they are not ready to be working with NAND flash partitions, which is why the beginning of the guide states “BASIC LINUX SKILLS AND ROOT ACCESS VIA SSH ARE REQUIRED”.


#7

Actually, I had analyzed and custom-compiled the firmware code of EX2 3 years ago…so I do know a bit more than basic Linux facts. I asked my earlier question because I did not see in your original post any mention of the NAND partitions being read/write - but I now see that it’s mentioned there…not sure if that added in of your 5 edits to the original post, or it was there from the beginning…I don’t recall seeing it there earlier when I asked my question, but it’s possible I missed it.

Anyway, good to see that you figured out what seems to be an alternate way to get the keys to the kingdom…I felt the same way 3 years ago when within a week I had hacked EX2’s code…and took the bold but risky step to custom compile it and load it on my EX2.


#8

I’ve also compiled the firmware, but must admit that my Linux/UNIX skills are a bit out of date. A home NAS is vastly different than a UNIX mainframe environment. so I’m learning as I go and sharing that knowledge with others.

The original post was last edited on the day it was posted, before there were any replies. Otherwise, I do tend to make many edits because I’m prone to making typos and I like to refine things after I write them.

Originally, I considered adding much more detail, including specific instructions about how to edit various files, but opted against it because I did not want to risk the possibility of someone blindly following instructions without knowing the consequences. If you think there is something I should add, by all means… please say so. I’m not above making additional edits.


#9

Hi @dswv42, Thank you for the outstanding insight! I’m really pissed off by not being able to add to cron simple rsync jobs for backing up the NAS to USB. As extensively explored other threads the built it solution on the dashboard never completes the task. Maybe you could show us how to do such thing by pointing out how to edit the config.xml file in the nand partition.

Thanks!


#10

As requested, I’ve edited the original post of this thread to include instructions for adding cron jobs to the config.xml file.


#11

Hi @dswv42. I own a EX4 instead of the 4100. Check out the partitions and blkid commands output:

# cat /proc/partitions

rootfs / rootfs rw 0 0
/dev/root / ext2 rw,relatime,errors=continue,user_xattr 0 0
sysfs /sys sysfs rw,relatime 0 0
mdev /dev tmpfs rw,relatime 0 0
proc /proc proc rw,relatime 0 0
cgroup_root /cgroup tmpfs rw,nosuid,nodev,noexec,relatime 0 0
memory /cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
ubi0:config /usr/local/config ubifs rw,relatime 0 0
squash /usr/local/tmp ramfs rw,relatime,size=105m 0 0
/dev/loop0 /usr/local/modules squashfs ro,relatime 0 0
tmpfs /mnt tmpfs rw,relatime,size=1024k,nr_inodes=0 0 0
tmpfs /var/log tmpfs rw,relatime,size=40960k,nr_inodes=0 0 0
tmpfs /tmp tmpfs rw,relatime,size=102400k,nr_inodes=20000 0 0
/dev/sda4 /mnt/HD_a4 ext4 rw,relatime,user_xattr,barrier=1,stripe=128,data=ordered 0 0
/dev/sdb4 /mnt/HD_b4 ext4 rw,relatime,user_xattr,barrier=1,stripe=128,data=ordered 0 0
/dev/sdd4 /mnt/HD_d4 ext4 rw,relatime,user_xattr,barrier=1,stripe=128,data=ordered 0 0
/dev/sde4 /mnt/HD_e4 ext4 rw,relatime,user_xattr,barrier=1,stripe=128,data=ordered 0 0
/dev/md1 /mnt/HD/HD_a2 ext4 rw,noatime,nodiratime,user_xattr,barrier=1,stripe=48,data=ordered,usrquota,grpquota 0 0
none /proc/bus/usb usbfs rw,relatime 0 0
/dev/sdc1 /mnt/USB/USB1_c1 ufsd rw,relatime,nls=utf8,fmask=0,dmask=0,force,user_xattr 0 0

# blkid -o list

device     fs_type label    mount point    UUID
-------------------------------------------------------------------------------
/dev/ubi0_0
           ubifs            (not mounted)  d6ecd034-8f8e-4d50-9dfd-222f985013c7
/dev/loop0 squashfs         /usr/local/modules 
/dev/sda1  linux_raid_member  (in use)     8d1319bb-64ff-3aff-ef17-b15d5db656ea
/dev/sda2  linux_raid_member 1 (in use)    79a7190c-6a6f-abfc-22ee-3092feec0922
/dev/sda4  ext4             /mnt/HD_a4     d9c223e2-0cb4-474c-9f59-69d5844e0115
/dev/sdb1  linux_raid_member  (in use)     8d1319bb-64ff-3aff-ef17-b15d5db656ea
/dev/sdb2  linux_raid_member 1 (in use)    79a7190c-6a6f-abfc-22ee-3092feec0922
/dev/sdb4  ext4             /mnt/HD_b4     809d7737-5fd4-4562-aa84-d5f0b22e31b5
/dev/sdd1  linux_raid_member  (in use)     8d1319bb-64ff-3aff-ef17-b15d5db656ea
/dev/sdd2  linux_raid_member 1 (in use)    79a7190c-6a6f-abfc-22ee-3092feec0922
/dev/sdd4  ext4             /mnt/HD_d4     2f953ec9-408d-4b00-bc4d-4a703195e699
/dev/sdc1  ntfs    Backup_RR /mnt/USB/USB1_c1 D8268EA9268E8868
/dev/sde1  linux_raid_member  (in use)     8d1319bb-64ff-3aff-ef17-b15d5db656ea
/dev/sde2  linux_raid_member 1 (in use)    79a7190c-6a6f-abfc-22ee-3092feec0922
/dev/sde4  ext4             /mnt/HD_e4     fc28f557-be9d-420f-a16f-2e12d25eb16b
/dev/md0   swap             <swap>         227ffad2-1b31-4134-9591-d60efb4d9c70
/dev/md1   ext4             /mnt/HD/HD_a2  cbbf678d-82a6-4790-b8c8-74081b801ffb

It seems that the NAND memory is mapped in ubifs by /dev/ubi0 (which is actually mounted to /usr/local/config and contains many .xml and .log files, as well as /dev/ubi0_0 which isn’t mounted.

# ls /usr/local/config/

CacheVolume
GAnalytics.xml-backup
access_lm.log
adjustTime
alert.xml
alert_email.conf
analytics_missed
certificate_https_all.pem
config.xml
dhcp6c.conf
dhcp6c.conf.bond0
dhcp6c.conf.egiga0
dhcp6c.conf.egiga1
dynamicconfig_config.ini
dynamicconfig_tmp.ini
ftp_download.xml
ga_default_flag
ganalytics
gid
gogoc.conf
group
hd_info.xml
hd_list.xml
hdd_white_list.xml
hosts
iconv_table
mail_event_conf.xml
mt-daapd.conf
mycl_id
mycloud.log
mycloud.log.1
onbrd.ini
orion.db
orion_cm.log
orion_cm.log.1
p2psettings.xml
passwd
passwd.webdav
power_schedule_info.xml
power_status
record_burn_in_fw_time
resolv.conf
routeap.conf
rtc-mfg-date.log
s3.conf
server.ca-bundle
server.crt
server.key
shadow
smbpasswd
sms_conf.xml
snmpd.conf
ssh_host_dsa_key
ssh_host_dsa_key.pub
syslog.conf
system.conf
tzmap.table
udhcpd.conf
udhcpd.conf.def
uid
usb_backup.xml
user.log
user.log.old
version.update
version_info
volume_encrypt.xml
wd_serial.txt
wdlog.conf
wdlog.filters
wdmcserver.log
wdmcserver.log.1
wdnas-rest-api.conf

I tried to mount /dev/ubi0_0 to check its contents but it yields:

# mount: /dev/ubi0_0 is not a block device

Which is as far as my superficial unix skills go :slight_smile:

Would you be interested in coaching me poke arround and dump some commands output here so we could maybe find a similar method to EX4 owners?

Regards

Rafael


#12

Sure, I’ll help if I can.

Indeed, the EX4 appears to be somewhat different than the PR4100, but you are correct. The /dev/ubi0 device mounted to /usr/local/config does appear to be where your configuration files are stored. The biggest clue is the config.xml file. However, the /dev/ubi0_0 device is interesting, and I’m not entirely certain why your attempt to mount it failed. Try mounting it with the following commands (one at a time) and see if it works.

# mkdir /tmp/ubifs_flash
# mount -t ubifs /dev/ubi0_0 /tmp/ubifs_flash
# cd /tmp/ubifs_flash
# ls -l

The EX4 flash memory uses a different type of filesystem (UBIFS) than the PR4100, and mounting it successfully will likely require different methods than the ones shown in the guide.

The following website has a lot of information about UBIFS partitions, which you may find helpful.

http://www.linux-mtd.infradead.org/faq/ubifs.html


#13

Thanks for the orientation @dswv42 !

It did mount using:

# mount -t ubifs /dev/ubi0_0 /tmp/ubifs_flash

Here is the directory listing:

CacheVolume
GAnalytics.xml-backup
access_lm.log
adjustTime
alert.xml
alert_email.conf
analytics_missed
certificate_https_all.pem
config.xml
dhcp6c.conf
dhcp6c.conf.bond0
dhcp6c.conf.egiga0
dhcp6c.conf.egiga1
dynamicconfig_config.ini
dynamicconfig_tmp.ini
ftp_download.xml
ga_default_flag
ganalytics
gid
gogoc.conf
group
hd_info.xml
hd_list.xml
hdd_white_list.xml
hosts
iconv_table
mail_event_conf.xml
mt-daapd.conf
mycl_id
mycloud.log
mycloud.log.1
onbrd.ini
orion.db
orion_cm.log
orion_cm.log.1
p2psettings.xml
passwd
passwd.webdav
power_schedule_info.xml
power_status
record_burn_in_fw_time
resolv.conf
routeap.conf
rtc-mfg-date.log
s3.conf
server.ca-bundle
server.crt
server.key
shadow
smbpasswd
sms_conf.xml
snmpd.conf
ssh_host_dsa_key
ssh_host_dsa_key.pub
syslog.conf
system.conf
tzmap.table
udhcpd.conf
udhcpd.conf.def
uid
usb_backup.xml
user.log
user.log.old
version.update
version_info
volume_encrypt.xml
wd_serial.txt
wdlog.conf
wdlog.filters
wdmcserver.log
wdmcserver.log.1
wdnas-rest-api.conf

Which seems to be exactly the same contents of:

> ubi0:config /usr/local/config ubifs rw,relatime 0 0

I wonder if the OS loads content from that partition on boot, which would be logically similar to the PR4100 or if it has some different behavior considering that ubi0 is permanently mounted during normal operation.

Would you like me to check some file contents within that directory, or maybe devise a test by adding a basic edit to the config.xml files in those partitions and performing reboots?


#14

It’s difficult to say for certain, but of the two UBIFS devices, I suspect that /dev/ubi0 may be a configuration partition, and /dev/ubi0_0 may be a backup partition. It should be fairly easy to determine which is which, especially since there are only two choices.

First, the file dates for the configuration partition are likely to be newer than those on the backup partition. Second, one could perform a simple test by adding a cron job to the config.xml file (as shown in the guide) in the /dev/ubi0 partition. If it’s the configuration partition, a new cron job should appear in the crontab after the NAS is rebooted. The following command will list the contents of the crontab file.

# crontab -l

My PR4100 NAS has a similar setup, where there are configuration and backup partitions.


#15

Timestamps:

root@WDMyCloudEX4 root # ls -lh /usr/local/config/config.xml
-rwxr-xr-x    1 root     root       11.6K Apr 10 00:00 /usr/local/config/config.xml
root@WDMyCloudEX4 root # mount -t ubifs /dev/ubi0_0 /tmp/nand
root@WDMyCloudEX4 root # ls -lh /tmp/nand/config.xml
-rwxr-xr-x    1 root     root       11.6K Apr 10 00:00 /tmp/nand/config.xml
root@WDMyCloudEX4 root # ls -lh /usr/local/modules/default/config.xml
-rwxrwxr-x    1 root     root       10.6K Mar 21 07:30 /usr/local/modules/default/config.xml
root@WDMyCloudEX4 root # ls -lh /etc/NAS_CFG/config.xml
-rwxr-xr-x    1 root     root       11.6K Apr 10 00:00 /etc/NAS_CFG/config.xml
root@WDMyCloudEX4 root #

By the way, the <crond></crond> section in config.xml file structure in EX4 is exactly the same as your example extracted from PR4100. You won’t need to make any observations in the main guide on that regard.What is odd is that the <list> structure has 11 entries and the <count> number is 6, which seems a bit strange.

Except for the supposedly failback config.xml file you mentioned, they are all the same date / time. I wonder which one is the main partition and which one is the backup file. So I added slightly different cron jobs to each file and rebooted to find out.

:grimacing: tension :grimacing:

It did not brick! :relieved:

And the winner is…

/dev/ubi0_0 :astonished:

As it turns out the persistent config.xml file comes from the unmounted partition, similar behavior to PR4100 except it is far more simple since it only has one partition for that purpose.

With this I guess we can affirm that for EX4, and maybe EX2 and similar, in order to make persistent system changes you have to edit config.xml inside /dev/ubi0_0

Thank you for your help @dswv42 :clap: :+1:

As a follow up test, maybe someone who owns EX2 and other hardware versions could verify if the information we provided for PR4100 and EX4 covers all possible variations.


#16

I had a 50/50 chance of being right, and I’m actually glad I was wrong because it helps to illustrate the concept of trial and error. We can’t learn if we never make mistakes.

Regardless, I’m glad it worked for you. It will also help to expand the knowledge base for everyone, above and beyond the often meaningless trite offered by Western Digital.


#17

I finally decided to take a chance and update my WD PR4100 NAS to firmware version 2.30.165. I was curious to see if the test cron job I added to the config.xml file would survive the firmware update process, and I’m pleased to say that it does.

# crontab -l

0 3 * * * /usr/sbin/daily_log_upload.sh &
0 3 * * * /usr/sbin/traceroute_wd.sh &
*/30 * * * * /usr/sbin/quota_monitor &
0 */4 * * * /usr/sbin/rlog -s /usr/local/modules/files/syslog_rotate.conf
01 */8 * * * [ -f /etc/init.d/atop ] && /etc/init.d/atop rotate
30 0 * * * /usr/local/sbin/ssl_cert_job.sh start > /var/log/ssl_cert_cron.out 2>&1
58 2 * * * /usr/local/sbin/PullWdlogConfig.sh
30 0 * * 1 logwdmsg -e &
0 3 * * * logwdmsg -o &
01 3 * * * /usr/local/sbin/LogDataSize.sh
00 3 * * * /usr/sbin/wd_rotate.sh
30 0 * * 1 /usr/sbin/wdappmgr_log_stats.py > /dev/null 2>&1 &
30 2 * * * /usr/sbin/stime&
0 3 * * * wd_crontab.sh&
0 4 * * * auto_fw -a -c&
0 0 * * * auto_clear_recycle_bin.sh &
30 3 * * * /usr/sbin/chk_wfs_download&
* * * * * date >> /shares/Public/test.txt &
0 0 * * * random_check -s &
13 10 * * * auto_fw -c 1 &
0 0 * * * expire.sh
* * * * * sysinfo_update.sh
0 3 * * 1 getHddWhiteList.sh

The * * * * * date >> /shares/Public/test.txt & test cron job I added to the config.xml file has been running for 1737 minutes (28.95 hours), as evidenced by the timestamps added to the text file it created. This means that the test cron job has also survived any processes which may be triggered by other cron jobs, except for the two cron jobs which run every Monday (once a week), but they appear to only affect system logs.

Time to end the test so my drive can sleep.


#18

Gentlemen, pardon the intrusion in this thread, but I am really at a loss here, with my MyCloud Mirror and this thread is the only thing that was suggested to me, for help (and it might very well help me).

The problem I am facing with my NAS, is that all shares created have permissions of 777. In other words, open widely to the public. Obviously, I can change the permissions, after the shares are created, but every file copied to them will get 777 permissions. If I manually edit /etc/netatalk/afp.conf, and restart the corresponding processes, files copied to the shares do get the proper permissions I want, but the file /etc/netatalk/afp.conf, gets rewritten whenever the NAS is rebooted.

I followed this thread and mounted /dev/ubi0_0 and went through it, but I can’t find anything related to netatalk and afp, either in config.xml or any other .xml file in there.

Do you guys have any idea where I can intervene to change the afp.conf file, permanently?

Many thanks!


#19

The changes you need to make would require making modifications to the root filesystem, which is stored in a special RAMDisk image file named uRamdisk. The uRamdisk file contains a read only SquashFS filesystem which is loaded when the system boots. The Linux Kernel is loaded from a file named uImage. The MyCloud Mirror has many differences from the My Cloud PR4100, so I can’t tell you exactly which flash partitions the uRamdisk and uImage files are stored on.

WARNING: Making modifications to the root filesystem requires advanced skills which are far beyond the scope of this guide. Extreme caution is advised.


#20

MANY THANKS for your reply, really appreciated!

One question, which perhaps can help me, without the need to access the SquashFS.

After the system is booted, can I just copy a modified afp.conf file to /etc/netatalk? The reason I am asking, is because if I manually change afp.conf file, after the system is booted, but before I mount the shares on my Mac, the system uses whatever permissions I have defined in the modified afp.conf. So I could -theoretically- save a modified afp.conf in one of my shares and copy that to /etc/netatalk before mounting the shares and have the proper permissions used.