1 /* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2
3 libparted - a library for manipulating disk partitions
4 Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 Contributor: Matt Wilson <msw@redhat.com>
20 */
21
22 #include <config.h>
23
24 #include <parted/parted.h>
25 #include <parted/debug.h>
26 #include <parted/endian.h>
27
28 #if ENABLE_NLS
29 # include <libintl.h>
30 # define _(String) dgettext (PACKAGE, String)
31 #else
32 # define _(String) (String)
33 #endif /* ENABLE_NLS */
34
35 #define AIX_LABEL_MAGIC 0xc9c2d4c1
36
37 static PedDiskType aix_disk_type;
38
39 static inline int
aix_label_magic_get(const char * label)40 aix_label_magic_get (const char *label)
41 {
42 return *(unsigned int *)label;
43 }
44
45 static inline void
aix_label_magic_set(char * label,int magic_val)46 aix_label_magic_set (char *label, int magic_val)
47 {
48 *(unsigned int *)label = magic_val;
49 }
50
51 /* Read a single sector, of length DEV->sector_size, into malloc'd storage.
52 If the read fails, free the memory and return zero without modifying *BUF.
53 Otherwise, set *BUF to the new buffer and return 1. */
54 static int
read_sector(const PedDevice * dev,char ** buf)55 read_sector (const PedDevice *dev, char **buf)
56 {
57 char *b = ped_malloc (dev->sector_size);
58 PED_ASSERT (b != NULL, return 0);
59 if (!ped_device_read (dev, b, 0, 1)) {
60 ped_free (b);
61 return 0;
62 }
63 *buf = b;
64 return 1;
65 }
66
67 static int
aix_probe(const PedDevice * dev)68 aix_probe (const PedDevice *dev)
69 {
70 PED_ASSERT (dev != NULL, return 0);
71
72 char *label;
73 if (!read_sector (dev, &label))
74 return 0;
75 unsigned int magic = aix_label_magic_get (label);
76 ped_free (label);
77 return magic == AIX_LABEL_MAGIC;
78 }
79
80 #ifndef DISCOVER_ONLY
81 static int
aix_clobber(PedDevice * dev)82 aix_clobber (PedDevice* dev)
83 {
84 PED_ASSERT (dev != NULL, return 0);
85
86 if (!aix_probe (dev))
87 return 0;
88
89 char *label;
90 if (!read_sector (dev, &label))
91 return 0;
92
93 aix_label_magic_set (label, 0);
94 int result = ped_device_write (dev, label, 0, 1);
95 ped_free (label);
96 return result;
97 }
98 #endif /* !DISCOVER_ONLY */
99
100 static PedDisk*
aix_alloc(const PedDevice * dev)101 aix_alloc (const PedDevice* dev)
102 {
103 PedDisk* disk;
104
105 disk = _ped_disk_alloc (dev, &aix_disk_type);
106 if (!disk)
107 return NULL;
108
109 return disk;
110 }
111
112 static PedDisk*
aix_duplicate(const PedDisk * disk)113 aix_duplicate (const PedDisk* disk)
114 {
115 PedDisk* new_disk;
116
117 new_disk = ped_disk_new_fresh (disk->dev, &aix_disk_type);
118 if (!new_disk)
119 return NULL;
120
121 return new_disk;
122 }
123
124 static void
aix_free(PedDisk * disk)125 aix_free (PedDisk *disk)
126 {
127 _ped_disk_free (disk);
128 }
129
130 static int
aix_read(PedDisk * disk)131 aix_read (PedDisk* disk)
132 {
133 ped_disk_delete_all (disk);
134 ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
135 PED_EXCEPTION_CANCEL,
136 _("Support for reading AIX disk labels is "
137 "is not implemented yet."));
138 return 0;
139 }
140
141 #ifndef DISCOVER_ONLY
142 static int
aix_write(const PedDisk * disk)143 aix_write (const PedDisk* disk)
144 {
145 ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
146 PED_EXCEPTION_CANCEL,
147 _("Support for writing AIX disk labels is "
148 "is not implemented yet."));
149 return 0;
150 }
151 #endif /* !DISCOVER_ONLY */
152
153 static PedPartition*
aix_partition_new(const PedDisk * disk,PedPartitionType part_type,const PedFileSystemType * fs_type,PedSector start,PedSector end)154 aix_partition_new (const PedDisk* disk, PedPartitionType part_type,
155 const PedFileSystemType* fs_type,
156 PedSector start, PedSector end)
157 {
158 ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
159 PED_EXCEPTION_CANCEL,
160 _("Support for adding partitions to AIX disk "
161 "labels is not implemented yet."));
162 return NULL;
163 }
164
165 static PedPartition*
aix_partition_duplicate(const PedPartition * part)166 aix_partition_duplicate (const PedPartition* part)
167 {
168 ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
169 PED_EXCEPTION_CANCEL,
170 _("Support for duplicating partitions in AIX "
171 "disk labels is not implemented yet."));
172 return NULL;
173 }
174
175 static void
aix_partition_destroy(PedPartition * part)176 aix_partition_destroy (PedPartition* part)
177 {
178 PED_ASSERT (part != NULL, return);
179
180 _ped_partition_free (part);
181 }
182
183 static int
aix_partition_set_system(PedPartition * part,const PedFileSystemType * fs_type)184 aix_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
185 {
186 ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
187 PED_EXCEPTION_CANCEL,
188 _("Support for setting system type of partitions "
189 "in AIX disk labels is not implemented yet."));
190 return 0;
191 }
192
193 static int
aix_partition_set_flag(PedPartition * part,PedPartitionFlag flag,int state)194 aix_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
195 {
196 ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
197 PED_EXCEPTION_CANCEL,
198 _("Support for setting flags "
199 "in AIX disk labels is not implemented yet."));
200 return 0;
201 }
202
203 static int
aix_partition_get_flag(const PedPartition * part,PedPartitionFlag flag)204 aix_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
205 {
206 return 0;
207 }
208
209
210 static int
aix_partition_is_flag_available(const PedPartition * part,PedPartitionFlag flag)211 aix_partition_is_flag_available (const PedPartition* part,
212 PedPartitionFlag flag)
213 {
214 return 0;
215 }
216
217
218 static int
aix_get_max_primary_partition_count(const PedDisk * disk)219 aix_get_max_primary_partition_count (const PedDisk* disk)
220 {
221 return 4;
222 }
223
224 static int
aix_partition_align(PedPartition * part,const PedConstraint * constraint)225 aix_partition_align (PedPartition* part, const PedConstraint* constraint)
226 {
227 PED_ASSERT (part != NULL, return 0);
228
229 return 1;
230 }
231
232 static int
aix_partition_enumerate(PedPartition * part)233 aix_partition_enumerate (PedPartition* part)
234 {
235 return 1;
236 }
237
238 static int
aix_alloc_metadata(PedDisk * disk)239 aix_alloc_metadata (PedDisk* disk)
240 {
241 return 1;
242 }
243
244 static PedDiskOps aix_disk_ops = {
245 .probe = aix_probe,
246 #ifndef DISCOVER_ONLY
247 .clobber = aix_clobber,
248 #else
249 .clobber = NULL,
250 #endif
251 .alloc = aix_alloc,
252 .duplicate = aix_duplicate,
253 .free = aix_free,
254 .read = aix_read,
255 #ifndef DISCOVER_ONLY
256 .write = aix_write,
257 #else
258 .write = NULL,
259 #endif
260
261 .partition_new = aix_partition_new,
262 .partition_duplicate = aix_partition_duplicate,
263 .partition_destroy = aix_partition_destroy,
264 .partition_set_system = aix_partition_set_system,
265 .partition_set_flag = aix_partition_set_flag,
266 .partition_get_flag = aix_partition_get_flag,
267 .partition_is_flag_available = aix_partition_is_flag_available,
268 .partition_align = aix_partition_align,
269 .partition_enumerate = aix_partition_enumerate,
270 .alloc_metadata = aix_alloc_metadata,
271 .get_max_primary_partition_count =
272 aix_get_max_primary_partition_count,
273
274 .partition_set_name = NULL,
275 .partition_get_name = NULL,
276 };
277
278 static PedDiskType aix_disk_type = {
279 .next = NULL,
280 .name = "aix",
281 .ops = &aix_disk_ops,
282 .features = 0
283 };
284
285 void
ped_disk_aix_init()286 ped_disk_aix_init ()
287 {
288 ped_disk_type_register (&aix_disk_type);
289 }
290
291 void
ped_disk_aix_done()292 ped_disk_aix_done ()
293 {
294 ped_disk_type_unregister (&aix_disk_type);
295 }
296